Guest User

Untitled

a guest
Feb 9th, 2020
1,010
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.28 KB | None | 0 0
  1. // ToyotaOBD1_Reader
  2. // In order to read the data from the OBD connector, short E1 + TE2. then to read the data connect to VF1.
  3. // Note the data line output is 12V - connecting it directly to one of the arduino pins might damage (proabably) the board
  4. // This is made for diaply with an OLED display using the U8glib - which allow wide range of display types with minor adjusments.
  5. // Many thanks to GadgetFreak for the greate base code for the reasding of the data.
  6. // If you want to use invert line - note the comments on the MY_HIGH and the INPUT_PULLUP in the SETUP void.
  7.  
  8. // display
  9. //#include "U8glib.h"
  10. //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
  11. #include <Wire.h>
  12. #include <LiquidCrystal_I2C.h>
  13. LiquidCrystal_I2C lcd(0x27,20,4);
  14. // for debug option - swith output to Serial
  15. #define DEBUG_OUTPUT true
  16. #define ENGINE_DATA_PIN 2 // pin 2
  17. #define ENGINE_DATA_INT 0 // for attachInterrupt
  18. #define LED_PIN 13
  19.  
  20. // I have inverted the Eng line using an Opto-Coupler, if yours isn't then reverse these low & high defines.
  21. #define MY_HIGH HIGH //LOW
  22. #define MY_LOW LOW //HIGH
  23.  
  24. #define TOYOTA_MAX_BYTES 24
  25. volatile uint8_t ToyotaNumBytes, ToyotaID;
  26. volatile uint8_t ToyotaData[TOYOTA_MAX_BYTES];
  27. volatile uint16_t ToyotaFailBit = 0;
  28.  
  29.  
  30. // "names" for the OND data to make life easier
  31. #define OBD_INJ 1 //Injector pulse width (INJ)
  32. #define OBD_IGN 2 //Ignition timing angle (IGN)
  33. #define OBD_IAC 3 //Idle Air Control (IAC)
  34. #define OBD_RPM 4 //Engine speed (RPM)
  35. #define OBD_MAP 5 //Manifold Absolute Pressure (MAP)
  36. #define OBD_ECT 6 //Engine Coolant Temperature (ECT)
  37. #define OBD_TPS 7 // Throttle Position Sensor (TPS)
  38. #define OBD_SPD 8 //Speed (SPD)
  39.  
  40. // dfeine connection flag and last success packet - for lost connection function.
  41. boolean OBDConnected;
  42. unsigned long OBDLastSuccessPacket;
  43.  
  44. #define TOGGLE_BTN_PIN 3
  45. #define TOGGLE_BTN_INT 1
  46. int CurrentDisplayIDX;
  47.  
  48. // VOID SETUP
  49. void setup() {
  50. Serial.begin(9600);//115200
  51. lcd.init();
  52. lcd.backlight();
  53. if (DEBUG_OUTPUT) {
  54. Serial.println("system Started");}
  55.  
  56. // Display no connection
  57. displayNoConnection();
  58.  
  59. // setup input and output pins
  60. pinMode(ENGINE_DATA_PIN, INPUT); // _PULLUP
  61. pinMode(LED_PIN, OUTPUT);
  62. //setup Interrupt for data line
  63. attachInterrupt(ENGINE_DATA_INT, ChangeState, CHANGE);
  64.  
  65. //setup button
  66. pinMode(TOGGLE_BTN_PIN, INPUT);
  67. attachInterrupt(TOGGLE_BTN_INT, ButtonChangeState, CHANGE);
  68.  
  69. // Set OBD to not connected
  70. OBDConnected=false;
  71. CurrentDisplayIDX = 1; // set to display 1
  72. } // END VOID SETUP
  73.  
  74.  
  75. // VOID LOOP
  76. void loop() {
  77. //lcd.clear();
  78. lcd.setCursor(0,0);
  79. lcd.print("0");
  80. Serial.print("loop");
  81. // if found bytes
  82. if (ToyotaNumBytes > 0) {
  83. Serial.print("if tnb");
  84. lcd.setCursor(1,0);
  85. lcd.print("1");
  86. if (DEBUG_OUTPUT) {
  87. Serial.print("if do");
  88. lcd.setCursor(2,0);
  89. lcd.print("2");
  90. debugdataoutput(); }
  91. // draw screen
  92.  
  93. Serial.print(int(getOBDdata(OBD_SPD)));
  94. lcd.setCursor(0,1);
  95. lcd.print(int(getOBDdata(OBD_SPD)));
  96.  
  97. Serial.print(int(getOBDdata(OBD_MAP)));
  98. lcd.setCursor(8,1);
  99. lcd.print(int(getOBDdata(OBD_MAP)));
  100.  
  101. // set last success
  102. OBDLastSuccessPacket = millis();
  103. // set connected to true
  104. OBDConnected = true;
  105. // reset the counter.
  106. ToyotaNumBytes = 0;
  107. } // end if (ToyotaNumBytes > 0)
  108.  
  109. // if found FAILBIT and dbug
  110. if (ToyotaFailBit > 0 && DEBUG_OUTPUT ) {
  111. Serial.print("found fb and db");
  112. lcd.setCursor(3,0);
  113. lcd.print("3"); debugfaildataoutput(); }
  114.  
  115. //check for lost connection
  116. if (OBDLastSuccessPacket + 3500 < millis() && OBDConnected) {
  117. Serial.print("last packet");
  118. lcd.setCursor(4,0);
  119. lcd.print("4");
  120. // show no connection
  121. displayNoConnection();
  122. // set OBDConnected to false.
  123. OBDConnected = false;
  124. } // end if loas conntcion
  125.  
  126. } // end void loop
  127.  
  128.  
  129. // VOID drawScreenSelector()
  130. /*void drawScreenSelector() {
  131. if (CurrentDisplayIDX == 1){
  132. drawSpeedRpm();
  133. } else if (CurrentDisplayIDX == 2){
  134. drawAllData();
  135. } else if (CurrentDisplayIDX == 3){
  136. drawFlagsBinnary();
  137. }
  138. } // end drawScreenSelector()
  139. */
  140. //void drawFlagsBinnary() {
  141. // graphic commands to redraw the complete screen should be placed here
  142. //u8g.setFont(u8g_font_osr18);
  143.  
  144. // picture loop
  145. //u8g.firstPage();
  146. //do {
  147. //u8g.setPrintPos(0, 17) ;
  148. //u8g.print( int(getOBDdata(11)),BIN);
  149. //u8g.setPrintPos(0, 50) ;
  150. //u8g.print( int(getOBDdata(12)),BIN);
  151. //} while( u8g.nextPage() ); // end picture loop
  152. //} // end void
  153. /*
  154. void drawAllData() {
  155. // graphic commands to redraw the complete screen should be placed here
  156. u8g.setFont(u8g_font_unifont);
  157.  
  158. // picture loop
  159. u8g.firstPage();
  160. do {
  161. u8g.drawStr( 0, 17, "INJ" );
  162. u8g.setPrintPos(25, 17) ;
  163. u8g.print( getOBDdata(OBD_INJ));
  164.  
  165. u8g.drawStr( 0, 32, "IGN");
  166. u8g.setPrintPos(25, 32) ;
  167. u8g.print( int(getOBDdata(OBD_IGN)));
  168.  
  169. u8g.drawStr( 0, 47, "IAC");
  170. u8g.setPrintPos(25, 47) ;
  171. u8g.print( int(getOBDdata(OBD_IAC)));
  172.  
  173. u8g.drawStr( 0, 62, "RPM");
  174. u8g.setPrintPos(25, 62) ;
  175. u8g.print( int(getOBDdata(OBD_RPM)));
  176.  
  177. u8g.drawStr( 65, 17, "MAP" );
  178. u8g.setPrintPos(92, 17) ;
  179. u8g.print( int(getOBDdata(OBD_MAP)));
  180.  
  181. u8g.drawStr( 65, 32, "ECT");
  182. u8g.setPrintPos(92, 32) ;
  183. u8g.print( int(getOBDdata(OBD_ECT)));
  184.  
  185. u8g.drawStr( 65, 47, "TPS");
  186. u8g.setPrintPos(92, 47) ;
  187. u8g.print( int(getOBDdata(OBD_TPS)));
  188.  
  189. u8g.drawStr( 65, 62, "SPD");
  190. u8g.setPrintPos(92, 62) ;
  191. u8g.print( int(getOBDdata(OBD_SPD)));
  192.  
  193. u8g.drawVLine(63, 0, 64);
  194. } while( u8g.nextPage() ); // end picture loop
  195. } // end void drawalldata
  196.  
  197. */
  198. // VOID DRAWSPEEDRPM
  199. /*void drawSpeedRpm() {
  200.  
  201. // define setytings for screen
  202. u8g.setFont(u8g_font_osb35n);
  203. u8g.setFontRefHeightExtendedText();
  204. u8g.setDefaultForegroundColor();
  205. u8g.setFontPosTop();
  206.  
  207. // convert into to char so we can get the width
  208. char buf[4];
  209. itoa (int(getOBDdata(OBD_SPD)), buf, 10);
  210.  
  211. // "calc" rpm bars to diaply - MAX 14
  212. int rpmToDisplay = int (float(getOBDdata(OBD_RPM))/500);// calc the rpm bars then check to add +1 if pased the +250
  213. if (double(double(getOBDdata(OBD_RPM))/500.0) - int(getOBDdata(OBD_RPM)/500) > 0.5) {
  214. rpmToDisplay += 1;
  215. } // end if
  216.  
  217. // picture loop
  218. u8g.firstPage();
  219. do {
  220. // draw box
  221. u8g.drawRFrame(20,4,90, 48,7);
  222. // print speed
  223. u8g.drawStr(int(108-u8g.getStrWidth(buf)),10, buf);
  224.  
  225. // draw RPM
  226. for (int i=0; i<rpmToDisplay; i++) {
  227. u8g.drawBox(20+((4+1)*i) + i, 55,4,8);
  228. } // end for
  229. } while( u8g.nextPage() ); // end picture loop
  230.  
  231. } //end void drawSpeedRpm()
  232.  
  233. // NO CONNECTION VOID
  234. */
  235. void displayNoConnection() { lcd.setCursor(5,0);
  236. lcd.print("5");
  237. Serial.print("noco");}
  238. /*
  239. u8g.setFont(u8g_font_courB12r);
  240. u8g.setFontRefHeightExtendedText();
  241. u8g.setDefaultForegroundColor();
  242. u8g.setFontPosTop();
  243. // picture loop
  244. u8g.firstPage();
  245. do {
  246. // draw box
  247. u8g.drawRFrame(0,0,127, 63,7);
  248. u8g.drawStr(15,25, "NO SIGNAL");
  249. } while( u8g.nextPage() );
  250.  
  251. } // end void
  252. */
  253.  
  254. // GET DATA FROM OBD
  255. float getOBDdata(int OBDdataIDX) {
  256. // define return value
  257. float returnValue;
  258. switch (OBDdataIDX) {
  259. case 0:// UNKNOWN
  260. returnValue = ToyotaData[0];
  261. break;
  262. case OBD_INJ: // Injector pulse width (INJ) - in milisec
  263. returnValue = ToyotaData[OBD_INJ]/10;
  264. break;
  265. case OBD_IGN: // Ignition timing angle (IGN) - degree- BTDC
  266. returnValue = ToyotaData[OBD_IGN]-90;
  267. break;
  268. case OBD_IAC: //Idle Air Control (IAC) - Step # X = 125 = open 100%
  269. returnValue = ToyotaData[OBD_IAC]/125*100;
  270. break;
  271. case OBD_RPM: //Engine speed (RPM)
  272. returnValue = ToyotaData[OBD_RPM]*25;
  273. break;
  274. case OBD_MAP: //Manifold Absolute Pressure (MAP) - kPa Abs
  275. returnValue = ToyotaData[OBD_MAP];
  276. break;
  277. case OBD_ECT: // Engine Coolant Temperature (ECT)
  278. if (ToyotaData[OBD_ECT] >= 244)
  279. returnValue = ((float)(ToyotaData[OBD_ECT] - 244) * 10.0) + 132.0;
  280. else if (ToyotaData[OBD_ECT] >= 238)
  281. returnValue = ((float)(ToyotaData[OBD_ECT] - 238) * 4.0) + 103.0;
  282. else if (ToyotaData[OBD_ECT] >= 228)
  283. returnValue = ((float)(ToyotaData[OBD_ECT] - 228) * 2.1) + 80.0;
  284. else if (ToyotaData[OBD_ECT] >= 210)
  285. returnValue = ((float)(ToyotaData[OBD_ECT] - 210) * 1.11) + 60.0;
  286. else if (ToyotaData[OBD_ECT] >= 180)
  287. returnValue = ((float)(ToyotaData[OBD_ECT] - 180) * 0.666) + 40.0;
  288. else if (ToyotaData[OBD_ECT] >= 135)
  289. returnValue = ((float)(ToyotaData[OBD_ECT] - 135) * 0.444) + 20.0;
  290. else if (ToyotaData[OBD_ECT] >= 82)
  291. returnValue = ((float)(ToyotaData[OBD_ECT] - 82) * 0.377) + 0.0;
  292. else if (ToyotaData[OBD_ECT] >= 39)
  293. returnValue = ((float)(ToyotaData[OBD_ECT] - 39) * 0.465) + (-20.0);
  294. else if (ToyotaData[OBD_ECT] >= 15)
  295. returnValue = ((float)(ToyotaData[OBD_ECT] - 15) * 0.833) + (-40.0);
  296. else
  297. returnValue = ((float)ToyotaData[OBD_ECT] * 2.0) + (-70.0);
  298.  
  299. break;
  300. case OBD_TPS: // Throttle Position Sensor (TPS) - DEGREE
  301. returnValue = ToyotaData[OBD_TPS]/2;
  302. break;
  303. case OBD_SPD: // Speed (SPD) - km/h
  304. returnValue = ToyotaData[OBD_SPD];
  305. break;
  306. case 9:// UNKNOWN
  307. returnValue = ToyotaData[9];
  308. break;
  309. case 10:// UNKNOWN
  310. returnValue = ToyotaData[10];
  311. break;
  312. case 11:// FLAG #1
  313. returnValue = ToyotaData[11];
  314. break;
  315. case 12:// FLAG # 2
  316. returnValue = ToyotaData[12];
  317. break;
  318. default: // DEFAULT CASE (in no match to number)
  319. // send "error" value
  320. returnValue = 9999.99;
  321. } // end switch
  322. // send value back
  323. return returnValue;
  324. } // end void getOBDdata
  325.  
  326.  
  327.  
  328. // VOID ButtonChangeState
  329. void ButtonChangeState() {/*
  330. int buttonState = digitalRead(TOGGLE_BTN_PIN);
  331. // only on HIGH ((press) and OBDConnected = true
  332. if (buttonState &&OBDConnected ) {
  333. CurrentDisplayIDX +=1;
  334. if (CurrentDisplayIDX > 3) {
  335. CurrentDisplayIDX = 1;}
  336. // all screen chnage
  337. drawScreenSelector();
  338. } // end if
  339. */
  340. } // end void ButtonChangeState()
  341.  
  342.  
  343. // VOID CHANGE
  344. void ChangeState()
  345. {
  346. //Serial.print(digitalRead(ENGINE_DATA_PIN));
  347. static uint8_t ID, EData[TOYOTA_MAX_BYTES];
  348. static boolean InPacket = false;
  349. static unsigned long StartMS;
  350. static uint16_t BitCount;
  351.  
  352. int state = digitalRead(ENGINE_DATA_PIN);
  353. digitalWrite(LED_PIN, state);
  354.  
  355. if (InPacket == false) {
  356. if (state == MY_HIGH) {
  357. StartMS = millis();
  358. } else { // else if (state == MY_HIGH)
  359. if ((millis() - StartMS) > (15 * 8)) {
  360. StartMS = millis();
  361. InPacket = true;
  362. BitCount = 0;
  363. } // end if ((millis() - StartMS) > (15 * 8))
  364. } // end if (state == MY_HIGH)
  365. } else { // else if (InPacket == false)
  366. uint16_t bits = ((millis() - StartMS)+1 ) / 8; // The +1 is to cope with slight time errors
  367. StartMS = millis();
  368. // process bits
  369. while (bits > 0) {
  370. if (BitCount < 4) {
  371. if (BitCount == 0)
  372. ID = 0;
  373. ID >>= 1;
  374. if (state == MY_LOW) // inverse state as we are detecting the change!
  375. ID |= 0x08;
  376. } else { // else if (BitCount < 4)
  377. uint16_t bitpos = (BitCount - 4) % 11;
  378. uint16_t bytepos = (BitCount - 4) / 11;
  379. if (bitpos == 0) {
  380.  
  381. // Start bit, should be LOW
  382. if ((BitCount > 4) && (state != MY_HIGH)) { // inverse state as we are detecting the change!
  383. ToyotaFailBit = BitCount;
  384. InPacket = false;
  385. break;
  386. } // end if ((BitCount > 4) && (state != MY_HIGH))
  387.  
  388. } else if (bitpos < 9) { //else TO if (bitpos == 0)
  389.  
  390. EData[bytepos] >>= 1;
  391. if (state == MY_LOW) // inverse state as we are detecting the change!
  392. EData[bytepos] |= 0x80;
  393.  
  394. } else { // else if (bitpos == 0)
  395.  
  396. // Stop bits, should be HIGH
  397. if (state != MY_LOW) { // inverse state as we are detecting the change!
  398. ToyotaFailBit = BitCount;
  399. InPacket = false;
  400. break;
  401. } // end if (state != MY_LOW)
  402.  
  403. if ( (bitpos == 10) && ((bits > 1) || (bytepos == (TOYOTA_MAX_BYTES - 1))) ) {
  404. ToyotaNumBytes = 0;
  405. ToyotaID = ID;
  406. for (int i=0; i<=bytepos; i++)
  407. ToyotaData[i] = EData[i];
  408. ToyotaNumBytes = bytepos + 1;
  409. if (bits >= 16) // Stop bits of last byte were 1's so detect preamble for next packet
  410. BitCount = 0;
  411. else {
  412. ToyotaFailBit = BitCount;
  413. InPacket = false;
  414. }
  415. break;
  416. }
  417. }
  418. }
  419. ++BitCount;
  420. --bits;
  421. } // end while
  422. } // end (InPacket == false)
  423. } // end void change
  424.  
  425.  
  426. // DEBUG OUTPUT VOIDS
  427.  
  428.  
  429. void debugdataoutput() {
  430. // output to Serial.
  431. Serial.print("ID=");
  432. Serial.print(ToyotaID);
  433. for (int i=0; i<ToyotaNumBytes; i++)
  434. {
  435. Serial.print(", ");
  436. Serial.print(ToyotaData[i]);
  437. }
  438. Serial.println(".");
  439. } // end void
  440.  
  441. void debugfaildataoutput() {
  442. Serial.print("FAIL = ");
  443. Serial.print(ToyotaFailBit);
  444. if (((ToyotaFailBit - 4) % 11) == 0)
  445. Serial.print(" (StartBit)");
  446. else if (((ToyotaFailBit - 4) % 11) > 8)
  447. Serial.print(" (StopBit)");
  448. Serial.println(".");
  449. ToyotaFailBit = 0;
  450. } // end void
Advertisement
Add Comment
Please, Sign In to add comment