Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE SDFileSystem mbed-rtos mbed
Revision 0:2fa4b8d8fbd0, committed 2014-12-09
- Comitter:
- julieefreeman
- Date:
- Tue Dec 09 18:12:57 2014 +0000
- Commit message:
- First stable version of dashboard project implementing CAN bus and OBDII
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ecu_reader.cpp Tue Dec 09 18:12:57 2014 +0000
@@ -0,0 +1,823 @@
+#include "mbed.h"
+#include "ecu_reader.h"
+#include "globals.h"
+// Use a timer to see if things take too long
+Timer CANTimer;
+namespace mbed {
+ecu_reader::ecu_reader(int can_speed) {
+ can2.frequency(can_speed);
+}
+
+#define TIMEOUT 1000
+unsigned char ecu_reader::request(unsigned char pid, char *buffer, char *buffer2, char *buffer3, char *buffer4) {
+ led1 = 1;
+ char can_msg[8];
+ float engine_data;
+ 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 (pid==VIN_MACRO) {
+ can_msg[1] = 0x9;
+ can_msg[2] = 0x2;
+ }
+
+ if (can2.write(CANMessage(PID_REQUEST, can_msg, 8))) {
+ pc.printf("*********Request write passed*********\n\r");
+ } else {
+ pc.printf("*********Request write failed*********\n\r");
+ }
+
+ led1 = 0;
+ CANTimer.reset();
+ CANTimer.start();
+
+ while (CANTimer.read_ms() < TIMEOUT) {
+
+ if (can2.read(can_MsgRx, 0)) {
+ if (((can_MsgRx.id == PID_REPLY) && can_MsgRx.data[2] == pid)) { //(can_MsgRx.id == PID_REPLY) &&
+ pc.printf("Valid OBD-II PID reply\n\r");
+ /* 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",(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);
+ sprintf(buffer,"%d",(int) engine_data);
+ break;
+ case VEHICLE_SPEED: // A [km/h]
+ engine_data = can_MsgRx.data[3];
+ sprintf(buffer,"%d",(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",(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",(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:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_ENGINE_COOLANT_T:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_INTAKE_TEMP:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_COMMANDED_EGR:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_COMMANDED_INTAKE:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_EGR_TEMP:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_COMMANDED_THROT:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_FUEL_PRESSURE:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_FUEL_INJ_PRES:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_TURBO_PRESSURE:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_BOOST_PRES_CONT:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_VGT_CONTROL:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_WASTEGATE_CONT:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_EXHAUST_PRESSURE:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_TURBO_RPM:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_TURBO_TEMP1:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_TURBO_TEMP2:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_CACT:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_EGT_B1:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_EGT_B2:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_DPF1:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_DPF2:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_DPF_TEMP:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_NOX_NTE_STATUS:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_PM_NTE_STATUS:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_ENGINE_RUNTUME:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_ENGINE_AECD_1:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_ENGINE_AECD_2:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_NOX_SENSOR:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_MANIFOLD_TEMP:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_NOX_SYSTEM:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_PM_SENSOR:
+ sprintf(buffer,"Not supported");
+ break;
+ case P_IN_MANIF_TEMP:
+ sprintf(buffer,"Not supported");
+ break;
+
+ }// End Switch (PID)
+ return 1;
+ }// End If Valid Reply
+ }// End If Read CAN Message
+ }
+ pc.printf("CANBus Timeout -- ");
+ return 0;
+}
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ecu_reader.h Tue Dec 09 18:12:57 2014 +0000
@@ -0,0 +1,258 @@
+#ifndef ECU_READER_H
+#define ECU_READER_H
+
+#define CANSPEED_125 125000 // CAN speed at 125 kbps
+#define CANSPEED_250 250000 // CAN speed at 250 kbps
+#define CANSPEED_500 500000 // CAN speed at 500 kbps
+
+/* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */
+#define PID_0_20 0x00 //PID 0 - 20 supported
+#define PID_0_20_DESC "PID 0x00 - 0x20 Supported"
+#define STATUS_DTC 0x01 ///
+#define STATUS_DTC_DESC "Status since DTC Cleared"
+#define FREEZE_DTC 0x02 ///
+#define FREEZE_DTC_DESC "Freeze Diagnostic Trouble Code"
+#define FUEL_SYS_STATUS 0x03 ///
+#define FUEL_SYS_STATUS_DESC "Fuel System Status"
+#define ENGINE_LOAD 0x04 //
+#define ENGINE_LOAD_DESC "Calculated Engine Load"
+#define ENGINE_COOLANT_TEMP 0x05
+#define ENGINE_COOLANT_TEMP_DESC "Engine Coolant Temperature"
+#define ST_FUEL_TRIM_1 0x06 ///
+#define ST_FUEL_TRIM_1_DESC "Short Term Fuel % Trim - Bank 1"
+#define LT_FUEL_TRIM_1 0x07 ///
+#define LT_FUEL_TRIM_1_DESC "Long Term Fuel % Trim - Bank 1"
+#define ST_FUEL_TRIM_2 0x08 ///
+#define ST_FUEL_TRIM_2_DESC "Short Term Fuel % Trim - Bank 2"
+#define LT_FUEL_TRIM_2 0x09 ///
+#define LT_FUEL_TRIM_2_DESC "Long Term Fuel % Trim - Bank 2"
+#define FUEL_PRESSURE 0x0A //
+#define FUEL_PRESSURE_DESC "Fuel Pressure"
+#define INTAKE_PRESSURE 0x0B //
+#define INTAKE_PRESSURE_DESC "Intake Manifold Absolute Pressure"
+#define ENGINE_RPM 0x0C
+#define ENGINE_RPM_DESC "Engine RPM"
+#define VEHICLE_SPEED 0x0D
+#define VEHICLE_SPEED_DESC "Vehicle Speed"
+#define TIMING_ADVANCE 0x0E //
+#define TIMING_ADVANCE_DESC "Timing Advance"
+#define INTAKE_TEMP 0x0F //
+#define INTAKE_TEMP_DESC "Intake Air Temperature"
+#define MAF_SENSOR 0x10
+#define MAF_SENSOR_DESC "MAF Sensor Air Flow Rate"
+#define THROTTLE 0x11
+#define THROTTLE_DESC "Throttle Position"
+#define COMMANDED_SEC_AIR 0x12 ///
+#define COMMANDED_SEC_AIR_DESC "Commanded Secondary Air Status"
+#define O2_SENS_PRES 0x13 ///
+#define O2_SENS_PRES_DESC "Detected O2 Sensors"
+#define O2_B1S1_VOLTAGE 0x14 ///
+#define O2_B1S1_VOLTAGE_DESC "O2 Sensor Voltage - Bank 1 Sensor 1"
+#define O2_B1S2_VOLTAGE 0x15 ///
+#define O2_B1S2_VOLTAGE_DESC "O2 Sensor Voltage - Bank 1 Sensor 2"
+#define O2_B1S3_VOLTAGE 0x16 ///
+#define O2_B1S3_VOLTAGE_DESC "O2 Sensor Voltage - Bank 1 Sensor 3"
+#define O2_B1S4_VOLTAGE 0x17 ///
+#define O2_B1S4_VOLTAGE_DESC "O2 Sensor Voltage - Bank 1 Sensor 4"
+#define O2_B2S1_VOLTAGE 0x18 ///
+#define O2_B2S1_VOLTAGE_DESC "O2 Sensor Voltage - Bank 2 Sensor 1"
+#define O2_B2S2_VOLTAGE 0x19 ///
+#define O2_B2S2_VOLTAGE_DESC "O2 Sensor Voltage - Bank 2 Sensor 2"
+#define O2_B2S3_VOLTAGE 0x1A ///
+#define O2_B2S3_VOLTAGE_DESC "O2 Sensor Voltage - Bank 2 Sensor 3"
+#define O2_B2S4_VOLTAGE 0x1B ///
+#define O2_B2S4_VOLTAGE_DESC "O2 Sensor Voltage - Bank 2 Sensor 4"
+#define OBDII_STANDARDS 0x1C //List of OBDII Standars the car conforms to
+#define OBDII_STANDARDS_DESC "Supported OBDII Standards"
+#define O2_SENS_PRES_ALT 0x1D ///
+#define O2_SENS_PRES_ALT_DESC "Detected O2 Sensors - Alternate Grouping"
+#define AUX_IN_STATUS 0x1E ///
+#define AUX_IN_STATUS_DESC "Auxiliary Input Status"
+#define ENGINE_RUNTIME 0x1F //
+#define ENGINE_RUNTIME_DESC "Run Time Since Engine Started"
+#define PID_21_40 0x20 //PID 21-40 supported
+#define PID_21_40_DESC "PID 0x21 - 0x40 Supported"
+#define DIST_TRAVELED_MIL 0x21 ///
+#define DIST_TRAVELED_MIL_DESC "Distance Traveled with MIL On"
+#define FUEL_RAIL_PRESSURE 0x22 //
+#define FUEL_RAIL_PRESSURE_DESC "Fuel Rail Pressure Relative to Manifold"
+#define FUEL_RAIL_PRES_ALT 0x23 ///
+#define FUEL_RAIL_PRES_ALT_DESC "MPI/Diesel Fuel Rail Pressure"
+#define O2S1_WR_LAMBDA_V 0x24 ///
+#define O2S1_WR_LAMBDA_V_DESC "O2 Sensor 1 Equivalence Ratio Voltage"
+#define O2S2_WR_LAMBDA_V 0x25 ///
+#define O2S2_WR_LAMBDA_V_DESC "O2 Sensor 2 Equivalence Ratio Voltage"
+#define O2S3_WR_LAMBDA_V 0x26 ///
+#define O2S3_WR_LAMBDA_V_DESC "O2 Sensor 3 Equivalence Ratio Voltage"
+#define O2S4_WR_LAMBDA_V 0x27 ///
+#define O2S4_WR_LAMBDA_V_DESC "O2 Sensor 4 Equivalence Ratio Voltage"
+#define O2S5_WR_LAMBDA_V 0x28 ///
+#define O2S5_WR_LAMBDA_V_DESC "O2 Sensor 5 Equivalence Ratio Voltage"
+#define O2S6_WR_LAMBDA_V 0x29 ///
+#define O2S6_WR_LAMBDA_V_DESC "O2 Sensor 6 Equivalence Ratio Voltage"
+#define O2S7_WR_LAMBDA_V 0x2A ///
+#define O2S7_WR_LAMBDA_V_DESC "O2 Sensor 7 Equivalence Ratio Voltage"
+#define O2S8_WR_LAMBDA_V 0x2B ///
+#define O2S8_WR_LAMBDA_V_DESC "O2 Sensor 8 Equivalence Ratio Voltage"
+#define COMMANDED_EGR 0x2C //
+#define COMMANDED_EGR_DESC "Commanded EGR"
+#define EGR_ERROR 0x2D //
+#define EGR_ERROR_DESC "EGR Error"
+#define COMMANDED_EVAP_P 0x2E ///
+#define COMMANDED_EVAP_P_DESC "Commanded Evaporative Purge"
+#define FUEL_LEVEL 0x2F //
+#define FUEL_LEVEL_DESC "Fuel Level Input"
+#define WARMUPS_SINCE_CLR 0x30 ///
+#define WARMUPS_SINCE_CLR_DESC "Number of Warmups since DTC Cleared"
+#define DIST_SINCE_CLR 0x31 ///
+#define DIST_SINCE_CLR_DESC "Distance Traveled Since DTC Cleared"
+#define EVAP_PRESSURE 0x32 //
+#define EVAP_PRESSURE_DESC "Evap. System Vapor Pressure"
+#define BAROMETRIC_PRESSURE 0x33 //
+#define BAROMETRIC_PRESSURE_DESC "Barometric Pressure"
+#define O2S1_WR_LAMBDA_I 0x34 ///
+#define O2S1_WR_LAMBDA_I_DESC "O2 Sensor 1 Equivalence Ratio Current"
+#define O2S2_WR_LAMBDA_I 0x35 ///
+#define O2S2_WR_LAMBDA_I_DESC "O2 Sensor 2 Equivalence Ratio Current"
+#define O2S3_WR_LAMBDA_I 0x36 ///
+#define O2S3_WR_LAMBDA_I_DESC "O2 Sensor 3 Equivalence Ratio Current"
+#define O2S4_WR_LAMBDA_I 0x37 ///
+#define O2S4_WR_LAMBDA_I_DESC "O2 Sensor 4 Equivalence Ratio Current"
+#define O2S5_WR_LAMBDA_I 0x38 ///
+#define O2S5_WR_LAMBDA_I_DESC "O2 Sensor 5 Equivalence Ratio Current"
+#define O2S6_WR_LAMBDA_I 0x39 ///
+#define O2S6_WR_LAMBDA_I_DESC "O2 Sensor 6 Equivalence Ratio Current"
+#define O2S7_WR_LAMBDA_I 0x3A ///
+#define O2S7_WR_LAMBDA_I_DESC "O2 Sensor 7 Equivalence Ratio Current"
+#define O2S8_WR_LAMBDA_I 0x3B ///
+#define O2S8_WR_LAMBDA_I_DESC "O2 Sensor 8 Equivalence Ratio Current"
+#define CAT_TEMP_B1S1 0x3C ///
+#define CAT_TEMP_B1S1_DESC "Catalyst Temperature Bank 1 Sensor 1"
+#define CAT_TEMP_B1S2 0x3E ///
+#define CAT_TEMP_B1S2_DESC "Catalyst Temperature Bank 1 Sensor 2"
+#define CAT_TEMP_B2S1 0x3D ///
+#define CAT_TEMP_B2S1_DESC "Catalyst Temperature Bank 2 Sensor 1"
+#define CAT_TEMP_B2S2 0x3F ///
+#define CAT_TEMP_B2S2_DESC "Catalyst Temperature Bank 2 Sensor 2"
+#define PID_41_60 0x40 //PID 41-60 supported
+#define PID_41_60_DESC "PID 0x41 - 0x60 Supported"
+#define MONITOR_STATUS 0x41 ///
+#define MONITOR_STATUS_DESC "Monitor Status This Drive Cycle"
+#define ECU_VOLTAGE 0x42 //
+#define ECU_VOLTAGE_DESC "Control Module Voltage"
+#define ABSOLUTE_LOAD 0x43 //
+#define ABSOLUTE_LOAD_DESC "Absolute Load Value"
+#define COMMANDED_EQUIV_R 0x44 ///
+#define COMMANDED_EQUIV_R_DESC "Commanded Equivalence Ratio"
+#define REL_THROTTLE_POS 0x45 ///
+#define REL_THROTTLE_POS_DESC "Relative Throttle Position"
+#define AMB_AIR_TEMP 0x46 ///
+#define AMB_AIR_TEMP_DESC "Ambient Air Temperature"
+#define ABS_THROTTLE_POS_B 0x47 ///
+#define ABS_THROTTLE_POS_B_DESC "Absolute Throttle Position B"
+#define ABS_THROTTLE_POS_C 0x48 ///
+#define ABS_THROTTLE_POS_C_DESC "Absolute Throttle Position C"
+#define ACCEL_POS_D 0x49 ///
+#define ACCEL_POS_D_DESC "Accelerator Pedal Position D"
+#define ACCEL_POS_E 0x4A ///
+#define ACCEL_POS_E_DESC "Accelerator Pedal Position E"
+#define ACCEL_POS_F 0x4B ///
+#define ACCEL_POS_F_DESC "Accelerator Pedal Position F"
+#define COMMANDED_THROTTLE 0x4C ///
+#define COMMANDED_THROTTLE_DESC "Commanded Throttle Actuator"
+#define TIME_RUN_WITH_MIL 0x4D ///
+#define TIME_RUN_WITH_MIL_DESC "Time Run with MIL on"
+#define TIME_SINCE_CLR 0x4E ///
+#define TIME_SINCE_CLR_DESC "Time Since DTC Cleared"
+#define MAX_R_O2_VI_PRES 0x4F ///
+#define MAX_R_O2_VI_PRES_DESC "Maximum Value - Equivalence ratio, O2 Voltage, O2 Current, Intake Manifold Pressure"
+#define MAX_AIRFLOW_MAF 0x50 ///
+#define MAX_AIRFLOW_MAF_DESC "Maximum MAF Airflow Value"
+#define FUEL_TYPE 0x51 //
+#define FUEL_TYPE_DESC "Fuel Type"
+#define ETHANOL_PERCENT 0x52 //
+#define ETHANOL_PERCENT_DESC "Ethanol fuel %"
+#define ABS_EVAP_SYS_PRES 0x53 ///
+#define ABS_EVAP_SYS_PRES_DESC "absolute Evap. System Vapor Pressure"
+#define EVAP_SYS_PRES 0x54 ///
+#define EVAP_SYS_PRES_DESC "Evap. System Vapor Pressure"
+#define ST_O2_TRIM_B1B3 0x55 ///
+#define ST_O2_TRIM_B1B3_DESC "Short Term Secondary O2 Sensor Trim - Bank 1 and 3"
+#define LT_O2_TRIM_B1B3 0x56 ///
+#define LT_O2_TRIM_B1B3_DESC "Long Term Secondary O2 Sensor Trim - Bank 1 and 3"
+#define ST_02_TRIM_B2B4 0x57 ///
+#define ST_O2_TRIM_B2B4_DESC "Short Term Secondary O2 Sensor Trim - Bank 2 and 4"
+#define LT_O2_TRIM_B2B4 0x58 ///
+#define LT_O2_TRIM_B2B4_DESC "Long Term Secondary O2 Sensor Trim - Bank 2 and 4"
+#define ABS_FUEL_RAIL_PRES 0x59 ///
+#define ABS_FUEL_RAIL_PRES_DESC "Absolute Fuel Rail Pressure"
+#define REL_ACCEL_POS 0x5A ///
+#define REL_ACCEL_POS_DESC "Relative Accelerator Pedal Position"
+#define HYBRID_BATT_PCT 0x5B ///
+#define HYBRID_BATT_PCT_DESC "Hybrid Battery Pack Charge Percent"
+#define ENGINE_OIL_TEMP 0x5C ///
+#define ENGINE_OIL_TEMP_DESC "Engine Oil Temperature"
+#define FUEL_TIMING 0x5D //
+#define FUEL_TIMING_DESC "Fuel Injection Timing"
+#define FUEL_RATE 0x5E //
+#define FUEL_RATE_DESC "Engine Fuel Rate"
+#define EMISSIONS_STANDARD 0x5F ///
+#define EMISSIONS_STANDARD_DESC "Emmissions Requirements"
+#define DEMANDED_TORQUE 0x61 ///
+#define DEMANDED_TORQUE_DESC "Driver's Demanded Torque - Percent"
+#define ACTUAL_TORQUE 0x62 ///
+#define ACTUAL_TORQUE_DESC "Actual Engine Torque - Percent"
+#define REFERENCE_TORQUE 0x63 //
+#define REFERENCE_TORQUE_DESC "Engine Reference Torque"
+#define ENGINE_PCT_TORQUE 0x64 ///
+#define ENGINE_PCT_TORQUE_DESC "Engine Percent Torque"
+#define AUX_IO_SUPPORTED 0x65 ///
+#define AUX_IO_SUPPORTED_DESC "Auxiliary Input/Output Supported"
+#define P_MAF_SENSOR 0x66 ///
+#define P_ENGINE_COOLANT_T 0x67 ///
+#define P_INTAKE_TEMP 0x68 ///
+#define P_COMMANDED_EGR 0x69 ///
+#define P_COMMANDED_INTAKE 0x6A ///
+#define P_EGR_TEMP 0x6B ///
+#define P_COMMANDED_THROT 0x6C ///
+#define P_FUEL_PRESSURE 0x6D ///
+#define P_FUEL_INJ_PRES 0x6E ///
+#define P_TURBO_PRESSURE 0x6F ///
+#define P_BOOST_PRES_CONT 0x70 ///
+#define P_VGT_CONTROL 0x71 ///
+#define P_WASTEGATE_CONT 0x72 ///
+#define P_EXHAUST_PRESSURE 0x73 ///
+#define P_TURBO_RPM 0x74 ///
+#define P_TURBO_TEMP1 0x75 ///
+#define P_TURBO_TEMP2 0x76 ///
+#define P_CACT 0x77 ///
+#define P_EGT_B1 0x78 ///
+#define P_EGT_B2 0x79 ///
+#define P_DPF1 0x7A ///
+#define P_DPF2 0x7B ///
+#define P_DPF_TEMP 0x7C ///
+#define P_NOX_NTE_STATUS 0x7D ///
+#define P_PM_NTE_STATUS 0x7E ///
+#define P_ENGINE_RUNTUME 0x7F ///
+#define P_ENGINE_AECD_1 0x81 ///
+#define P_ENGINE_AECD_2 0x82 ///
+#define P_NOX_SENSOR 0x83 ///
+#define P_MANIFOLD_TEMP 0x84 ///
+#define P_NOX_SYSTEM 0x85 ///
+#define P_PM_SENSOR 0x86 ///
+#define P_IN_MANIF_TEMP 0x87 ///
+#define VIN_MACRO 0x902 // VIN requests mode 9, pid 02
+
+#define PID_REQUEST 0x7DF
+#define PID_REPLY 0x7E8
+
+namespace mbed {
+class ecu_reader {
+public:
+ ecu_reader(int can_speed);
+ unsigned char request(unsigned char pid, char *buffer, char *buffer2 = NULL, char *buffer3 = NULL, char *buffer4 = NULL);
+private:
+ int i;
+};
+}
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/globals.cpp Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,14 @@ +#include "globals.h" + +uLCD_4DGL lcd(p9,p10,p11); // serial tx, serial rx, reset pin; +Serial pc (USBTX,USBRX); + +DigitalOut led1 (LED1); +DigitalOut led2 (LED2); +DigitalOut led3 (LED3); +DigitalOut led4 (LED4); + +// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD). +CAN can2(p30, p29); +CANMessage can_MsgRx; +int PID020, PID2140, PID4160; //PID Support Masks \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/globals.h Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,20 @@ +#ifndef GLOBALS_H +#define GLOBALS_H + +#include "mbed.h" +#include "uLCD_4DGL.h" + +extern Serial pc; +extern uLCD_4DGL lcd; +extern DigitalOut led1; +extern DigitalOut led2; +extern DigitalOut led3; +extern DigitalOut led4; + +// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD). +extern CAN can2; +extern CANMessage can_MsgRx; +extern int PID020; +extern int PID2140; +extern int PID4160; //PID Support Masks +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Dec 09 18:12:57 2014 +0000
@@ -0,0 +1,348 @@
+/*
+mbed Dashboard trip computer
+December 2014
+********************************************************************************
+WARNING: Use at your own risk, sadly this software comes with no guarantees.
+This software is provided 'free' and in good faith, but the author does not
+accept liability for any damage arising from its use.
+********************************************************************************
+*/
+
+#include "mbed.h"
+#include "ecu_reader.h"
+#include "globals.h"
+#include "rtos.h"
+#include "SDFileSystem.h"
+
+Mutex stdio_mutex;
+ecu_reader obdii1(CANSPEED_125); //supports different CAN speeds
+ecu_reader obdii2(CANSPEED_250);
+ecu_reader obdii3(CANSPEED_500);
+InterruptIn switch_reading(p8);
+SDFileSystem sd(p5, p6, p7, p12, "sd");
+DigitalOut myled4(LED4);
+DigitalOut myled3(LED3);
+
+int flag; //indicates which reading to get from vehicle
+int change; //signifies that the system is switching readings
+char temp_buffer[20]; //buffers for readings from vehicle
+char rpm_buffer[20];
+char speed_buffer[20];
+char time_buff[32];
+char buffer[20];
+float dial_len;
+int ui_temp, ui_rpm;
+float ui_speed;
+int dist_init;
+float dist;
+time_t seconds;
+int testing_temp; //not connected to car
+int testing_rpm; //not connected to car
+int testing_speed;
+
+void display_coolant_temp();
+void display_rpm();
+void draw_tachometer();
+void draw_thermometer();
+void display_speed();
+void draw_speedometer();
+void display_trip();
+
+void pb_hit_interrupt (void) {
+ myled4 = 1;
+ flag = flag+1;
+ if (flag>3) {
+ flag = 0;
+ ui_temp = -1;
+ }
+ else if (flag == 1)
+ ui_rpm = -1;
+ else if (flag == 2)
+ ui_speed = -1;
+ wait(0.5);
+ myled4 = 0;
+ change = 1;
+}
+void testingThread(void const *args) { // run this thread and set main OBD request conditions to 0 to test UI
+ ui_temp = -1;
+ ui_rpm = -1;
+ testing_temp = 100;
+ testing_rpm = 0;
+ dist_init = 0;
+ testing_speed = 0;
+ while(1){
+ // --- TESTING ONLY - WITHOUT CAR ---
+ sprintf(temp_buffer,"%d",testing_temp);
+ sprintf(rpm_buffer,"%d",testing_rpm);
+ sprintf(speed_buffer,"%d", testing_speed);
+ dist += 0.1;
+ testing_temp -= 1;
+ testing_rpm += 100;
+ testing_speed +=5;
+ if (testing_temp<5) {
+ testing_temp = 100;
+ }
+ if (testing_rpm>5000) {
+ testing_rpm = 900;
+ }
+ // --- TESTING ONLY - WITHOUT CAR ---
+ Thread::wait(1000);
+ }
+}
+
+void sdThread(void const *args) {
+ dist = -1;
+ dist_init = -1;
+ set_time(0);
+ char file[35];
+ char buffer[32];
+ char hours[5];
+ char minutes[5];
+ float hrs = 0;
+ FILE *fp;
+
+ mkdir("/sd/tripStats",0777);
+ sprintf(file, "/sd/tripStats/log.txt");
+ while (dist_init == -1){ //
+ stdio_mutex.lock();
+ if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){
+ dist_init = atoi(buffer);
+ }
+ stdio_mutex.unlock();
+ }
+
+ while (1){
+ fp = fopen(file, "w");
+ myled3 = 1;
+ seconds = time(NULL);
+ strftime(time_buff, 32, "%R:%S", localtime(&seconds));
+ strftime(hours, 5, "%H", localtime(&seconds));
+ strftime(minutes, 5, "%M", localtime(&seconds));
+ hrs = atoi(hours) + ((float)atoi(minutes))/60;
+ if(fp == NULL) {
+ error("Could not open file for write\n");
+ }
+ stdio_mutex.lock();
+ if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){
+ dist = ((float)atoi(buffer)-dist_init)*0.62;
+ }
+ stdio_mutex.unlock();
+ fprintf(fp, "Time since mbed start: %s\n\n", time_buff);
+ fprintf(fp, "Distance Traveled: %2.2f miles\n", dist);
+ fprintf(fp, "Average Speed: %2.2f mph\n", dist/hrs);
+ fclose(fp);
+ myled3 = 0;
+ Thread::wait(30000); //write to SD card every 30 seconds
+ }
+}
+
+int main() {
+ ui_temp = -1; //initialize default values
+ ui_rpm = -1;
+ ui_speed = -1;
+ change = 0;
+ flag = 0;
+ dial_len = 60.0;
+ lcd.cls();
+ lcd.baudrate(3000000);
+ switch_reading.mode(PullUp);
+ wait(0.2);
+ switch_reading.fall(&pb_hit_interrupt);
+ Thread t2(sdThread);
+ //Thread test(testingThread); //run this thread and change OBD request conditions to 0 to test UI
+
+ while (1) { //main thread
+ if (change == 0) { //update LCD only when not in process of switching screens
+ switch (flag){
+ case 0: //engine coolant temperature
+ if(obdii3.request(ENGINE_COOLANT_TEMP, temp_buffer) == 1){ //set to 1 for car, 0 for testing UI
+ stdio_mutex.lock();
+ display_coolant_temp();
+ stdio_mutex.unlock();
+ }
+ else {
+ can2.reset();
+ wait(0.5);
+ }
+ break;
+ case 1: //engine rpm
+ if (obdii3.request(ENGINE_RPM, rpm_buffer) == 1){ //set to 1 for car, 0 for testing UI
+ stdio_mutex.lock();
+ display_rpm();
+ stdio_mutex.unlock();
+ }
+ else {
+ can2.reset();
+ wait(0.5);
+ }
+ break;
+ case 2: //vehicle speed
+ if (obdii3.request(VEHICLE_SPEED, speed_buffer) == 1){ //set to 1 for car, 0 for testing UI
+ stdio_mutex.lock();
+ display_speed();
+ stdio_mutex.unlock();
+ }
+ else {
+ can2.reset();
+ wait(0.5);
+ }
+ break;
+ case 3: //distance since codes last cleared
+ if(obdii3.request(DIST_SINCE_CLR, buffer) == 1){
+ dist = ((float)atoi(buffer)-(float)dist_init)*0.62;
+ stdio_mutex.lock();
+ display_trip();
+ stdio_mutex.unlock();
+ }
+ else {
+ stdio_mutex.lock();
+ display_trip();
+ stdio_mutex.unlock();
+ can2.reset();
+ wait(0.5);
+ }
+ break;
+ }
+ }
+ else {
+ lcd.cls();
+ change = 0;
+ }
+ }
+}
+
+void display_coolant_temp(){ //displays temperature
+ float farenheit = atoi(temp_buffer) * 9/5 +32;
+ draw_thermometer();
+ lcd.color(0x909090);
+ lcd.text_width(2);
+ lcd.text_height(2);
+ lcd.locate(1,0);
+ lcd.printf("%s\n\r", "COOLANT\n TEMP.");
+ lcd.color(0x66CCFF);
+ lcd.locate(0,3);
+ lcd.printf("%3.0f \n\r", farenheit);
+ lcd.locate(0,4);
+ lcd.printf("oF\n\r");
+}
+
+void draw_thermometer(){ //draws temperature animation
+ lcd.rectangle(73,47,119,128,0xFFFFFF);
+ int new_temp = atoi(temp_buffer);
+ int height = 128-ceil((float)new_temp*.8);
+
+ if (new_temp > 100 && ui_temp!=new_temp) { //red
+ lcd.filled_rectangle(74,48,118,67,0xFF0000);
+ }
+ else if (new_temp > 75 && ui_temp!=new_temp) {
+ if (ui_temp>new_temp) lcd.filled_rectangle(74,48,118,height,0x000000);
+ lcd.filled_rectangle(74,height,118,67,0xFF0000);
+ }
+ else lcd.filled_rectangle(74,48,118,67,0x000000);
+ if (new_temp > 75 && ui_temp!=new_temp) { //dark orange
+ lcd.filled_rectangle(74,68,118,87,0xFF4719);
+ }
+ else if (new_temp > 50 && ui_temp!=new_temp) {
+ if (ui_temp>new_temp) lcd.filled_rectangle(74,68,118,height,0x000000);
+ lcd.filled_rectangle(74,height,118,87,0xFF4719);
+ }
+ else lcd.filled_rectangle(74,68,118,87,0x000000);
+ if (new_temp > 50 && ui_temp!=new_temp) { //orange
+ lcd.filled_rectangle(74,88,118,107,0xFF9933);
+ }
+ else if (new_temp > 25 && ui_temp!=new_temp) {
+ if (ui_temp>new_temp) lcd.filled_rectangle(74,88,118,height,0x000000);
+ lcd.filled_rectangle(74,height,118,107,0xFF9933);
+ }
+ else lcd.filled_rectangle(74,88,118,107,0x000000);
+ if (new_temp > 25 && ui_temp!=new_temp) { //yellow
+ lcd.filled_rectangle(74,108,118,128,0xFFFF99);
+ }
+ else if (new_temp > 0 && ui_temp!=new_temp) {
+ if (ui_temp>new_temp) lcd.filled_rectangle(74,108,118,height,0x000000);
+ lcd.filled_rectangle(74,height,118,128,0xFFFF99);
+ }
+ else lcd.filled_rectangle(74,108,118,128,0x000000);
+ ui_temp = new_temp;
+}
+
+void display_rpm(){ //displays rpm
+ draw_tachometer();
+ lcd.color(0x909090);
+ lcd.text_width(2);
+ lcd.text_height(2);
+ lcd.locate(1,0);
+ lcd.printf("%s\n\r", "ENG RPM");
+ lcd.color(0x66CCFF);
+ lcd.text_width(3);
+ lcd.text_height(3);
+ lcd.locate(1,1);
+ lcd.printf("%s \n\r", rpm_buffer);
+}
+
+void draw_tachometer(){ //draws rpm gauge
+ lcd.circle(64,120,60,0xFFFFFF);
+ int new_rpm = atoi(rpm_buffer);
+ int x = int(cos(float(new_rpm)*0.00041887902)*dial_len);
+ int y = int(sin(float(new_rpm)*0.00041887902)*dial_len);
+ if (ui_rpm!=new_rpm && ui_rpm!=-1) {
+ int old_x = int(cos(float(ui_rpm)*0.00041887902)*dial_len);
+ int old_y = int(sin(float(ui_rpm)*0.00041887902)*dial_len);
+ lcd.line(64-old_x,120-old_y,64,120,0x000000);
+ }
+ lcd.line(64-x,120-y,64,120,0xFF8C00);
+ ui_rpm = new_rpm;
+}
+
+void display_speed() { //displays speed
+ draw_speedometer();
+ lcd.color(0x909090);
+ lcd.text_width(2);
+ lcd.text_height(2);
+ lcd.locate(1,0);
+ lcd.printf("%s\n\r", "SPEED");
+ lcd.color(0x66CCFF);
+ lcd.text_width(3);
+ lcd.text_height(3);
+ lcd.locate(1,1);
+ lcd.printf("%3.0f \n\r", (((float)atoi(speed_buffer))*0.62));
+}
+
+void draw_speedometer(){ //draws gauge for speed
+ lcd.circle(64,120,60,0xFFFFFF);
+ float new_speed = atoi(speed_buffer) * 0.62;
+ int x = int(cos(new_speed*0.0314159265)*dial_len);
+ int y = int(sin(new_speed*0.0314159265)*dial_len);
+ if (ui_speed!=new_speed && ui_speed!=-1) {
+ int old_x = int(cos(ui_speed*0.0314159265)*dial_len);
+ int old_y = int(sin(ui_speed*0.0314159265)*dial_len);
+ lcd.line(64-old_x,120-old_y,64,120,0x000000);
+ }
+ lcd.line(64-x,120-y,64,120,0xFF8C00);
+ ui_speed = new_speed;
+}
+
+void display_trip() { //displays data being output to SD card
+ lcd.color(0x909090);
+ lcd.text_width(2);
+ lcd.text_height(2);
+ lcd.locate(0,0);
+ lcd.printf("%s\n\r", "TOTALTIME");
+ lcd.color(0x66CCFF);
+ lcd.text_width(3);
+ lcd.text_height(3);
+ lcd.locate(0,1);
+ strftime(time_buff, 32, "%R", localtime(&seconds));
+ lcd.printf("%s \n\r", time_buff);
+
+ lcd.color(0x909090);
+ lcd.text_width(2);
+ lcd.text_height(2);
+ lcd.locate(0,4);
+ lcd.printf("%s\n\r", "DISTANCE");
+ lcd.color(0x66CCFF);
+ lcd.text_width(3);
+ lcd.text_height(3);
+ lcd.locate(0,4);
+ lcd.printf("%3.1f \n\r", dist);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#631c0f1008c3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Dec 09 18:12:57 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89 \ No newline at end of file