CAN-Bus ECU simulator. Only part of the SAE J1979 are implemented. Uses CAN-Bus demo board as hardware platform. http://skpang.co.uk/catalog/canbus-ecu-simulator-with-lpc1768-module-p-1400.html Useful for testing diagnostic tools.
Fork of ecu_reader by
ecu_simulator.cpp@6:41a4ad385daa, 2014-12-30 (annotated)
- Committer:
- pangsk
- Date:
- Tue Dec 30 10:10:02 2014 +0000
- Revision:
- 6:41a4ad385daa
- Parent:
- ecu_reader.cpp@3:05bb8f0bd7a4
Initial version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pangsk | 0:908be729d27c | 1 | #include "mbed.h" |
pangsk | 6:41a4ad385daa | 2 | #include "ecu_simulator.h" |
pangsk | 0:908be729d27c | 3 | #include "globals.h" |
pangsk | 0:908be729d27c | 4 | |
pangsk | 0:908be729d27c | 5 | |
pangsk | 0:908be729d27c | 6 | // Use a timer to see if things take too long |
pangsk | 0:908be729d27c | 7 | Timer CANTimer; |
pangsk | 0:908be729d27c | 8 | namespace mbed { |
pangsk | 0:908be729d27c | 9 | |
pangsk | 0:908be729d27c | 10 | |
pangsk | 6:41a4ad385daa | 11 | ecu_sim::ecu_sim(int can_speed) |
pangsk | 6:41a4ad385daa | 12 | { |
pangsk | 6:41a4ad385daa | 13 | can2.frequency(can_speed); |
pangsk | 6:41a4ad385daa | 14 | } |
pangsk | 6:41a4ad385daa | 15 | |
pangsk | 6:41a4ad385daa | 16 | void ecu_sim::canspeed(int can_speed) |
pangsk | 0:908be729d27c | 17 | { |
pangsk | 0:908be729d27c | 18 | can2.frequency(can_speed); |
pangsk | 0:908be729d27c | 19 | } |
pangsk | 0:908be729d27c | 20 | |
pangsk | 3:05bb8f0bd7a4 | 21 | |
pangsk | 6:41a4ad385daa | 22 | |
pangsk | 0:908be729d27c | 23 | #define TIMEOUT 200 |
pangsk | 6:41a4ad385daa | 24 | unsigned char ecu_sim::request(void) |
pangsk | 0:908be729d27c | 25 | { |
pangsk | 0:908be729d27c | 26 | char can_msg[8]; |
pangsk | 6:41a4ad385daa | 27 | |
pangsk | 6:41a4ad385daa | 28 | |
pangsk | 6:41a4ad385daa | 29 | |
pangsk | 6:41a4ad385daa | 30 | |
pangsk | 6:41a4ad385daa | 31 | if ((can2.read(can_MsgRx)) && (can_MsgRx.id == PID_REQUEST) ){ |
pangsk | 6:41a4ad385daa | 32 | led2 = 1; |
pangsk | 6:41a4ad385daa | 33 | if(can_MsgRx.data[1] == MODE3) // Request trouble codes |
pangsk | 6:41a4ad385daa | 34 | { |
pangsk | 6:41a4ad385daa | 35 | if(ecu.dtc == false){ |
pangsk | 6:41a4ad385daa | 36 | can_msg[0] = 0x02; |
pangsk | 6:41a4ad385daa | 37 | can_msg[1] = MODE3_RESPONSE; |
pangsk | 6:41a4ad385daa | 38 | can_msg[2] = 0x00; |
pangsk | 6:41a4ad385daa | 39 | }else{ |
pangsk | 6:41a4ad385daa | 40 | can_msg[0] = 0x06; |
pangsk | 6:41a4ad385daa | 41 | can_msg[1] = MODE3_RESPONSE; |
pangsk | 6:41a4ad385daa | 42 | can_msg[2] = 0x02; |
pangsk | 6:41a4ad385daa | 43 | can_msg[3] = 0x01; |
pangsk | 6:41a4ad385daa | 44 | can_msg[4] = 0x00; |
pangsk | 6:41a4ad385daa | 45 | can_msg[5] = 0x02; |
pangsk | 6:41a4ad385daa | 46 | can_msg[6] = 0x00; |
pangsk | 6:41a4ad385daa | 47 | } |
pangsk | 6:41a4ad385daa | 48 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 49 | } |
pangsk | 0:908be729d27c | 50 | |
pangsk | 6:41a4ad385daa | 51 | if(can_MsgRx.data[1] == MODE4) // Clear trouble codes, clear Check engine light |
pangsk | 6:41a4ad385daa | 52 | { |
pangsk | 6:41a4ad385daa | 53 | ecu.dtc = false; |
pangsk | 6:41a4ad385daa | 54 | led4 = 0; |
pangsk | 6:41a4ad385daa | 55 | |
pangsk | 6:41a4ad385daa | 56 | can_msg[0] = 0x00; |
pangsk | 6:41a4ad385daa | 57 | can_msg[1] = MODE4_RESPONSE; |
pangsk | 6:41a4ad385daa | 58 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 59 | } |
pangsk | 0:908be729d27c | 60 | |
pangsk | 6:41a4ad385daa | 61 | if(can_MsgRx.data[1] == MODE1) |
pangsk | 6:41a4ad385daa | 62 | { |
pangsk | 6:41a4ad385daa | 63 | can_msg[1] = MODE1_RESPONSE; |
pangsk | 6:41a4ad385daa | 64 | switch(can_MsgRx.data[2]) |
pangsk | 6:41a4ad385daa | 65 | { /* Details from http://en.wikipedia.org/wiki/OBD-II_PIDs */ |
pangsk | 6:41a4ad385daa | 66 | case PID_SUPPORTED: |
pangsk | 6:41a4ad385daa | 67 | can_msg[0] = 0x06; |
pangsk | 6:41a4ad385daa | 68 | can_msg[2] = PID_SUPPORTED; |
pangsk | 6:41a4ad385daa | 69 | can_msg[3] = 0xE8; |
pangsk | 6:41a4ad385daa | 70 | can_msg[4] = 0x19; |
pangsk | 6:41a4ad385daa | 71 | can_msg[5] = 0x30; |
pangsk | 6:41a4ad385daa | 72 | can_msg[6] = 0x12; |
pangsk | 6:41a4ad385daa | 73 | can_msg[5] = 0x00; |
pangsk | 6:41a4ad385daa | 74 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 75 | |
pangsk | 6:41a4ad385daa | 76 | break; |
pangsk | 6:41a4ad385daa | 77 | |
pangsk | 6:41a4ad385daa | 78 | case MONITOR_STATUS: |
pangsk | 6:41a4ad385daa | 79 | can_msg[0] = 0x05; |
pangsk | 6:41a4ad385daa | 80 | can_msg[2] = MONITOR_STATUS; |
pangsk | 6:41a4ad385daa | 81 | |
pangsk | 6:41a4ad385daa | 82 | if(ecu.dtc == true) can_msg[3] = 0x82; |
pangsk | 6:41a4ad385daa | 83 | else can_msg[3] = 0x00; |
pangsk | 6:41a4ad385daa | 84 | |
pangsk | 6:41a4ad385daa | 85 | can_msg[4] = 0x07; |
pangsk | 6:41a4ad385daa | 86 | can_msg[5] = 0xFF; |
pangsk | 6:41a4ad385daa | 87 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 88 | break; |
pangsk | 6:41a4ad385daa | 89 | |
pangsk | 6:41a4ad385daa | 90 | case ENGINE_RPM: // ((A*256)+B)/4 [RPM] |
pangsk | 6:41a4ad385daa | 91 | can_msg[0] = 0x04; |
pangsk | 6:41a4ad385daa | 92 | can_msg[2] = ENGINE_RPM; |
pangsk | 6:41a4ad385daa | 93 | can_msg[3] = (ecu.engine_rpm & 0xff00) >> 8; |
pangsk | 6:41a4ad385daa | 94 | can_msg[4] = ecu.engine_rpm & 0x00ff; |
pangsk | 6:41a4ad385daa | 95 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 96 | break; |
pangsk | 6:41a4ad385daa | 97 | |
pangsk | 6:41a4ad385daa | 98 | case ENGINE_COOLANT_TEMP: // A-40 [degree C] |
pangsk | 6:41a4ad385daa | 99 | can_msg[0] = 0x03; |
pangsk | 6:41a4ad385daa | 100 | can_msg[2] = ENGINE_COOLANT_TEMP; |
pangsk | 6:41a4ad385daa | 101 | can_msg[3] = ecu.coolant_temp; |
pangsk | 6:41a4ad385daa | 102 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 103 | break; |
pangsk | 6:41a4ad385daa | 104 | |
pangsk | 6:41a4ad385daa | 105 | case VEHICLE_SPEED: // A [km] |
pangsk | 6:41a4ad385daa | 106 | can_msg[0] = 0x03; |
pangsk | 6:41a4ad385daa | 107 | can_msg[2] = VEHICLE_SPEED; |
pangsk | 6:41a4ad385daa | 108 | can_msg[3] = ecu.vehicle_speed; |
pangsk | 6:41a4ad385daa | 109 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 110 | break; |
pangsk | 6:41a4ad385daa | 111 | |
pangsk | 6:41a4ad385daa | 112 | case MAF_SENSOR: // ((256*A)+B) / 100 [g/s] |
pangsk | 6:41a4ad385daa | 113 | can_msg[0] = 0x04; |
pangsk | 6:41a4ad385daa | 114 | can_msg[2] = MAF_SENSOR; |
pangsk | 6:41a4ad385daa | 115 | can_msg[3] = (ecu.maf_airflow & 0xff00) >> 8; |
pangsk | 6:41a4ad385daa | 116 | can_msg[4] = ecu.maf_airflow & 0x00ff; |
pangsk | 6:41a4ad385daa | 117 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 118 | break; |
pangsk | 6:41a4ad385daa | 119 | |
pangsk | 6:41a4ad385daa | 120 | case O2_VOLTAGE: // A * 0.005 (B-128) * 100/128 (if B==0xFF, sensor is not used in trim calc) |
pangsk | 6:41a4ad385daa | 121 | can_msg[0] = 0x04; |
pangsk | 6:41a4ad385daa | 122 | can_msg[2] = O2_VOLTAGE; |
pangsk | 6:41a4ad385daa | 123 | can_msg[3] = ecu.o2_voltage & 0x00ff; |
pangsk | 6:41a4ad385daa | 124 | can_msg[4] = (ecu.o2_voltage & 0xff00) >> 8; |
pangsk | 6:41a4ad385daa | 125 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 126 | break;; |
pangsk | 6:41a4ad385daa | 127 | |
pangsk | 6:41a4ad385daa | 128 | case THROTTLE: // |
pangsk | 6:41a4ad385daa | 129 | can_msg[0] = 0x03; |
pangsk | 6:41a4ad385daa | 130 | can_msg[2] = THROTTLE; |
pangsk | 6:41a4ad385daa | 131 | can_msg[3] = ecu.throttle_position; |
pangsk | 6:41a4ad385daa | 132 | can2.write(CANMessage(PID_REPLY, can_msg, 8)); |
pangsk | 6:41a4ad385daa | 133 | break; |
pangsk | 6:41a4ad385daa | 134 | }//switch |
pangsk | 6:41a4ad385daa | 135 | } |
pangsk | 6:41a4ad385daa | 136 | |
pangsk | 6:41a4ad385daa | 137 | |
pangsk | 6:41a4ad385daa | 138 | |
pangsk | 6:41a4ad385daa | 139 | pc.printf("\n\r%x %x %x %x %x %x %x %x %x",can_MsgRx.id,can_MsgRx.data[0], |
pangsk | 6:41a4ad385daa | 140 | can_MsgRx.data[1], |
pangsk | 6:41a4ad385daa | 141 | can_MsgRx.data[2], |
pangsk | 6:41a4ad385daa | 142 | can_MsgRx.data[3], |
pangsk | 6:41a4ad385daa | 143 | can_MsgRx.data[4], |
pangsk | 6:41a4ad385daa | 144 | can_MsgRx.data[5], |
pangsk | 6:41a4ad385daa | 145 | can_MsgRx.data[6], |
pangsk | 6:41a4ad385daa | 146 | can_MsgRx.data[7]); |
pangsk | 6:41a4ad385daa | 147 | led2 = 0; |
pangsk | 0:908be729d27c | 148 | } |
pangsk | 6:41a4ad385daa | 149 | |
pangsk | 6:41a4ad385daa | 150 | return 0; |
pangsk | 0:908be729d27c | 151 | |
pangsk | 0:908be729d27c | 152 | } |
pangsk | 6:41a4ad385daa | 153 | |
pangsk | 6:41a4ad385daa | 154 | |
pangsk | 0:908be729d27c | 155 | } // namespace mbed |