Advertisement
Guest User

Webasto arduino code

a guest
Jun 9th, 2015
12,232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.82 KB | None | 0 0
  1.  
  2. //hacked together by is0-mick 2015
  3.  
  4. #include "wbus.h"
  5. #include <LiquidCrystal.h>
  6. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  7.  
  8.  
  9. #define     MINS_TO_RUN     15
  10. #define     MAX_TEMP        75
  11.  
  12. #define     XTAL                18432000
  13. #define     TICKS_PER_SECOND    1000
  14. #define     DIVIDE              (XTAL/4/32/TICKS_PER_SECOND)
  15.  
  16. #define ON      1
  17. #define OFF     0
  18.  
  19. #define led_circ_pump 8
  20. #define tx_line 18 //pin for TX
  21.  
  22.  
  23. #define RESPONSE_TIMEOUT    (TICKS_PER_SECOND/2)
  24. #define ERROR_DELAY     (1*TICKS_PER_SECOND)
  25. #define NACK_DELAY      (5*TICKS_PER_SECOND)
  26. #define RESET_SLEEP             (10*TICKS_PER_SECOND)
  27. #define ERROR_TMO_CHK_ADR    250
  28. #define ERROR_NACK       240
  29.  
  30. #define btnRIGHT  0
  31. #define btnUP     1
  32. #define btnDOWN   2
  33. #define btnLEFT   3
  34. #define btnSELECT 4
  35. #define btnNONE   5
  36.  
  37. int adc_key_in  = 0;
  38. byte    rs232_dummy, rs232_byte;
  39. byte    bytes_count, cnt;
  40.  
  41. byte    error, tries1, tries2;
  42.  
  43. byte    msgbuffer[15], message_data[10], message_length;
  44. byte    checksum_byte;
  45.  
  46. word    rx_ticks, delay_ticks, pump_check_ticks, low_beam_ticks, sleep_ticks;
  47.  
  48. long    active_time, post_active_time;
  49. byte    start_pressed, stop_pressed;
  50. char tbs[32];//buffer for printf
  51. bool keepalive = false;
  52. int statustype = 0;
  53. unsigned long currm = millis();
  54. unsigned long prevm = 0;
  55.  
  56. void setup()
  57. {
  58.   //pinMode(13, OUTPUT);
  59.   lcd.begin(16, 2);
  60.   GenerateBarGraphChars();
  61.   lcd.clear();
  62.   Serial.begin(57600);//debug info on serial
  63.   lcd.setCursor(0, 0);
  64.   lcd.print("Init...");
  65. }
  66.  
  67. void GenerateBarGraphChars()
  68. {
  69.   byte charData[8];
  70.   for (int i = 0; i < 8; i++)
  71.   {
  72.     for (int j = 0; j < 8; j++)
  73.     {
  74.       if (i + j > 6)
  75.       {
  76.         charData[j] = (0x1F);
  77.       }
  78.       else
  79.       {
  80.         charData[j] = (0x00);
  81.       }
  82.     }
  83.     lcd.createChar(i, charData);
  84.   }
  85. }
  86.  
  87. unsigned char checksum(unsigned char *buf, unsigned char len)
  88. {
  89.   //Serial.print("length =");
  90.   //Serial.println(len,DEC);
  91.   unsigned char chk = 0;
  92.   for ( ; len != 0; len--) {
  93.     chk ^= *buf++;
  94.   }
  95.   //Serial.print("checksum = ");
  96.   //Serial.println(chk,HEX);
  97.   return chk;
  98. }
  99.  
  100. //--------------------------------------------------------------------------------
  101. void send_Serial_byte(byte value)
  102. {
  103.   Serial1.write(value);
  104. }
  105.  
  106. //--------------------------------------------------------------------------------
  107. byte read_Serial_byte(void)
  108. {
  109.   if (Serial1.available() > 0)
  110.   {
  111.     rs232_byte = Serial1.read();
  112.     return 1;
  113.   }
  114.   return 0;
  115. }
  116.  
  117. //--------------------------------------------------------------------------------
  118. void msg_send(byte cmd)
  119. {
  120.   msgbuffer[0] = ((WBUS_CLIENT_ADDR << 4) | WBUS_HOST_ADDR);
  121.   msgbuffer[1] = message_length + 2;
  122.   msgbuffer[2] = cmd;
  123.   for (cnt = 0, bytes_count = 3; cnt < message_length; cnt++, bytes_count++) msgbuffer[bytes_count] = message_data[cnt];
  124.   // make checksum
  125.   msgbuffer[bytes_count] = 0;//clear old checksum
  126.   msgbuffer[bytes_count++] = checksum(msgbuffer, bytes_count);
  127.   // Send message
  128.   Serial.print("Sending: ");
  129.   PrintHex8(msgbuffer, bytes_count);
  130.   for (cnt = 0; cnt < bytes_count; cnt++) send_Serial_byte(msgbuffer[cnt]);
  131.   Serial1.flush();
  132.   // wait if any other transmission
  133.   // and purge all receptions
  134.   while (Serial1.available() > 0)
  135.   {
  136.     delay(1);
  137.     byte waste = Serial1.read();
  138.   }
  139. }
  140.  
  141. //--------------------------------------------------------------------------------
  142. void PrintHex8(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
  143. {
  144.   for (int i = 0; i < length; i++) {
  145.     Serial.print("0x");
  146.     if (data[i] < 0x10) {
  147.       Serial.print("0");
  148.     }
  149.     Serial.print(data[i], HEX);
  150.     Serial.print(" ");
  151.   }
  152. }
  153.  
  154. //--------------------------------------------------------------------------------
  155. byte msg_recv(byte cmd, byte skip)
  156. {
  157.   Serial.print("recv: ");
  158.  message_data[0] = 0;
  159.     message_data[1] = 0;
  160.     message_data[2] = 0;
  161.     message_data[3] = 0;
  162.     message_data[4] = 0;
  163.     message_data[5] = 0;
  164.     message_data[6] = 0;
  165.     message_data[7] = 0;
  166.     message_data[8] = 0;
  167.     message_data[9] = 0;
  168.    Serial.print("recv: 2");
  169.   bytes_count = 0;
  170.   unsigned long currentMillis = millis();
  171.   unsigned long previousMillis = currentMillis;
  172.   do
  173.   {
  174.     currentMillis = millis();
  175.     if (read_Serial_byte() != 0)
  176.     {
  177.       msgbuffer[bytes_count] = rs232_byte;
  178.       bytes_count++;
  179.       previousMillis = currentMillis;
  180.     }
  181.   }
  182.   while (currentMillis - previousMillis < RESPONSE_TIMEOUT && bytes_count < sizeof(msgbuffer));
  183.   //
  184.   // check timeout
  185.   if (bytes_count == 0)
  186.   {
  187.     // Timeout
  188.     Serial.println("Timeout");
  189.   lcd.clear();
  190.   lcd.setCursor(0, 0);
  191.   lcd.print("TIMEOUT!! ");
  192.   delay(500);
  193.   lcd.clear();
  194.     return ERROR_TMO_CHK_ADR;
  195.   }
  196.   Serial.print("\nReceived: ");
  197.   PrintHex8(msgbuffer, bytes_count);
  198.   // check checksum
  199.   if (checksum(msgbuffer, bytes_count) != 0)
  200.   {
  201.     // Checksum error
  202.     Serial.println("Checksum error");
  203.     return ERROR_TMO_CHK_ADR;
  204.   }
  205.   // check address
  206.   if (msgbuffer[0] != ((WBUS_HOST_ADDR << 4) | WBUS_CLIENT_ADDR))
  207.   {
  208.     // Incorrect address
  209.     Serial.println("Incorrect address");
  210.     return ERROR_TMO_CHK_ADR;
  211.   }
  212.   // check validity
  213.   if (msgbuffer[2] != (cmd | 0x80))
  214.   {
  215.     // Request was rejected...
  216.     Serial.println("Request was rejected");
  217.     message_length = 0;
  218.     return ERROR_NACK;
  219.   }
  220.   // copy info to data
  221.   message_length = msgbuffer[1] - 2 - skip;
  222.   bytes_count = 3 + skip;
  223.  
  224.   for (cnt = 0; cnt < message_length; cnt++, bytes_count++)
  225.   {
  226.     message_data[cnt] = msgbuffer[bytes_count];
  227.  
  228.   }
  229.   return 0;
  230. }
  231.  
  232. //--------------------------------------------------------------------------------
  233. //
  234. // Send a client W-Bus request and read answer from Heater.
  235. //
  236. void wb_io(byte cmd, byte skip)
  237. {
  238.   tries2 = 0;
  239.   do
  240.   {
  241.     if (tries2 != 0) delay(NACK_DELAY);
  242.     tries1 = 0;
  243.     do
  244.     {
  245.       if (tries1 != 0) delay(ERROR_DELAY);
  246.       SendBreak(50);
  247.       msg_send(cmd);
  248.       // receive reply
  249.       error = msg_recv(cmd, skip);
  250.       tries1++;
  251.     }
  252.     while (tries1 < 10 && error == ERROR_TMO_CHK_ADR); // timeout, bad checksum or invalid address
  253.     tries2++;
  254.   }
  255.   while (tries2 < 2 && error == ERROR_NACK); // request denied
  256. }
  257.  
  258. void SendBreak(byte duration)
  259. {
  260.   Serial.println("\n**** BREAK SENT ****\n");
  261.   Serial1.end();              // disable Serial1 transmission
  262.   pinMode(tx_line, OUTPUT);
  263.   digitalWrite(tx_line, 0); // set low the tx pin
  264.   delay(duration);            // wait 25 ms
  265.   digitalWrite(tx_line, 1); // set high the tx pin
  266.   delay(duration);
  267.   Serial1.begin(2400, SERIAL_8E1); // re-enable Serial1 transmission
  268.   delay(25);
  269. }
  270.  
  271. //--------------------------------------------------------------------------------
  272. //
  273. // Turn heater on for time minutes
  274. //
  275. void turnOn(byte time)
  276. {
  277.   message_data[0] = time;
  278.   message_length = 1;
  279.   wb_io(WBUS_CMD_ON_PH, 0);
  280.   keepalive=true;
  281. }
  282.  
  283. //--------------------------------------------------------------------------------
  284. //
  285. // Turn heater off
  286. //
  287. void turnOff(void)
  288. {
  289.   message_length = 0;
  290.   wb_io(WBUS_CMD_OFF, 0);
  291.   keepalive=false;
  292. }
  293.  
  294. //--------------------------------------------------------------------------------
  295. //
  296. // keepAlive - poll the heater
  297. //
  298. void keepAlive()
  299. {
  300.   message_data[0] = WBUS_CMD_ON_PH; // polling (keep-alive)
  301.   message_data[1] = 0;
  302.   message_length = 2;
  303.   wb_io(WBUS_CMD_CHK, 0);
  304.   if (error != 0) return;
  305. }
  306.  
  307. //--------------------------------------------------------------------------------
  308. //
  309. // get status 2
  310. //
  311. void get_status2(void)
  312. {
  313.   message_data[0] = QUERY_STATUS2; // status 2 - level of devices
  314.   message_length = 1;
  315.   wb_io(WBUS_CMD_QUERY, 1);
  316.   if (error != 0)
  317.   {
  318.     return;
  319.   }
  320.  
  321.   unsigned char  glowplug_percentage = message_data[STA2_GP] / 28;//divide by 28 to give char 0-7 for bar display
  322.   unsigned char  fuelpump_percentage = message_data[STA2_FP] / 28;
  323.   unsigned char  airfan_percentage = message_data[STA2_CAF] / 28;
  324.   unsigned char  circpump_percentage = message_data[STA2_CP] / 28;
  325.  
  326.   lcd.setCursor(0, 0);
  327.   lcd.print("PLUG ");
  328.   lcd.write(glowplug_percentage);
  329.   lcd.print("   FPUMP ");
  330.   lcd.write(fuelpump_percentage);
  331.   lcd.print("     ");
  332.   //sprintf(tbs, "PLUG %c FPUMP %c" , glowplug_percentage,fuelpump_percentage);
  333.   //lcd.print(tbs);
  334.   lcd.setCursor(0, 1);
  335.   lcd.print("FAN  ");
  336.   lcd.write(airfan_percentage);
  337.   lcd.print("   CPUMP ");
  338.   lcd.write(circpump_percentage);
  339.   lcd.print("      ");
  340. }
  341.  
  342. //--------------------------------------------------------------------------------
  343. //
  344. // get status
  345. //
  346. void get_status(void)
  347. {
  348.   message_data[0] = QUERY_SENSORS; // sensors - temperature, volts, flame detection, glow plug resistance
  349.   message_length = 1;
  350.   wb_io(WBUS_CMD_QUERY, 1); if (error != 0) return;
  351.   int temp =  message_data[SEN_TEMP] - 50;
  352.   float voltage = ((message_data[SEN_VOLT] * 256) + message_data[SEN_VOLT + 1]) ;//in millivolts
  353.   int FlameOn = message_data[SEN_FD];
  354.   int watts = ((message_data[SEN_HE] * 256) + message_data[SEN_HE + 1]);
  355.   int resistance = ((message_data[SEN_GPR] * 256) + message_data[SEN_GPR + 1]);
  356.  
  357.   lcd.setCursor(0, 0);
  358.   Serial.println();
  359.   sprintf(tbs, "%d%cC V=",  temp, 223, voltage, FlameOn); //223 = degree sign
  360.   Serial.println(tbs);
  361.  
  362.   lcd.print(tbs);
  363.   lcd.print(voltage / 1000);//to give volts
  364.   sprintf(tbs, " F=%d  " , FlameOn);
  365.   lcd.print(tbs);
  366.   lcd.setCursor(0, 1);
  367.   sprintf(tbs, "Watts=%d %d%c    ", watts, resistance, 244); //244 = ohm sign
  368.   Serial.println(tbs);
  369.   lcd.print(tbs);
  370. }
  371.  
  372. // read the buttons
  373. int readLCDbuttons()
  374. {
  375.   adc_key_in = analogRead(0);// read the value from the sensor
  376.   if (adc_key_in > 1000) return btnNONE;
  377.   if (adc_key_in < 50)   return btnRIGHT;
  378.   if (adc_key_in < 195)  return btnUP;
  379.   if (adc_key_in < 380)  return btnDOWN;
  380.   if (adc_key_in < 555)  return btnLEFT;
  381.   if (adc_key_in < 790)  return btnSELECT;
  382.   return btnNONE;  // when all others fail, return this...
  383. }
  384.  
  385. void loop()
  386. {
  387.   currm = millis();
  388.   if (currm - prevm > 2000)
  389.   {
  390.     prevm = currm;
  391.     if (keepalive == true) keepAlive();
  392.     switch (statustype)
  393.     {
  394.       case 1:
  395.       case 2:
  396.         get_status();
  397.         break;
  398.       case 3:
  399.       case 4:
  400.         get_status2();
  401.         statustype = 0;
  402.         break;
  403.     }
  404.     statustype++;
  405.   }
  406.  
  407.   int lcd_key = readLCDbuttons();  // read the buttons
  408.   switch (lcd_key)               // depending on which button was pushed, we perform an action
  409.   {
  410.     case btnRIGHT:
  411.         lcd.print("NOT IMPLEMENTED      ");
  412.         break;
  413.     case btnLEFT:
  414.         lcd.print("NOT IMPLEMENTED      ");
  415.         break;
  416.     case btnUP:      
  417.         lcd.setCursor(0, 0);
  418.         lcd.print("Turn On     ");
  419.         turnOn(50);//50 mins
  420.         break;    
  421.     case btnDOWN:
  422.         lcd.setCursor(0, 0);
  423.         lcd.print("Turn Off   ");
  424.         turnOff();
  425.         break;
  426.     case btnSELECT:
  427.         lcd.print("NOT IMPLEMENTED      ");
  428.         break;
  429.     case btnNONE:
  430.         break;
  431.   }
  432.  
  433. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement