// librairie ports série multiples #include // AltSoftSerial always uses these pins: // // Board Transmit Receive PWM Unusable // ----- -------- ------- ------------ // Arduino Mega 46 48 44, 45 AltSoftSerial altSerial; // Librairies Thermocouples #include // chargement de la librairie Thermocouple 6675 (fumées) int thermoDO = 11; // déclaration Pin de données int thermoCS = 12; // déclaration Pin Chip Select int thermoCLK = 13; // déclaration Pin Clock #include "MAX31855.h" // chargement de la librairie Thermocouple 31855 (allumage) const unsigned char thermocoupleSO = 14; // déclaration Pin de données const unsigned char thermocoupleCS = 15; // déclaration Pin Chip Select const unsigned char thermocoupleCLK = 16; // déclaration Pin Clock MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); // configuration du MAX6675 MAX31855 MAX31855(thermocoupleSO, thermocoupleCS, thermocoupleCLK); // configuration du MAX31855 // Librairie CTN #include "Thermistor.h" Thermistor temp_13(13); // on déclare le pin d'entrée Ana de la CTN chaudière (A13) Thermistor temp_12(12); // on déclare le pin d'entrée Ana de la CTN circuit (A12) Thermistor temp_11(11); // on déclare le pin d'entrée Ana de la CTN ECS (A11) Thermistor temp_10(10); // on déclare le pin d'entrée Ana de la CTN extérieure (A10) // Déclaration des constantes pour l'affichage LCD *********************************************** #include "LiquidCrystal.h" const int RS = 2; //declaration constante de broche LCD const int E = 3; //declaration constante de broche LCD const int D4 = 4; //declaration constante de broche LCD Data const int D5 = 5; //declaration constante de broche LCD Data const int D6 = 6; //declaration constante de broche LCD Data const int D7 = 7; //declaration constante de broche LCD Data LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Déclaration pins sorties PWM ******************************************************************* const byte pinVentil = 9; // declaration pin variateur ventilateur const byte pinAllum = 8; // declaration pin variateur allumage const byte pinCirc = 10; // declaration pin variateur circulateur ECC // Déclaration des variables *********************************************************************** const int cellule = 14; int valTempChaud = 0; // variable pour récupérer la valeur lue. On l'initialise à 0. int valTempCirc = 0; // variable pour récupérer la valeur lue. On l'initialise à 0. int valTempEcs = 0; // variable pour récupérer la valeur lue. On l'initialise à 0. float valTempExt = 0; // variable pour récupérer la valeur lue. On l'initialise à 0. int valCellFlam = 0; // variable pour récupérer la valeur lue. On l'initialise à 0. int valConsChaud = 0; // variable de la consigne Temp chaudière. On l'initialise à 0. int valConsCirc = 0; // variable de la consigne Temp circuit. On l'initialise à 0. int valConsEcs = 50; // variable de la consigne Temp circuit. On l'initialise à 50. int valConsTempAll = 300; // variable de consigne de Temp résistance allumage int valTempAll = 0; // variable de la température de résistance allumage int valPuissAll = 0; // variable de puissance PWM de la résistance d'allumage int valDeltaTChaud = 13; // variable du delta T Chaudière. On l'initialise à 15. int valDeltaTEcs = 6; // variable du delta T ECS. On l'initialise à 6. int valDeltaCct = 0; // variable du delta T circuit. int valNeedEcs = 0; // variable du besoin ECS. On l'initialise à 0 int etatEcs = 1; // variable de l'état du graphe ECS int etat = 1; // variable de l'état de l'installation initialisée à "prêt" unsigned soufflage = 2000; // consigne EV soufflage à 2s unsigned PostExtinction = 10000; // temps de maintien de ventilation après flamme éteinte unsigned preVent = 5000; // consigne préventilation à 8s unsigned TpChargt = 20000; // consigne de chargement à 20s int flamOK = 650; // valeur photoresistance pour flamme correcte int flamEteint = 550; // valeur photoresistance pour flamme éteinte unsigned TpPreComb = 5000; // consigne temps de précombustion int alarm = 0; // variable pour buzzer (0 = Ok, 1 = nettoyage bruleur, 2 = nettoyage Chaudière, 3 = panne) int tempFum = 0; // variable de température de fumée int maxTempFum = 0; // variable de température de fumée maxi int valMaxTempFum = 170; // variable de limite de température pour avertissement de nettoyage unsigned long varTpAll = 0; // duréee d'allumage unsigned long maxTpAll = 30000; // temps maxi d'allumage à 120s unsigned long previousMillis0 = 0; // stocke le moment du dernier départ de vis unsigned long currentMillis0 = 0; // stocke le moment actuel pour la vis unsigned long previousMillis1 = 0; // stocke le moment du dernier affichage de temps limite d'allumage pour nettoyage unsigned long currentMillis1 = 0; // stocke le moment actuel pour clignotement durée d'allumage unsigned long previousMillis2 = 0; // stocke le moment du dernier affichage série unsigned long currentMillis2 = 0; // stocke le moment actuel pour l'affichage série unsigned long previousMillis3 = 0; // stocke le moment du dernier événemant du graphe de chauffe unsigned long currentMillis3 = 0; // stocke le moment actuel pour le graphe de chauffe unsigned long previousMillis5 = 0; // stocke le moment du dernier affichage (rafraichissement) unsigned long currentMillis5 = 0; // stocke le moment actuel pour le rafraichissement d'affichage unsigned long previousMillis4 = 0; // stocke le moment du dernier affichage de teméprature de fumées pour nettoyage unsigned long currentMillis4 = 0; // stocke le moment actuel pour clignotement température fumées pour nettoyage unsigned long previousMillis6 = 0; // stocke le moment du dernier événement de post extinction unsigned long currentMillis6 = 0; // stocke le moment actuel pour la post extinction unsigned long previousMillis7 = 0; // stocke le moment du dernier départ de vanne unsigned long currentMillis7 = 0; // stocke le moment actuel pour la vanne unsigned long previousMillis8 = 0; // stocke le moment du dernier événement de transmission série unsigned long currentMillis8 = 0; // stocke le moment actuel pour la transmission série unsigned long previousMillis9 = 0; // stocke le moment du dernier paquet de vis unsigned long currentMillis9 = 0; // stocke le moment actuel pour le temps de vis unsigned interval0 = 16000; // intervalle entre 2 ticks de vis unsigned interval1 = 2000; // longueur tick de vis unsigned interval2 = 30000; // intervalle entre 2 ticks de vanne unsigned interval3 = 0; // longueur tick de vanne boolean VisOK = 0; // vis active int vis = 0; // variable de l'allure de chauffre de la vis boolean vanne = 0; // moteurs de vanne actifs boolean BtnOn =0; // état Bouton ON boolean BtnVis = 0; // état bouton forçage Vis boolean hiver; // état bouton hiver boolean defautPression = 0; // état capteur de pression de chmabre boolean defautClick = 0; // état capteur de surchauffe d'entrée boolean vanFerm = 0; // régulation vanne sens fermeture boolean vanOuv = 0; // régulation vanne sens ouverture boolean forcageVis = 0; // état du forçage de la vis (en état arrêt) float cumul = 0 ; // valeur cumulée de secondes d'appro de pellets int visTourn = 0; // état graphe cumul pellets // initialisation ************************************************************************************ void setup() { // Initialisation des liaisons série******************************************************************* Serial.begin(9600); // liaison moniteur série altSerial.begin(9600); // liaison série 46/48 //Initialisation LCD ********************************************************************* lcd.begin(20, 4); // assignation des pins de sortie de la carte 4 relais *********************************************** pinMode(41, OUTPUT); // relais EV soufflage pinMode(43, OUTPUT); // relais libre pinMode(45, OUTPUT); // relais circulateur ECS pinMode(47, OUTPUT); // relais libre digitalWrite(41,HIGH); // on monte les sorties relais pour mettre les relais OFF digitalWrite(43,HIGH); // on monte les sorties relais pour mettre les relais OFF digitalWrite(45,HIGH); // on monte les sorties relais pour mettre les relais OFF digitalWrite(47,HIGH); // on monte les sorties relais pour mettre les relais OFF pinMode(38, OUTPUT); // Triac ouverture vanne 4V pinMode(40, OUTPUT); // Triac fermeture vanne 4V pinMode(42, OUTPUT); // Triac vis pellets pinMode(49, OUTPUT); // Buzzer1 pinMode(51, OUTPUT); // Buzzer2 // assignation des pins des entrées ************************************************************** pinMode(22, INPUT); // Bouton "ON" pinMode(24, INPUT); // Bouton "VIS CONTINUE" (en état Stop) pinMode(34, INPUT); // Position 'HIVER" (Chauffage + ECS) pinMode(28, INPUT); // Contacteur Klicson (surchauffe entrée pellets) pinMode(30, INPUT); // Contact sur-pression chambre pinMode(32, INPUT); // Bouton Reprise // assignation des pins d'autres sorties ********************************************************* pinMode(23, OUTPUT); // LED "ON" pinMode(25, OUTPUT); // LED "Flamme" pinMode(27, OUTPUT); // LED "Hiver" pinMode(29, OUTPUT); // LED "Eté" } // Boucle de cycle ************************************************************************************ void loop() { //Affichage des constantes LCD ********************************************************************* lcd.setCursor(0,0); lcd.print("Ch"); lcd.setCursor(5,0); lcd.print("/"); lcd.setCursor(8,0); lcd.print("C"); lcd.setCursor(11,0); lcd.print("Ct"); lcd.setCursor(16,0); lcd.print("/"); lcd.setCursor(19,0); lcd.print("C"); lcd.setCursor(0, 1) ; lcd.print("Eau Ch"); lcd.setCursor(9,1); lcd.print("C"); lcd.setCursor(11,1); lcd.print("Ext."); lcd.setCursor(19,1); lcd.print("C"); lcd.setCursor(0, 3) ; lcd.print("Fum"); lcd.setCursor(9,3); lcd.print("Tps all"); // gestion du bouton Marche BtnOn = digitalRead(22); // variable d'état du bouton marche if (BtnOn == 0) // si bouton en position arrêt { etat = 0; // on passe le graphe Etat en étape 0 (arrêt) maxTempFum = 0; // on remet à zéro la température de fumées digitalWrite(23,LOW); } // on éteint la LED ON else // s'l st position marche { digitalWrite(23,HIGH); } // on allume la LED ON hiver = digitalRead(34); // acquisition position hiver ou été // Acquisition et pré-traitement des valeurs analogiques *********************************************** valTempChaud = temp_13.getTemp(); // on capture la valeur de la température de la CTN chaudière valTempCirc = temp_12.getTemp(); // on capture la valeur de la température de la CTN circuit valTempEcs = temp_11.getTemp(); // on capture la valeur de la température de la CTN ECS valTempExt = temp_10.getTemp(); // on capture la valeur de la température de la CTN Ext valTempExt = 22 - ((22 - valTempExt)*1.33); // ajustement pour température réelle valCellFlam = analogRead(cellule); // acquisition de la lumière de flamme tempFum = analogRead(cellule); // acquisition de la température de fumée A REMPLACER par ACQUISITION THERMOCOUPLE // tempFum = thermocouple.readCelsius(); // acquisition de la température de fumée if (etat == 5) // si on est en état d'allumage { valTempAll = MAX31855.readThermocouple(CELSIUS); } // acquisition température de résistance d'allumage else // sinon { valTempAll = 0; } // on met la valeur à zéro valConsCirc = (46 - (valTempExt * 0.65)); // calcul consigne température circuit fonction de la temp extérieure if (hiver == 1) { // si position hiver if (etatEcs == 2) // si besoin d'ECS { valConsChaud = ((valConsCirc) + 20 - (valTempExt / 4)); // calcul de la consigne température chaudière fonction de la temp extérieure if (valConsChaud < 65) // si la consigne calculée est < 65 { valConsChaud = 65; } } // on fixe la consigne à 65 else { valConsChaud = ((valConsCirc) + 20 - (valTempExt / 4)); } // si pas de besoin d'ECS, reprend le calcul fonction de la temp extérieure if (valConsChaud >= 75) { // si la consigne calculée est de 75° ou plus valConsChaud = 75; // on limite la consigne chaudière haute à 75° } if (valConsChaud <= 50) { // si la consigne calculée est de 50° ou moins valConsChaud = 50; // on limite la consigne chaudière basse à 50° } } if ((hiver == 0) && (etatEcs == 2)) // si position été et besoin d'ECS { valConsChaud = 65; } // la consigne température chaudière est fixée à 65° if (((hiver == 0) || (valTempExt > 23)) && (etatEcs == 1)) // si position été ou Temp ext > 23 et pas besoin d'ECS { valConsChaud = 10; } // la consigne température chaudière est fixée à 10° defautPression = digitalRead(30); // acquisition capteur surpression defautClick = digitalRead(28); // acquisition capteur clickson if ((hiver == 1) && (BtnOn == 1)) // si bouton en position hiver et position marche { digitalWrite(27, HIGH); // on allume la LED hiver digitalWrite(29, LOW); } // on éteint la LED été // on éteint la LED été if ((hiver == 1) && (BtnOn == 0)) // si position hiver et mode arrêt { digitalWrite(27,LOW); // on éteint la LED hiver digitalWrite(29,LOW); } // on éteint la LED été if ((hiver == 0) && (BtnOn == 1)) // si position été et mode marche { digitalWrite(27,LOW); // on éteint la LED hiver digitalWrite(29,HIGH); } // on allume la LED été if ((hiver ==0) && (BtnOn == 0)) // si postion été et mode arrêt { digitalWrite(27,LOW); // on éteint la LED hiver digitalWrite(29,LOW); } // on éteint la LED été currentMillis5 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis5 - previousMillis5 >= 1000) // si 0,5s se sont écoulées depuis le dernier affichage { previousMillis5 = currentMillis5; // on ractualise le temps précédent lcd.setCursor(3, 0); // affichage des valeurs variables analogiques lcd.print(valTempChaud); lcd.setCursor(6, 0); lcd.print(valConsChaud); lcd.setCursor(14, 0); lcd.print(valTempCirc); lcd.setCursor(17, 0); lcd.print(valConsCirc); lcd.setCursor(7, 1); lcd.print(valTempEcs); currentMillis1 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis1 - previousMillis1 >= 1000) // si 1s se sont écoulées depuis le dernier affichage { if (varTpAll/1000 <10) // si le temps d'allumage est à 1 chiffre {lcd.setCursor(17,3); // on affiche à la case 18 lcd.print(varTpAll/1000); lcd.setCursor(18,3); //et on efface les cases 19 et 20 avec 2 espaces lcd.print(" "); } if ((varTpAll/1000 <100) && (varTpAll/1000 > 9)) // si le temps d'allumage est à 2 chiffres {lcd.setCursor(17,3); // on affiche à la case 18 lcd.print(varTpAll/1000); lcd.setCursor(19,3); // et on efface la case 20 avec 1 espace lcd.print(" "); } if (varTpAll/1000 >99) // si le temps d'allumage est à 3 chiffres {lcd.setCursor(17,3); // on affiche à la case 18 lcd.print(varTpAll/1000); }} if ((currentMillis1 - previousMillis1 >= 2000) && (varTpAll >(maxTpAll * 0.7))) // si 2s se sont écoulées depuis le dernier affichage et que le temps d'allumage dépasse le suil d'alerte { previousMillis1 = currentMillis1; // on ractualise le temps précédent alarm = 1; // on active le niveau d'alarme 1 lcd.setCursor(17,3); // on efface la valeur pour clignotement lcd.print(" "); } if (valTempExt < 0) { // test valeur temp. ext négative pour position signe "-" lcd.setCursor(16, 1); // positionne le curseur pour écrire la température signée lcd.print(valTempExt); // affiche la température ext. négative lcd.print(" "); // on ajoute un espace pour écraser le digit des unités en cas d'absence de dizaine (<10) lcd.setCursor(19, 1); // on positionne le curseur après l'affichage sur 3 digits (ex. "-8_" ou "-15" lcd.print("C"); // on affiche le signe "C" } else { // si temp. ext. nulle ou positive lcd.setCursor(16, 1); // on positionne le curseur pour écrire la température signée lcd.print("+ "); //on affiche le signe "+" avec 2 espaces pour écraser le digit des unités en cas d'absence de dizaine (<10) lcd.setCursor(17, 1); //on positionne le curseur pour afficher la valeur lcd.print((int)valTempExt); //on affiche la valeur lcd.setCursor(19, 1); //on positionne le curseur après l'affichage sur 3 digits (ex. "+8_" ou "+15" lcd.print("C"); // on affiche le signe "C" } } if ((tempFum > maxTempFum) && (etat == 13)) // si la nouvelle température de fumée dépasse la précédente pendant l'extinction { maxTempFum = tempFum; } // on rafraîchit la valeur maxi currentMillis4 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis4 - previousMillis4 >= 1000) // si 1 seconde s'est écoulée depuis le dernier affichage { if (maxTempFum > 100) // et si la température max est > à 100 { lcd.setCursor(4, 3); lcd.print(maxTempFum); } // on affiche la valeur else { lcd.setCursor(4, 3); // si elle est < à 100 lcd.print("---"); } } // on affiche des tirets if ((currentMillis4 - previousMillis4 >= 2000) && (maxTempFum > valMaxTempFum)) // si 2s se sont écoulées depuis le dernier affichage et que la température de fumée dépasse 400 { previousMillis4 = currentMillis4; // on ractualise le temps précédent alarm = 1; // on active le niveau d'alarme 1 lcd.setCursor(4,3); // on efface la valeur pour clignotement lcd.print(" "); } // Gestion du moteur de vis currentMillis0 = millis(); if (currentMillis0 - previousMillis0 >= interval0) // on soustrait au temps présent celui du dernier front montant {previousMillis0 = currentMillis0; // l'ancien temps devient le nouveau vis = 1; } // front montant pour la vis toutes les "interval0" secondes if ((currentMillis0 - previousMillis0 >= interval1) && (vis = 1)) // on soustrait au temps présent celui du dernier front descendant {vis = 0; } // front descendant pour la vis après "interval1" secondes if (((VisOK == 1) && (vis == 1)) || (etat == 4) || (forcageVis == 1)) // si la vis est autorisée et le cadencement est à 1, ou état chargement ou forçage { digitalWrite(42,HIGH); } // on faut tourner la vis else // sinon { digitalWrite(42,LOW); } // on arrête la vis // Gestion des moteurs de vanne 4 voies currentMillis7 = millis(); if (currentMillis7 - previousMillis7 >= interval2) // on soustrait au temps présent celui du dernier front montant {previousMillis7 = currentMillis7; // l'ancien temps devient le nouveau vanne = 1; } // front montant pour la vis toutes les "interval2" secondes if ((currentMillis7 - previousMillis7 >= interval3) && (vanne = 1)) // on soustrait au temps présent celui du dernier front descendant {vanne = 0; } // front descendant pour la vanne après "interval3" secondes valDeltaCct = (valTempCirc - valConsCirc) ; // calcul de l'écart de température réalité - consigne if ((abs(valDeltaCct) >1) && (valDeltaCct > 1)) // si l'écart est positif et > 1° { vanFerm = 1; // on autorise la fermeture de vanne vanOuv = 0; } // on interdit l'ouverture de vanne if ((abs(valDeltaCct) >1) && (valDeltaCct < 1)) // si l'écart est négatif et > 1° { vanFerm = 0; // on interdit la fermeture de vanne vanOuv = 1; } // on autorise l'ouverture de vanne if (abs(valDeltaCct) < 1 ) // si l'écart est <1 en valeur absolue { vanFerm = 0; // on interdit la fermeture vanOuv = 0; // on interdit l'ouverture interval3 =0; } // on passe la durée du front haut du cadenceur à zéro else // si l'écart est >1 en valeur absolue { interval3 = (abs(valDeltaCct)) * 1000; // on fixe la durée du front haut du cadenceur à autant de secondes que de degrés d'écart if (interval3 > 4000) { interval3 = 4000; }} // avec un maxi de 4 secondes if (((vanne == 1) && (vanFerm == 1) && (BtnOn == 1)) || (hiver == 0)) // si le bouton est en position été { digitalWrite(38,LOW); // on désactive la sortie fermeture de vanne digitalWrite(40,HIGH); } // on active la sortie fermeture de vanne // on désactive la sortie ouverture de vanne if ((vanne == 1) && (vanOuv == 1) && (hiver == 1) && (BtnOn == 1)) // si le cadencement l'autorise et l'ouverture est permise et le bouton en position hiver { digitalWrite(40,LOW); // on désactive la sortie fermeture de vanne digitalWrite(38,HIGH); } // on active la sortie ouverture de vanne if ((vanne == 0) || (BtnOn == 0)) // si le cadenceur est en période "Off" ou mode arrêt { digitalWrite(40,LOW); // on désactive la sortie fermeture de vanne digitalWrite(38,LOW); } // on désactive la sortie ouverture de vanne // gestion circulateur ECC ***************************************** if ((BtnOn == 1) && (hiver == 1)) // si on est en position marche et en mode hiver { if (valTempExt > 18) // et si la température extérieure est > 18° { analogWrite(10,100); } // on alimente de circulateur à 100/255 else // si la temp. ext. < ou = 18° { if (valTempExt > -8) // et si la temp. ext. > -8° {analogWrite(10,180);} // on alimente le circulateur à 180/255 else // si la temp. ext. < ou = -8° {analogWrite(10,255);}}} // on alimente le circulateur à 255/255 else // si on est en position arrêt ou en mode été { analogWrite(10,0); } // on arrête le circulateur // surveillance des capteurs de défaut if (defautPression > 0) // si surpression de chambre, on place le graphe état en étape 22 { etat = 22; } if (defautClick > 0) // si surchauffe d'entré, on place le graphe état en étape 24 { etat = 24; } // Gestion de la LED flamme OK********************************************************************************************** if (valCellFlam > flamOK) // si la cellule atteint le seuil de flamme allumée { digitalWrite(25,HIGH); } // on allume la LED flamme else // sinon { digitalWrite(25,LOW); } // on éteint la LED flamme // Graphe d'état de chauffe ************************************************************************************************ switch (etat) { case 0: // étape 0 (position arrêt) analogWrite(pinAllum,0); // on éteint la résistance d'allumage valPuissAll = 0; // on passe la puissance d'allumage à zéro BtnVis = digitalRead(24); // acquisition de l'état du bouton de forçage vis pellets if (valCellFlam >= flamEteint) // si on arrête alors que la flamme n'est pas éteinte { analogWrite(pinVentil, 255); // on met le ventilateur en vitesse max lcd.setCursor(0, 2); lcd.print("EXTINCTION pr ARRET "); } // on affiche l'état d'arrêt après extinction else // si on arrête sans flamme (ou flamme éteinte) { analogWrite(pinVentil, 0); // on arrête le ventilateur lcd.setCursor(0, 2); if ((BtnVis == 1) && (valCellFlam <= flamEteint)) // si bouton de vis actif et pas de flamme { forcageVis = 1; // on démarre la vis lcd.setCursor(0, 2); lcd.print("FORCAGE VIS PELLETS "); } // on affiche le forçage vis if (BtnVis == 0) // si bouton de vis inactif { forcageVis = 0; // on arrête la vis lcd.setCursor(0, 2); lcd.print(" CHAUDIERE ARRETEE "); } // on affiche l'état d'arrêt if (BtnOn == 1) // si bouton marche { etat = 1;} // on passe le graphe à l'état 1 (attente) break; case 1: // étape initiale, en attente des besoins analogWrite(pinAllum,0); valPuissAll = 0; currentMillis3 = millis(); previousMillis3 = currentMillis3; // l'ancien temps devient le nouveau lcd.setCursor(0, 2); if (etatEcs > 1) // si besoin d'ECS { lcd.print(" EAU CHAUDE "); } // on affiche la production d'ECS else // si pas de besoin d'ECS { lcd.print(" OK "); } // affiche l'état OK VisOK = 0; // on interdit la vis if (valTempChaud <= (valConsChaud - valDeltaTChaud)) {etat = 2;} // si la température de consigne - delta T est atteinte, on passe à l'étape 2 (soufflage) break; case 2 : // étape du soufflage digitalWrite(41, LOW); // on active l'EV soufflage VisOK = 0; // on interdit la vis lcd.setCursor(0, 2); lcd.print(" SOUFFLAGE "); // on affiche le détail de l'état currentMillis3 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis3 - previousMillis3 >= soufflage) // on soustrait au temps présent celui du soufflage {previousMillis3 = currentMillis3; // l'ancien temps devient le nouveau digitalWrite(41, HIGH); // arrêt soufflage etat = 3; } // on passe à l'étape 3 (pré-ventilation) break; case 3 : // étape de la pré-ventilation analogWrite(pinVentil, 255); // on lance le ventilateur vitesse max VisOK = 0; // on interdit la vis lcd.setCursor(0, 2); lcd.print(" PRE-VENTILATION "); // affiche le détail de l'état currentMillis3 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis3 - previousMillis3 >= preVent) // on soustrait au temps présent celui de la pré-ventilation {previousMillis3 = currentMillis3; etat = 4; // si le temps de préventilation est atteint, on passe à l'étape 4 (chargement) analogWrite(pinVentil, 0); } // On arrête le ventilateur break; case 4 : // étape de chargement VisOK = 1; // on demarre la vis pellets vis = 1; lcd.setCursor(0, 2); lcd.print(" CHARGEMENT "); // affiche le détail de l'état currentMillis3 = millis(); // capture à chaque cycle la valeur de millis() if (currentMillis3 - previousMillis3 >= TpChargt) // on soustrait au temps présent celui du chargement {previousMillis3 = currentMillis3; // l'ancien temps devient le nouveau etat = 5; // si le chargement est terminé, on passe à l'état 5 (allumage) VisOK = 0; // arrêt de la vis vis = 0; } break; case 5 : // étape d'allumage if (valTempAll < (valConsTempAll * 0.7)) // si chauffe < de 30% { valPuissAll = 150; } // allure de chauffe 150 if ((valTempAll < (valConsTempAll * 0.8)) && (valTempAll >= (valConsTempAll *0.7))) // si chauffe entre 30% et 20% { valPuissAll = 50; } // allure de chauffe 50 if ((valTempAll < (valConsTempAll * 0.9)) && (valTempAll >= (valConsTempAll *0.8))) // si chauffe entre 80% et 90% { valPuissAll = 20; } // allure de chauffe 20 if ((valTempAll < (valConsTempAll * 0.98)) && (valTempAll >= (valConsTempAll *0.9))) // si chauffe entre 90% et 98% { valPuissAll = 12; } // allure de chauffe 12 if (valTempAll >= valConsTempAll) // si chauffe atteint ou dépasse la consigne { valPuissAll = 0; } // on arrête la chauffe analogWrite(pinAllum, valPuissAll); // chauffe de la résistance d'allumage analogWrite(pinVentil, 15); // lancement ventilateur vitesse 1 VisOK = 0; // on interdit la vis lcd.setCursor(0, 2); lcd.print(" ALLUMAGE "); // affiche le détail de l'état currentMillis3 = millis(); // capture à chaque cycle la valeur de millis() if ((currentMillis3 - previousMillis3 >= maxTpAll) || (valCellFlam >= flamOK)) // si la flamme est détectée ou que le délai autorisé d'allumage est atteint {varTpAll = (currentMillis3 - previousMillis3); previousMillis3 = currentMillis3; // l'ancien temps devient le nouveau etat = 6; // si flamme établie ou limite de temps d'allumage atteinte, on passe à l'état 6 (précombustion ou alarme allumage) analogWrite(pinAllum, 0); } // arrêt de l'allumage break; case 6 : // étape de pré-combustion if (valCellFlam < flamOK) // si flamme non détectée {etat = 20; } // on passe à l'étape 20 (défaut d'allumage) else { // si flamme détectée analogWrite(pinVentil, 15); // lancement ventilateur vitesse 1 VisOK = 0; // on interdit la vis lcd.setCursor(0, 2); lcd.print(" PRE-COMBUSTION "); // affiche le détail de l'état currentMillis3 = millis();} // capture à chaque cycle la valeur de millis() if (currentMillis3 - previousMillis3 >= TpPreComb) // on soustrait au temps présent celui de la pré-combustion {previousMillis3 = currentMillis3; // l'ancien temps devient le nouveau if ((etat = 6) && (valCellFlam >= flamOK)) { etat = 7;} } // si précombustion terminée et flamme détectée, on passe à l'état 7 (définition des niveaux de puissance) break; case 7 : // étape de définition des niveaux de puissance if ((valConsChaud - valTempChaud) > (valDeltaTChaud * 0.4)) // tant qu'on n'a pas atteint 40% du delta T { if((valConsChaud - valTempChaud) > valDeltaTChaud) // si l'écart dépasse le delta T {etat = 15; } // on va à l'étape 15 (TurboBoost) else {etat = 8;} } // sinon on passe à l'étape 8 (Puissance 5) if ((valConsChaud - valTempChaud) <= (valDeltaTChaud * 0.4)) // si l'écart est inférieur à 40% { (etat = 9);} // on va à l'étape 9 (puissance 4) if ((valConsChaud - valTempChaud) <= (valDeltaTChaud * 0.3)) // si l'écart est inférieur à 30% { (etat = 10);} // on va à l'étape 10 (puissance 3) if ((valConsChaud - valTempChaud) <= (valDeltaTChaud * 0.2)) // si l'écart est inférieur à 20% { (etat = 11);} // on va à l'étape 11 (puissance 2) if ((valConsChaud - valTempChaud) <= (valDeltaTChaud * 0.1)) // si l'écart est inférieur à 10% { (etat = 12);} // on va à l'étape 12 (puissance 1) if (valCellFlam <= (flamOK - 20)) // si on perd la flamme { etat = 21; } // on active l'étape 21 (alarme manque pellets) break; case 8 : // étape de chauffe puissance 5 analogWrite(pinVentil, 60); // lancement ventilateur vitesse 5 VisOK = 1; // vis autorisée interval1 = 2600; // durée de vis 2,6s lcd.setCursor(0, 2); if (etatEcs == 1) // si pas de besoin d'ECS { lcd.print(" CHAUFFE PUISS. 5 "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUFFE+ECS PUISS. 5"); } // affiche le détail de l'état { etat = 7;} // on retourne au choix de puissance break; case 9 : // étape de chauffe puissance 4 analogWrite(pinVentil, 45); // lancement ventilateur vitesse 4 VisOK = 1; // vis autorisée interval1 = 2500; // durée de vis 2,5s lcd.setCursor(0, 2); if (etatEcs == 1) // si pas de besoin d'ECS { lcd.print(" CHAUFFE PUISS. 4 "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUFFE+ECS PUISS. 4"); } // affiche le détail de l'état { etat = 7;} // on retourne au choix de puissance break; case 10 : // étape de chauffe puissance 3 analogWrite(pinVentil, 35); // lancement ventilateur vitesse 3 VisOK = 1; // vis autorisée interval1 = 2400; // durée de vis 2,4s lcd.setCursor(0, 2); if (etatEcs == 1) // si pas de besoin d'ECS { lcd.print(" CHAUFFE PUISS. 3 "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUFFE+ECS PUISS. 3"); } // affiche le détail de l'état { etat = 7;} // on retourne au choix de puissance break; case 11 : // étape de chauffe puissance 2 analogWrite(pinVentil, 25); // lancement ventilateur vitesse 2 VisOK = 1; // vis autorisée interval1 = 2200; // durée de vis 2,2s lcd.setCursor(0, 2); if (etatEcs < 2) // si pas de besoin d'ECS { lcd.print(" CHAUFFE PUISS. 2 "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUFFE+ECS PUISS. 2"); } // affiche le détail de l'état { etat = 7;} // on retourne au choix de puissance break; case 12 : // étape de chauffe puissance 1 analogWrite(pinVentil, 15); // lancement ventilateur vitesse 1 VisOK = 1; // vis autorisée interval1 = 2000; // durée de vis 2s lcd.setCursor(0, 2); if (etatEcs < 2) // si pas de besoin d'ECS { lcd.print(" CHAUFFE PUISS. 1 "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUFFE+ECS PUISS. 1"); } // affiche le détail de l'état if (valTempChaud >= valConsChaud) // si pas de besoin d'ECS { etat = 13; } // si temp chaudière atteint la consigne, on passe à l'état 13 (extinction) else { etat = 7; } // sinon on retourne au choix de puissance break; case 13 : // étape de chauffe puissance 1 analogWrite(pinVentil, 255); // lance le ventilateur vitesse max VisOK = 0; // vis interdite lcd.setCursor(0, 2); lcd.print(" EXTINCTION "); // affiche le détail de l'état if (valCellFlam <= flamEteint) // si flamme éteinte { etat = 14 ; // on passe à l'étape de post-extinction (14) previousMillis6 = millis();} // on ractualise le temps précédent break; case 14 : // étape de post extinction currentMillis6 = millis(); // capture à chaque cycle la valeur de millis() if ((currentMillis6 - previousMillis6) >= PostExtinction) // si délai de pré-combustion atteint { previousMillis6 = currentMillis6; // on ractualise le temps précédent analogWrite(pinVentil, 0); // arrêt du ventilateur (etat = 1);} // on revient à l'étape 1 (OK) break; case 15 : // étape de chauffe TurboBoost analogWrite(pinVentil, 220); // lancement ventilateur vitesse 6 VisOK = 1; // vis autorisée interval1 = 2900; // durée de vis 2,9s lcd.setCursor(0, 2); if (etatEcs == 1) // si pas de besoin d'ECS { lcd.print(" CHAUFFE TURBOBOOST "); } // affiche le détail de l'état else // si besoin d'ECS { lcd.print("CHAUF+ECS TURBOBOOST"); } // affiche le détail de l'état { etat = 7;} // si temp chaudière atteint 20% du delta T, on passe à l'état 9 (combustion puissance 4) break; case 20 : // étape d'alarme allumage raté analogWrite(pinVentil, 0); // arrêt du ventilateur VisOK = 0; // vis interdite lcd.setCursor(0, 2); lcd.print(" DEFAUT ALLUMAGE "); // affiche le détail de l'état if (digitalRead(32) == 1) {etat = 5; } break; case 21 : // étape d'alarme manque pellets analogWrite(pinVentil, 0); // arrêt du ventilateur VisOK = 0; // vis interdite lcd.setCursor(0, 2); lcd.print(" MANQUE PELLETS "); // affiche le détail de l'état break; case 22 : // étape d'alarme surpression analogWrite(pinVentil, 255); // ventilateur à 100% VisOK = 0; // vis interdite lcd.setCursor(0, 2); lcd.print(" DEFAUT PRESSION CH."); // affiche le détail de l'état previousMillis6 = millis(); // on ractualise le temps précédent (etat = 25); // on passe à l'étape 25 (extinction après alarme) break; case 24 : // étape d'alarme surchauffe d'entrée analogWrite(pinVentil, 255); // ventilateur à 100% VisOK = 0; // vis interdite lcd.setCursor(0, 2); lcd.print(" DEFAUT CLICKSON "); // affiche le détail de l'état previousMillis6 = millis(); // on ractualise le temps précédent (etat = 25); // on passe à l'étape 25 (extinction après alarme) case 25 : // étape d'extinction après alarme currentMillis6 = millis(); // capture à chaque cycle la valeur de millis() if ((currentMillis6 - previousMillis6) >= PostExtinction) // si le délai de post-extinction atteint { previousMillis6 = currentMillis6; // on ractualise le temps précédent analogWrite(pinVentil, 0); // arrêt du ventilateur break; }}} // Graphe de gestion ECS switch (etatEcs) { case 1 : // étape d'analyse de besoin d'ECS digitalWrite(45, HIGH); // arrêt du circulateur ECS if (((valTempEcs + valDeltaTEcs) < valConsEcs)) // && (BtnOn == 1)) // si on a besoin d'ECS { valNeedEcs = 1; // on enregistre la variable de besoin etatEcs = 2;} // on passe à l'étape 2 (chauffe ECS) else // si pas besoin d'ECS { valNeedEcs = 0; } // on enregistre la variable de non-besoin break; case 2 : // étape de chauffe ECS digitalWrite(45,LOW); // on démarre le circulateur ECS if (valTempEcs >= valConsEcs) // si la température ECS est atteinte {digitalWrite(45 , LOW); // on arrête le circulateur ECS etatEcs = 1; } // on retourne à l'étape 1 break; } // cumul du temps de vis pour la période de chauffe switch (visTourn) { case 0 : if (digitalRead(42) == 1) { previousMillis9 = millis(); visTourn = 1; } break; case 1 : if (digitalRead(42) == 0) { currentMillis9 = millis(); cumul = (cumul + ((currentMillis9 - previousMillis9) / 1000)); visTourn = 0; } break; } // affichage sur moniteur série currentMillis2 = millis(); if (currentMillis2 - previousMillis2 >= 200) // on soustrait au temps présent 1 seconde {previousMillis2 = currentMillis2; // l'ancien temps devient le nouveau Serial.print("Etat : "); Serial.println(etat); // affiche le numéro d'étape du graphe Etat } // Transmission données sur posrt série currentMillis8 = millis(); if (currentMillis8 - previousMillis8 >= 5000) // on soustrait au temps présent 5 secondes { altSerial.print(valTempCirc); // on envoie la température circuit altSerial.print((int)valTempExt + 20); // on envoie la température extérieure altSerial.print(valNeedEcs); // on envoie le besoin d'ECS altSerial.print(alarm); // on envoie le niveau d'alarme prédictive altSerial.print(etat + 20); // on envoie l'état du graphe de chauffe (pour gestion alarmes) if (etat == 14) // si on est en post-extinction {altSerial.println((int) cumul); // on envoie la valeur de cucmul pellets sur 3 digits if (currentMillis8 - previousMillis8 >= 6000) // après une seconde {cumul = 0; // on remet à zéro le cumul previousMillis8 = currentMillis8;} } // l'ancien temps devient le nouveau else // si le cycle de chauffe n'est pas terminé {altSerial.println("000"); // on envoie 000 if (currentMillis8 - previousMillis8 >= 6000) // après une seconde { previousMillis8 = currentMillis8; }} // l'ancien temps devient le nouveau } }