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

Dependencies:   OBD2 mbed

Revision:
0:c6f40de7ab86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ecu_reader/ecu_reader.cpp	Wed Dec 20 07:21:57 2017 +0000
@@ -0,0 +1,777 @@
+#include "mbed.h"
+#include "ecu_reader.h"
+
+extern Serial pc;
+
+// Use a timer to see if things take too long
+namespace mbed { 
+
+
+ecu_reader::ecu_reader(PinName rd, PinName td, int can_speed) : can2(rd, td)
+{
+    can2.frequency(can_speed);
+}
+
+
+#define TIMEOUT 200
+unsigned char ecu_reader::request(unsigned char pid,  float *engine_data)
+{
+    char can_msg[8];
+//    float *engine_data;
+        
+//    led1 = 1;
+  
+    can_msg[0] = 0x02;  
+    can_msg[1] = 0x01;
+    can_msg[2] = pid;  
+    can_msg[3] = 0;
+    can_msg[4] = 0;  
+    can_msg[5] = 0;
+    can_msg[6] = 0;  
+    can_msg[7] = 0;
+
+    if (! can2.write(CANMessage(PID_REQUEST, can_msg, 8))) {
+        pc.printf("*********Request write failed*********\n\r");
+    }
+ 
+    CANTimer.reset();
+    CANTimer.start();
+ 
+    while (CANTimer.read_ms() < TIMEOUT) {
+ 
+        if (can2.read(can_MsgRx)) {
+            pc.printf("CANTimer.read_ms(): %dms\r\n", CANTimer.read_ms());
+            //print message id
+            pc.printf("can_MsgRx.id: %x\r\n", can_MsgRx.id);
+            //print length of message
+            pc.printf("Hex: can_MsgRx.len: %x\r\n", can_MsgRx.len);
+            //print data[2] and PID
+            pc.printf("can_MsgRx.data[2]: %x, pid: %x\r\n", can_MsgRx.data[2], pid);
+ 
+            for (int i = 0; i < (int)can_MsgRx.len; i++) {
+                pc.printf(" %02x", can_MsgRx.data[i]);
+            }
+            pc.printf("\r\n");
+ 
+            if ((can_MsgRx.id == PID_REPLY) && (can_MsgRx.data[2] == pid)) {
+                CANTimer.stop();
+                /* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */                
+                switch (can_MsgRx.data[2]) {                /* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */
+                    case PID_0_20:                          // PID 0-20 Supported
+                        PID020 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
+                        break;
+                    case STATUS_DTC: {                      // bit encoded
+                        if (can_MsgRx.data[4] & 0x04) {     //Compression Ignition (Diesel)
+                            if (can_MsgRx.data[3] & 0x80) { //MIL Light on
+                                *engine_data = (can_MsgRx.data[3] - 128);
+                                //sprintf(buffer,"MIL ON, %d DTCs", (int) *engine_data);
+                            } else {                        //MIL Light off
+                                *engine_data = (can_MsgRx.data[3]);
+                                //sprintf(buffer,"MIL OFF, %d DTCs", (int) *engine_data);
+                            }
+                            // Diesel C and D bytes (can_MsgRx.data[5] and can_MsgRx.data[6])
+                            //                      Test available  Test incomplete
+                            // Catalyst             C0              D0
+                            // Heated Catalyst      C1              D1
+                            // Evap System          C2              D2
+                            // Secondary Air        C3              D3
+                            // A/C Refrigerant      C4              D4
+                            // O2 Sensor            C5              D5
+                            // O2 Sensor Heater     C6              D6
+                            // EGR System           C7              D7
+                        } else {                            //Spark Ignition (Gasoline)
+                            if (can_MsgRx.data[3] & 0x80) { //MIL Light on
+                                *engine_data = (can_MsgRx.data[3] - 128);
+                                //sprintf(buffer,"MIL ON, %d DTCs", (int) *engine_data);
+                            } else {                        //MIL Light off
+                                *engine_data = (can_MsgRx.data[3]);
+                                //sprintf(buffer,"MIL OFF, %d DTCs", (int) *engine_data);
+                            }
+                            // Gasoline C and D bytes (can_MsgRx.data[5] and can_MsgRx.data[6])
+                            //                      Test available  Test incomplete
+                            // NMHC Catalyst        C0              D0
+                            // NOx/SCR Monitoring   C1              D1
+                            // Boost Pressure       C3              D3
+                            // Exhaust Gas Sensor   C5              D5
+                            // Particulate Filter   C6              D6
+                            // EGR and/or VVT/VTEC  C7              D7
+                        }
+                        // Common Tests between Gas and Diesel Engines, byte B (can_MsgRx.data[4])
+                        //                  Test available  Test incomplete
+                        // Misfire          B0              B4
+                        // Fuel System      B1              B5
+                        // Components       B2              B6
+                        break;
+                    }
+                    case FREEZE_DTC:                        // Locks in Diagnostic trouble Codes
+                        break;
+                    case FUEL_SYS_STATUS:                   // bit encoded
+                        //This tells us the warmup status of the engine. Only 1 bit should be set
+                        *engine_data = can_MsgRx.data[3];
+                        if (((int) *engine_data) & 0x01) {   // Open loop - Engine warmup
+                            //sprintf(buffer,"Open Loop - Warmup");
+                        }
+                        if (((int) *engine_data) & 0x02) {   // Closed Loop - O2 Sensor feedback
+                            //sprintf(buffer,"Closed Loop - Normal");
+                        }
+                        if (((int) *engine_data) & 0x04) {   // Open loop,
+                            //sprintf(buffer,"Open Loop-Load/Decel");
+                        }
+                        if (((int) *engine_data) & 0x08) {   // Open loop - system failure
+                            //sprintf(buffer,"Open Loop - FAILURE");
+                        }
+                        if (((int) *engine_data) & 0x10) {   // Closed Loop - O2 Sensor feedback failure
+                            //sprintf(buffer,"Closed Loop - O2Fail");
+                        }
+                        if ((((int) *engine_data) & 0x20) | (((int) *engine_data) & 0x40) | (((int) *engine_data) & 0x80)) { //These shouldnt be on, assume Proprietary status
+                            //sprintf(buffer,"Unsupported Status");
+                        }
+                        break;
+                    case ENGINE_LOAD:                       // A*100/255
+                        *engine_data = (can_MsgRx.data[3]*100)/255;
+                        //sprintf(buffer,"%d %% ",(int) *engine_data);
+                        break;
+                    case ENGINE_COOLANT_TEMP:               //     A-40              [degree C]
+                        *engine_data = can_MsgRx.data[3] - 40;
+                        //sprintf(buffer,"%d degC ",(int) *engine_data);
+                        break;
+                    case ST_FUEL_TRIM_1:                    // (A-128)*100/128
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %% ", (int) *engine_data);
+                        break;
+                    case LT_FUEL_TRIM_1:                    // (A-128)*100/128
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %% ", (int) *engine_data);
+                        break;
+                    case ST_FUEL_TRIM_2:                    // (A-128)*100/128
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %% ", (int) *engine_data);
+                        break;
+                    case LT_FUEL_TRIM_2:                    // (A-128)*100/128
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %% ", (int) *engine_data);
+                        break;
+                    case FUEL_PRESSURE:                     // A*3
+                        *engine_data = (can_MsgRx.data[3]*3);
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case INTAKE_PRESSURE:                   // A
+                        *engine_data = can_MsgRx.data[3];
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case ENGINE_RPM:                        //   ((A*256)+B)/4    [RPM]
+                        *engine_data = ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/4;
+                        //sprintf(buffer,"%d rpm ",(int) *engine_data);
+                        break;
+                    case VEHICLE_SPEED:                     // A                  [km]
+                        *engine_data = can_MsgRx.data[3];
+                        //sprintf(buffer,"%d km ",(int) *engine_data);
+                        break;
+                    case TIMING_ADVANCE:                    // A/2 - 64
+                        *engine_data = (can_MsgRx.data[3]/2) - 64;
+                        //sprintf(buffer,"%d Deg",(int) *engine_data);
+                        break;
+                    case INTAKE_TEMP:                       // A - 40
+                        *engine_data = (can_MsgRx.data[3] - 40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case MAF_SENSOR:                        // ((256*A)+B) / 100  [g/s]
+                        *engine_data = ((can_MsgRx.data[3]*256) + can_MsgRx.data[4])/100;
+                        //sprintf(buffer,"%d g/s",(int) *engine_data);
+                        break;
+                    case THROTTLE:                          // A*100/255
+                        *engine_data = (can_MsgRx.data[3]*100)/255;
+                        //sprintf(buffer,"%d %% ",(int) *engine_data);
+                        break;
+                    case COMMANDED_SEC_AIR:                 // bit encoded
+                        *engine_data = can_MsgRx.data[3];
+                        if (((int) *engine_data) & 0x01) {           //Upstream of Catalytic Converter
+                            //sprintf(buffer,"Upstream of Cat.");
+                        }
+                        if (((int) *engine_data) & 0x02) {           //Downstream of Catalytic Converter
+                            //sprintf(buffer,"Downstream of Cat.");
+                        }
+                        if (((int) *engine_data) & 0x04) {           //From outside atmosphere or off
+                            //sprintf(buffer,"Off");
+                        }
+                        break;
+                    case O2_SENS_PRES: {                    // A [A0..A3] == Bank 1, [A4..A7] == Bank 2
+                        *engine_data = (can_MsgRx.data[3]);  //Check # of O2 sensors present by masking individual bits and counting
+                        int o2pres = 0;
+                        if (((int) *engine_data) & 0x01) {           // Bank 1 Sensor 1
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x02) {           // Bank 1 Sensor 2
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x04) {           // Bank 1 Sensor 3
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x08) {           // Bank 1 Sensor 4
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x10) {           // Bank 2 Sensor 1
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x20) {           // Bank 2 Sensor 2
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x40) {           // Bank 2 Sensor 3
+                            o2pres++;
+                        }
+                        if (((int) *engine_data) & 0x80) {           // Bank 2 Sensor 4
+                            o2pres++;
+                        }
+                        //sprintf(buffer,"%d Present",(int) o2pres);
+                        break;
+                    }
+                    case O2_B1S1_VOLTAGE:                   // A/200, (B-128) * 100/128
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);              //Raw O2 Voltage
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);        //Calculated lean/rich
+                        }
+                        break;
+                    case O2_B1S2_VOLTAGE:                   //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    case O2_B1S3_VOLTAGE:                   //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    case O2_B1S4_VOLTAGE:                   //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    case O2_B2S1_VOLTAGE:                   //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    case O2_B2S2_VOLTAGE:                   //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    case O2_B2S3_VOLTAGE: {                 //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    }
+                    case O2_B2S4_VOLTAGE: {                 //
+                        *engine_data = (can_MsgRx.data[3]/200);
+                        //sprintf(buffer,"%d V ",(int) *engine_data);
+                        if (can_MsgRx.data[4] & 0xFF) {
+                            //sprintf(buffer,"Not Present");
+                        } else {
+                            *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                            //sprintf(buffer2,"%d %% ",(int) *engine_data);
+                        }
+                        break;
+                    }
+                    case OBDII_STANDARDS: {                 //bit encoded NOT DONE
+                        *engine_data = can_MsgRx.data[3];
+                        if (((int) *engine_data) & 0x0D) {           //JOBD, EOBD, and OBD II
+                            //sprintf(buffer,"JOBD,EOBD,OBDII");
+                        }
+                        if (((int) *engine_data) & 0x0C) {           //JOBD and EOBD
+                            //sprintf(buffer,"JOBD,EOBD");
+                        }
+                        if (((int) *engine_data) & 0x0B) {           //JOBD and OBDII
+                            //sprintf(buffer,"JOBD,OBDII");
+                        }
+                        if (((int) *engine_data) & 0x0A) {           //JOBD
+                            //sprintf(buffer,"JOBD");
+                        }
+                        if (((int) *engine_data) & 0x09) {           //EOBD, OBD, and OBD II
+                            //sprintf(buffer,"EOBD,OBDI,OBDII");
+                        }
+                        if (((int) *engine_data) & 0x08) {           //EOBD and OBD
+                            //sprintf(buffer,"EOBD,OBDI");
+                        }
+                        if (((int) *engine_data) & 0x07) {           //EOBD and OBDII
+                            //sprintf(buffer,"EOBD,OBDII");
+                        }
+                        if (((int) *engine_data) & 0x06) {           //EOBD
+                            //sprintf(buffer,"EOBD");
+                        }
+                        if (((int) *engine_data) & 0x05) {           //Not meant to comply with any OBD standard
+                            //sprintf(buffer,"No Compliance");
+                        }
+                        if (((int) *engine_data) & 0x04) {           //OBDI
+                            //sprintf(buffer,"OBDI");
+                        }
+                        if (((int) *engine_data) & 0x03) {           //OBD and OBDII
+                            //sprintf(buffer,"OBDI,OBDII");
+                        }
+                        if (((int) *engine_data) & 0x02) {           //OBD and defined by the EPA
+                            //sprintf(buffer,"OBD");
+                        }
+                        if (((int) *engine_data) & 0x01) {           //OBD-II as defined by CARB
+                            //sprintf(buffer,"OBDII");
+                        }
+                        //sprintf(buffer,"ERROR");
+                        break;
+                    }
+                    case O2_SENS_PRES_ALT: {                //*******************
+                        *engine_data = (can_MsgRx.data[3]);  //Check # of O2 sensors present by masking individual bits and counting
+                        int o2presalt = 0;
+                        if (((int) *engine_data) & 0x01) {           // Bank 1 Sensor 1
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x02) {           // Bank 1 Sensor 2
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x04) {           // Bank 2 Sensor 1
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x08) {           // Bank 2 Sensor 2
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x10) {           // Bank 3 Sensor 1
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x20) {           // Bank 3 Sensor 2
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x40) {           // Bank 4 Sensor 1
+                            o2presalt++;
+                        }
+                        if (((int) *engine_data) & 0x80) {           // Bank 4 Sensor 2
+                            o2presalt++;
+                        }
+                        //sprintf(buffer,"%d Present",(int) o2presalt);
+                        break;
+                    }
+                    case AUX_IN_STATUS: {                   // A (A0 == PTO Active)
+                        *engine_data = can_MsgRx.data[3];
+                        if (((int) *engine_data) & 0x01) {
+                            //sprintf(buffer,"PTO Active");
+                        } else {
+                            //sprintf(buffer,"PTO Inactive");
+                        }
+                        break;
+                    }
+                    case ENGINE_RUNTIME:                    // (A*256)+B
+                        *engine_data = (can_MsgRx.data[3]*256)+(can_MsgRx.data[4]);
+                        //sprintf(buffer,"%d Sec",(int) *engine_data);
+                        break;
+                    case PID_21_40:                         // bit encoded NOT DONE
+                        PID2140 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
+                        break;
+                    case DIST_TRAVELED_MIL:                 // (A*256) + B
+                        *engine_data = ((can_MsgRx.data[3] * 256) + can_MsgRx.data[4]);
+                        //sprintf(buffer,"%d km",(int) *engine_data);
+                        break;
+                    case FUEL_RAIL_PRESSURE:                // ((A*256)+B)*0.079
+                        *engine_data = ((can_MsgRx.data[3] * 256)+can_MsgRx.data[4])*0.079;
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case FUEL_RAIL_PRES_ALT:                // ((A*256)+B)*0.079
+                        *engine_data = ((can_MsgRx.data[3] * 256) + can_MsgRx.data[4])*10;
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case O2S1_WR_LAMBDA_V:                  // ((A*256)+B)*2/65535 [ratio], ((C*256)+D)*8/65535 [V]
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S2_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S3_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S4_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S5_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S6_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S7_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case O2S8_WR_LAMBDA_V:                  //
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*2)/65535);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])*8)/65535);
+                        //sprintf(buffer2,"%d V",(int) *engine_data);
+                        break;
+                    case COMMANDED_EGR:                     // 100*A/255
+                        *engine_data = (can_MsgRx.data[3]*100/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case EGR_ERROR:                         // (A-128)*100/128
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case COMMANDED_EVAP_P:                  // 100*A/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case FUEL_LEVEL:                        //100*A/255
+                        *engine_data = ((100*can_MsgRx.data[3])/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case WARMUPS_SINCE_CLR:                 //A
+                        *engine_data = (can_MsgRx.data[3]);
+                        //sprintf(buffer,"%d Warmups",(int) *engine_data);
+                        break;
+                    case DIST_SINCE_CLR:                    //A*256+B   [km]
+                        *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]);
+                        //sprintf(buffer,"%d km",(int) *engine_data);
+                        break;
+                    case EVAP_PRESSURE:                     //((A*256)+B)/4
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/4);
+                        //sprintf(buffer,"%d Pa",(int) *engine_data); //Yes it's in pascals
+                        break;
+                    case BAROMETRIC_PRESSURE:               //A
+                        *engine_data = can_MsgRx.data[3];
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case O2S1_WR_LAMBDA_I:                  //((A*256)+B)/32,768 [Ratio], ((C*256)+D)/256 - 128 [mA]
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S2_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S3_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S4_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S5_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S6_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S7_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case O2S8_WR_LAMBDA_I:
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = ((((can_MsgRx.data[5]*256)+can_MsgRx.data[6])/256)-128);
+                        //sprintf(buffer2,"%d mA",(int) *engine_data);
+                        break;
+                    case CAT_TEMP_B1S1:                     //((A*256)+B)/10 - 40 [DegC]
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case CAT_TEMP_B1S2:
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case CAT_TEMP_B2S1:
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case CAT_TEMP_B2S2:
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/10)-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case PID_41_60:                         //bit encoded NOT DONE
+                        PID4160 = ((can_MsgRx.data[3] << 24) | (can_MsgRx.data[4] << 16) | (can_MsgRx.data[5] << 8) | (can_MsgRx.data[6]));
+                        break;
+                    case MONITOR_STATUS:                    // bit encoded
+                        //LUT: (Uses multiple bytes) A7..0 always 0
+                        //                  Test enabled    Test Incomplete
+                        // Misfire          B0              B4
+                        // Fuel System      B1              B5
+                        // Components       B2              B6
+                        // Reserved         B3              B7
+                        // Catalyst         C0              D0
+                        // Heated Catalyst  C1              D1
+                        // Evap System      C2              D2
+                        // Sec. Ait system  C3              D3
+                        // A/C Refrigerant  C4              D4
+                        // O2 Sensor        C5              D5
+                        // O2 Sensor Heater C6              D6
+                        // EGR System       C7              D7
+                        break;
+                    case ECU_VOLTAGE:                       //((A*256)+B)/1000 [V]
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/1000);
+                        //sprintf(buffer,"%d V",(int) *engine_data);
+                        break;
+                    case ABSOLUTE_LOAD:                     //((A*256)+B)*100/255 [%]
+                        *engine_data = ((((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case COMMANDED_EQUIV_R:                 //((A*256)+B)/32768 [Ratio]
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])/32768);
+                        //sprintf(buffer,"Ratio %d",(int) *engine_data);
+                        break;
+                    case REL_THROTTLE_POS:                  // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case AMB_AIR_TEMP:                      // A-40 [DegC]
+                        *engine_data = (can_MsgRx.data[3]-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case ABS_THROTTLE_POS_B:                // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ABS_THROTTLE_POS_C:                // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ACCEL_POS_D:                       // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ACCEL_POS_E:                       // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ACCEL_POS_F:                       // A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case COMMANDED_THROTTLE:                //A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case TIME_RUN_WITH_MIL:                 //(A*256)+B [minutes]
+                        *engine_data = ((can_MsgRx.data[3]*256)/(can_MsgRx.data[4]));
+                        //sprintf(buffer,"%d Mins",(int) *engine_data);
+                        break;
+                    case TIME_SINCE_CLR:                    //(A*256)+B [minutes]
+                        *engine_data = ((can_MsgRx.data[3]*256)/(can_MsgRx.data[4]));
+                        //sprintf(buffer,"%d Mins",(int) *engine_data);
+                        break;
+                    case MAX_R_O2_VI_PRES:                  //A,B,C,D*10 [Ratio,V,mA,kPa]
+                        *engine_data = can_MsgRx.data[3];
+                        //sprintf(buffer,"Ratio: %d",(int) *engine_data);
+                        *engine_data = can_MsgRx.data[4];
+                        //sprintf(buffer,"%d V",(int) *engine_data);
+                        *engine_data = can_MsgRx.data[5];
+                        //sprintf(buffer,"%d mA",(int) *engine_data);
+                        *engine_data = (can_MsgRx.data[6]*10);
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case MAX_AIRFLOW_MAF:                   //A*10 [g/s]
+                        *engine_data = (can_MsgRx.data[3]*10);
+                        //sprintf(buffer,"%d g/s",(int) *engine_data);
+                        break;
+                    case FUEL_TYPE:                         // USE LUT NOT DONE
+                        break;
+                    case ETHANOL_PERCENT:                   //A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ABS_EVAP_SYS_PRES:                 //1/200 per bit [kPa] ----NOT DONE----
+                        break;
+                    case EVAP_SYS_PRES:                     // (A*256)+B - 32768 [Pa]
+                        *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]-32768);
+                        //sprintf(buffer,"%d Pa",(int) *engine_data);
+                        break;
+                    case ST_O2_TRIM_B1B3:                   // ((A-128)*100/128 (B-128)*100/128 [%]
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case LT_O2_TRIM_B1B3:
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ST_02_TRIM_B2B4:
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case LT_O2_TRIM_B2B4:
+                        *engine_data = ((can_MsgRx.data[3]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        *engine_data = ((can_MsgRx.data[4]-128)*(100/128));
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ABS_FUEL_RAIL_PRES:                //((A*256)+B)*10 [kPa]
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*10);
+                        //sprintf(buffer,"%d kPa",(int) *engine_data);
+                        break;
+                    case REL_ACCEL_POS:                     //A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case HYBRID_BATT_PCT:                   //A*100/255 [%]
+                        *engine_data = ((can_MsgRx.data[3]*100)/255);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ENGINE_OIL_TEMP:                   //A-40 [DegC]
+                        *engine_data = (can_MsgRx.data[3]-40);
+                        //sprintf(buffer,"%d DegC",(int) *engine_data);
+                        break;
+                    case FUEL_TIMING:                       //(38655-((A*256)+B))/128
+                        *engine_data = ((38655 - ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]))/128);
+                        //sprintf(buffer,"%d Deg",(int) *engine_data);
+                        break;
+                    case FUEL_RATE:                         //((A*256)+B)*0.05
+                        *engine_data = (((can_MsgRx.data[3]*256)+can_MsgRx.data[4])*0.05);
+                        //sprintf(buffer,"%d L/m",(int) *engine_data);
+                        break;
+                    case EMISSIONS_STANDARD:                //bit encoded ----NOT DONE----
+                        break;
+                    case DEMANDED_TORQUE:                   //A-125 [%]
+                        *engine_data = (can_MsgRx.data[3]-125);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case ACTUAL_TORQUE:                     //A-125 [%]
+                        *engine_data = (can_MsgRx.data[3]-125);
+                        //sprintf(buffer,"%d %%",(int) *engine_data);
+                        break;
+                    case REFERENCE_TORQUE:                  //A*256+b [Nm]
+                        *engine_data = ((can_MsgRx.data[3]*256)+can_MsgRx.data[4]);
+                        //sprintf(buffer,"%d Nm",(int) *engine_data);
+                        break;
+                    case ENGINE_PCT_TORQUE:                 //A-125 idle, B-125 pt 1, C-125, D-125
+                        *engine_data = (can_MsgRx.data[3]);
+                        //sprintf(buffer,"%d %% - Idle",(int) *engine_data);
+                        *engine_data = (can_MsgRx.data[4]);
+                        //sprintf(buffer2,"%d %% - Point 1",(int) *engine_data);
+                        *engine_data = (can_MsgRx.data[5]);
+                        //sprintf(buffer3,"%d %% - Point 2",(int) *engine_data);
+                        *engine_data = (can_MsgRx.data[6]);
+                        //sprintf(buffer4,"%d %% - Point 3",(int) *engine_data);
+                        break;
+                    case AUX_IO_SUPPORTED:                  //Bit encoded ----NOT DONE----
+                        break;
+                    case P_MAF_SENSOR:
+                    case P_ENGINE_COOLANT_T:
+                    case P_INTAKE_TEMP:
+                    case P_COMMANDED_EGR:
+                    case P_COMMANDED_INTAKE:
+                    case P_EGR_TEMP:
+                    case P_COMMANDED_THROT:
+                    case P_FUEL_PRESSURE:
+                    case P_FUEL_INJ_PRES:
+                    case P_TURBO_PRESSURE:
+                    case P_BOOST_PRES_CONT:
+                    case P_VGT_CONTROL:
+                    case P_WASTEGATE_CONT:
+                    case P_EXHAUST_PRESSURE:
+                    case P_TURBO_RPM:
+                    case P_TURBO_TEMP1:
+                    case P_TURBO_TEMP2:
+                    case P_CACT:
+                    case P_EGT_B1:
+                    case P_EGT_B2:
+                    case P_DPF1:
+                    case P_DPF2:
+                    case P_DPF_TEMP:
+                    case P_NOX_NTE_STATUS:
+                    case P_PM_NTE_STATUS:
+                    case P_ENGINE_RUNTUME:
+                    case P_ENGINE_AECD_1:
+                    case P_ENGINE_AECD_2:
+                    case P_NOX_SENSOR:
+                    case P_MANIFOLD_TEMP:
+                    case P_NOX_SYSTEM:
+                    case P_PM_SENSOR:
+                    case P_IN_MANIF_TEMP:
+                        //sprintf(buffer,"Not supported");
+                        break;
+                } // switch
+        
+                return 1;
+        
+             } // if
+
+         } // if read
+     } // while
+
+     return 0;
+  
+
+
+
+}
+} // namespace mbed 
\ No newline at end of file