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
main.cpp@6:41a4ad385daa, 2014-12-30 (annotated)
- Committer:
- pangsk
- Date:
- Tue Dec 30 10:10:02 2014 +0000
- Revision:
- 6:41a4ad385daa
- Parent:
- 3:05bb8f0bd7a4
Initial version.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pangsk | 0:908be729d27c | 1 | /* |
pangsk | 0:908be729d27c | 2 | |
pangsk | 6:41a4ad385daa | 3 | mbed Can-Bus ECU simulator |
pangsk | 0:908be729d27c | 4 | |
pangsk | 6:41a4ad385daa | 5 | v1.0 December 2014 |
pangsk | 0:908be729d27c | 6 | |
pangsk | 0:908be729d27c | 7 | ******************************************************************************** |
pangsk | 0:908be729d27c | 8 | |
pangsk | 0:908be729d27c | 9 | WARNING: Use at your own risk, sadly this software comes with no guarantees. |
pangsk | 0:908be729d27c | 10 | This software is provided 'free' and in good faith, but the author does not |
pangsk | 0:908be729d27c | 11 | accept liability for any damage arising from its use. |
pangsk | 0:908be729d27c | 12 | |
pangsk | 0:908be729d27c | 13 | ******************************************************************************** |
pangsk | 0:908be729d27c | 14 | |
pangsk | 0:908be729d27c | 15 | */ |
pangsk | 0:908be729d27c | 16 | |
pangsk | 0:908be729d27c | 17 | #include "mbed.h" |
pangsk | 6:41a4ad385daa | 18 | #include "ecu_simulator.h" |
pangsk | 0:908be729d27c | 19 | #include "globals.h" |
pangsk | 0:908be729d27c | 20 | #include "TextLCD.h" |
pangsk | 0:908be729d27c | 21 | |
pangsk | 0:908be729d27c | 22 | TextLCD lcd(p18, p19, p20, p17, p16, p15, p14); // rs, rw, e, d0, d1, d2, d3 |
pangsk | 0:908be729d27c | 23 | |
pangsk | 0:908be729d27c | 24 | DigitalIn click(p21); // Joystick inputs |
pangsk | 0:908be729d27c | 25 | DigitalIn right(p22); |
pangsk | 0:908be729d27c | 26 | DigitalIn down(p23); |
pangsk | 0:908be729d27c | 27 | DigitalIn left(p24); |
pangsk | 0:908be729d27c | 28 | DigitalIn up(p25); |
pangsk | 3:05bb8f0bd7a4 | 29 | |
pangsk | 6:41a4ad385daa | 30 | ecu_sim sim(CANSPEED_500); //Create object and set CAN speed |
pangsk | 6:41a4ad385daa | 31 | ecu_t ecu; |
pangsk | 6:41a4ad385daa | 32 | |
pangsk | 6:41a4ad385daa | 33 | void update_menu(void); |
pangsk | 6:41a4ad385daa | 34 | void update_param(unsigned char dir); |
pangsk | 0:908be729d27c | 35 | |
pangsk | 6:41a4ad385daa | 36 | // Menu defines |
pangsk | 6:41a4ad385daa | 37 | #define L0_MAIN_MENU 0 |
pangsk | 6:41a4ad385daa | 38 | #define L0_RPM 1 |
pangsk | 6:41a4ad385daa | 39 | #define L0_THROTTLE 2 |
pangsk | 6:41a4ad385daa | 40 | #define L0_SPEED 3 |
pangsk | 6:41a4ad385daa | 41 | #define L0_COOLANT 4 |
pangsk | 6:41a4ad385daa | 42 | #define L0_MAF 5 |
pangsk | 6:41a4ad385daa | 43 | #define L0_O2 6 |
pangsk | 6:41a4ad385daa | 44 | #define L0_DTC 7 |
pangsk | 0:908be729d27c | 45 | |
pangsk | 6:41a4ad385daa | 46 | #define INC 0 |
pangsk | 6:41a4ad385daa | 47 | #define DEC 1 |
pangsk | 6:41a4ad385daa | 48 | |
pangsk | 6:41a4ad385daa | 49 | #define CAN250 0 |
pangsk | 6:41a4ad385daa | 50 | #define CAN500 1 |
pangsk | 6:41a4ad385daa | 51 | unsigned char menu_state; |
pangsk | 6:41a4ad385daa | 52 | unsigned char canspeed; |
pangsk | 6:41a4ad385daa | 53 | |
pangsk | 6:41a4ad385daa | 54 | int main() |
pangsk | 6:41a4ad385daa | 55 | { |
pangsk | 3:05bb8f0bd7a4 | 56 | pc.baud(115200); |
pangsk | 6:41a4ad385daa | 57 | |
pangsk | 3:05bb8f0bd7a4 | 58 | //Enable Pullup |
pangsk | 3:05bb8f0bd7a4 | 59 | click.mode(PullUp); |
pangsk | 3:05bb8f0bd7a4 | 60 | right.mode(PullUp); |
pangsk | 3:05bb8f0bd7a4 | 61 | down.mode(PullUp); |
pangsk | 3:05bb8f0bd7a4 | 62 | left.mode(PullUp); |
pangsk | 3:05bb8f0bd7a4 | 63 | up.mode(PullUp); |
pangsk | 6:41a4ad385daa | 64 | |
pangsk | 6:41a4ad385daa | 65 | printf("\n\nECU Simulator v1.0 \n"); |
pangsk | 6:41a4ad385daa | 66 | |
pangsk | 6:41a4ad385daa | 67 | led1 = 1; |
pangsk | 6:41a4ad385daa | 68 | wait(0.1); |
pangsk | 6:41a4ad385daa | 69 | led2 = 1; |
pangsk | 6:41a4ad385daa | 70 | wait(0.1); |
pangsk | 6:41a4ad385daa | 71 | led3 = 1; |
pangsk | 6:41a4ad385daa | 72 | wait(0.1); |
pangsk | 6:41a4ad385daa | 73 | led4 = 1; |
pangsk | 6:41a4ad385daa | 74 | wait(0.2); |
pangsk | 6:41a4ad385daa | 75 | led1 = 0; led2 = 0; led3 = 0; led4 = 0; |
pangsk | 6:41a4ad385daa | 76 | |
pangsk | 6:41a4ad385daa | 77 | lcd.cls(); |
pangsk | 2:e7b3b8da71ff | 78 | lcd.locate(0,0); // Set LCD cursor position |
pangsk | 6:41a4ad385daa | 79 | lcd.printf("ECU Simulator v1.0"); |
pangsk | 0:908be729d27c | 80 | lcd.locate(0,1); |
pangsk | 0:908be729d27c | 81 | lcd.printf("www.skpang.co.uk"); |
pangsk | 0:908be729d27c | 82 | |
pangsk | 6:41a4ad385daa | 83 | wait(1); |
pangsk | 0:908be729d27c | 84 | lcd.cls(); |
pangsk | 6:41a4ad385daa | 85 | |
pangsk | 6:41a4ad385daa | 86 | lcd.printf("<- Params ->"); |
pangsk | 0:908be729d27c | 87 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 88 | lcd.printf("500kb/s"); |
pangsk | 3:05bb8f0bd7a4 | 89 | |
pangsk | 6:41a4ad385daa | 90 | canspeed = CAN500; |
pangsk | 6:41a4ad385daa | 91 | menu_state = L0_MAIN_MENU; |
pangsk | 6:41a4ad385daa | 92 | ecu.dtc = false; |
pangsk | 6:41a4ad385daa | 93 | |
pangsk | 6:41a4ad385daa | 94 | wait(0.2); |
pangsk | 6:41a4ad385daa | 95 | led1 = 1; |
pangsk | 6:41a4ad385daa | 96 | |
pangsk | 6:41a4ad385daa | 97 | while(1) { // Main CAN loop |
pangsk | 0:908be729d27c | 98 | |
pangsk | 6:41a4ad385daa | 99 | sim.request(); |
pangsk | 0:908be729d27c | 100 | |
pangsk | 6:41a4ad385daa | 101 | if(!down){ |
pangsk | 6:41a4ad385daa | 102 | update_param(DEC); |
pangsk | 6:41a4ad385daa | 103 | } |
pangsk | 6:41a4ad385daa | 104 | |
pangsk | 6:41a4ad385daa | 105 | if(!up){ |
pangsk | 6:41a4ad385daa | 106 | update_param(INC); |
pangsk | 6:41a4ad385daa | 107 | } |
pangsk | 0:908be729d27c | 108 | |
pangsk | 6:41a4ad385daa | 109 | if(!left){ |
pangsk | 6:41a4ad385daa | 110 | if(menu_state != L0_MAIN_MENU) menu_state--; |
pangsk | 6:41a4ad385daa | 111 | update_menu(); |
pangsk | 0:908be729d27c | 112 | } |
pangsk | 0:908be729d27c | 113 | |
pangsk | 6:41a4ad385daa | 114 | if(!right){ |
pangsk | 6:41a4ad385daa | 115 | if(menu_state != L0_DTC) menu_state++; |
pangsk | 6:41a4ad385daa | 116 | update_menu(); |
pangsk | 0:908be729d27c | 117 | } |
pangsk | 6:41a4ad385daa | 118 | |
pangsk | 6:41a4ad385daa | 119 | } |
pangsk | 6:41a4ad385daa | 120 | } |
pangsk | 6:41a4ad385daa | 121 | void update_param(unsigned char dir) |
pangsk | 6:41a4ad385daa | 122 | { |
pangsk | 6:41a4ad385daa | 123 | char buffer[20]; |
pangsk | 6:41a4ad385daa | 124 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 125 | switch(menu_state) |
pangsk | 6:41a4ad385daa | 126 | { |
pangsk | 6:41a4ad385daa | 127 | case L0_MAIN_MENU: |
pangsk | 6:41a4ad385daa | 128 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 129 | sim.canspeed(CANSPEED_500); |
pangsk | 6:41a4ad385daa | 130 | lcd.printf("500kb/s"); |
pangsk | 6:41a4ad385daa | 131 | canspeed = CAN500; |
pangsk | 6:41a4ad385daa | 132 | }else { |
pangsk | 6:41a4ad385daa | 133 | sim.canspeed(CANSPEED_250); |
pangsk | 6:41a4ad385daa | 134 | lcd.printf("250kb/s"); |
pangsk | 6:41a4ad385daa | 135 | canspeed = CAN250; |
pangsk | 6:41a4ad385daa | 136 | } |
pangsk | 6:41a4ad385daa | 137 | |
pangsk | 6:41a4ad385daa | 138 | break; |
pangsk | 6:41a4ad385daa | 139 | |
pangsk | 6:41a4ad385daa | 140 | case L0_RPM: |
pangsk | 6:41a4ad385daa | 141 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 142 | ecu.engine_rpm = ecu.engine_rpm +10; |
pangsk | 6:41a4ad385daa | 143 | } else ecu.engine_rpm = ecu.engine_rpm - 10; |
pangsk | 6:41a4ad385daa | 144 | |
pangsk | 6:41a4ad385daa | 145 | sprintf(buffer,"%d RPM ", (int)((((ecu.engine_rpm & 0xff00) >> 8) * 256) + (ecu.engine_rpm & 0x00ff)) / 4); |
pangsk | 6:41a4ad385daa | 146 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 147 | break; |
pangsk | 6:41a4ad385daa | 148 | |
pangsk | 6:41a4ad385daa | 149 | case L0_THROTTLE: |
pangsk | 6:41a4ad385daa | 150 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 151 | ecu.throttle_position++; |
pangsk | 6:41a4ad385daa | 152 | } else ecu.throttle_position--; |
pangsk | 6:41a4ad385daa | 153 | |
pangsk | 6:41a4ad385daa | 154 | sprintf(buffer,"%d %% ", (int)ecu.throttle_position); |
pangsk | 6:41a4ad385daa | 155 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 156 | break; |
pangsk | 6:41a4ad385daa | 157 | |
pangsk | 6:41a4ad385daa | 158 | case L0_SPEED: |
pangsk | 6:41a4ad385daa | 159 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 160 | ecu.vehicle_speed++; |
pangsk | 6:41a4ad385daa | 161 | } else ecu.vehicle_speed--; |
pangsk | 6:41a4ad385daa | 162 | |
pangsk | 6:41a4ad385daa | 163 | sprintf(buffer,"%d km/h ",(int) ecu.vehicle_speed); |
pangsk | 6:41a4ad385daa | 164 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 165 | break; |
pangsk | 6:41a4ad385daa | 166 | |
pangsk | 6:41a4ad385daa | 167 | case L0_COOLANT: |
pangsk | 6:41a4ad385daa | 168 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 169 | ecu.coolant_temp++; |
pangsk | 6:41a4ad385daa | 170 | } else ecu.coolant_temp--; |
pangsk | 0:908be729d27c | 171 | |
pangsk | 6:41a4ad385daa | 172 | sprintf(buffer,"%d C ",(int) ecu.coolant_temp - 40); |
pangsk | 6:41a4ad385daa | 173 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 174 | break; |
pangsk | 6:41a4ad385daa | 175 | |
pangsk | 6:41a4ad385daa | 176 | case L0_MAF: |
pangsk | 6:41a4ad385daa | 177 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 178 | ecu.maf_airflow = ecu.maf_airflow +10; |
pangsk | 6:41a4ad385daa | 179 | } else ecu.maf_airflow = ecu.maf_airflow - 10; |
pangsk | 6:41a4ad385daa | 180 | |
pangsk | 6:41a4ad385daa | 181 | sprintf(buffer,"%d g/s ", (int)((((ecu.maf_airflow & 0xff00) >> 8) * 256) + (ecu.maf_airflow & 0x00ff)) / 100); |
pangsk | 6:41a4ad385daa | 182 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 183 | break; |
pangsk | 6:41a4ad385daa | 184 | |
pangsk | 6:41a4ad385daa | 185 | case L0_O2: |
pangsk | 6:41a4ad385daa | 186 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 187 | ecu.o2_voltage = ecu.o2_voltage +10; |
pangsk | 6:41a4ad385daa | 188 | } else ecu.o2_voltage = ecu.o2_voltage - 10; |
pangsk | 6:41a4ad385daa | 189 | |
pangsk | 6:41a4ad385daa | 190 | sprintf(buffer,"%d ", (int)ecu.o2_voltage); |
pangsk | 6:41a4ad385daa | 191 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 192 | break; |
pangsk | 6:41a4ad385daa | 193 | |
pangsk | 6:41a4ad385daa | 194 | case L0_DTC: |
pangsk | 6:41a4ad385daa | 195 | if(dir == INC){ |
pangsk | 6:41a4ad385daa | 196 | ecu.dtc = true; |
pangsk | 6:41a4ad385daa | 197 | led4 = 1; |
pangsk | 6:41a4ad385daa | 198 | } else { |
pangsk | 6:41a4ad385daa | 199 | ecu.dtc = false; |
pangsk | 6:41a4ad385daa | 200 | led4 = 0; |
pangsk | 6:41a4ad385daa | 201 | } |
pangsk | 6:41a4ad385daa | 202 | |
pangsk | 6:41a4ad385daa | 203 | sprintf(buffer,"%d ", (int)ecu.dtc); |
pangsk | 6:41a4ad385daa | 204 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 205 | break; |
pangsk | 6:41a4ad385daa | 206 | |
pangsk | 0:908be729d27c | 207 | } |
pangsk | 6:41a4ad385daa | 208 | |
pangsk | 6:41a4ad385daa | 209 | wait(0.1); //Delay for auto repeat |
pangsk | 6:41a4ad385daa | 210 | |
pangsk | 6:41a4ad385daa | 211 | |
pangsk | 6:41a4ad385daa | 212 | } |
pangsk | 6:41a4ad385daa | 213 | void update_menu(void) |
pangsk | 6:41a4ad385daa | 214 | { |
pangsk | 6:41a4ad385daa | 215 | char buffer[20]; |
pangsk | 6:41a4ad385daa | 216 | lcd.cls(); |
pangsk | 6:41a4ad385daa | 217 | lcd.locate(0,0); |
pangsk | 6:41a4ad385daa | 218 | |
pangsk | 6:41a4ad385daa | 219 | switch(menu_state) |
pangsk | 6:41a4ad385daa | 220 | { |
pangsk | 6:41a4ad385daa | 221 | case L0_MAIN_MENU: |
pangsk | 6:41a4ad385daa | 222 | lcd.printf("CAN speed"); |
pangsk | 6:41a4ad385daa | 223 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 224 | if(canspeed == CAN500) lcd.printf("500kb/s"); |
pangsk | 6:41a4ad385daa | 225 | else lcd.printf("250kb/s"); |
pangsk | 6:41a4ad385daa | 226 | break; |
pangsk | 6:41a4ad385daa | 227 | |
pangsk | 6:41a4ad385daa | 228 | case L0_RPM: |
pangsk | 6:41a4ad385daa | 229 | lcd.printf("Engine RPM"); |
pangsk | 6:41a4ad385daa | 230 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 231 | sprintf(buffer,"%d RPM ", (int) ((((ecu.engine_rpm & 0xff00) >> 8) * 256) + (ecu.engine_rpm & 0x00ff)) / 4); |
pangsk | 6:41a4ad385daa | 232 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 233 | break; |
pangsk | 6:41a4ad385daa | 234 | |
pangsk | 6:41a4ad385daa | 235 | case L0_THROTTLE: |
pangsk | 6:41a4ad385daa | 236 | lcd.printf("Throttle pos"); |
pangsk | 6:41a4ad385daa | 237 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 238 | sprintf(buffer,"%d % ", ecu.throttle_position); |
pangsk | 6:41a4ad385daa | 239 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 240 | break; |
pangsk | 6:41a4ad385daa | 241 | |
pangsk | 6:41a4ad385daa | 242 | case L0_SPEED: |
pangsk | 6:41a4ad385daa | 243 | lcd.printf("Vehicle speed"); |
pangsk | 6:41a4ad385daa | 244 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 245 | sprintf(buffer,"%d kph ", ecu.vehicle_speed); |
pangsk | 6:41a4ad385daa | 246 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 247 | break; |
pangsk | 6:41a4ad385daa | 248 | |
pangsk | 6:41a4ad385daa | 249 | case L0_COOLANT: |
pangsk | 6:41a4ad385daa | 250 | lcd.printf("Coolant temp"); |
pangsk | 6:41a4ad385daa | 251 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 252 | sprintf(buffer,"%d C ",(int) ecu.coolant_temp - 40); |
pangsk | 6:41a4ad385daa | 253 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 254 | break; |
pangsk | 6:41a4ad385daa | 255 | |
pangsk | 6:41a4ad385daa | 256 | case L0_MAF: |
pangsk | 6:41a4ad385daa | 257 | lcd.printf("MAF air flow "); |
pangsk | 6:41a4ad385daa | 258 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 259 | sprintf(buffer,"%d g/s ", ecu.maf_airflow); |
pangsk | 6:41a4ad385daa | 260 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 261 | break; |
pangsk | 6:41a4ad385daa | 262 | |
pangsk | 6:41a4ad385daa | 263 | case L0_O2: |
pangsk | 6:41a4ad385daa | 264 | lcd.printf("Oxygen sensor v."); |
pangsk | 6:41a4ad385daa | 265 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 266 | sprintf(buffer,"%d ", ecu.o2_voltage); |
pangsk | 6:41a4ad385daa | 267 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 268 | break; |
pangsk | 6:41a4ad385daa | 269 | |
pangsk | 6:41a4ad385daa | 270 | case L0_DTC: |
pangsk | 6:41a4ad385daa | 271 | lcd.printf("DTC"); |
pangsk | 6:41a4ad385daa | 272 | lcd.locate(0,1); |
pangsk | 6:41a4ad385daa | 273 | sprintf(buffer,"%d ", ecu.dtc); |
pangsk | 6:41a4ad385daa | 274 | lcd.printf(buffer); |
pangsk | 6:41a4ad385daa | 275 | break; |
pangsk | 6:41a4ad385daa | 276 | |
pangsk | 6:41a4ad385daa | 277 | } |
pangsk | 6:41a4ad385daa | 278 | |
pangsk | 6:41a4ad385daa | 279 | while(!left); //Wait for key to be released |
pangsk | 6:41a4ad385daa | 280 | while(!right); |
pangsk | 6:41a4ad385daa | 281 | wait(0.05); |
pangsk | 6:41a4ad385daa | 282 | |
pangsk | 0:908be729d27c | 283 | } |
pangsk | 0:908be729d27c | 284 | |
pangsk | 0:908be729d27c | 285 | |
pangsk | 6:41a4ad385daa | 286 |