You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dashboard.ino 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. //##############################################################################################################
  2. // Volkswagen Dashboard CAN BUS
  3. // Arduino Sketch v0.1
  4. // (C) by Niklas Schütrumpf 2018
  5. //##############################################################################################################
  6. // https://github.com/Flori1989/MCP2515_lib
  7. #include "Arduino.h"
  8. #include <mcp_can.h>
  9. #include <SPI.h>
  10. #include <ArduinoJson.h>
  11. #define lo8(x) ((int)(x)&0xff)
  12. #define hi8(x) ((int)(x)>>8)
  13. int high_beam = A3;
  14. int fog_beam = A2;
  15. int park_brake = A0;
  16. String inputString = "";
  17. boolean stringComplete = false;
  18. //Variables (Dashboard Functions)
  19. int turning_lights = 3;
  20. boolean turning_lights_blinking = true;
  21. int turning_lights_counter = 0;
  22. int temp_turning_lights = 0;
  23. boolean backlight = false;
  24. int oilpswitch = A1;
  25. int pack_counter = 0;
  26. boolean add_distance = false;
  27. int drive_mode = 0;
  28. int distance_multiplier = 2;
  29. boolean oil_pressure_simulation = true;
  30. boolean door_open = false;
  31. boolean clutch_control = false;
  32. int temp_clutch_control = 0;
  33. boolean check_lamp = false;
  34. int temp_check_lamp = 0;
  35. boolean trunklid_open = false;
  36. int temp_trunklid_open = 0;
  37. boolean battery_warning = false;
  38. int temp_battery_warning = 0;
  39. boolean keybattery_warning = false;
  40. int temp_keybattery_warning = 0;
  41. int lightmode = 0;
  42. boolean seat_belt = false;
  43. int temp_seat_belt = 0;
  44. int engine_control = 0;
  45. int temp_dpf_warning = 0;
  46. boolean dpf_warning = false;
  47. boolean light_fog = false;
  48. int temp_light_fog = 0;
  49. boolean light_highbeam = false;
  50. int temp_light_highbeam = 0;
  51. boolean signal_abs = false;
  52. boolean signal_offroad = false;
  53. boolean signal_handbrake = false;
  54. boolean signal_lowtirepressure = false;
  55. boolean signal_dieselpreheat = false;
  56. boolean signal_watertemp = false;
  57. int temp_signal_abs = 0;
  58. int temp_signal_offroad = 0;
  59. int temp_signal_handbrake = 0;
  60. int temp_signal_lowtirepressure = 0;
  61. int temp_signal_dieselpreheat = 0;
  62. int temp_signal_watertemp = 0;
  63. //Variables (Speed and RPM)
  64. int speed = 0;
  65. int speedTmp = 0;
  66. byte speedL = 0;
  67. byte speedH = 0;
  68. int rpm = 0;
  69. short tempRPM = 0;
  70. byte rpmL = 0;
  71. byte rpmH = 0;
  72. int distance_adder = 0;
  73. int distance_counter = 0;
  74. const int SPI_CS_PIN = 10;
  75. MCP_CAN CAN(SPI_CS_PIN);
  76. //Setup Configuration
  77. void setup()
  78. {
  79. pinMode(high_beam, OUTPUT);
  80. pinMode(fog_beam, OUTPUT);
  81. pinMode(park_brake, OUTPUT);
  82. pinMode(oilpswitch, OUTPUT);
  83. digitalWrite(park_brake, HIGH);
  84. digitalWrite(high_beam, LOW);
  85. digitalWrite(fog_beam, LOW);
  86. Serial.begin(115200);
  87. while (!Serial) continue;
  88. //Begin with CAN Bus Initialization
  89. START_INIT:
  90. if (CAN_OK == CAN.begin(CAN_500KBPS, MCP_16MHz)) // init can bus : baudrate = 500k
  91. {
  92. Serial.println("CAN BUS Shield init ok!");
  93. }
  94. else
  95. {
  96. Serial.println("CAN BUS Shield init fail");
  97. Serial.println("Init CAN BUS Shield again");
  98. delay(100);
  99. //goto START_INIT;
  100. }
  101. //##############################################################################################################
  102. //MAIN SETUP FOR OPERATION
  103. //Set constant speed and RPM to show on Dashboard
  104. speed = 0; //Set the speed in km/h
  105. rpm = 0; //Set the rev counter
  106. Fuel(100); //Set the fuel gauge in percent
  107. //Set Dashboard Functions
  108. backlight = true; //Turn the automatic dashboard backlight on or off
  109. turning_lights = 0; //Turning Lights: 0 = none, 1 = left, 2 = right, 3 = both
  110. turning_lights_blinking = true; //Choose the mode of the turning lights (blinking or just shining)
  111. add_distance = false; //Dashboard counts the kilometers (can't be undone)
  112. distance_multiplier = 2; //Sets the refresh rate of the odometer (Standard 2)
  113. signal_abs = false; //Shows ABS Signal on dashboard
  114. signal_offroad = false; //Simulates Offroad drive mode
  115. signal_handbrake = false; //Enables handbrake
  116. signal_lowtirepressure = false; //Simulates low tire pressure
  117. oil_pressure_simulation = false; //Set this to true if dashboard starts to beep
  118. door_open = false; //Simulate open doors
  119. clutch_control = false; //Displays the Message "Kupplung" (German for Clutch) on the dashboard's LCD
  120. check_lamp = false; //Show 'Check Lamp' Signal on dashboard. B00010000 = on, B00000 = off
  121. trunklid_open = false; //Simulate open trunk lid (Kofferraumklappe). B00100000 = open, B00000 = closed
  122. battery_warning = false; //Show Battery Warning.
  123. keybattery_warning = false; //Show message 'Key Battery Low' on Display. But just after first start of dashboard.
  124. light_fog = false; //Enable Fog Light
  125. light_highbeam = false; //Enable High Beam Light
  126. seat_belt = false; //Switch Seat Betl warning light.
  127. signal_dieselpreheat = false; //Simualtes Diesel Preheating
  128. signal_watertemp = false; //Simualtes high water temperature
  129. dpf_warning = false; //Shows the Diesel particle filter warning signal.
  130. //##############################################################################################################
  131. }
  132. void CanSend(short address, byte a, byte b, byte c, byte d, byte e, byte f, byte g, byte h)
  133. {
  134. unsigned char DataToSend[8] = {a, b, c, d, e, f, g, h};
  135. CAN.sendMsgBuf(address, 0, 8, DataToSend);
  136. }
  137. void Fuel(int amount)
  138. {
  139. pinMode(A4, INPUT);
  140. pinMode(A5, INPUT);
  141. pinMode(3, INPUT);
  142. pinMode(4, INPUT);
  143. pinMode(5, INPUT);
  144. pinMode(6, INPUT);
  145. pinMode(7, INPUT);
  146. pinMode(8, INPUT);
  147. pinMode(9, INPUT);
  148. if (amount >= 87)
  149. {
  150. pinMode(A4, OUTPUT);
  151. digitalWrite(A4, LOW);
  152. return;
  153. }
  154. if (amount >= 75)
  155. {
  156. pinMode(A5, OUTPUT);
  157. digitalWrite(A5, LOW);
  158. return;
  159. }
  160. if (amount >= 62)
  161. {
  162. pinMode(3, OUTPUT);
  163. digitalWrite(3, LOW);
  164. return;
  165. }
  166. if (amount >= 50)
  167. {
  168. pinMode(4, OUTPUT);
  169. digitalWrite(4, LOW);
  170. return;
  171. }
  172. if (amount >= 37)
  173. {
  174. pinMode(5, OUTPUT);
  175. digitalWrite(5, LOW);
  176. return;
  177. }
  178. if (amount >= 25)
  179. {
  180. pinMode(6, OUTPUT);
  181. digitalWrite(6, LOW);
  182. return;
  183. }
  184. if (amount >= 18)
  185. {
  186. pinMode(7, OUTPUT);
  187. digitalWrite(7, LOW);
  188. return;
  189. }
  190. if (amount >= 12)
  191. {
  192. pinMode(8, OUTPUT);
  193. digitalWrite(8, LOW);
  194. return;
  195. }
  196. if (amount >= 0)
  197. {
  198. pinMode(9, OUTPUT);
  199. digitalWrite(9, LOW);
  200. return;
  201. }
  202. }
  203. //Loop
  204. void loop()
  205. {
  206. if (stringComplete) {
  207. Serial.print(inputString.length());
  208. Serial.print(": ");
  209. Serial.println(inputString);
  210. if(inputString.length() >= 39 && inputString.length() <= 46) {
  211. if(getValue(inputString, ',', 19) != "") {
  212. speed = getValue(inputString, ',', 0).toInt();
  213. rpm = getValue(inputString, ',', 1).toInt();
  214. Fuel(getValue(inputString, ',', 2).toInt());
  215. backlight = getValue(inputString, ',', 3).toInt();
  216. if(getValue(inputString, ',', 4).toInt() == 1 && getValue(inputString, ',', 5).toInt() == 1) {
  217. turning_lights = 3;
  218. } else if (getValue(inputString, ',', 4).toInt()) {
  219. turning_lights = 1;
  220. } else if (getValue(inputString, ',', 5).toInt()) {
  221. turning_lights = 2;
  222. } else {
  223. turning_lights = 0;
  224. }
  225. signal_offroad = getValue(inputString, ',', 6).toInt();
  226. signal_watertemp = getValue(inputString, ',', 7).toInt();
  227. seat_belt = getValue(inputString, ',', 8).toInt();
  228. battery_warning = getValue(inputString, ',', 9).toInt();
  229. check_lamp = getValue(inputString, ',', 10).toInt();
  230. door_open = getValue(inputString, ',', 11).toInt();
  231. light_fog = getValue(inputString, ',', 12).toInt();
  232. light_highbeam = getValue(inputString, ',', 13).toInt();
  233. signal_handbrake = getValue(inputString, ',', 14).toInt();
  234. signal_abs = getValue(inputString, ',', 15).toInt();
  235. oil_pressure_simulation = getValue(inputString, ',', 16).toInt();
  236. signal_lowtirepressure = getValue(inputString, ',', 17).toInt();
  237. clutch_control = getValue(inputString, ',', 18).toInt();
  238. trunklid_open = getValue(inputString, ',', 29).toInt();
  239. Serial.print("CHECK:");
  240. Serial.print(speed);
  241. Serial.print(" - ");
  242. Serial.print(rpm);
  243. Serial.print(" - ");
  244. Serial.print(light_fog);
  245. Serial.print(" - ");
  246. Serial.println(turning_lights);
  247. } else {
  248. Serial.println("INVALID STRING!");
  249. }
  250. } else {
  251. Serial.println("INVALID STRING!");
  252. }
  253. inputString = "";
  254. stringComplete = false;
  255. }
  256. //Conversion Speed
  257. speedTmp = speed / 0.0075; //KMH=1.12 MPH=0.62
  258. //Conversion Low and High Bytes
  259. speedL = lo8(speedTmp);
  260. speedH = hi8(speedTmp);
  261. tempRPM = rpm * 4;
  262. rpmL = lo8(tempRPM);
  263. rpmH = hi8(tempRPM);
  264. if (add_distance == true)
  265. {
  266. distance_adder = speedTmp * distance_multiplier;
  267. distance_counter += distance_adder;
  268. if (distance_counter > distance_adder) {
  269. distance_counter = 0;
  270. }
  271. }
  272. if ( oil_pressure_simulation == true)
  273. {
  274. //Set Oil Pressure Switch
  275. if (rpm > 1500) {
  276. digitalWrite(oilpswitch, LOW);
  277. }
  278. else {
  279. digitalWrite(oilpswitch, HIGH);
  280. }
  281. }
  282. /*Send CAN BUS Data*/
  283. //Immobilizer
  284. CanSend(0x3D0, 0, 0x80, 0, 0, 0, 0, 0, 0);
  285. //Engine on and ESP enabled
  286. CanSend(0xDA0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  287. //Enable Cruise Control
  288. //CanSend(0x289, 0x00, B00000001, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  289. //Dashboard Functions
  290. //Turning Light blinking
  291. if (turning_lights_blinking == true)
  292. {
  293. if (turning_lights_counter == 15)
  294. {
  295. temp_turning_lights = turning_lights;
  296. turning_lights_counter = turning_lights_counter + 1;
  297. }
  298. if (turning_lights_counter == 30)
  299. {
  300. temp_turning_lights = 0;
  301. turning_lights_counter = 0;
  302. }
  303. else
  304. {
  305. turning_lights_counter = turning_lights_counter + 1;
  306. }
  307. }
  308. else
  309. {
  310. temp_turning_lights = turning_lights;
  311. }
  312. //Check main settings
  313. //DPF
  314. if (dpf_warning == true) temp_dpf_warning = B00000010;
  315. else temp_dpf_warning = B00000000;
  316. //Seat Belt
  317. if (seat_belt == true) temp_seat_belt = B00000100;
  318. else temp_seat_belt = B00000000;
  319. //Battery Warning
  320. if (battery_warning == true) temp_battery_warning = B10000000;
  321. else temp_battery_warning = B00000000;
  322. //Trunk Lid (Kofferraumklappe)
  323. if (trunklid_open == true) temp_trunklid_open = B00100000;
  324. else temp_trunklid_open = B00000000;
  325. //Check Lamp Signal
  326. if (check_lamp == true) temp_check_lamp = B00010000;
  327. else temp_check_lamp = B00000000;
  328. //Clutch Text on LCD
  329. if (clutch_control == true) temp_clutch_control = B00000001;
  330. else temp_clutch_control = B00000000;
  331. //Warning for low key battery
  332. if (keybattery_warning == true) temp_keybattery_warning = B10000000;
  333. else temp_keybattery_warning = B00000000;
  334. //Lightmode Selection (Fog Light and/or High Beam)
  335. if (light_highbeam == true) temp_light_highbeam = B01000000;
  336. else temp_light_highbeam = B00000000;
  337. if (light_fog == true) temp_light_fog = B00100000;
  338. else temp_light_fog = B00000000;
  339. lightmode = temp_light_highbeam + temp_light_fog;
  340. //Engine Options (Water Temperature, Diesel Preheater)
  341. if (signal_dieselpreheat == true) temp_signal_dieselpreheat = B00000010;
  342. else temp_signal_dieselpreheat = B00000000;
  343. if (signal_watertemp == true) temp_signal_watertemp = B00010000;
  344. else temp_signal_watertemp = B00000000;
  345. engine_control = temp_signal_dieselpreheat + temp_signal_watertemp;
  346. //Drivemode Selection (ABS, Offroad, Low Tire Pressure, handbrake)
  347. if (signal_abs == true) temp_signal_abs = B0001;
  348. else temp_signal_abs = B0000;
  349. if (signal_offroad == true) temp_signal_offroad = B0010;
  350. else temp_signal_offroad = B0000;
  351. if (signal_handbrake == true) temp_signal_handbrake = B0100;
  352. else temp_signal_handbrake = B0000;
  353. if (signal_lowtirepressure == true) temp_signal_lowtirepressure = B1000;
  354. else temp_signal_lowtirepressure = B0000;
  355. drive_mode = temp_signal_abs + temp_signal_offroad + temp_signal_handbrake + temp_signal_lowtirepressure;
  356. //Send CAN data every 200ms
  357. pack_counter++;
  358. if (pack_counter == 20)
  359. {
  360. //Turning Lights 2
  361. CanSend(0x470, temp_battery_warning + temp_turning_lights, temp_trunklid_open + door_open, backlight, 0x00, temp_check_lamp + temp_clutch_control, temp_keybattery_warning, 0x00, lightmode);
  362. //Diesel engine
  363. CanSend(0x480, 0x00, engine_control, 0x00, 0x00, 0x00, temp_dpf_warning, 0x00, 0x00);
  364. ///Engine
  365. //CanSend(0x388, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  366. //Cruise Control
  367. //CanSend(0x289, 0x00, B00000101, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  368. pack_counter = 0;
  369. }
  370. //Motorspeed
  371. CanSend(0x320, 0x00, (speedL * 100), (speedH * 100), 0x00, 0x00, 0x00, 0x00, 0x00);
  372. //RPM
  373. CanSend(0x280, 0x49, 0x0E, rpmL, rpmH, 0x0E, 0x00, 0x1B, 0x0E);
  374. //Speed
  375. CanSend(0x5A0, 0xFF, speedL, speedH, drive_mode, 0x00, lo8(distance_counter), hi8(distance_counter), 0xad);
  376. //ABS
  377. CanSend(0x1A0, 0x18, speedL, speedH, 0x00, 0xfe, 0xfe, 0x00, 0xff);
  378. //Airbag
  379. CanSend(0x050, 0x00, 0x80, temp_seat_belt, 0x00, 0x00, 0x00, 0x00, 0x00);
  380. //Wait a time
  381. delay(5);
  382. }
  383. void serialEvent() {
  384. while (Serial.available()) {
  385. char inChar = (char)Serial.read();
  386. if (inChar == ';') {
  387. stringComplete = true;
  388. } else {
  389. inputString += inChar;
  390. }
  391. }
  392. }
  393. String getValue(String data, char separator, int index)
  394. {
  395. int found = 0;
  396. int strIndex[] = { 0, -1 };
  397. int maxIndex = data.length() - 1;
  398. for (int i = 0; i <= maxIndex && found <= index; i++) {
  399. if (data.charAt(i) == separator || i == maxIndex) {
  400. found++;
  401. strIndex[0] = strIndex[1] + 1;
  402. strIndex[1] = (i == maxIndex) ? i+1 : i;
  403. }
  404. }
  405. return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
  406. }