1
+ /*
2
+ * OBD-II-UART Quickstart Sketch
3
+ * Written by Ryan Owens for SparkFun Electronics 7/5/2011
4
+ * Updates for Arduino 1.0+ by Toni Klopfenstein
5
+ *
6
+ * Released under the 'beerware' license
7
+ * (Do what you want with the code, but if we ever meet then you buy me a beer)
8
+ *
9
+ * This sketch will grab RPM and Vehicle Speed data from a vehicle with an OBD port
10
+ * using the OBD-II-UART board from SparkFun electronics. The data will be displayed
11
+ * on a serial 16x2 LCD. See the tutorial at https://www.sparkfun.com/tutorials/294
12
+ * to learn how to hook up the hardware:
13
+ *
14
+ */
15
+
16
+ #include < SoftwareSerial.h>
17
+
18
+ // Create an instance of the new soft serial library to control the serial LCD
19
+ // Note, digital pin 3 of the Arduino should be connected to Rx of the serial LCD.
20
+
21
+ SoftwareSerial lcd (2 ,3 );
22
+
23
+ // This is a character buffer that will store the data from the serial port
24
+ char rxData[20 ];
25
+ char rxIndex=0 ;
26
+
27
+ // Variables to hold the speed and RPM data.
28
+ int vehicleSpeed=0 ;
29
+ int vehicleRPM=0 ;
30
+
31
+ void setup (){
32
+ // Both the Serial LCD and the OBD-II-UART use 9600 bps.
33
+ lcd.begin (9600 );
34
+ Serial.begin (9600 );
35
+
36
+ // Clear the old data from the LCD.
37
+ lcd.write (254 );
38
+ lcd.write (1 );
39
+
40
+ // Put the speed header on the first row.
41
+ lcd.print (" Speed: " );
42
+ lcd.write (254 );
43
+ // Put the RPM header on the second row.
44
+ lcd.write (128 +64 );
45
+ lcd.print (" RPM: " );
46
+
47
+ // Wait for a little while before sending the reset command to the OBD-II-UART
48
+ delay (1500 );
49
+ // Reset the OBD-II-UART
50
+ Serial.println (" ATZ" );
51
+ // Wait for a bit before starting to send commands after the reset.
52
+ delay (2000 );
53
+
54
+ // Delete any data that may be in the serial port before we begin.
55
+ Serial.flush ();
56
+ }
57
+
58
+ void loop (){
59
+ // Delete any data that may be in the serial port before we begin.
60
+ Serial.flush ();
61
+ // Set the cursor in the position where we want the speed data.
62
+ lcd.write (254 );
63
+ lcd.write (128 +8 );
64
+ // Clear out the old speed data, and reset the cursor position.
65
+ lcd.print (" " );
66
+ lcd.write (254 );
67
+ lcd.write (128 +8 );
68
+ // Query the OBD-II-UART for the Vehicle Speed
69
+ Serial.println (" 010D" );
70
+ // Get the response from the OBD-II-UART board. We get two responses
71
+ // because the OBD-II-UART echoes the command that is sent.
72
+ // We want the data in the second response.
73
+ getResponse ();
74
+ getResponse ();
75
+ // Convert the string data to an integer
76
+ vehicleSpeed = strtol (&rxData[6 ],0 ,16 );
77
+ // Print the speed data to the lcd
78
+ lcd.print (vehicleSpeed);
79
+ lcd.print (" km/h" );
80
+ delay (100 );
81
+
82
+ // Delete any data that may be left over in the serial port.
83
+ Serial.flush ();
84
+ // Move the serial cursor to the position where we want the RPM data.
85
+ lcd.write (254 );
86
+ lcd.write (128 + 69 );
87
+ // Clear the old RPM data, and then move the cursor position back.
88
+ lcd.print (" " );
89
+ lcd.write (254 );
90
+ lcd.write (128 +69 );
91
+
92
+ // Query the OBD-II-UART for the Vehicle rpm
93
+ Serial.println (" 010C" );
94
+ // Get the response from the OBD-II-UART board
95
+ getResponse ();
96
+ getResponse ();
97
+ // Convert the string data to an integer
98
+ // NOTE: RPM data is two bytes long, and delivered in 1/4 RPM from the OBD-II-UART
99
+ vehicleRPM = ((strtol (&rxData[6 ],0 ,16 )*256 )+strtol (&rxData[9 ],0 ,16 ))/4 ;
100
+ // Print the rpm data to the lcd
101
+ lcd.print (vehicleRPM);
102
+
103
+ // Give the OBD bus a rest
104
+ delay (100 );
105
+
106
+ }
107
+
108
+ // The getResponse function collects incoming data from the UART into the rxData buffer
109
+ // and only exits when a carriage return character is seen. Once the carriage return
110
+ // string is detected, the rxData buffer is null terminated (so we can treat it as a string)
111
+ // and the rxData index is reset to 0 so that the next string can be copied.
112
+ void getResponse (void ){
113
+ char inChar=0 ;
114
+ // Keep reading characters until we get a carriage return
115
+ while (inChar != ' \r ' ){
116
+ // If a character comes in on the serial port, we need to act on it.
117
+ if (Serial.available () > 0 ){
118
+ // Start by checking if we've received the end of message character ('\r').
119
+ if (Serial.peek () == ' \r ' ){
120
+ // Clear the Serial buffer
121
+ inChar=Serial.read ();
122
+ // Put the end of string character on our data string
123
+ rxData[rxIndex]=' \0 ' ;
124
+ // Reset the buffer index so that the next character goes back at the beginning of the string.
125
+ rxIndex=0 ;
126
+ }
127
+ // If we didn't get the end of message character, just add the new character to the string.
128
+ else {
129
+ // Get the new character from the Serial port.
130
+ inChar = Serial.read ();
131
+ // Add the new character to the string, and increment the index variable.
132
+ rxData[rxIndex++]=inChar;
133
+ }
134
+ }
135
+ }
136
+ }
0 commit comments