talofer99

Toyota corolla OBD-I code

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