Advertisement
zoroastre74

heater.pde

Dec 16th, 2011
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 34.33 KB | None | 0 0
  1. /*
  2. ############################################################################
  3. MEGA 1280 - DOMOTIC PROJECT
  4.  
  5. Binary sketch size: 29512 bytes (of a 126976 byte maximum)
  6. ############################################################################
  7.  
  8. Le 13 Decembre 2011
  9.  
  10. TAG : programme en cours. Utilisation ancienne librairie S1D13700.
  11.       Ajout mode hors-gel ou off.
  12.  
  13. Le 16 decembre 2011
  14.       Refonte inertie -1, 0, 1. Perdition, stable, distribution.
  15.       Moyenne sur 5 valeurs, 1 valeur/mn pour coller à la courbe.
  16.       TouchScreen.cpp --> NUMSAMPLE 1
  17.  
  18. Modification du calcul inertie par comparaison de la valeur moyenne sur un echantillon de 5 temperatures.
  19. Ajout menu, layer1.
  20. Essai image : pluie
  21.  
  22. MODIFICATION :
  23.     - liaison pc seriel a la demande
  24.     - variable temperature de declenchement chauffage fixe a t+O.8
  25.     - default temperatures : 18.4, 17.5, 15.0, 5.0 (Jour, nuit, abs, vac, hors-gel)
  26.         - DS18B20 OneWire Pin 3
  27.                 - Ajout securite mauvaise lecture (DEVICE_DISCONNECTED = -127)
  28.     - Rs485 Pin 2 declaration (Tx3, Rx3)
  29.         - bit 1, Tx
  30.         - bit 0, release
  31.     - Modification librairie Time (Time.cpp)
  32.         - Ligne 239/259 : Desactivation de la synchro automatique.
  33.     - LED Pins :
  34.                 - Pin 8, voyant Auto.
  35.                 - Pin 9, voyant Absence.
  36.                 - Pin 10, voyant Vacances.
  37.                 - Pin 11, voyant OFF.
  38.         - GLCD S1D13700
  39.                 - Modification librairie S1D13700.h :
  40.                        - Utilisation du port A, pins D0 a D7.
  41.                        - DDRA, PORTA, PINA
  42.                 - Pins : rd = 38
  43.                          wr = 39
  44.                          a0 = 40
  45.                          cs = 41
  46.                          rst = 42
  47.         - TouchScreen (librairie from ladyada)
  48.                 - Pins : YP (Y2 ou YD) A13
  49.                          YM (Y1 ou YU) A15
  50.                          XM (X1 ou XL) A12
  51.                          XP (X2 ou XR) A14
  52.                 - Utilisation function map.
  53.  
  54. TODO :
  55.         - GLCD menu.
  56.                 - layer0 : affichage principal (date, heure, mode en cours, temperatures, etat de chauffe)
  57.                 - layer1 : boutons options (auto, off, abs, vac, cycle)
  58.                 - layer2 :
  59.                 - layer3 :
  60.         >> - Securiser la chauffe avec une temporisation.(20*60*1000)
  61.         >> - determiner une zone rouge avant la chauffe en mode nocturne.
  62.         >> - calibration glcd/touchscreen
  63.  
  64. REMARQUE :
  65.         - suppression application carte Sd (manque de fiabilite: 1 ecriture sur 2).
  66.                 - Sd Card Pins
  67.                 - CS pin 53
  68.                 - DI pin 51
  69.                 - DO pin 50
  70.                 - CLK pin 52
  71.  
  72. HELP :
  73.         - char * dtostrf(double val, signed char width, unsigned char prec, char * s) // convert double to string.
  74.         - int sprintf(char * str, const char * format, ...)                           // write formatted data to string.
  75.         - int printf ( const char * format, ...)                                      // print formatted data to stdout.
  76. */
  77.  
  78. /*
  79. ############################################################################
  80. GLOBAL : GLOBAL TIME DECLARATIONS
  81. ############################################################################
  82. */
  83. #include <Time.h>
  84. #define TIME_REQUEST  7
  85. #define TIME_MSG_LEN  11
  86. /*
  87. ############################################################################
  88. GLOBAL : DECLARATION VARIABLES TEMPS
  89. ############################################################################
  90. */
  91. int _hour; //= (hour());
  92. int _minute; //= (minute());
  93. //int _seconde = (second());
  94. int current_time; //= (_hour*60) + _minute;
  95. int last_minute;
  96.  
  97. time_t timeAbsence, timeVacances;                                          // sauvegarde since epoch time
  98.  
  99. int run_task;
  100. int tempo3;
  101. boolean overheat;
  102. /*
  103. ############################################################################
  104. GLOBAL : GLOBAL TEMPERATURE SENSORS DECLARATIONS
  105. ############################################################################
  106. */
  107. #include <OneWire.h>
  108. #include <DallasTemperature.h>
  109. #define ONE_WIRE_BUS 3
  110. //#define TEMPERATURE_PRECISION 9
  111. OneWire oneWire(ONE_WIRE_BUS);
  112. DallasTemperature sensors(&oneWire);
  113. uint8_t sonde_ds18b20_1[8] = {0x28, 0xFC, 0x97, 0x56, 0x2, 0x0, 0x0, 0x69};
  114. //uint8_t sonde_ds18b20_2[8] = {};
  115. //uint8_t sonde_ds18b20_3[8] = {};
  116. //uint8_t sonde_ds18b20_4[8] = {};
  117. /*
  118. ############################################################################
  119. GLOBAL : GLOBAL SERIAL MESSAGE DECLARATIONS
  120. ############################################################################
  121. */
  122. #define STARTBIT '*'
  123. #define STOPBIT '!'
  124. #define BUFFERSIZE 96
  125. char buffer[BUFFERSIZE + 1];
  126. char* TRAME[12]; // Set there default data
  127. /*
  128. ############################################################################
  129. GLOBAL : SERIAL RELAY CARD PIN DECLARATION
  130. ############################################################################
  131. */
  132. #define txPin 2
  133.  
  134. /*
  135. ############################################################################
  136. GLOBAL : GLCD S1D13700 DECLARATIONS
  137. ############################################################################
  138. */
  139. #include "lucida_font.h"
  140. #include "pluie.h"
  141. #include <S1D13700.h>
  142. S1D13700 glcd;
  143. /*
  144. ############################################################################
  145. GLOBAL : TOUCH SCREEN DECLARATIONS
  146. ############################################################################
  147. */
  148. #include <stdint.h>
  149. #include "TouchScreen.h"
  150.  
  151. #define YP A13                                                              // must be an analog pin, use "An" notation! (Y2 = YD)
  152. #define XM A12                                                              // must be an analog pin, use "An" notation! (X1 = XL)
  153. #define YM A15                                                              // can be a digital pin (Y1 = YU)
  154. #define XP A14                                                              // can be a digital pin (X2 = XR)
  155.  
  156. TouchScreen ts = TouchScreen(XP, YP, XM, YM, 630);                          // mesured : 630 ohms
  157. /*
  158. ############################################################################
  159. GLOBAL : DECLARATION VARIABLES INERTIE
  160. ############################################################################
  161. */
  162. #define ROW 5
  163. int comparateur[ROW];
  164. //boolean inertie, last_inertie;
  165. int inertie, last_inertie;
  166. int total = 0, average = 0, prev_average;
  167. int index = 0;
  168. //int eventTimer1 = _minute % 4;                                             // fill inertie formula every 4 mn
  169. int eventTimer2 = _minute % 10;
  170. /*
  171. ############################################################################
  172. GLOBAL : DECLARATION VARIABLES CHAUFFAGE
  173. ############################################################################
  174. */
  175. int intervalle_journuit[] = {390, 1365};                                   // 06h30 a 22h45
  176. float consigne_chauffage[] = {18.4, 17.5, 16.0, 10.0, 5.0};                // values to start with (jour, nuit, abs, vac, hors-gel)
  177. float calibrage;                                                           // temperature_marche_max = temperature1 + calibrage
  178.  
  179. boolean redzone;
  180. int h_redzone = intervalle_journuit[1] - 15;
  181.  
  182. float temperature1;
  183. float temperature1_saved, temperature_marche_max;
  184. float consigne_courante;
  185.  
  186. int mode_select;
  187. int etat_chauffage, prev_etat_chauffage;
  188. /*
  189. ############################################################################
  190. GLOBAL : DECLARATION VARIABLES IHM
  191. ############################################################################
  192. */
  193. int menu;
  194. int prev_led;
  195. int localClient, remoteClient;
  196. /*
  197. ############################################################################
  198. GLOBAL : DECLARATION VARIABLES ACTIONNEUR
  199. ############################################################################
  200. */
  201. int state_relay1;
  202. /*
  203. ############################################################################
  204. GLOBAL : DECLARATION VARIABLES MILLIS
  205. ############################################################################
  206. */
  207. unsigned long timer1 = 0, timer2 = 0;
  208. unsigned long timeout1 = 60*1000, timeout2 = 10*1000;
  209. /*
  210. ############################################################################
  211. GLOBAL : CLASS IHM
  212. ############################################################################
  213. */
  214. #define PIXH 14
  215.  
  216. class Objet {
  217.   public:
  218.     Objet();
  219.     int gadget;
  220.     char *text;
  221.    
  222.     //int _layer;
  223.     int radius;
  224.    
  225.     Objet(int,char*,int,int,int,int);     // type, text, x0, y0, x1, y1
  226.  
  227.     void draw() {
  228.       switch(gadget) {
  229.         case 0 : {                                                 // BitmapText
  230.           glcd.writeBitmapText(text, x1, y1, LUCIDA_FONT);
  231.           break;
  232.         }
  233.         case 1 : {                                                 // Box
  234.           //int dx1 = ((x2 + sizeof(text)) - x1)/2;
  235.           int dx1 = (x2 + x1 - (strlen(text)*PIXH))/2;
  236.           int dy1 = ((y2 + y1)/2) - PIXH;
  237.      
  238.           glcd.drawBox(x1, y1, x2, y2);
  239.           glcd.writeBitmapText(text, dx1, dy1, LUCIDA_FONT);
  240.           break;
  241.         }
  242.         case 2 : {                                                 // circle
  243.           int dx1 = x1 - (PIXH/2);
  244.           int dy1 = y1 + (PIXH/2);
  245.           radius = x2;
  246.           glcd.drawCircle(x1, y1, radius);
  247.           if (radius > PIXH) { glcd.writeBitmapText(text, dx1, dy1, LUCIDA_FONT); }
  248.           break;
  249.         }
  250.       }
  251.     };
  252.  
  253.     void disable() {
  254.       switch(gadget) {
  255.         case 0 : { break; }
  256.         case 1 : { break; }
  257.         case 2 : { break; }
  258.       }
  259.     };
  260.    
  261.     boolean check(int x, int y) {
  262.         // Adjust value from determinated calibration formula.
  263.         int X = float((1.22*x) + (-0.02*y) - 26.08);    // Xd = 1.22*x + -0.02*y - 26.06
  264.         int Y = float((-0.01*x) + (1.28*y) - 35.53);    // Yd = -0.01*x + 1.28*y - 35.53
  265.        
  266.         if ((gadget == 1) && (X > x1) && (X < x2) && (Y > y1) && (Y < y2))
  267.         { return true; }
  268.         else if ((gadget == 2) && (X > (x1 - (radius/2))) && (X < (x1 + (radius/2))) && (Y > (y1 - (radius/2))) && (Y < (y1 + (radius/2))))
  269.         { return true; }
  270.       return false;
  271.     };
  272.          
  273.   private:
  274.     int x1,y1,x2,y2;
  275. };
  276.  
  277. Objet::Objet(int g, char *t, int a, int b, int c=0, int d=0) {
  278.   gadget = g;
  279.   text = t;
  280.   x1 = a;
  281.   y1 = b;
  282.   x2 = c;
  283.   y2 = d;
  284. }
  285.  
  286. /*
  287. ############################################################################
  288. GLOBAL : DECLARATION DES OBJETS IHM
  289. ############################################################################
  290. */
  291. //Objet IHM_auto(1, "auto", 165, 190, 300, 230);                            // box
  292. //Objet IHM_off(1, "off", 20, 190, 155, 230);                               // box
  293. // LAYER 0
  294. Objet IHM_menu(1, "menu", 165, 190, 300, 230);                              // box
  295. Objet IHM_clock(0, "", 230, 10);                                            // text
  296. Objet IHM_mode(0, "", 10, 10);                                              // text
  297. Objet IHM_temp1(0, "", 10, 100);                                            // text
  298. Objet IHM_etat1(0, "", 100, 40);                                            // text
  299. // LAYER 1
  300. Objet IHM_auto(1, "auto", 20, 20, 150, 60);                                 // box
  301. Objet IHM_off(1, "off", 20, 80, 150, 120);                                  // box
  302. Objet IHM_abs2(1, "Absence 2H", 170, 20, 300, 60);                          // box
  303. Objet IHM_abs4(1, "Absence 4H", 170, 80, 300, 120);                         // box
  304. Objet IHM_return(1, "Back", 200, 180, 300, 220);                            // box
  305. Objet IHM_selectionLayer0(0, "", 30, 160);                                  // text
  306. // LAYER 2
  307.  
  308. /*
  309. ############################################################################
  310. ############################################################################
  311. ############################################################################
  312. SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP
  313. ############################################################################
  314. ############################################################################
  315. ############################################################################
  316. */
  317. void setup() {
  318. /*
  319. ############################################################################
  320. SETUP : INITIALISER LES VOYANTS
  321. ############################################################################
  322. */
  323.   pinMode(8, OUTPUT);                                                      // voyant auto
  324.   pinMode(9, OUTPUT);                                                      // voyant absence
  325.   pinMode(10, OUTPUT);                                                     // voyant vacances
  326.   pinMode(11, OUTPUT);                                                     // voyant off
  327. /*
  328. ############################################################################
  329. SETUP : INITIALISER LES VARIABLES DE CHAUFFE
  330. ############################################################################
  331. */
  332.   calibrage = 0.75;
  333.   temperature_marche_max = consigne_chauffage[0];
  334.   etat_chauffage = 0;
  335.   mode_select = 1;
  336.   overheat = false;
  337.   tempo3 = 0;
  338. /*
  339. ############################################################################
  340. SETUP : INITIALISER LES VARIABLES IHM
  341. ############################################################################
  342. */  
  343.   menu = 1;
  344.   localClient = 0;
  345.   remoteClient = 0;
  346. /*
  347. ############################################################################
  348. SETUP : INITIALISER LES VARIABLES SEQUENTIELLES
  349. ############################################################################
  350. */    
  351.   run_task = 0;
  352. /*
  353. ############################################################################
  354. SETUP : INITIALISER LA LIAISON SERIE
  355. ############################################################################
  356. */
  357.   Serial.begin(57600);
  358.   delay(1000);
  359. /*
  360. ############################################################################
  361. SETUP : INITIALISER LA CARTE RELAIS RS485
  362. ############################################################################
  363. */
  364.   Serial3.begin(9600);
  365.   delay(1000);
  366.   pinMode(txPin, OUTPUT);
  367.   digitalWrite(txPin, LOW);
  368.   delay(50);
  369. /*
  370. ############################################################################
  371. SETUP : INITIALISER LE RELAIS DE CHAUFFE
  372. ############################################################################
  373. */
  374.  rs485TxMsg("\xFF\x01\x00");
  375.  state_relay1 = 0;
  376.  delay(50);
  377. /*
  378. ############################################################################
  379. SETUP : INITIALISER LES SONDES DE TEMPERATURES
  380. ############################################################################
  381. */
  382.   sensors.begin();
  383.   sensors.setResolution(sonde_ds18b20_1, 12);
  384.   sensors.requestTemperatures();
  385.   delay(1000);
  386. /*
  387. ############################################################################
  388. SETUP : INITIALISER AFFICHEUR
  389. ############################################################################
  390. */  
  391.  glcd.pins.rd = 38;
  392.  glcd.pins.wr = 39;
  393.  glcd.pins.a0 = 40;
  394.  glcd.pins.cs = 41;
  395.  glcd.pins.rst = 42;
  396.  delay(50);
  397.  
  398.  glcd.initLCD();
  399.  glcd.clearText();
  400.  glcd.clearGraphic();
  401.  delay(2000);
  402.  
  403.  layer0();                                                                  // draw initial display.
  404. /*
  405. ############################################################################
  406. SETUP :
  407. ############################################################################
  408. */
  409.   Serial.println("LOG : Setup complete");
  410. }
  411. /*
  412. ############################################################################
  413. ############################################################################
  414. ############################################################################
  415. LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP
  416. ############################################################################
  417. ############################################################################
  418. ############################################################################
  419. */
  420. void loop() {
  421.   Point p = ts.getPoint();
  422.   if (p.z > 0) {                                                       //if (p.z > ts.pressureThreshhold)
  423.     int x = map(p.x, 0, 1023, 0, 320);                                // to test : map(p.x, 128, 895, 0, 320)
  424.     int y = map(p.y, 0, 1023, 0, 240);                                // to test : map(p.y, 170, 853, 0, 240)
  425.     switch(menu) {
  426.       case 1: {
  427.         if (IHM_menu.check(x, y)) { layer1(); }
  428.         break;
  429.       }
  430.       case 2: {
  431.         if (IHM_auto.check(x, y)) { mode_select = 1; IHM_selectionLayer0.text = "Auto"; IHM_selectionLayer0.draw(); }
  432.         if (IHM_off.check(x, y)) { mode_select = 4; IHM_selectionLayer0.text = "Off"; IHM_selectionLayer0.draw(); }
  433.         if (IHM_abs2.check(x, y)) { mode_select = 2; timeAbsence = now() + (2*3600); IHM_selectionLayer0.text = "Abs 2H"; IHM_selectionLayer0.draw(); }
  434.         if (IHM_abs4.check(x, y)) { mode_select = 2; timeAbsence = now() + (4*3600); IHM_selectionLayer0.text = "Abs 4H"; IHM_selectionLayer0.draw(); }
  435.         if (IHM_return.check(x, y)) { layer0(); }
  436.         break;
  437.       }
  438.     }
  439.   }
  440.  
  441. if (!localClient) { checkMsg(); }
  442. // AMELIORER CETTE PARTIE
  443. /*
  444. if (touched) {
  445.   unsigned long timer0 = millis();
  446.  
  447.   if (timer2 == 0) { timer2 = timer0; localClient = 1; remoteClient = 0; }
  448.   else {
  449.     if ((timer0 - timer2) > timeout2) { localClient = 0; timer2 = 0;}
  450.   }
  451.   Tactile();
  452. }
  453. */
  454.  
  455. switch (run_task) {
  456.   case 0 :
  457.       {
  458.       if (timeStatus() == timeNotSet) { Serial.println(TIME_REQUEST, BYTE); delay(1000); checkMsg();}
  459.       else { Serial.println("CLOCK UPDATED"); voyant(8); run_task = 1; }
  460.       break;
  461.       }
  462.   case 1 :
  463.     {
  464.       mainProgram();
  465.       break;
  466.     }
  467.   default :
  468.     {
  469.       run_task = 0;
  470.     }
  471.   }
  472. }
  473.  
  474. void voyant(int led) {
  475.   if (prev_led != led) {
  476.     switch (led) {
  477.       case 8 : { digitalWrite(led, HIGH); digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); break; }
  478.       case 9 : { digitalWrite(8, LOW); digitalWrite(led, HIGH); digitalWrite(10, LOW); digitalWrite(11, LOW); break; }
  479.       case 10 : { digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(led, HIGH); digitalWrite(11, LOW); break; }
  480.       case 11 : { digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(led, HIGH); break; }
  481.       default : ;;
  482.     }
  483.     prev_led = led;
  484.   }
  485. }
  486.  
  487. /*
  488. MAIN ROUTINE
  489. */
  490. void mainProgram() {
  491. /*
  492. ############################################################################
  493. LOOP : DECLARATION OF ROLLING VARIABLES
  494. ############################################################################
  495. */
  496.     _hour = (hour());
  497.     _minute = (minute());
  498.  
  499.     current_time = (_hour*60) + _minute;
  500.  
  501.         //eventTimer1 = _minute % 4;
  502.         eventTimer2 = _minute % 10;
  503. /*
  504. ############################################################################
  505. LOOP : FURNACE MODE : 1-AUTO, 2-AWAY, 3-HOLLYDAYS, 4-OFF
  506. ############################################################################
  507. */  
  508.   switch(mode_select) {
  509.         case 1 :      // auto
  510.                 {
  511.           if (intervalle_journuit[0] < current_time && current_time < intervalle_journuit[1])
  512.           {
  513.             if (consigne_courante != consigne_chauffage[0]) { consigne_courante = consigne_chauffage[0]; }
  514.             if (h_redzone != (intervalle_journuit[1] - 15)) { h_redzone = intervalle_journuit[1] - 15; }// consigne diurne
  515.           }
  516.           else
  517.           {
  518.             if (consigne_courante != consigne_chauffage[1]) { consigne_courante = consigne_chauffage[1];}// consigne nocturne
  519.           }
  520.           voyant(8);
  521.                   if ((IHM_mode.text != "Auto") && (menu == 1)) { IHM_mode.text = "Auto"; IHM_mode.draw(); }
  522.               break;
  523.                 }
  524.         case 2 :      // absence
  525.                 {
  526.                   if (timeAbsence <= now()) { mode_select = 1; timeAbsence = 0; }
  527.                   else { if (consigne_courante != consigne_chauffage[2]) { consigne_courante = consigne_chauffage[2]; } }                      
  528.           voyant(9);
  529.                   if ((IHM_mode.text != "Abs") && (menu == 1)) { IHM_mode.text = "Abs"; IHM_mode.draw(); }
  530.           break;
  531.                 }
  532.         case 3 :      // vacances
  533.                 {
  534.                   if (timeVacances <= now()) { mode_select = 1; timeVacances = 0; }
  535.                   else { if (consigne_courante != consigne_chauffage[3]) { consigne_courante = consigne_chauffage[3]; } }                      
  536.           voyant(10);
  537.                   if ((IHM_mode.text != "Vac") && (menu == 1)) { IHM_mode.text = "Vac"; IHM_mode.draw(); }
  538.           break;
  539.                 }
  540.         case 4 :      // OFF ou hors-gel
  541.                 {
  542.           if (etat_chauffage != 0)
  543.           {
  544.             rs485TxMsg("\xFF\x01\x00");
  545.           }
  546.                   if (consigne_courante != consigne_chauffage[4]) { consigne_courante = consigne_chauffage[4]; }
  547.           voyant(11);
  548.                   if ((IHM_mode.text != "Off") && (menu == 1)) { IHM_mode.text = "Off"; IHM_mode.draw(); }
  549.           break;
  550.                 }
  551.                 case 5 :      // launch 1 cycle
  552.                 {
  553.                   if (temperature1 >= consigne_courante) { mode_select = 1; }
  554.                   if ((IHM_mode.text != "Cyc") && (menu == 1)) { IHM_mode.text = "Cyc"; IHM_mode.draw(); }
  555.                   break;
  556.                 }
  557.         default :
  558.                 {
  559.               mode_select = 1;
  560.                 }
  561.               }
  562. /*
  563. ############################################################################
  564. LOOP : UPDATE TIME AND TEMPERATURE EVERY MINUTE
  565. ############################################################################
  566. */
  567.           if (_minute != last_minute) {
  568.    
  569.             last_minute = _minute;
  570.    
  571.                 sensors.requestTemperaturesByAddress(sonde_ds18b20_1);
  572.                 temperature1 = sensors.getTempC(sonde_ds18b20_1);
  573.            
  574.             if (h_redzone < current_time && current_time < intervalle_journuit[1]) { redzone = true; }
  575.             else { redzone = false; }
  576.  
  577.             //if ((eventTimer1 == 0) && (temperature1 != DEVICE_DISCONNECTED))
  578.                 if (temperature1 != DEVICE_DISCONNECTED) {
  579.                     total = total - comparateur[index];
  580.                     comparateur[index] = temperature1*100;
  581.                     total = total + comparateur[index];
  582.                     index++;
  583.                     if (index >= ROW) {
  584.                       index = 0;
  585.                       average = total/ROW;
  586.                       //if (average > prev_average) { inertie = 1; }
  587.                       //else if (average < prev_average) { inertie = -1; }
  588.                       //else if (average = prev_average) { inertie = 0; }
  589.                       if ((average - prev_average) >= 5) { inertie = 1; }                              // DISTRIBUTIOn
  590.                       else if ((average - prev_average) <= -5) { inertie = -1; }                       // PERDITION
  591.                       else if (((average - prev_average) < 5) && ((average - prev_average) > -5)) { inertie = 0; } // STABLE
  592.                       prev_average = average;
  593.                     }
  594.                   }
  595.  
  596.             if ((temperature1 < consigne_courante) && (inertie == -1) && (!redzone) && (temperature1 != DEVICE_DISCONNECTED))
  597.           {
  598.           etat_chauffage = 1;
  599.           if (etat_chauffage != prev_etat_chauffage)
  600.             {
  601.             temperature_marche_max = temperature1 + calibrage;      // ajustement de la temperature
  602.             rs485TxMsg("\xFF\x01\x01");                             // marche
  603.                     if (menu == 1) { IHM_etat1.text = "Marche"; IHM_etat1.draw(); }
  604.             }
  605.           }
  606.         if ((temperature1 >= temperature_marche_max) || (overheat))
  607.           {
  608.           etat_chauffage = 0;
  609.           if (etat_chauffage != prev_etat_chauffage)
  610.             {
  611.             overheat = false;
  612.             temperature_marche_max = consigne_courante;
  613.             rs485TxMsg("\xFF\x01\x00");                             // arret
  614.                     if (menu == 1) { IHM_etat1.text = "Arret"; IHM_etat1.draw(); }
  615.             }
  616.           }
  617.                 prev_etat_chauffage = etat_chauffage;
  618.         if(remoteClient) { sendData(); }
  619.            
  620.                 if (etat_chauffage) {
  621.           if (tempo3 > 20) { overheat = true; tempo3 = 0; }         // temps maxi chauffe.
  622.           else { tempo3++; }
  623.           }
  624.                 else { if (tempo3 != 0) { tempo3 = 0; } }                   // reinitialisation de la tempo si la temperature est atteinte avant.
  625.                
  626.           if ((etat_chauffage) || (eventTimer2 == 0)) { logs(); }
  627.                
  628.                 if (menu == 1) {
  629.                   IHM_clock.text = update_clock(); IHM_clock.draw();
  630.                   IHM_temp1.text = update_temp1(); IHM_temp1.draw();
  631.                 }
  632.           }
  633. }
  634. /*
  635. ############################################################################
  636. SECTION : LOOK AND MANAGE INCOMING SERIAL MESSAGE
  637. ############################################################################
  638. The getSerialString function looks for a valid message, with a header and a foot.
  639. if message is valid, it is split to each TRAME spaces in filldata function.
  640. Every splited data begins with a unique identifier flag, which will build valid
  641. functions and variables depending on position. This is my choice!
  642. For exemple, the 'T' flag means that data is concerning clock update.
  643. More things could be combined.
  644. ############################################################################
  645. */
  646. void checkMsg() {
  647.   if (getSerialString()) {                                                  // On verifie que la trame soit complete
  648.     filldata(buffer);                                                       // On remplit la structure des donnees
  649.     checkdata();                                                            // On renseigne les variables modifiees
  650.   }
  651. }
  652.  
  653. boolean getSerialString() {
  654.   int dataBufferIndex = 0;
  655.   boolean storebuffer = false;
  656.   delay(20);
  657.   if(Serial.available() > 1){
  658.         char incoming = Serial.read();
  659.         if(incoming==STARTBIT){
  660.             dataBufferIndex = 0;                                            //Initialize our dataBufferIndex variable
  661.             storebuffer = true;
  662.         }
  663.         if(storebuffer){
  664.           while(Serial.available()){
  665.             char incoming = Serial.read();
  666.             delay(50);
  667.             if(dataBufferIndex == BUFFERSIZE){dataBufferIndex = 0; break; }
  668.             if(incoming == STOPBIT) {buffer[dataBufferIndex] = 0; dataBufferIndex = 0; storebuffer = false; return true; }
  669.             else { buffer[dataBufferIndex++] = incoming; }
  670.           }
  671.         }
  672.   }
  673.   return false;
  674. }
  675.  
  676. void filldata(char *buffer) {
  677.   char *p = buffer;
  678.   char *str;
  679.   int i = 0;
  680.   while ((str = strtok_r(p, ";", &p)) != NULL) {                             // delimiter is the semicolon
  681.     char *q = str;
  682.     TRAME[i] = q;
  683.     i++;
  684.   }
  685. }
  686.  
  687. void checkdata() {
  688.   if (strcmp(TRAME[0], "CLOCK") == 0) {
  689.     if (strcmp(TRAME[1], "#") != 0) { updateTime(); }                        // Auto update Time
  690.   }
  691.   if (strcmp(TRAME[0], "SYNCTIME") == 0) { Serial.println(TIME_REQUEST, BYTE); delay(50); } // Manual update Time
  692.   if (strcmp(TRAME[0], "RELAY") == 0) {
  693.     // 0, relay number, relay state
  694.     if ((strcmp(TRAME[1], "1") == 0) && (strcmp(TRAME[2], "0") == 0)) { rs485TxMsg("\xFF\x01\x00"); state_relay1 = 0; Serial.print("@relay1:"); Serial.println(state_relay1); etat_chauffage = 0; }
  695.     if ((strcmp(TRAME[1], "1") == 0) && (strcmp(TRAME[2], "1") == 0)) { rs485TxMsg("\xFF\x01\x01"); state_relay1 = 1; Serial.print("@relay1:"); Serial.println(state_relay1); etat_chauffage = 1; }
  696.   }
  697.   if (strcmp(TRAME[0], "PARAM") == 0) {
  698.     // 'mode':'#', 'abs':'#', 'vac':'#', 't_jour':'#', 't_nuit':'#', 't_abs':'#', 't_vac':'#', 'cal':'#', 'day_at':'#', 'night_at':'#'
  699.     if (strcmp(TRAME[1], "#") != 0) { mode_select = string2integer(TRAME[1]); }
  700.     if (strcmp(TRAME[2], "#") != 0) { timeAbsence = string2long(TRAME[2]); }
  701.     if (strcmp(TRAME[3], "#") != 0) { timeVacances = string2long(TRAME[3]); }
  702.     if (strcmp(TRAME[4], "#") != 0) { consigne_chauffage[0] = string2float(TRAME[4]); }
  703.     if (strcmp(TRAME[5], "#") != 0) { consigne_chauffage[1] = string2float(TRAME[5]); }
  704.     if (strcmp(TRAME[6], "#") != 0) { consigne_chauffage[2] = string2float(TRAME[6]); }
  705.     if (strcmp(TRAME[7], "#") != 0) { consigne_chauffage[3] = string2float(TRAME[7]); }
  706.     if (strcmp(TRAME[8], "#") != 0) { calibrage = string2float(TRAME[8]); }
  707.     if (strcmp(TRAME[9], "#") != 0) { intervalle_journuit[0] = string2integer(TRAME[9]); }
  708.     if (strcmp(TRAME[10], "#") != 0) { intervalle_journuit[1] = string2integer(TRAME[10]); }                           
  709.   }
  710.   if (strcmp(TRAME[0], "START_CLI") == 0) {
  711.     // send data next to real time (1 mn)
  712.     remoteClient = 1; Serial.println("LOG : Client connected");
  713.     }
  714.   if (strcmp(TRAME[0], "STOP_CLI") == 0) {
  715.     // send data to normal timer (5 mn)
  716.     remoteClient = 0; Serial.println("LOG : Client dropped");
  717.   }
  718. }
  719.  
  720. void updateTime() {
  721.   int i = 0;
  722.   time_t pctime = 0;    
  723.   for(i = 0; i < TIME_MSG_LEN; i++) {
  724.       if( int(TRAME[1][i]) >= '0' && int(TRAME[1][i]) <= '9'){  
  725.         pctime = (10 * pctime) + (int(TRAME[1][i]) - '0') ;                 // convert digits to a number    
  726.         }
  727.       }
  728.       setTime(pctime);                                                      // Sync Arduino clock to the time received on the serial port
  729. }
  730.  
  731. /*
  732. ############################################################################
  733. SECTION : CONVERT STRING TO SOMETHING
  734. ############################################################################
  735. */
  736. int string2integer(char* data) { return atoi(data); }
  737. float string2float(char* data) { return atof(data); }
  738. unsigned long string2long(char* data) { return atol(data); }
  739.  
  740. /*
  741. ############################################################################
  742. SECTION : SWITCH RS485 FURNACE RELAY
  743. ############################################################################
  744. */
  745. void rs485TxMsg(char *msg) {
  746.   Serial3.flush();
  747.   digitalWrite(txPin, HIGH);
  748.   delay(10);
  749.   Serial3.print(msg);
  750.   delay(10);
  751.   digitalWrite(txPin, LOW);
  752. }
  753.  
  754. /*
  755. ############################################################################
  756. SECTION : SEND STATUS TO REMOTE CLIENT
  757. ############################################################################
  758. */
  759. void sendData() {
  760.     // 'mode':'#', 'abs':'#', 'vac':'#', 't_jour':'#', 't_nuit':'#', 't_abs':'#', 't_vac':'#', 'cal':'#', 'day_at':'#', 'night_at':'#'
  761.     Serial.flush();
  762.     Serial.print("@data;");
  763.     Serial.print(temperature1); Serial.print(";");                           // temperature 1
  764.     Serial.print("00.0"); Serial.print(";");                                 // temperature 2
  765.     Serial.print("00.0"); Serial.print(";");                                 // temperature 3
  766.     Serial.print("00.0"); Serial.print(";");                                 // temperature 4
  767.     Serial.print("0"); Serial.print(";");                                    // luminosite 1
  768.     Serial.print("0"); Serial.print(";");                                    // lux 1
  769.     Serial.print(mode_select); Serial.print(";");                            // mode
  770.     Serial.print(etat_chauffage); Serial.print(";");                         // chauffage on/off          
  771.     Serial.print(_hour); Serial.print(";");                                  // heure
  772.     Serial.print(_minute); Serial.print(";");                                // minute
  773.     if (mode_select == 2) { Serial.print(timeAbsence); }                 // Absence
  774.     else { Serial.print("0"); }
  775.     Serial.print(";");
  776.     if (mode_select == 3) { Serial.print(timeVacances); }                // Vacances
  777.     else { Serial.print("0"); }
  778.     Serial.print(";");
  779.     Serial.print(consigne_chauffage[0]); Serial.print(";");              // consigne jour
  780.     Serial.print(consigne_chauffage[1]); Serial.print(";");              // consigne nuit
  781.     Serial.print(consigne_chauffage[2]); Serial.print(";");              // consigne abs
  782.     Serial.print(consigne_chauffage[3]); Serial.print(";");              // consigne vac
  783.     Serial.print(calibrage); Serial.print(";");                          // calibrage
  784.     Serial.print(intervalle_journuit[0]); Serial.print(";");             // debut horaire jour
  785.     Serial.print(intervalle_journuit[1]);                                // fin horaire jour
  786.     Serial.println();
  787.     Serial.print("Zone rouge="); Serial.println(h_redzone);
  788. }
  789. /*
  790. ############################################################################
  791. SECTION : SEND LOGS TO SERVER
  792. ############################################################################
  793. */
  794. void logs() {
  795.     Serial.print("LOG:");
  796.     Serial.print(_hour); Serial.print("h"); Serial.print(_minute);
  797.     Serial.print(";T°="); Serial.print(temperature1); Serial.print(";State=");
  798.     Serial.print(etat_chauffage); Serial.print(";Mode=");
  799.     Serial.print(mode_select); Serial.print(";Inertie=");
  800.         //if(inertie == true) { Serial.println("true"); }
  801.         //if(inertie == false) { Serial.println("false"); }
  802.     Serial.println(inertie);
  803. }
  804. /*
  805. ############################################################################
  806. SECTION : GLCD S1D13700 MENU
  807. ############################################################################
  808. */
  809. char* update_clock() {
  810.   static char time_buff[17] = { '\0' };
  811.   snprintf(time_buff, 17, "%02dh%02d", _hour, _minute);
  812.   return time_buff;
  813. }
  814.  
  815. char* update_temp1() {
  816.   char ibuff1[6] = { '\0' };
  817.   //char ibuff2[7] = { '\0' };
  818.   static char obuff1[20] = { '\0' };                                       // static = conserver en memoire, non detruite a la fin de la fonction.
  819.   //float delta = consigne_courante - temperature1;
  820.   dtostrf(temperature1,5,2,ibuff1);
  821.   //dtostrf(delta,6,2,ibuff1);
  822.   //if (delta >= 0) { snprintf(obuff1, 15, "T: %s    +%s", ibuff1, ibuff2); }
  823.   //else { snprintf(obuff1, 20, "T: %s    %s", ibuff1, ibuff2); }
  824.   snprintf(obuff1, 20, "T: %s", ibuff1);
  825.   return obuff1;
  826. }
  827.  
  828. void layer0() {
  829.   glcd.clearText();
  830.   glcd.clearGraphic();
  831.   glcd.drawBitmap(RAIN, 180, 60, 128, 75);
  832.   IHM_menu.draw();
  833.   IHM_clock.text = "##h##"; IHM_clock.draw();
  834.   IHM_mode.text = "###"; IHM_mode.draw();
  835.   IHM_temp1.text = "###"; IHM_temp1.draw();
  836.   IHM_etat1.text = "###"; IHM_etat1.draw();
  837.   menu = 1;
  838.   delay(200);
  839. }
  840.  
  841. void layer1() {
  842.   glcd.clearText();
  843.   glcd.clearGraphic();
  844.   IHM_auto.draw();
  845.   IHM_off.draw();
  846.   IHM_abs2.draw();
  847.   IHM_abs4.draw();
  848.   IHM_return.draw();
  849.   IHM_selectionLayer0.text = IHM_mode.text; IHM_selectionLayer0.draw();
  850.   menu = 2;
  851.   delay(200);
  852. }
  853.  
  854. void layer2() {
  855. }
  856.  
  857. void layer3() {
  858. }
  859.  
  860. int availableMemory() {
  861.   int size = 8192; // Use 2048 with ATmega328, 8192 with mega1280
  862.   byte *buf;
  863.  
  864.   while ((buf = (byte *) malloc(--size)) == NULL)
  865.     ;
  866.  
  867.   free(buf);
  868.  
  869.   return size;
  870. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement