OBD II see: https://os.mbed.com/users/okini3939/notebook/obd2-can-bus/

Dependencies:   OBD2 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ecu_reader.cpp Source File

ecu_reader.cpp

00001 #include "mbed.h"
00002 #include "ecu_reader.h"
00003 
00004 extern Serial pc;
00005 
00006 // Use a timer to see if things take too long
00007 namespace mbed { 
00008 
00009 
00010 ecu_reader::ecu_reader(PinName rd, PinName td, int can_speed) : can2(rd, td)
00011 {
00012     can2.frequency(can_speed);
00013 }
00014 
00015 
00016 #define TIMEOUT 200
00017 unsigned char ecu_reader::request(unsigned char pid,  float *engine_data)
00018 {
00019     char can_msg[8];
00020 //    float *engine_data;
00021         
00022 //    led1 = 1;
00023   
00024     can_msg[0] = 0x02;  
00025     can_msg[1] = 0x01;
00026     can_msg[2] = pid;  
00027     can_msg[3] = 0;
00028     can_msg[4] = 0;  
00029     can_msg[5] = 0;
00030     can_msg[6] = 0;  
00031     can_msg[7] = 0;
00032 
00033     if (! can2.write(CANMessage(PID_REQUEST, can_msg, 8))) {
00034         pc.printf("*********Request write failed*********\n\r");
00035     }
00036  
00037     CANTimer.reset();
00038     CANTimer.start();
00039  
00040     while (CANTimer.read_ms() < TIMEOUT) {
00041  
00042         if (can2.read(can_MsgRx)) {
00043             pc.printf("CANTimer.read_ms(): %dms\r\n", CANTimer.read_ms());
00044             //print message id
00045             pc.printf("can_MsgRx.id: %x\r\n", can_MsgRx.id);
00046             //print length of message
00047             pc.printf("Hex: can_MsgRx.len: %x\r\n", can_MsgRx.len);
00048             //print data[2] and PID
00049             pc.printf("can_MsgRx.data[2]: %x, pid: %x\r\n", can_MsgRx.data[2], pid);
00050  
00051             for (int i = 0; i < (int)can_MsgRx.len; i++) {
00052                 pc.printf(" %02x", can_MsgRx.data[i]);
00053             }
00054             pc.printf("\r\n");
00055  
00056             if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == pid)) {
00057                 CANTimer.stop();
00058                 /* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */                
00059                 switch (can_MsgRx.data[2]) {                /* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */
00060                     case PID_0_20:                          // PID 0-20 Supported
00061                         PID020 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
00062                         break;
00063                     case STATUS_DTC: {                      // bit encoded
00064                         if (can_MsgRx.data[4] & 0x04) {     //Compression Ignition (Diesel)
00065                             if (can_MsgRx.data[3] & 0x80) { //MIL Light on
00066                                 *engine_data = (can_MsgRx.data[3] - 128);
00067                                 //sprintf(buffer,"MIL ON, %d DTCs", (int) *engine_data);
00068                             } else {                        //MIL Light off
00069                                 *engine_data = (can_MsgRx.data[3]);
00070                                 //sprintf(buffer,"MIL OFF, %d DTCs", (int) *engine_data);
00071                             }
00072                             // Diesel C and D bytes (can_MsgRx.data[5] and can_MsgRx.data[6])
00073                             //                      Test available  Test incomplete
00074                             // Catalyst             C0              D0
00075                             // Heated Catalyst      C1              D1
00076                             // Evap System          C2              D2
00077                             // Secondary Air        C3              D3
00078                             // A/C Refrigerant      C4              D4
00079                             // O2 Sensor            C5              D5
00080                             // O2 Sensor Heater     C6              D6
00081                             // EGR System           C7              D7
00082                         } else {                            //Spark Ignition (Gasoline)
00083                             if (can_MsgRx.data[3] & 0x80) { //MIL Light on
00084                                 *engine_data = (can_MsgRx.data[3] - 128);
00085                                 //sprintf(buffer,"MIL ON, %d DTCs", (int) *engine_data);
00086                             } else {                        //MIL Light off
00087                                 *engine_data = (can_MsgRx.data[3]);
00088                                 //sprintf(buffer,"MIL OFF, %d DTCs", (int) *engine_data);
00089                             }
00090                             // Gasoline C and D bytes (can_MsgRx.data[5] and can_MsgRx.data[6])
00091                             //                      Test available  Test incomplete
00092                             // NMHC Catalyst        C0              D0
00093                             // NOx/SCR Monitoring   C1              D1
00094                             // Boost Pressure       C3              D3
00095                             // Exhaust Gas Sensor   C5              D5
00096                             // Particulate Filter   C6              D6
00097                             // EGR and/or VVT/VTEC  C7              D7
00098                         }
00099                         // Common Tests between Gas and Diesel Engines, byte B (can_MsgRx.data[4])
00100                         //                  Test available  Test incomplete
00101                         // Misfire          B0              B4
00102                         // Fuel System      B1              B5
00103                         // Components       B2              B6
00104                         break;
00105                     }
00106                     case FREEZE_DTC:                        // Locks in Diagnostic trouble Codes
00107                         break;
00108                     case FUEL_SYS_STATUS:                   // bit encoded
00109                         //This tells us the warmup status of the engine. Only 1 bit should be set
00110                         *engine_data = can_MsgRx.data[3];
00111                         if (((int) *engine_data) & 0x01) {   // Open loop - Engine warmup
00112                             //sprintf(buffer,"Open Loop - Warmup");
00113                         }
00114                         if (((int) *engine_data) & 0x02) {   // Closed Loop - O2 Sensor feedback
00115                             //sprintf(buffer,"Closed Loop - Normal");
00116                         }
00117                         if (((int) *engine_data) & 0x04) {   // Open loop,
00118                             //sprintf(buffer,"Open Loop-Load/Decel");
00119                         }
00120                         if (((int) *engine_data) & 0x08) {   // Open loop - system failure
00121                             //sprintf(buffer,"Open Loop - FAILURE");
00122                         }
00123                         if (((int) *engine_data) & 0x10) {   // Closed Loop - O2 Sensor feedback failure
00124                             //sprintf(buffer,"Closed Loop - O2Fail");
00125                         }
00126                         if ((((int) *engine_data) & 0x20) | (((int) *engine_data) & 0x40) | (((int) *engine_data) & 0x80)) { //These shouldnt be on, assume Proprietary status
00127                             //sprintf(buffer,"Unsupported Status");
00128                         }
00129                         break;
00130                     case ENGINE_LOAD:                       // A*100/255
00131                         *engine_data = (can_MsgRx.data[3]*100)/255;
00132                         //sprintf(buffer,"%d %% ",(int) *engine_data);
00133                         break;
00134                     case ENGINE_COOLANT_TEMP:               //     A-40              [degree C]
00135                         *engine_data = can_MsgRx.data[3] - 40;
00136                         //sprintf(buffer,"%d degC ",(int) *engine_data);
00137                         break;
00138                     case ST_FUEL_TRIM_1:                    // (A-128)*100/128
00139                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00140                         //sprintf(buffer,"%d %% ", (int) *engine_data);
00141                         break;
00142                     case LT_FUEL_TRIM_1:                    // (A-128)*100/128
00143                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00144                         //sprintf(buffer,"%d %% ", (int) *engine_data);
00145                         break;
00146                     case ST_FUEL_TRIM_2:                    // (A-128)*100/128
00147                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00148                         //sprintf(buffer,"%d %% ", (int) *engine_data);
00149                         break;
00150                     case LT_FUEL_TRIM_2:                    // (A-128)*100/128
00151                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00152                         //sprintf(buffer,"%d %% ", (int) *engine_data);
00153                         break;
00154                     case FUEL_PRESSURE:                     // A*3
00155                         *engine_data = (can_MsgRx.data[3]*3);
00156                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00157                         break;
00158                     case INTAKE_PRESSURE:                   // A
00159                         *engine_data = can_MsgRx.data[3];
00160                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00161                         break;
00162                     case ENGINE_RPM:                        //   ((A*256)+B)/4    [RPM]
00163                         *engine_data = ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/4;
00164                         //sprintf(buffer,"%d rpm ",(int) *engine_data);
00165                         break;
00166                     case VEHICLE_SPEED:                     // A                  [km]
00167                         *engine_data = can_MsgRx.data[3];
00168                         //sprintf(buffer,"%d km ",(int) *engine_data);
00169                         break;
00170                     case TIMING_ADVANCE:                    // A/2 - 64
00171                         *engine_data = (can_MsgRx.data[3]/2) - 64;
00172                         //sprintf(buffer,"%d Deg",(int) *engine_data);
00173                         break;
00174                     case INTAKE_TEMP:                       // A - 40
00175                         *engine_data = (can_MsgRx.data[3] - 40);
00176                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00177                         break;
00178                     case MAF_SENSOR:                        // ((256*A)+B) / 100  [g/s]
00179                         *engine_data = ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/100;
00180                         //sprintf(buffer,"%d g/s",(int) *engine_data);
00181                         break;
00182                     case THROTTLE:                          // A*100/255
00183                         *engine_data = (can_MsgRx.data[3]*100)/255;
00184                         //sprintf(buffer,"%d %% ",(int) *engine_data);
00185                         break;
00186                     case COMMANDED_SEC_AIR:                 // bit encoded
00187                         *engine_data = can_MsgRx.data[3];
00188                         if (((int) *engine_data) & 0x01) {           //Upstream of Catalytic Converter
00189                             //sprintf(buffer,"Upstream of Cat.");
00190                         }
00191                         if (((int) *engine_data) & 0x02) {           //Downstream of Catalytic Converter
00192                             //sprintf(buffer,"Downstream of Cat.");
00193                         }
00194                         if (((int) *engine_data) & 0x04) {           //From outside atmosphere or off
00195                             //sprintf(buffer,"Off");
00196                         }
00197                         break;
00198                     case O2_SENS_PRES: {                    // A [A0..A3] == Bank 1, [A4..A7] == Bank 2
00199                         *engine_data = (can_MsgRx.data[3]);  //Check # of O2 sensors present by masking individual bits and counting
00200                         int o2pres = 0;
00201                         if (((int) *engine_data) & 0x01) {           // Bank 1 Sensor 1
00202                             o2pres++;
00203                         }
00204                         if (((int) *engine_data) & 0x02) {           // Bank 1 Sensor 2
00205                             o2pres++;
00206                         }
00207                         if (((int) *engine_data) & 0x04) {           // Bank 1 Sensor 3
00208                             o2pres++;
00209                         }
00210                         if (((int) *engine_data) & 0x08) {           // Bank 1 Sensor 4
00211                             o2pres++;
00212                         }
00213                         if (((int) *engine_data) & 0x10) {           // Bank 2 Sensor 1
00214                             o2pres++;
00215                         }
00216                         if (((int) *engine_data) & 0x20) {           // Bank 2 Sensor 2
00217                             o2pres++;
00218                         }
00219                         if (((int) *engine_data) & 0x40) {           // Bank 2 Sensor 3
00220                             o2pres++;
00221                         }
00222                         if (((int) *engine_data) & 0x80) {           // Bank 2 Sensor 4
00223                             o2pres++;
00224                         }
00225                         //sprintf(buffer,"%d Present",(int) o2pres);
00226                         break;
00227                     }
00228                     case O2_B1S1_VOLTAGE:                   // A/200, (B-128) * 100/128
00229                         *engine_data = (can_MsgRx.data[3]/200);
00230                         //sprintf(buffer,"%d V ",(int) *engine_data);              //Raw O2 Voltage
00231                         if (can_MsgRx.data[4] & 0xFF) {
00232                             //sprintf(buffer,"Not Present");
00233                         } else {
00234                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00235                             //sprintf(buffer2,"%d %% ",(int) *engine_data);        //Calculated lean/rich
00236                         }
00237                         break;
00238                     case O2_B1S2_VOLTAGE:                   //
00239                         *engine_data = (can_MsgRx.data[3]/200);
00240                         //sprintf(buffer,"%d V ",(int) *engine_data);
00241                         if (can_MsgRx.data[4] & 0xFF) {
00242                             //sprintf(buffer,"Not Present");
00243                         } else {
00244                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00245                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00246                         }
00247                         break;
00248                     case O2_B1S3_VOLTAGE:                   //
00249                         *engine_data = (can_MsgRx.data[3]/200);
00250                         //sprintf(buffer,"%d V ",(int) *engine_data);
00251                         if (can_MsgRx.data[4] & 0xFF) {
00252                             //sprintf(buffer,"Not Present");
00253                         } else {
00254                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00255                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00256                         }
00257                         break;
00258                     case O2_B1S4_VOLTAGE:                   //
00259                         *engine_data = (can_MsgRx.data[3]/200);
00260                         //sprintf(buffer,"%d V ",(int) *engine_data);
00261                         if (can_MsgRx.data[4] & 0xFF) {
00262                             //sprintf(buffer,"Not Present");
00263                         } else {
00264                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00265                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00266                         }
00267                         break;
00268                     case O2_B2S1_VOLTAGE:                   //
00269                         *engine_data = (can_MsgRx.data[3]/200);
00270                         //sprintf(buffer,"%d V ",(int) *engine_data);
00271                         if (can_MsgRx.data[4] & 0xFF) {
00272                             //sprintf(buffer,"Not Present");
00273                         } else {
00274                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00275                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00276                         }
00277                         break;
00278                     case O2_B2S2_VOLTAGE:                   //
00279                         *engine_data = (can_MsgRx.data[3]/200);
00280                         //sprintf(buffer,"%d V ",(int) *engine_data);
00281                         if (can_MsgRx.data[4] & 0xFF) {
00282                             //sprintf(buffer,"Not Present");
00283                         } else {
00284                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00285                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00286                         }
00287                         break;
00288                     case O2_B2S3_VOLTAGE: {                 //
00289                         *engine_data = (can_MsgRx.data[3]/200);
00290                         //sprintf(buffer,"%d V ",(int) *engine_data);
00291                         if (can_MsgRx.data[4] & 0xFF) {
00292                             //sprintf(buffer,"Not Present");
00293                         } else {
00294                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00295                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00296                         }
00297                         break;
00298                     }
00299                     case O2_B2S4_VOLTAGE: {                 //
00300                         *engine_data = (can_MsgRx.data[3]/200);
00301                         //sprintf(buffer,"%d V ",(int) *engine_data);
00302                         if (can_MsgRx.data[4] & 0xFF) {
00303                             //sprintf(buffer,"Not Present");
00304                         } else {
00305                             *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00306                             //sprintf(buffer2,"%d %% ",(int) *engine_data);
00307                         }
00308                         break;
00309                     }
00310                     case OBDII_STANDARDS: {                 //bit encoded NOT DONE
00311                         *engine_data = can_MsgRx.data[3];
00312                         if (((int) *engine_data) & 0x0D) {           //JOBD, EOBD, and OBD II
00313                             //sprintf(buffer,"JOBD,EOBD,OBDII");
00314                         }
00315                         if (((int) *engine_data) & 0x0C) {           //JOBD and EOBD
00316                             //sprintf(buffer,"JOBD,EOBD");
00317                         }
00318                         if (((int) *engine_data) & 0x0B) {           //JOBD and OBDII
00319                             //sprintf(buffer,"JOBD,OBDII");
00320                         }
00321                         if (((int) *engine_data) & 0x0A) {           //JOBD
00322                             //sprintf(buffer,"JOBD");
00323                         }
00324                         if (((int) *engine_data) & 0x09) {           //EOBD, OBD, and OBD II
00325                             //sprintf(buffer,"EOBD,OBDI,OBDII");
00326                         }
00327                         if (((int) *engine_data) & 0x08) {           //EOBD and OBD
00328                             //sprintf(buffer,"EOBD,OBDI");
00329                         }
00330                         if (((int) *engine_data) & 0x07) {           //EOBD and OBDII
00331                             //sprintf(buffer,"EOBD,OBDII");
00332                         }
00333                         if (((int) *engine_data) & 0x06) {           //EOBD
00334                             //sprintf(buffer,"EOBD");
00335                         }
00336                         if (((int) *engine_data) & 0x05) {           //Not meant to comply with any OBD standard
00337                             //sprintf(buffer,"No Compliance");
00338                         }
00339                         if (((int) *engine_data) & 0x04) {           //OBDI
00340                             //sprintf(buffer,"OBDI");
00341                         }
00342                         if (((int) *engine_data) & 0x03) {           //OBD and OBDII
00343                             //sprintf(buffer,"OBDI,OBDII");
00344                         }
00345                         if (((int) *engine_data) & 0x02) {           //OBD and defined by the EPA
00346                             //sprintf(buffer,"OBD");
00347                         }
00348                         if (((int) *engine_data) & 0x01) {           //OBD-II as defined by CARB
00349                             //sprintf(buffer,"OBDII");
00350                         }
00351                         //sprintf(buffer,"ERROR");
00352                         break;
00353                     }
00354                     case O2_SENS_PRES_ALT: {                //*******************
00355                         *engine_data = (can_MsgRx.data[3]);  //Check # of O2 sensors present by masking individual bits and counting
00356                         int o2presalt = 0;
00357                         if (((int) *engine_data) & 0x01) {           // Bank 1 Sensor 1
00358                             o2presalt++;
00359                         }
00360                         if (((int) *engine_data) & 0x02) {           // Bank 1 Sensor 2
00361                             o2presalt++;
00362                         }
00363                         if (((int) *engine_data) & 0x04) {           // Bank 2 Sensor 1
00364                             o2presalt++;
00365                         }
00366                         if (((int) *engine_data) & 0x08) {           // Bank 2 Sensor 2
00367                             o2presalt++;
00368                         }
00369                         if (((int) *engine_data) & 0x10) {           // Bank 3 Sensor 1
00370                             o2presalt++;
00371                         }
00372                         if (((int) *engine_data) & 0x20) {           // Bank 3 Sensor 2
00373                             o2presalt++;
00374                         }
00375                         if (((int) *engine_data) & 0x40) {           // Bank 4 Sensor 1
00376                             o2presalt++;
00377                         }
00378                         if (((int) *engine_data) & 0x80) {           // Bank 4 Sensor 2
00379                             o2presalt++;
00380                         }
00381                         //sprintf(buffer,"%d Present",(int) o2presalt);
00382                         break;
00383                     }
00384                     case AUX_IN_STATUS: {                   // A (A0 == PTO Active)
00385                         *engine_data = can_MsgRx.data[3];
00386                         if (((int) *engine_data) & 0x01) {
00387                             //sprintf(buffer,"PTO Active");
00388                         } else {
00389                             //sprintf(buffer,"PTO Inactive");
00390                         }
00391                         break;
00392                     }
00393                     case ENGINE_RUNTIME:                    // (A*256)+B
00394                         *engine_data = (can_MsgRx.data[3]*256)+(can_MsgRx.data[4]);
00395                         //sprintf(buffer,"%d Sec",(int) *engine_data);
00396                         break;
00397                     case PID_21_40:                         // bit encoded NOT DONE
00398                         PID2140 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
00399                         break;
00400                     case DIST_TRAVELED_MIL:                 // (A*256) + B
00401                         *engine_data = ((can_MsgRx.data[3] * 256) + can_MsgRx.data[4]);
00402                         //sprintf(buffer,"%d km",(int) *engine_data);
00403                         break;
00404                     case FUEL_RAIL_PRESSURE:                // ((A*256)+B)*0.079
00405                         *engine_data = ((can_MsgRx.data[3] * 256)+can_MsgRx.data[4])*0.079;
00406                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00407                         break;
00408                     case FUEL_RAIL_PRES_ALT:                // ((A*256)+B)*0.079
00409                         *engine_data = ((can_MsgRx.data[3] * 256) + can_MsgRx.data[4])*10;
00410                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00411                         break;
00412                     case O2S1_WR_LAMBDA_V:                  // ((A*256)+B)*2/65535 [ratio], ((C*256)+D)*8/65535 [V]
00413                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00414                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00415                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00416                         //sprintf(buffer2,"%d V",(int) *engine_data);
00417                         break;
00418                     case O2S2_WR_LAMBDA_V:                  //
00419                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00420                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00421                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00422                         //sprintf(buffer2,"%d V",(int) *engine_data);
00423                         break;
00424                     case O2S3_WR_LAMBDA_V:                  //
00425                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00426                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00427                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00428                         //sprintf(buffer2,"%d V",(int) *engine_data);
00429                         break;
00430                     case O2S4_WR_LAMBDA_V:                  //
00431                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00432                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00433                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00434                         //sprintf(buffer2,"%d V",(int) *engine_data);
00435                         break;
00436                     case O2S5_WR_LAMBDA_V:                  //
00437                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00438                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00439                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00440                         //sprintf(buffer2,"%d V",(int) *engine_data);
00441                         break;
00442                     case O2S6_WR_LAMBDA_V:                  //
00443                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00444                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00445                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00446                         //sprintf(buffer2,"%d V",(int) *engine_data);
00447                         break;
00448                     case O2S7_WR_LAMBDA_V:                  //
00449                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00450                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00451                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00452                         //sprintf(buffer2,"%d V",(int) *engine_data);
00453                         break;
00454                     case O2S8_WR_LAMBDA_V:                  //
00455                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
00456                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00457                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
00458                         //sprintf(buffer2,"%d V",(int) *engine_data);
00459                         break;
00460                     case COMMANDED_EGR:                     // 100*A/255
00461                         *engine_data = (can_MsgRx.data[3]*100/255);
00462                         //sprintf(buffer,"%d %%",(int) *engine_data);
00463                         break;
00464                     case EGR_ERROR:                         // (A-128)*100/128
00465                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00466                         //sprintf(buffer,"%d %%",(int) *engine_data);
00467                         break;
00468                     case COMMANDED_EVAP_P:                  // 100*A/255 [%]
00469                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00470                         //sprintf(buffer,"%d %%",(int) *engine_data);
00471                         break;
00472                     case FUEL_LEVEL:                        //100*A/255
00473                         *engine_data = ((100*can_MsgRx.data[3])/255);
00474                         //sprintf(buffer,"%d %%",(int) *engine_data);
00475                         break;
00476                     case WARMUPS_SINCE_CLR:                 //A
00477                         *engine_data = (can_MsgRx.data[3]);
00478                         //sprintf(buffer,"%d Warmups",(int) *engine_data);
00479                         break;
00480                     case DIST_SINCE_CLR:                    //A*256+B   [km]
00481                         *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]);
00482                         //sprintf(buffer,"%d km",(int) *engine_data);
00483                         break;
00484                     case EVAP_PRESSURE:                     //((A*256)+B)/4
00485                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/4);
00486                         //sprintf(buffer,"%d Pa",(int) *engine_data); //Yes it's in pascals
00487                         break;
00488                     case BAROMETRIC_PRESSURE:               //A
00489                         *engine_data = can_MsgRx.data[3];
00490                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00491                         break;
00492                     case O2S1_WR_LAMBDA_I:                  //((A*256)+B)/32,768 [Ratio], ((C*256)+D)/256 - 128 [mA]
00493                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00494                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00495                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00496                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00497                         break;
00498                     case O2S2_WR_LAMBDA_I:
00499                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00500                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00501                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00502                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00503                         break;
00504                     case O2S3_WR_LAMBDA_I:
00505                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00506                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00507                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00508                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00509                         break;
00510                     case O2S4_WR_LAMBDA_I:
00511                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00512                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00513                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00514                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00515                         break;
00516                     case O2S5_WR_LAMBDA_I:
00517                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00518                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00519                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00520                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00521                         break;
00522                     case O2S6_WR_LAMBDA_I:
00523                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00524                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00525                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00526                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00527                         break;
00528                     case O2S7_WR_LAMBDA_I:
00529                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00530                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00531                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00532                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00533                         break;
00534                     case O2S8_WR_LAMBDA_I:
00535                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00536                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00537                         *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
00538                         //sprintf(buffer2,"%d mA",(int) *engine_data);
00539                         break;
00540                     case CAT_TEMP_B1S1:                     //((A*256)+B)/10 - 40 [DegC]
00541                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
00542                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00543                         break;
00544                     case CAT_TEMP_B1S2:
00545                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
00546                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00547                         break;
00548                     case CAT_TEMP_B2S1:
00549                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
00550                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00551                         break;
00552                     case CAT_TEMP_B2S2:
00553                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
00554                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00555                         break;
00556                     case PID_41_60:                         //bit encoded NOT DONE
00557                         PID4160 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
00558                         break;
00559                     case MONITOR_STATUS:                    // bit encoded
00560                         //LUT: (Uses multiple bytes) A7..0 always 0
00561                         //                  Test enabled    Test Incomplete
00562                         // Misfire          B0              B4
00563                         // Fuel System      B1              B5
00564                         // Components       B2              B6
00565                         // Reserved         B3              B7
00566                         // Catalyst         C0              D0
00567                         // Heated Catalyst  C1              D1
00568                         // Evap System      C2              D2
00569                         // Sec. Ait system  C3              D3
00570                         // A/C Refrigerant  C4              D4
00571                         // O2 Sensor        C5              D5
00572                         // O2 Sensor Heater C6              D6
00573                         // EGR System       C7              D7
00574                         break;
00575                     case ECU_VOLTAGE:                       //((A*256)+B)/1000 [V]
00576                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/1000);
00577                         //sprintf(buffer,"%d V",(int) *engine_data);
00578                         break;
00579                     case ABSOLUTE_LOAD:                     //((A*256)+B)*100/255 [%]
00580                         *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*100)/255);
00581                         //sprintf(buffer,"%d %%",(int) *engine_data);
00582                         break;
00583                     case COMMANDED_EQUIV_R:                 //((A*256)+B)/32768 [Ratio]
00584                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
00585                         //sprintf(buffer,"Ratio %d",(int) *engine_data);
00586                         break;
00587                     case REL_THROTTLE_POS:                  // A*100/255 [%]
00588                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00589                         //sprintf(buffer,"%d %%",(int) *engine_data);
00590                         break;
00591                     case AMB_AIR_TEMP:                      // A-40 [DegC]
00592                         *engine_data = (can_MsgRx.data[3]-40);
00593                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00594                         break;
00595                     case ABS_THROTTLE_POS_B:                // A*100/255 [%]
00596                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00597                         //sprintf(buffer,"%d %%",(int) *engine_data);
00598                         break;
00599                     case ABS_THROTTLE_POS_C:                // A*100/255 [%]
00600                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00601                         //sprintf(buffer,"%d %%",(int) *engine_data);
00602                         break;
00603                     case ACCEL_POS_D:                       // A*100/255 [%]
00604                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00605                         //sprintf(buffer,"%d %%",(int) *engine_data);
00606                         break;
00607                     case ACCEL_POS_E:                       // A*100/255 [%]
00608                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00609                         //sprintf(buffer,"%d %%",(int) *engine_data);
00610                         break;
00611                     case ACCEL_POS_F:                       // A*100/255 [%]
00612                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00613                         //sprintf(buffer,"%d %%",(int) *engine_data);
00614                         break;
00615                     case COMMANDED_THROTTLE:                //A*100/255 [%]
00616                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00617                         //sprintf(buffer,"%d %%",(int) *engine_data);
00618                         break;
00619                     case TIME_RUN_WITH_MIL:                 //(A*256)+B [minutes]
00620                         *engine_data = ((can_MsgRx.data[3]*256)/(can_MsgRx.data[4]));
00621                         //sprintf(buffer,"%d Mins",(int) *engine_data);
00622                         break;
00623                     case TIME_SINCE_CLR:                    //(A*256)+B [minutes]
00624                         *engine_data = ((can_MsgRx.data[3]*256)/(can_MsgRx.data[4]));
00625                         //sprintf(buffer,"%d Mins",(int) *engine_data);
00626                         break;
00627                     case MAX_R_O2_VI_PRES:                  //A,B,C,D*10 [Ratio,V,mA,kPa]
00628                         *engine_data = can_MsgRx.data[3];
00629                         //sprintf(buffer,"Ratio: %d",(int) *engine_data);
00630                         *engine_data = can_MsgRx.data[4];
00631                         //sprintf(buffer,"%d V",(int) *engine_data);
00632                         *engine_data = can_MsgRx.data[5];
00633                         //sprintf(buffer,"%d mA",(int) *engine_data);
00634                         *engine_data = (can_MsgRx.data[6]*10);
00635                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00636                         break;
00637                     case MAX_AIRFLOW_MAF:                   //A*10 [g/s]
00638                         *engine_data = (can_MsgRx.data[3]*10);
00639                         //sprintf(buffer,"%d g/s",(int) *engine_data);
00640                         break;
00641                     case FUEL_TYPE:                         // USE LUT NOT DONE
00642                         break;
00643                     case ETHANOL_PERCENT:                   //A*100/255 [%]
00644                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00645                         //sprintf(buffer,"%d %%",(int) *engine_data);
00646                         break;
00647                     case ABS_EVAP_SYS_PRES:                 //1/200 per bit [kPa] ----NOT DONE----
00648                         break;
00649                     case EVAP_SYS_PRES:                     // (A*256)+B - 32768 [Pa]
00650                         *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]-32768);
00651                         //sprintf(buffer,"%d Pa",(int) *engine_data);
00652                         break;
00653                     case ST_O2_TRIM_B1B3:                   // ((A-128)*100/128 (B-128)*100/128 [%]
00654                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00655                         //sprintf(buffer,"%d %%",(int) *engine_data);
00656                         *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00657                         //sprintf(buffer,"%d %%",(int) *engine_data);
00658                         break;
00659                     case LT_O2_TRIM_B1B3:
00660                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00661                         //sprintf(buffer,"%d %%",(int) *engine_data);
00662                         *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00663                         //sprintf(buffer,"%d %%",(int) *engine_data);
00664                         break;
00665                     case ST_02_TRIM_B2B4:
00666                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00667                         //sprintf(buffer,"%d %%",(int) *engine_data);
00668                         *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00669                         //sprintf(buffer,"%d %%",(int) *engine_data);
00670                         break;
00671                     case LT_O2_TRIM_B2B4:
00672                         *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
00673                         //sprintf(buffer,"%d %%",(int) *engine_data);
00674                         *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
00675                         //sprintf(buffer,"%d %%",(int) *engine_data);
00676                         break;
00677                     case ABS_FUEL_RAIL_PRES:                //((A*256)+B)*10 [kPa]
00678                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*10);
00679                         //sprintf(buffer,"%d kPa",(int) *engine_data);
00680                         break;
00681                     case REL_ACCEL_POS:                     //A*100/255 [%]
00682                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00683                         //sprintf(buffer,"%d %%",(int) *engine_data);
00684                         break;
00685                     case HYBRID_BATT_PCT:                   //A*100/255 [%]
00686                         *engine_data = ((can_MsgRx.data[3]*100)/255);
00687                         //sprintf(buffer,"%d %%",(int) *engine_data);
00688                         break;
00689                     case ENGINE_OIL_TEMP:                   //A-40 [DegC]
00690                         *engine_data = (can_MsgRx.data[3]-40);
00691                         //sprintf(buffer,"%d DegC",(int) *engine_data);
00692                         break;
00693                     case FUEL_TIMING:                       //(38655-((A*256)+B))/128
00694                         *engine_data = ((38655 - ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]))/128);
00695                         //sprintf(buffer,"%d Deg",(int) *engine_data);
00696                         break;
00697                     case FUEL_RATE:                         //((A*256)+B)*0.05
00698                         *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*0.05);
00699                         //sprintf(buffer,"%d L/m",(int) *engine_data);
00700                         break;
00701                     case EMISSIONS_STANDARD:                //bit encoded ----NOT DONE----
00702                         break;
00703                     case DEMANDED_TORQUE:                   //A-125 [%]
00704                         *engine_data = (can_MsgRx.data[3]-125);
00705                         //sprintf(buffer,"%d %%",(int) *engine_data);
00706                         break;
00707                     case ACTUAL_TORQUE:                     //A-125 [%]
00708                         *engine_data = (can_MsgRx.data[3]-125);
00709                         //sprintf(buffer,"%d %%",(int) *engine_data);
00710                         break;
00711                     case REFERENCE_TORQUE:                  //A*256+b [Nm]
00712                         *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]);
00713                         //sprintf(buffer,"%d Nm",(int) *engine_data);
00714                         break;
00715                     case ENGINE_PCT_TORQUE:                 //A-125 idle, B-125 pt 1, C-125, D-125
00716                         *engine_data = (can_MsgRx.data[3]);
00717                         //sprintf(buffer,"%d %% - Idle",(int) *engine_data);
00718                         *engine_data = (can_MsgRx.data[4]);
00719                         //sprintf(buffer2,"%d %% - Point 1",(int) *engine_data);
00720                         *engine_data = (can_MsgRx.data[5]);
00721                         //sprintf(buffer3,"%d %% - Point 2",(int) *engine_data);
00722                         *engine_data = (can_MsgRx.data[6]);
00723                         //sprintf(buffer4,"%d %% - Point 3",(int) *engine_data);
00724                         break;
00725                     case AUX_IO_SUPPORTED:                  //Bit encoded ----NOT DONE----
00726                         break;
00727                     case P_MAF_SENSOR:
00728                     case P_ENGINE_COOLANT_T:
00729                     case P_INTAKE_TEMP:
00730                     case P_COMMANDED_EGR:
00731                     case P_COMMANDED_INTAKE:
00732                     case P_EGR_TEMP:
00733                     case P_COMMANDED_THROT:
00734                     case P_FUEL_PRESSURE:
00735                     case P_FUEL_INJ_PRES:
00736                     case P_TURBO_PRESSURE:
00737                     case P_BOOST_PRES_CONT:
00738                     case P_VGT_CONTROL:
00739                     case P_WASTEGATE_CONT:
00740                     case P_EXHAUST_PRESSURE:
00741                     case P_TURBO_RPM:
00742                     case P_TURBO_TEMP1:
00743                     case P_TURBO_TEMP2:
00744                     case P_CACT:
00745                     case P_EGT_B1:
00746                     case P_EGT_B2:
00747                     case P_DPF1:
00748                     case P_DPF2:
00749                     case P_DPF_TEMP:
00750                     case P_NOX_NTE_STATUS:
00751                     case P_PM_NTE_STATUS:
00752                     case P_ENGINE_RUNTUME:
00753                     case P_ENGINE_AECD_1:
00754                     case P_ENGINE_AECD_2:
00755                     case P_NOX_SENSOR:
00756                     case P_MANIFOLD_TEMP:
00757                     case P_NOX_SYSTEM:
00758                     case P_PM_SENSOR:
00759                     case P_IN_MANIF_TEMP:
00760                         //sprintf(buffer,"Not supported");
00761                         break;
00762                 } // switch
00763         
00764                 return 1;
00765         
00766              } // if
00767 
00768          } // if read
00769      } // while
00770 
00771      return 0;
00772   
00773 
00774 
00775 
00776 }
00777 } // namespace mbed