/* ############################################################################ MEGA 1280 - DOMOTIC PROJECT Binary sketch size: 28598 bytes (of a 126976 byte maximum) ############################################################################ Le 13 Decembre 2011 TAG : programme en cours. Utilisation ancienne librairie S1D13700. Ajout mode hors-gel ou off. Le 16 decembre 2011 Refonte inertie -1, 0, 1. Perdition, stable, distribution. Moyenne sur 5 valeurs, 1 valeur/mn pour coller à la courbe. TouchScreen.cpp --> NUMSAMPLE 1 Le 19 decembre 2011 Modification inertie --> regulation Ajout variable sommetCourbe, HYSTERESIS, ecart. Le 26 decembre 2011 Regulation en logique floue. Le temperature exterieure est fixe : 6 Ajout cycle de forcage Ajout menu, layer1. MODIFICATION : - liaison pc seriel a la demande - variable temperature de declenchement chauffage fixe a t+O.8 - default temperatures : 18.4, 17.5, 15.0, 5.0 (Jour, nuit, abs, vac, hors-gel) - DS18B20 OneWire Pin 3 - Ajout securite mauvaise lecture (DEVICE_DISCONNECTED = -127) - Rs485 Pin 2 declaration (Tx3, Rx3) - bit 1, Tx - bit 0, release - Modification librairie Time (Time.cpp) - Ligne 239/259 : Desactivation de la synchro automatique. - LED Pins : - Pin 8, voyant Auto. - Pin 9, voyant Absence. - Pin 10, voyant Vacances. - Pin 11, voyant OFF. - GLCD S1D13700 - Modification librairie S1D13700.h : - Utilisation du port A, pins D0 a D7. - DDRA, PORTA, PINA - Pins : rd = 38 wr = 39 a0 = 40 cs = 41 rst = 42 - TouchScreen (librairie from ladyada) - Pins : YP (Y2 ou YD) A13 YM (Y1 ou YU) A15 XM (X1 ou XL) A12 XP (X2 ou XR) A14 - Utilisation function map. TODO : - GLCD menu. - layer0 : affichage principal (date, heure, mode en cours, temperatures, etat de chauffe) - layer1 : boutons options (auto, off, abs, vac, cycle) - layer2 : - layer3 : >> - Securiser la chauffe avec une temporisation.(20*60*1000) >> - determiner une zone rouge avant la chauffe en mode nocturne. >> - calibration glcd/touchscreen REMARQUE : - suppression application carte Sd (manque de fiabilite: 1 ecriture sur 2). - Sd Card Pins - CS pin 53 - DI pin 51 - DO pin 50 - CLK pin 52 HELP : - char * dtostrf(double val, signed char width, unsigned char prec, char * s) // convert double to string. - int sprintf(char * str, const char * format, ...) // write formatted data to string. - int printf ( const char * format, ...) // print formatted data to stdout. */ /* ############################################################################ GLOBAL : GLOBAL TIME DECLARATIONS ############################################################################ */ #include #define TIME_REQUEST 7 #define TIME_MSG_LEN 11 /* ############################################################################ GLOBAL : DECLARATION VARIABLES TEMPS ############################################################################ */ int _hour; //= (hour()); int _minute; //= (minute()); int current_time; //= (_hour*60) + _minute; int last_minute; time_t timeAbsence, timeVacances; // sauvegarde since epoch time int run_task; int tempo3; boolean overheat; /* ############################################################################ GLOBAL : GLOBAL TEMPERATURE SENSORS DECLARATIONS ############################################################################ */ #include #include #define ONE_WIRE_BUS 3 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); uint8_t sonde_ds18b20_1[8] = {0x28, 0xFC, 0x97, 0x56, 0x2, 0x0, 0x0, 0x69}; //uint8_t sonde_ds18b20_2[8] = {}; //uint8_t sonde_ds18b20_3[8] = {}; //uint8_t sonde_ds18b20_4[8] = {}; /* ############################################################################ GLOBAL : GLOBAL SERIAL MESSAGE DECLARATIONS ############################################################################ */ #define STARTBIT '*' #define STOPBIT '!' #define BUFFERSIZE 96 char buffer[BUFFERSIZE + 1]; char* TRAME[12]; // Set there default data /* ############################################################################ GLOBAL : SERIAL RELAY CARD PIN DECLARATION ############################################################################ */ #define txPin 2 /* ############################################################################ GLOBAL : GLCD S1D13700 DECLARATIONS ############################################################################ */ #include "lucida_font.h" #include S1D13700 glcd; /* ############################################################################ GLOBAL : TOUCH SCREEN DECLARATIONS ############################################################################ */ #include #include "TouchScreen.h" #define YP A13 // must be an analog pin, use "An" notation! (Y2 = YD) #define XM A12 // must be an analog pin, use "An" notation! (X1 = XL) #define YM A15 // can be a digital pin (Y1 = YU) #define XP A14 // can be a digital pin (X2 = XR) TouchScreen ts = TouchScreen(XP, YP, XM, YM, 630); // mesured : 630 ohms /* ############################################################################ GLOBAL : DECLARATION VARIABLES CHAUFFAGE ############################################################################ */ int intervalle_journuit[] = {390, 1365}; // 06h30 a 22h45 float consigne_chauffage[] = {18.4, 17.5, 16.0, 10.0, 5.0}; // values to start with (jour, nuit, abs, vac, hors-gel) float calibrage; // temperature_marche_max = temperature1 + calibrage boolean redzone; int h_redzone = intervalle_journuit[1] - 15; float temperature1; float temperature_marche_max; float consigne_courante; int mode_select; int etat_chauffage, prev_etat_chauffage; /* ############################################################################ GLOBAL : DECLARATION REGULATION ############################################################################ */ const float POIDS1 = 0.7; /* CONSIGNE */ const float POIDS2 = 0.1; /* PROBABILITE DEPERDITION CALORIFIQUE */ const float POIDS3 = 0.15; /* TEMPERATURE EXTERIEURE */ float CIBLE[4][3] = { { -127.0, 0.0, POIDS1*100 }, /* UNDER */ { 0.0, 0.1, POIDS1*86 }, /* TOUCH */ { 0.1, 0.2, POIDS1*80 }, /* MEDIUM */ { 0.2, 127.0, POIDS1*0 }, /* FAR */ }; float PROBABILITY[5][3] = { { -127.0, 0.0, POIDS2*0 }, { 0.0, 0.1, POIDS2*10 }, /* ECART P1 */ { 0.1, 0.15, POIDS2*30 }, /* ECART P2 */ { 0.15, 0.2, POIDS2*80 }, /* ECART P3 */ { 0.2, 127.0, POIDS2*100 } /* ECART P4 */ }; float EXTERIEUR[6][3] = { { -127.0, -2.0, POIDS3*100 }, /* FREEZE */ { -2.0, 2.0, POIDS3*80 }, /* COLD */ { 2.0, 6.0, POIDS3*60 }, /* WINTER */ { 6.0, 10.0, POIDS3*40 }, /* AUTOMN */ { 10.0, 16.0, POIDS3*20 }, /* SPRING */ { 16.0, 127.0, POIDS3*0 } /* SUMMER */ }; const int longueurTable1 = sizeof(EXTERIEUR)/sizeof(EXTERIEUR[0]); const int longueurTable2 = sizeof(CIBLE)/sizeof(CIBLE[0]); const int longueurTable3 = sizeof(PROBABILITY)/sizeof(PROBABILITY[0]); float sommetCourbe, ecart; float temperature_ext = 6.0; boolean check_regulation, chauffage, forcage; int value1, value2, value3; /* ############################################################################ GLOBAL : LOGS DELAY ############################################################################ */ int eventTimer2 = _minute % 10; /* ############################################################################ GLOBAL : DECLARATION VARIABLES IHM ############################################################################ */ int menu; int prev_led; int localClient, remoteClient; /* ############################################################################ GLOBAL : DECLARATION VARIABLES ACTIONNEUR ############################################################################ */ int state_relay1; /* ############################################################################ GLOBAL : DECLARATION VARIABLES MILLIS ############################################################################ */ //unsigned long timer1 = 0, timer2 = 0; //unsigned long timeout1 = 60*1000, timeout2 = 10*1000; unsigned long timeout2 = 10*1000; /* ############################################################################ GLOBAL : CLASS IHM ############################################################################ */ #define PIXH 14 class Objet { public: Objet(); int gadget; char *text; //int _layer; int radius; Objet(int,char*,int,int,int,int); // type, text, x0, y0, x1, y1 void draw() { switch(gadget) { case 0 : { // BitmapText glcd.writeBitmapText(text, x1, y1, LUCIDA_FONT); break; } case 1 : { // Box //int dx1 = ((x2 + sizeof(text)) - x1)/2; int dx1 = (x2 + x1 - (strlen(text)*PIXH))/2; int dy1 = ((y2 + y1)/2) - PIXH; glcd.drawBox(x1, y1, x2, y2); glcd.writeBitmapText(text, dx1, dy1, LUCIDA_FONT); break; } case 2 : { // circle int dx1 = x1 - (PIXH/2); int dy1 = y1 + (PIXH/2); radius = x2; glcd.drawCircle(x1, y1, radius); if (radius > PIXH) { glcd.writeBitmapText(text, dx1, dy1, LUCIDA_FONT); } break; } } }; void disable() { switch(gadget) { case 0 : { break; } case 1 : { break; } case 2 : { break; } } }; boolean check(int x, int y) { // Adjust value from determinated calibration formula. int X = float((1.22*x) + (-0.02*y) - 26.08); // Xd = 1.22*x + -0.02*y - 26.06 int Y = float((-0.01*x) + (1.28*y) - 35.53); // Yd = -0.01*x + 1.28*y - 35.53 if ((gadget == 1) && (X > x1) && (X < x2) && (Y > y1) && (Y < y2)) { return true; } else if ((gadget == 2) && (X > (x1 - (radius/2))) && (X < (x1 + (radius/2))) && (Y > (y1 - (radius/2))) && (Y < (y1 + (radius/2)))) { return true; } return false; }; private: int x1,y1,x2,y2; }; Objet::Objet(int g, char *t, int a, int b, int c=0, int d=0) { gadget = g; text = t; x1 = a; y1 = b; x2 = c; y2 = d; } /* ############################################################################ GLOBAL : DECLARATION DES OBJETS IHM ############################################################################ */ // LAYER 0 Objet IHM_menu(1, "menu", 165, 190, 300, 230); // box Objet IHM_clock(0, "", 230, 10); // text Objet IHM_mode(0, "", 10, 10); // text Objet IHM_temp1(0, "", 10, 100); // text Objet IHM_etat1(0, "", 100, 40); // text // LAYER 1 Objet IHM_auto(1, "auto", 20, 20, 150, 60); // box Objet IHM_off(1, "off", 20, 80, 150, 120); // box Objet IHM_abs2(1, "Abs 2H", 170, 20, 300, 60); // box Objet IHM_abs4(1, "Abs 4H", 170, 80, 300, 120); // box Objet IHM_forcage(1, "forcage", 20, 140, 150, 180); // box Objet IHM_return(1, "Back", 200, 180, 300, 220); // box Objet IHM_selectionLayer0(0, "", 30, 200); // text // LAYER 2 /* ############################################################################ ############################################################################ ############################################################################ SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP - SETUP ############################################################################ ############################################################################ ############################################################################ */ void setup() { /* ############################################################################ SETUP : INITIALISER LES VOYANTS ############################################################################ */ pinMode(8, OUTPUT); // voyant auto pinMode(9, OUTPUT); // voyant absence pinMode(10, OUTPUT); // voyant vacances pinMode(11, OUTPUT); // voyant off /* ############################################################################ SETUP : INITIALISER LES VARIABLES DE CHAUFFE ############################################################################ */ calibrage = 0.75; temperature_marche_max = consigne_chauffage[0]; etat_chauffage = 0; mode_select = 1; overheat = false; tempo3 = 0; check_regulation = true; forcage = false; /* ############################################################################ SETUP : INITIALISER LES VARIABLES IHM ############################################################################ */ menu = 1; localClient = 0; remoteClient = 0; /* ############################################################################ SETUP : INITIALISER LES VARIABLES SEQUENTIELLES ############################################################################ */ run_task = 0; /* ############################################################################ SETUP : INITIALISER LA LIAISON SERIE ############################################################################ */ Serial.begin(57600); delay(1000); /* ############################################################################ SETUP : INITIALISER LA CARTE RELAIS RS485 ############################################################################ */ Serial3.begin(9600); delay(1000); pinMode(txPin, OUTPUT); digitalWrite(txPin, LOW); delay(50); /* ############################################################################ SETUP : INITIALISER LE RELAIS DE CHAUFFE ############################################################################ */ rs485TxMsg("\xFF\x01\x00"); state_relay1 = 0; delay(50); /* ############################################################################ SETUP : INITIALISER LES SONDES DE TEMPERATURES ############################################################################ */ sensors.begin(); sensors.setResolution(sonde_ds18b20_1, 12); sensors.requestTemperatures(); delay(1000); /* ############################################################################ SETUP : INITIALISER AFFICHEUR ############################################################################ */ glcd.pins.rd = 38; glcd.pins.wr = 39; glcd.pins.a0 = 40; glcd.pins.cs = 41; glcd.pins.rst = 42; delay(50); glcd.initLCD(); glcd.clearText(); glcd.clearGraphic(); delay(2000); layer0(); // draw initial display. /* ############################################################################ SETUP : ############################################################################ */ Serial.println("LOG : Setup complete"); } /* ############################################################################ ############################################################################ ############################################################################ LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP - LOOP ############################################################################ ############################################################################ ############################################################################ */ void loop() { Point p = ts.getPoint(); if (p.z > 0) { //if (p.z > ts.pressureThreshhold) int x = map(p.x, 0, 1023, 0, 320); // to test : map(p.x, 128, 895, 0, 320) int y = map(p.y, 0, 1023, 0, 240); // to test : map(p.y, 170, 853, 0, 240) switch(menu) { case 1: { if (IHM_menu.check(x, y)) { layer1(); } break; } case 2: { if (IHM_auto.check(x, y)) { mode_select = 1; IHM_selectionLayer0.text = "Auto"; IHM_selectionLayer0.draw(); } if (IHM_off.check(x, y)) { mode_select = 4; IHM_selectionLayer0.text = "Off"; IHM_selectionLayer0.draw(); } if (IHM_forcage.check(x, y)) { mode_select = 5; IHM_selectionLayer0.text = "Run"; IHM_selectionLayer0.draw(); check_regulation = false; forcage = true; } if (IHM_abs2.check(x, y)) { mode_select = 2; timeAbsence = now() + (2*3600); IHM_selectionLayer0.text = "Abs 2H"; IHM_selectionLayer0.draw(); } if (IHM_abs4.check(x, y)) { mode_select = 2; timeAbsence = now() + (4*3600); IHM_selectionLayer0.text = "Abs 4H"; IHM_selectionLayer0.draw(); } if (IHM_return.check(x, y)) { layer0(); } break; } } } if (!localClient) { checkMsg(); } // AMELIORER CETTE PARTIE /* if (touched) { unsigned long timer0 = millis(); if (timer2 == 0) { timer2 = timer0; localClient = 1; remoteClient = 0; } else { if ((timer0 - timer2) > timeout2) { localClient = 0; timer2 = 0;} } Tactile(); } */ switch (run_task) { case 0 : { if (timeStatus() == timeNotSet) { Serial.println(TIME_REQUEST, BYTE); delay(1000); checkMsg();} else { Serial.println("CLOCK UPDATED"); voyant(8); run_task = 1; } break; } case 1 : { mainProgram(); break; } default : { run_task = 0; } } } void voyant(int led) { if (prev_led != led) { switch (led) { case 8 : { digitalWrite(led, HIGH); digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(11, LOW); break; } case 9 : { digitalWrite(8, LOW); digitalWrite(led, HIGH); digitalWrite(10, LOW); digitalWrite(11, LOW); break; } case 10 : { digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(led, HIGH); digitalWrite(11, LOW); break; } case 11 : { digitalWrite(8, LOW); digitalWrite(9, LOW); digitalWrite(10, LOW); digitalWrite(led, HIGH); break; } default : ;; } prev_led = led; } } /* MAIN ROUTINE */ void mainProgram() { /* ############################################################################ LOOP : DECLARATION OF ROLLING VARIABLES ############################################################################ */ _hour = (hour()); _minute = (minute()); current_time = (_hour*60) + _minute; //eventTimer1 = _minute % 4; eventTimer2 = _minute % 10; /* ############################################################################ LOOP : FURNACE MODE : 1-AUTO, 2-AWAY, 3-HOLLYDAYS, 4-OFF ############################################################################ */ switch(mode_select) { case 1 : // auto { if (intervalle_journuit[0] < current_time && current_time < intervalle_journuit[1]) { if (consigne_courante != consigne_chauffage[0]) { consigne_courante = consigne_chauffage[0]; } if (h_redzone != (intervalle_journuit[1] - 15)) { h_redzone = intervalle_journuit[1] - 15; }// consigne diurne } else { if (consigne_courante != consigne_chauffage[1]) { consigne_courante = consigne_chauffage[1];}// consigne nocturne } voyant(8); if ((IHM_mode.text != "Auto") && (menu == 1)) { IHM_mode.text = "Auto"; IHM_mode.draw(); } break; } case 2 : // absence { if (timeAbsence <= now()) { mode_select = 1; timeAbsence = 0; } else { if (consigne_courante != consigne_chauffage[2]) { consigne_courante = consigne_chauffage[2]; } } voyant(9); if ((IHM_mode.text != "Abs") && (menu == 1)) { IHM_mode.text = "Abs"; IHM_mode.draw(); } break; } case 3 : // vacances { if (timeVacances <= now()) { mode_select = 1; timeVacances = 0; } else { if (consigne_courante != consigne_chauffage[3]) { consigne_courante = consigne_chauffage[3]; } } voyant(10); if ((IHM_mode.text != "Vac") && (menu == 1)) { IHM_mode.text = "Vac"; IHM_mode.draw(); } break; } case 4 : // OFF ou hors-gel { if (etat_chauffage != 0) { rs485TxMsg("\xFF\x01\x00"); } if (consigne_courante != consigne_chauffage[4]) { consigne_courante = consigne_chauffage[4]; } voyant(11); if ((IHM_mode.text != "Off") && (menu == 1)) { IHM_mode.text = "Off"; IHM_mode.draw(); } break; } case 5 : // launch 1 cycle { if ((IHM_mode.text != "Run") && (menu == 1)) { IHM_mode.text = "Run"; IHM_mode.draw(); } if (forcage == false) { mode_select = 1; } break; } default : { mode_select = 1; } } /* ############################################################################ LOOP : UPDATE TIME AND TEMPERATURE EVERY MINUTE ############################################################################ */ if (_minute != last_minute) { last_minute = _minute; sensors.requestTemperaturesByAddress(sonde_ds18b20_1); temperature1 = sensors.getTempC(sonde_ds18b20_1); if (h_redzone < current_time && current_time < intervalle_journuit[1]) { redzone = true; } else { redzone = false; } if ((temperature1 != DEVICE_DISCONNECTED) && check_regulation) { chauffage = regulation(); } if (((chauffage == true) && (!redzone)) || (forcage == true)) { etat_chauffage = 1; if (etat_chauffage != prev_etat_chauffage) { temperature_marche_max = temperature1 + calibrage; // ajustement de la temperature sommetCourbe = 0.0; // init sommetCourbe check_regulation = false; rs485TxMsg("\xFF\x01\x01"); // marche if (menu == 1) { IHM_etat1.text = "Marche"; IHM_etat1.draw(); } } } if ((temperature1 >= temperature_marche_max) || (overheat)) { etat_chauffage = 0; if (etat_chauffage != prev_etat_chauffage) { overheat = false; check_regulation = true; if (forcage == true) { forcage = false; } temperature_marche_max = consigne_courante; rs485TxMsg("\xFF\x01\x00"); // arret if (menu == 1) { IHM_etat1.text = "Arret"; IHM_etat1.draw(); } } } prev_etat_chauffage = etat_chauffage; if(remoteClient) { sendData(); } if (etat_chauffage) { if (tempo3 >= 20) { overheat = true; tempo3 = 0; } // temps maxi chauffe. else { tempo3++; } } else { if (tempo3 != 0) { tempo3 = 0; } } // reinitialisation de la tempo si la temperature est atteinte avant. if ((etat_chauffage) || (eventTimer2 == 0)) { logs(); } if (menu == 1) { IHM_clock.text = update_clock(); IHM_clock.draw(); IHM_temp1.text = update_temp1(); IHM_temp1.draw(); } } } /* ############################################################################ SECTION : LOOK AND MANAGE INCOMING SERIAL MESSAGE ############################################################################ The getSerialString function looks for a valid message, with a header and a foot. if message is valid, it is split to each TRAME spaces in filldata function. Every splited data begins with a unique identifier flag, which will build valid functions and variables depending on position. This is my choice! For exemple, the 'T' flag means that data is concerning clock update. More things could be combined. ############################################################################ */ void checkMsg() { if (getSerialString()) { // On verifie que la trame soit complete filldata(buffer); // On remplit la structure des donnees checkdata(); // On renseigne les variables modifiees } } boolean getSerialString() { int dataBufferIndex = 0; boolean storebuffer = false; delay(20); if(Serial.available() > 1){ char incoming = Serial.read(); if(incoming==STARTBIT){ dataBufferIndex = 0; //Initialize our dataBufferIndex variable storebuffer = true; } if(storebuffer){ while(Serial.available()){ char incoming = Serial.read(); delay(50); if(dataBufferIndex == BUFFERSIZE){dataBufferIndex = 0; break; } if(incoming == STOPBIT) {buffer[dataBufferIndex] = 0; dataBufferIndex = 0; storebuffer = false; return true; } else { buffer[dataBufferIndex++] = incoming; } } } } return false; } void filldata(char *buffer) { char *p = buffer; char *str; int i = 0; while ((str = strtok_r(p, ";", &p)) != NULL) { // delimiter is the semicolon char *q = str; TRAME[i] = q; i++; } } void checkdata() { if (strcmp(TRAME[0], "CLOCK") == 0) { if (strcmp(TRAME[1], "#") != 0) { updateTime(); } // Auto update Time } if (strcmp(TRAME[0], "SYNCTIME") == 0) { Serial.println(TIME_REQUEST, BYTE); delay(50); } // Manual update Time if (strcmp(TRAME[0], "RELAY") == 0) { // 0, relay number, relay state 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; } 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; } } if (strcmp(TRAME[0], "PARAM") == 0) { // 'mode':'#', 'abs':'#', 'vac':'#', 't_jour':'#', 't_nuit':'#', 't_abs':'#', 't_vac':'#', 'cal':'#', 'day_at':'#', 'night_at':'#' if (strcmp(TRAME[1], "#") != 0) { mode_select = string2integer(TRAME[1]); } if (strcmp(TRAME[2], "#") != 0) { timeAbsence = string2long(TRAME[2]); } if (strcmp(TRAME[3], "#") != 0) { timeVacances = string2long(TRAME[3]); } if (strcmp(TRAME[4], "#") != 0) { consigne_chauffage[0] = string2float(TRAME[4]); } if (strcmp(TRAME[5], "#") != 0) { consigne_chauffage[1] = string2float(TRAME[5]); } if (strcmp(TRAME[6], "#") != 0) { consigne_chauffage[2] = string2float(TRAME[6]); } if (strcmp(TRAME[7], "#") != 0) { consigne_chauffage[3] = string2float(TRAME[7]); } if (strcmp(TRAME[8], "#") != 0) { calibrage = string2float(TRAME[8]); } if (strcmp(TRAME[9], "#") != 0) { intervalle_journuit[0] = string2integer(TRAME[9]); } if (strcmp(TRAME[10], "#") != 0) { intervalle_journuit[1] = string2integer(TRAME[10]); } } if (strcmp(TRAME[0], "START_CLI") == 0) { // send data next to real time (1 mn) remoteClient = 1; Serial.println("LOG : Client connected"); } if (strcmp(TRAME[0], "STOP_CLI") == 0) { // send data to normal timer (5 mn) remoteClient = 0; Serial.println("LOG : Client dropped"); } } void updateTime() { int i = 0; time_t pctime = 0; for(i = 0; i < TIME_MSG_LEN; i++) { if( int(TRAME[1][i]) >= '0' && int(TRAME[1][i]) <= '9'){ pctime = (10 * pctime) + (int(TRAME[1][i]) - '0') ; // convert digits to a number } } setTime(pctime); // Sync Arduino clock to the time received on the serial port } /* ############################################################################ SECTION : CONVERT STRING TO SOMETHING ############################################################################ */ int string2integer(char* data) { return atoi(data); } float string2float(char* data) { return atof(data); } unsigned long string2long(char* data) { return atol(data); } /* ############################################################################ SECTION : SWITCH RS485 FURNACE RELAY ############################################################################ */ void rs485TxMsg(char *msg) { Serial3.flush(); digitalWrite(txPin, HIGH); delay(10); Serial3.print(msg); delay(10); digitalWrite(txPin, LOW); } /* ############################################################################ SECTION : SEND STATUS TO REMOTE CLIENT ############################################################################ */ void sendData() { // 'mode':'#', 'abs':'#', 'vac':'#', 't_jour':'#', 't_nuit':'#', 't_abs':'#', 't_vac':'#', 'cal':'#', 'day_at':'#', 'night_at':'#' Serial.flush(); Serial.print("@data;"); Serial.print(temperature1); Serial.print(";"); // temperature 1 Serial.print("00.0"); Serial.print(";"); // temperature 2 Serial.print("00.0"); Serial.print(";"); // temperature 3 Serial.print("00.0"); Serial.print(";"); // temperature 4 Serial.print("0"); Serial.print(";"); // luminosite 1 Serial.print("0"); Serial.print(";"); // lux 1 Serial.print(mode_select); Serial.print(";"); // mode Serial.print(etat_chauffage); Serial.print(";"); // chauffage on/off Serial.print(_hour); Serial.print(";"); // heure Serial.print(_minute); Serial.print(";"); // minute if (mode_select == 2) { Serial.print(timeAbsence); } // Absence else { Serial.print("0"); } Serial.print(";"); if (mode_select == 3) { Serial.print(timeVacances); } // Vacances else { Serial.print("0"); } Serial.print(";"); Serial.print(consigne_chauffage[0]); Serial.print(";"); // consigne jour Serial.print(consigne_chauffage[1]); Serial.print(";"); // consigne nuit Serial.print(consigne_chauffage[2]); Serial.print(";"); // consigne abs Serial.print(consigne_chauffage[3]); Serial.print(";"); // consigne vac Serial.print(calibrage); Serial.print(";"); // calibrage Serial.print(intervalle_journuit[0]); Serial.print(";"); // debut horaire jour Serial.print(intervalle_journuit[1]); // fin horaire jour Serial.println(); Serial.print("Zone rouge="); Serial.println(h_redzone); } /* ############################################################################ SECTION : SEND LOGS TO SERVER ############################################################################ */ void logs() { Serial.print("LOG:"); Serial.print(_hour); Serial.print("h"); Serial.print(_minute); Serial.print(";"); Serial.print(temperature1); Serial.print(";"); Serial.print(etat_chauffage); Serial.print(";"); Serial.print(mode_select); Serial.print(";"); //if(inertie == true) { Serial.println("true"); } //if(inertie == false) { Serial.println("false"); } Serial.println(ecart); } /* ############################################################################ SECTION : GLCD S1D13700 MENU ############################################################################ */ char* update_clock() { static char time_buff[17] = { '\0' }; snprintf(time_buff, 17, "%02dh%02d", _hour, _minute); return time_buff; } char* update_temp1() { char ibuff1[6] = { '\0' }; static char obuff1[20] = { '\0' }; // static = conserver en memoire, non detruite a la fin de la fonction. dtostrf(temperature1,5,2,ibuff1); snprintf(obuff1, 20, "T: %s", ibuff1); return obuff1; } void layer0() { glcd.clearText(); glcd.clearGraphic(); //glcd.drawBitmap(RAIN, 180, 60, 128, 75); IHM_menu.draw(); IHM_clock.text = "##h##"; IHM_clock.draw(); IHM_mode.text = "###"; IHM_mode.draw(); IHM_temp1.text = "###"; IHM_temp1.draw(); IHM_etat1.text = "###"; IHM_etat1.draw(); menu = 1; delay(200); } void layer1() { glcd.clearText(); glcd.clearGraphic(); IHM_auto.draw(); IHM_off.draw(); IHM_forcage.draw(); IHM_abs2.draw(); IHM_abs4.draw(); IHM_return.draw(); IHM_selectionLayer0.text = IHM_mode.text; IHM_selectionLayer0.draw(); menu = 2; delay(200); } void layer2() { } void layer3() { } boolean regulation() { sommetCourbe = max(sommetCourbe, temperature1); ecart = (sommetCourbe - temperature1); for (int i = 0; i < longueurTable1; i++) { if ((temperature_ext > EXTERIEUR[i][0]) && (temperature_ext <= EXTERIEUR[i][1])) { value1 = EXTERIEUR[i][2]; } } for (int i = 0; i < longueurTable2; i++) { if (((temperature1 - consigne_courante) > CIBLE[i][0]) && ((temperature1 - consigne_courante) <= CIBLE[i][1])) { value2 = CIBLE[i][2]; } } for (int i = 0; i < longueurTable3; i++) { if ((ecart > PROBABILITY[i][0]) && (ecart <= PROBABILITY[i][1])) { value3 = PROBABILITY[i][2]; } } if ((value1+value2+value3) >= 80) { return true; } else { return false; }; }