#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet3.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp3.h>
#include <Key.h> // Bibliothèque pour le clavier
#include <Keypad.h> // Bibliothèque pour le clavier
#include <EEPROM.h> // Bibliothèque pour enregistrer dans l'eeprom
#include <SPI.h>
#include <max6675.h> // Bibliothèque pour les capteur thermocouple
#include <PID_v1_bc.h> // Bibliothèque pour la gestion PID
#include <LiquidCrystal_I2C.h> // Bibliothèque pour LCD I2C
#include <RTClib.h> // Bibliothèque pour l'horloge
#include <Arduino.h>
// ******************************paramètres stockés dans l'eeprom**********************************************
//const byte modeaut=EEPROM.read(4); // mode auto ou off(0 mode off->1 mode auto)
const byte p5=EEPROM.read(16); //(p5) vitesse d'alimentation de la vis sans fin
const byte p6=EEPROM.read(17); //(p6) Période de nettoyage du brûleur
const byte p7=EEPROM.read(18); //(p7) Fenêtre de modulation
const byte p8=EEPROM.read(19); //(p8) Hysteresis
const byte p9=EEPROM.read(20); //(p9) Période d'alimentation
const byte p10=EEPROM.read(21); //(p10) Vitesse du ventilateur à faible puissance
const byte p11=EEPROM.read(22); //(p11) Vitesse du ventilateur à haut rendement
const byte p17=EEPROM.read(23); //(p17) Limite de temperature de gaz d'échappement en °c
const byte p29=EEPROM.read(1); //(p29) temps d'alimentation pellet au demarrage en secondes defaut:40
const byte p30=EEPROM.read(2); //(p30) temps d'allumage résistance au demarrage en minutes defaut:20
const byte P31=EEPROM.read(0); //(P31) vitesse du ventilateur des gaz au demarrage du bruleur defaut:140
const byte p32=EEPROM.read(3); //(p32) difference de temperature pendant phase d'allumage
const byte p33=EEPROM.read(6); //(p33) temps de rodage pendant allumage pellets
const byte p34=EEPROM.read(7); //(p34) Vitesse du ventilateur pendant le rodage
const byte p35=EEPROM.read(8); //(p35) temps d'extinction de flammes
const byte p36=EEPROM.read(9); //(p36) detection temperature echappement en phase d'arrêt
const byte p37=EEPROM.read(5); //(p37) temperature minimum pour demarrage pompe de circulation chaidière
const byte p38=EEPROM.read(10); //(p38) hysteresis de la pompe de circulation
const byte p39=EEPROM.read(11); //(p39) P Gain du contrôleur PID
const byte p40=EEPROM.read(12); //(p40) I Gain du contrôleur PID
const byte p41=EEPROM.read(13); //(p41) D Gain du contrôleur PID
const byte p42=EEPROM.read(14); //(p42) Temps d'échantillonnage PID
const byte p53=EEPROM.read(15); //(p53) reset du bruleur
const byte p60=EEPROM.read(24); //(p60) temperature de reference eau chaudière
//********************************* parametrage carte ethernet-************************************************
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,143);
EthernetServer local_server(49152);
char *url = (char *)malloc(100);
//char url[100];
//***************************Initialiser les écrans LCD I2C 20x4***********************************************
LiquidCrystal_I2C lcd1(0x27, 20, 4); // Adresse 0x27, écran 20x4 (1)
LiquidCrystal_I2C lcd2(0x3F, 20, 4); // Adresse 0x27, écran 20x4 (2)
//***********************Définir les lignes et les colonnes du clavier 4x4*************************************
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Pins du clavier (L1, L2, L3, L4 pour les lignes et C1, C2, C3, C4 pour les colonnes)
byte rowpins[ROWS] = {28, 29, 30, 31}; // Les broches des lignes
byte colpins[COLS] = {32, 33, 34, 35}; // Les broches des colonnes
// Créer un objet Keypad
Keypad keypad = Keypad( makeKeymap(keys), rowpins, colpins, ROWS, COLS );
//*************************************************************************************************************
byte degc[8] = {B11100,B10100,B11100,B00000,B00111,B00100,B00100,B00111};
byte tedegc[8] = {B10011,B10011,B10000,B11100,B10000,B10011,B10010,B10011};
//***************************initialisation horloge RTC_DS1307*************************************************
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
boolean ecran=0;
//************************** Déclaration des broches de relais**********-**************************************
int relaisPin[3] = {11,12,13};// 11 résistance, 12 au moteur de l'auge, 13 pompe circulation eau chaudière
bool relais3=false; // etat du relais de pompe de circulation activé ou desactivé
//*************************************************************************************************************
int modeauto=1;// 1->arret, 2->auto, 3->perso, 4->h/gel
boolean defautbrul = 0; //permet de boucle une seul fois sur demarrage bruleur si echoué
//************************declaration des variables pour le capteur hc-sr04************************************
const int trigPin = 6; // Pin pour le signal Trigger
const int echoPin = 7; // Pin pour le signal Echo
long duration; // Durée du signal Echo
float distance; // Distance mesurée en cm
float distanceMin = 0; // Distance minimale en cm
float distanceMax = 50; // Distance maximale en cm
float pourcentage; // Pourcentage calculé
float pourcentage2;
//**********************************Déclaration des pins SPI***************************************************
//pin thermocouple temperature sortie cheminee
const int pinCLK = 22; // Pin horloge (SCK)
const int pinCS = 24; // Pin CS (Chip Select)
const int pinSO = 23; // Pin MISO (SO)
// pin thermocouple temperature eau chaudiere
const int pinCLK2 = 25; // Pin horloge (SCK)
const int pinCS2 = 26; // Pin CS (Chip Select)
const int pinSO2 = 27; // Pin MISO (SO)
// Déclaration des broches
MAX6675 thermocouple1( pinCLK, pinCS, pinSO ); // Initialiser le capteur MAX6675 1 temperature fumée
MAX6675 thermocouple2( pinCLK2, pinCS2, pinSO2 ); // Initialiser le capteur MAX6675 2 temperature eau chaudière
//***************************declaration pin pwm ventilateur de tirage*****************************************
const byte FAN_PIN = 4; // Pin PWM pour contrôler la vitesse ventilateur tirage
byte vitesse = 0; // Valeur initiale de la vitesse (0 = éteint)
char index = 0; // index indiquant où l'on est rendu dans la chaîne
boolean etats[3] = {LOW, LOW, LOW}; // L'état des 3 sorties
unsigned char pwm = 0; // La valeur de la pwm
//************************Variables de gestion de la température pour demarrage bruleur************************
float tempInitiale =0;
float tempActuelle = 0;
unsigned long startTime=0;
unsigned long elapsedTime = 0;
float seuildifference=EEPROM.read(3); //difference de temperature mini pendant la phase de demarrage du bruleur
//************************variable PID pour gestion du bruleur pendant une chauffe*****************************
double temperaturepid; //température mesuré
double setPoint = p60; //température cible (en°c)
double input, output; // entree PID(temperature mesuré), sortie PID(valeur de commande pour le chauffage)
double Kp = 2.0, Ki = 5.0, Kd = 1.0; // Gain P, I et D // PID constants (à ajuster en fonction de votre système)
PID myPID(&input, &output, &setPoint, Kp, Ki, Kd, DIRECT); // Création d'un objet PID
//*************************************************************************************************************
int tempSansVirgule1=0;
int tempSansVirgule2=0;
//float temp1=0;
//float temp2=0;
// ****************Définir les caractères personnalisés pour le ventilateur************************************
byte ventilateur2[8] = {B00000,B00110,B10100,B11111,B00101,B01100,B00000,B00000};
byte ventilateur3[8] = {B00000,B11001,B01011,B00100,B11010,B10011,B00000,B00000};
bool exitLoop=0;
int consigne=40; // consigne temperature eau chaudière
//****************************************SETUP****************************************************************
int consacc=0;
//*************************************************************************************************************
//*****************************Variables pour la navigation du menu********************************************
int menuLevel = 0; // Niveau du menu : 0 - Menu principal, 1 - Sous-menu 1, etc.
int menuIndex = 0; // Index de la sélection dans le menu
// --------------------------------------Menu principal--------------------------------------------------------
const char* mainMenu[] = {"Mode", "Parametres"};
const int mainMenuSize = 2;
// ---------------------------------------Sous-menu(mode)------------------------------------------------------
const char* subMenu1[] = {"Arret", "Auto", "Perso", "Hors/Gel"};
const int subMenu1Size = 4;
//----------------------------------------Sous-menu(parametres)------------------------------------------------
const char* subMenu3[] = {"1-Valeurs usine", "2-modif valeurs", "3-Planning", "4-Consigne (fin)"};
const int subMenu3Size = 4;
//-------------------------------------Sous menu(parametres/planning)------------------------------------------
int jourIndex = 0;
const char* subsubMenu1[] = {"Lundi", "Mardi","Mercredi" , "Jeudi", "Vendredi", "Samedi", "Dimanche"};
const int subsubMenu1Size = 7;
//-------------------------------------Sous menu(parametres/planning/jours)------------------------------------------
const char* temps[] = {"Matin", "Apres-Midi"};
const int tempsSize = 2;
void setup() {
// démarre le port série pour déboguer
Serial.begin(9600);Ethernet.begin(mac, ip);local_server.begin();
capteur_niveau_pellets();
//delay(1000);
accueil();
// Créer les caractères personnalisés pour le ventilateur
//lcd2.init();lcd2.backlight();
lcd1.createChar(3, ventilateur2);
lcd1.createChar(4, ventilateur3);
// rtc.begin();
// rtc.adjust(DateTime(2023, 6, 31, 14, 21, 0));
//lcd2.init();
//----------------------- Initialisation des broches de relais en tant que sortie------------------------------
for (byte i = 0; i < 3; i++)
{
pinMode(relaisPin[i], OUTPUT);
digitalWrite(relaisPin[i], LOW); // Éteindre tous les relais au départ
}
// Configure la broche PWM comme une sortie
pinMode(FAN_PIN, OUTPUT);
//configure pins echo hc-sr04
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
delay(3000);
myPID.SetMode(AUTOMATIC); // Mettre le PID en mode automatique
myPID.SetOutputLimits(0, 255); // La sortie du PID sera entre 0 et 255 (contrôle du chauffage)
pinMode(trigPin, OUTPUT); // Configurer le pin Trigger comme sortie
pinMode(echoPin, INPUT); // Configurer le pin Echo comme entrée
}
//*********************************************LOOP************************************************************
void loop() {
//-----------------------------------------gestion du menu-----------------------------------------------------
char key = keypad.getKey(); // Lire la touche du clavier
ecran=0;
if (key) {
if ((key=='*') && (ecran==0)){
lcd2.init();lcd2.backlight();
lcd1.backlight();
afficherMenuPrincipal();
switch_menu();
}
//--------------------- apuyer sur la touche 1 pour demarrer le mode auto--------------------------------------
if (key=='1'){
lcd2.init();lcd2.backlight();
modeauto=2;
menu_mode(2,1);
}
if(key=='C'){
lcd2.init();lcd2.backlight();
consacc=1;
consigne1();
}
if(key=='3'){
cycle_chauffe ();
}
}
//ventilateur();
}
//******************************mise en route circulateur chaudiere********************************************
void fonctionnement_pompe(){
//float temp2 = thermocouple2.readCelsius();
liretemp2();
if (tempSansVirgule2>=p37 && !relais3){
digitalWrite(relaisPin[3],HIGH);
relais3 = true;
Serial.println("pompe en fonction");
}
if (tempSansVirgule2<(p37-p38) && relais3){
digitalWrite(relaisPin[3],LOW);
relais3=false;
Serial.println("pompe arrete");
}
}
//************************lecture des temperatures eau chaudière et temperature fumées*************************
void liretemp1(){// lecture température des fumées
float temp1=0;
temp1 = thermocouple1.readCelsius(); // Lire la température en °C
tempSansVirgule1 = int(temp1);
Serial.print("Température fumée : ");
Serial.print(tempSansVirgule1); // Afficher la température
Serial.println(" °C");
}
void liretemp2()// lecture temperature eau chaudière
{
float temp2=0;
temp2 = thermocouple2.readCelsius(); // Lire la température en °C
tempSansVirgule2 = int(temp2);
//delay(60000); // Attendre 1 seconde avant la prochaine lecture
}
//*************************************************************************************************************
void ventilateur(){// Affichage du ventilateur tournant
lcd1.setCursor(3, 16);lcd1.write(byte(3)); // Ventilateur 2
delay(500);
lcd1.setCursor(3, 16);lcd1.write(byte(4)); // Ventilateur 3
delay(500);
}
//*************************************************************************************************************
mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
lcd1:GND
lcd1:VCC
lcd1:SDA
lcd1:SCL
lcd2:GND
lcd2:VCC
lcd2:SDA
lcd2:SCL
keypad1:R1
keypad1:R2
keypad1:R3
keypad1:R4
keypad1:C1
keypad1:C2
keypad1:C3
keypad1:C4
ultrasonic1:VCC
ultrasonic1:TRIG
ultrasonic1:ECHO
ultrasonic1:GND
rtc1:GND
rtc1:5V
rtc1:SDA
rtc1:SCL
rtc1:SQW
relay1:VCC
relay1:GND
relay1:IN
relay1:NC
relay1:COM
relay1:NO
relay2:VCC
relay2:GND
relay2:IN
relay2:NC
relay2:COM
relay2:NO
relay3:VCC
relay3:GND
relay3:IN
relay3:NC
relay3:COM
relay3:NO