![]() |
Optimisation PAC |
avril 2025 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
|
Les fichiers STL pour l'impression sont disponibles dans la partie "Impression3D" du site.
Aprés avoir saisie l'adresse dans un navigateur le menu principal suivant apparait.
En cas de coupure secteur il est important que l'asservissement puisse redémarer dans de bonnes conditions. C'est pourquoi des données essentiels sont sauvegardées dans une mémoire non volatile. Le nom des différentes sondes et le délai entre deux mesures. La valeur des seuils de la PWM sera sauvegardée dans une prochaine version...
Il est possible de régler le délai entre deux mesures entre 2 secondes et 1 heure. Ceci afin de donner le maximum de possibilité pour déterminer l'utilité de chaque sonde. Le délai est exprimé en seconde.
Cet écran donne l'adresse réseau des sondes et il permet d'attribuer un nom à chacune des sondes.
Cet écran est trés important dans la premiere phase de la recherche d'optimisation, c'est lui qui va permettre
d'élaborer les différents parametres pour gerer l'asservissement de la soufflerie.
Il est possible de suivre la date et l'heure des mesures ainsi que les valeurs de 8 sondes.
Le graphique donne une vue générale des valeurs des sondes aux horaires de captures.
Il est important de connaitre l'horaire des mesures, en principe l'horloge interne est à jour, mais avec les changement d'horaire été/hiver il est possible ici de se resynchroniser.
Il est possible ici de tester la conversion PWM vers la tension de commande du variateur 0 à 10v. Cette variation sera gerer aprés la formulation de l'optimisation par une formule qui tiendra compte des différentes mesures des sondes et le processeur l'appliquera automatiquement au variateur du moteur triphasé de la soufflerie.
Le code de base qui doit vous permettre de démarrer pour vos propres projets...
Il y a des choses à modifier pour l'optimiser mais il sera revu lorsque l'optimisation sera effective...
#include <Arduino.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <RTClib.h>
#include "ESP_EEPROM.h"
RTC_DS3231 rtc;
DateTime timeinfo;
unsigned long temps_qui_passe; // Mesure le delai depuis la derniere mesure
int nb_sec_inter_mesure = 10; // temps en seconde entre deux mesure
unsigned long temp_t; // nb_sec_inter_mesure * 10000 pour résultat en milliseconde (évite un warning de compilation)
#define MAXTABTEMP 60
struct gr_temp { // Info du graph
uint8_t v_j; // jour (1 - 31)
uint8_t v_h; // heure (0 - 23)
uint8_t v_m; // minute (0 - 60)
uint8_t v_s; // seconde (0 - 60)
float v_t1; // temp1
float v_t2; // temp2
float v_t3; // temp2
float v_t4; // temp4
float v_t5; // temp5
float v_t6; // temp6
float v_t7; // temp7
float v_t8; // temp8
};
gr_temp tgr_temp[MAXTABTEMP];
float val_mesure[8];
#define PinPWM D5 // Gpio PWM commande moteur convertion 0-10v
int val_PWM = 255; // PWM au max
//int i2c_sda = D2; // I2C
//int i2c_scl = D1; // I2C
#define ONE_WIRE_BUS D6 // Gpio capteur temperature
#define TEMPERATURE_PRECISION 12 // (avant ct 9) resolution
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int nb_capteur;
DeviceAddress tempDeviceAddress;
bool capteur_HS = false;
#define MAXTCAPTEUR 8
struct t_capt { // tableau des capteurs
uint8_t v_n; // num
uint8_t v_ad[8]; // adresse
// char v_nom[11]; // nom 10 car max
String v_coul; // couleur
};
t_capt tb_capteurs[MAXTCAPTEUR];
// Définir les informations du point d'accès
const char* ap_ssid = "CHAUFFAGE-AP"; // Nom du réseau Wi-Fi de l'ESP8266
const char* ap_password = "12345678"; // Mot de passe du réseau Wi-Fi
// Créer une instance du serveur web
ESP8266WebServer server(80);
// Variables pour les valeurs des capteurs
float temperature;
float humidity;
String const v_css_body = "body { background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center; display: flex; justify-content: center; align-items: center; height: 100vh;}";
String const v_css_lien = "a.btn { text-decoration: none; padding: 10px; font-family: arial; font-size: 1em; color: #FFFFFF; background-color: #b2a2c7; border-radius: 24px;-webkit-border-radius: 24px; -moz-border-radius: 24px; border: 4px solid #ffffff; box-shadow: 3px 3px 8px #444444; -webkit-box-shadow: 3px 3px 8px #444444; -moz-box-shadow: 3px 3px 8px #444444; }";
String const v_css_lien_vol = "a.btn:hover { padding: 10px; color: #ffff00; background-color: #5f497a; border: 4px solid #fbd5b5; box-shadow: 1px 1px 4px #777777; -webkit-box-shadow: 1px 1px 4px #777777; -moz-box-shadow: 1px 1px 4px #777777; }";
// gestion de l'eeprom
struct s_memo_rom {
int delai_inter_mesure; // Delai entre deux mesures de temperature
int seuil_min_pwm; // Seuil mini pour la PWM du moteur
int seuil_max_pwm; // Seuil maxi pour la PWM du moteur
char nom_s[8][10]; // Nom des sondes
} memo_rom, v_ram;
int adr_deb_memo_rom = 0;
// Affiche compte-rendu enregistrement eeprom
String aff_eeprom(){
String html_s = "<!DOCTYPE html>";
html_s += "<html lang='fr'><head> <meta charset='UTF-8'><head>";
html_s += "<style> " + v_css_lien + v_css_lien_vol + " </style>";
html_s += "<title>Lecture EEPROM</title></head>";
html_s += "<body style='background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center;'><br/><br/><br/>";
html_s += "<table align='center' border='2'>";
html_s += "<caption><h1>Liste des données mémorisées (en cas de coupure secteur)</h1></caption>";
html_s += "<tr><td>Délai entre les mesures de température : </td><td>" + String(v_ram.delai_inter_mesure) + "</td></tr>";
html_s += "<tr><td>Seuil minimum PWM commande moteur : </td><td>" + String(v_ram.seuil_min_pwm) + "</td></tr>";
html_s += "<tr><td>Seuil maximum PWM commande moteur : </td><td>" + String(v_ram.seuil_max_pwm) + "</td></tr>";
for(int i=0; i<8; i++) html_s += "<tr><td>Nom capteur 0 : </td><td>" + String(v_ram.nom_s[i]) + "</td></tr>";
html_s += "</table><br/><br/><br/>";
html_s += "<p align='center'><br/><br/><a class='btn' href='/' target='_self'>Retour Accueil</a></p>";
html_s += "<p align='center'><br/>Ces données doivent permettre un redémarrage autonome suite à une coupure secteur, les autres données peuvent être recalculées.</p>";
html_s += "</body></html>";
return html_s;
}
// Lecture eeprom
void lecture_eeprom(){
EEPROM.begin(sizeof(s_memo_rom));
delay(300);
EEPROM.get(adr_deb_memo_rom, memo_rom);
delay(300);
v_ram.delai_inter_mesure = memo_rom.delai_inter_mesure;
v_ram.seuil_min_pwm = memo_rom.seuil_min_pwm;
v_ram.seuil_max_pwm = memo_rom.seuil_max_pwm;
for(int i=0; i<8; i++) strcpy(v_ram.nom_s[i], memo_rom.nom_s[i]);
EEPROM.end();
delay(300);
aff_eeprom();
}
// Ecriture eeprom
void ecriture_eeprom(){
EEPROM.begin(sizeof(s_memo_rom));
delay(300);
memo_rom.delai_inter_mesure = v_ram.delai_inter_mesure;
memo_rom.seuil_min_pwm = v_ram.seuil_min_pwm;
memo_rom.seuil_max_pwm = v_ram.seuil_max_pwm;
for(int i=0; i<8; i++) strcpy(memo_rom.nom_s[i], v_ram.nom_s[i]);
EEPROM.put(adr_deb_memo_rom, memo_rom);
delay(300);
EEPROM.commit();
delay(300);
aff_eeprom();
EEPROM.end();
delay(300);
}
// -----------------------------------------------------------------------------------------------------------------------------------
// Initialise la totalité des tableaux de variables
void vinit_tab_val(){
for(int v_adr = 0; v_adr <= MAXTABTEMP-1; v_adr++){
tgr_temp[v_adr].v_j = 0;
tgr_temp[v_adr].v_h = 0;
tgr_temp[v_adr].v_m = 0;
tgr_temp[v_adr].v_s = 0;
tgr_temp[v_adr].v_t1 = 0;
tgr_temp[v_adr].v_t2 = 0;
tgr_temp[v_adr].v_t3 = 0;
tgr_temp[v_adr].v_t4 = 0;
tgr_temp[v_adr].v_t5 = 0;
tgr_temp[v_adr].v_t6 = 0;
tgr_temp[v_adr].v_t7 = 0;
tgr_temp[v_adr].v_t8 = 0;
}
}
String htmldateheure() {
String html_s = "<!DOCTYPE html>";
html_s += "<html lang='fr'><head> <meta charset='UTF-8'><head>";
html_s += "<style> " + v_css_lien + v_css_lien_vol + " </style>";
html_s += "<title>Initialisation Date / Heure</title></head>";
html_s += "<body style='background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center;'><br/><br/><br/>";
html_s += "<table align='center'>";
html_s += "<caption><h1>Définir la date et l'heure</h1></caption><tr><td>";
html_s += "<form action='/setDateTime' method='POST'>";
html_s += "<br/>Date et Heure (YYYY-MM-DDTHH:MM):";
html_s += "<input type='datetime-local' name='datetime'></br><br/><br/><br/></td></tr>";
html_s += "<tr><td><br/><br/><br/><button>Valider la modification</button> <input type='reset' value='Annuler la modification' /></td></tr>";
html_s += "</table><br/><br/><br/><br/></form>";
html_s += "<p align='center'><br/><br/><a class='btn' href='/' target='_self'>Retour Accueil</a></p>";
html_s += "</body></html>";
return html_s;
}
String modif_delai_m(){
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'><head>";
html_s += "<title>Modif delai 2 dates</title>";
html_s += "<style> " + v_css_lien + v_css_lien_vol + " </style></head>";
html_s += "<body style='background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center;'><br/><br/><br/>";
html_s += "<table width='80%' align='center'><caption><h1>Définir le délai entre deux mesures</h1></caption><tr><td>";
html_s += "<form action='/setDelaiMesure' method='POST'>";
html_s += "Délai en seconde (mini 2 secondes - maxi 3600):";
html_s += "<input type='number' name='v_d_mesure' min='2' max='3600' value='" + String(nb_sec_inter_mesure) + "'/></br><br/><br/><br/>";
html_s += "</td></tr><tr><td><button>Valider la modification</button> <input type='reset' value='Annuler la modification' /></td></tr>";
html_s += "</form></table><br/><br/><br/><br/>";
html_s += "<p align='center'><br/><br/><a class='btn' href='/' target='_self'>Retour Accueil</a></p>";
html_s += "</body></html>";
return html_s;
}
String modif_PWM(){
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'><head>";
html_s += "<title>Modif PWM</title>";
html_s += "<style> " + v_css_lien + v_css_lien_vol + " </style></head>";
html_s += "<body style='background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center;'><br/>";
html_s += "<table width='80%' align='center'><caption><h1>Modification de la vitesse du moteur</h1></caption>";
html_s += "<tr><td>Valeur PWM : " + String(val_PWM) + "</br><br/><br/><br/></td></tr>";
html_s += "<tr><td align='center'><form action='/inc_vit'><button><h1>+</h1></button> Augmenter la vitesse.</form></td></tr> ";
html_s += "<tr><td align='center'><form action='/dec_vit'><button><h1>-</h1></button> Diminuer la vitesse.</form></td></tr><br/><br/>";
html_s += "</table><br/><br/><br/><br/>";
html_s += "<p align='center'><br/><br/>La vitesse du moteur est commandée par une tension qui varie de 0 à 10 volts (10 volts -> Vitesse max).</p>";
html_s += "<br/><br/><p align='center'><br/><br/><a class='btn' href='/' target='_self'>Retour Accueil</a></p>";
html_s += "</body></html>";
return html_s;
}
// --------- Demande de page inexistante ------
void page_inexistante() {
String page_inexist = "Page inexistante";
page_inexist += "<br/>URL: ";
page_inexist += server.uri();
page_inexist += "<br/>Method: ";
page_inexist += (server.method() == HTTP_GET) ? "GET" : "POST";
page_inexist += "<br/>Arguments: ";
page_inexist += server.args();
page_inexist += "<br/>";
for (uint8_t i = 0; i < server.args(); i++) { page_inexist += " " + server.argName(i) + ": " + server.arg(i) + "<br/>"; }
server.send(404, "text/plain", page_inexist);
#ifdef debug_sur_usb
Serial.println("Envoi : page_inexistante");
#endif
}
void printAddress(DeviceAddress deviceAddress)
{
// exemple : 28FF5246601705AF
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
String adr_string(DeviceAddress deviceAddress)
{
// exemple : 28FF5246601705AF
char ch_temp[20];
sprintf(ch_temp, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
deviceAddress[0],
deviceAddress[1],
deviceAddress[2],
deviceAddress[3],
deviceAddress[4],
deviceAddress[5],
deviceAddress[6],
deviceAddress[7]
);
Serial.print(ch_temp);
return String(ch_temp);
}
String page_capteurs() {
// Page de description des capteurs
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'><title>PAC Chauffage</title>";
html_s += "<style> " + v_css_body + v_css_lien + v_css_lien_vol + " </style>";
html_s += "</head><body>";
html_s += "<table width='80%' border=2>";
html_s += "<caption><h1>Identification des Capteurs</h1></caption>";
html_s += "<tr><th align='center'>Numero</th>";
html_s += "<th align='center'>Adresse</th>";
html_s += "<th align='center'>Nom</th>";
html_s += "<th align='center'>Modif.</th></tr>";
html_s += "<form action='/setNomCapt' method='POST'>";
for (uint8_t i = 0; i < 8; i++){
html_s += "<tr><td align='center'>";
if(nb_capteur > i) html_s += String(tb_capteurs[i].v_n);
html_s += "</td><td align='center'>" + adr_string(tb_capteurs[i].v_ad) + "</td>";
html_s += "<td align='center'>" + String(v_ram.nom_s[i]) + "</td>";
html_s += "<td align='center'>";
String v_temp;
if(nb_capteur > i){ v_temp = String(v_ram.nom_s[i]); html_s += "(de 4 à 10 car.) <input type='text' id='nom_capt_" + String(i) + "' name='nom_capt_" + String(i) + "' minlength='4' maxlength='10' value='" + v_temp + "'/>";}
html_s += "</td></tr>";
}
html_s += "<tr><td align='center' colspan='4'><br/><p align='center'><a class='btn' href='/' target='_self'>Retour Accueil</a> <button>Valider les modifications</button> <input type='reset' value='Annuler les modifications' /><br/><br/></p></td></tr>";
html_s += "</form>";
html_s += "</table>";
html_s += "</body></html>";
return html_s;
}
String page_valeurs(){
// Page de description des capteurs
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'><title>PAC Chauffage</title>";
html_s += "<style> " + v_css_lien + v_css_lien_vol + "</style>";
html_s += "</head><body style='background-color: grey; font-family: Sans-Serif; Color: orange; text-align: center;'>";
html_s += "<div align='center'><table width='80%' border=2>";
html_s += "<caption><h1>Valeurs des Capteurs</h1></caption>";
html_s += "<tr>";
html_s += "<th width='10%' align='center'>Jour</th>";
html_s += "<th width='10%' align='center'>Heure</th>";
html_s += "<th width='10%' align='center'>Minute</th>";
html_s += "<th width='10%' align='center'>Seconde</th>";
for(int i=0; i<8; i++) html_s += "<th width='5%' align='center'>" + String(v_ram.nom_s[i]) + "</th>";
html_s += "</tr>";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += "<tr>";
html_s += "<td width='10%' align='center'>" + String(tgr_temp[vadr].v_j) + "</td>";
html_s += "<td width='10%' align='center'>" + String(tgr_temp[vadr].v_h) + "</td>";
html_s += "<td width='10%' align='center'>" + String(tgr_temp[vadr].v_m) + "</td>";
html_s += "<td width='10%' align='center'>" + String(tgr_temp[vadr].v_s) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t1) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t2) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t3) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t4) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t5) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t6) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t7) + "</td>";
html_s += "<td width='5%' align='center'>" + String(tgr_temp[vadr].v_t8) + "</td>";
html_s += "</tr>";
}
}
html_s += "</table></div><p align='center'><br/><br/><a class='btn' href='/' target='_self'>Retour Accueil</a></p>";
html_s += "</body></html>";
return html_s;
}
String page_graph() {
// Page graph
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'><title>PAC Chauffage</title>";
html_s += "<style>";
html_s += ".chart-container { width: 600px; height: 400px; margin: 0 auto;}";
html_s += ".chart {position:relative; width: 600px; height: 500px; background-color: #fff; border: 1px solid #ccc; margin:0 auto;}";
html_s += ".line-chart {width: 100%; height: calc(100% - 80px);}";
html_s += ".y-axis {position: absolute; top: 20px; bottom: 30px; left: 20; width: 40px; height: 390; display: flex; flex-direction: column; justify-content: space-between;}";
html_s += ".y-tick {text-align: right; font-size: 12px; padding-right: 5px; font-weight: bold; color: #999;}";
html_s += ".x-axis {position: absolute; bottom: 5px; left: 70px; right: 40px; height: 20px; display: flex; justify-content: space-between;}";
html_s += ".x-axis2 {position: absolute; bottom: 20px; left: 70px; right: 40px; height: 20px; display: flex; justify-content: space-between;}";
html_s += ".x-axis3 {position: absolute; bottom: 35px; left: 70px; right: 40px; height: 20px; display: flex; justify-content: space-between;}";
html_s += ".x-axis4 {position: absolute; bottom: 50px; left: 70px; right: 40px; height: 20px; display: flex; justify-content: space-between;}";
html_s += ".x-tick {font-size: 12px; text-align: center; font-weight: bold; color: #999;}";
html_s += "</style>";
html_s += "</head><body style='background-color: grey;'>";
html_s += "<div class='chart-container'><div class='chart'>";
html_s += "<svg viewBox='0 0 150 120' preserveAspectRatio='none' class='line-chart'>";
html_s += "<line x1='0' y1='7' x2='150' y2='7' stroke='#f1f1f1' stroke-width='0.5'/><line x1='0' y1='25.5' x2='150' y2='25.5' stroke='#f1f1f1' stroke-width='0.5'/><line x1='0' y1='44' x2='150' y2='44' stroke='#f1f1f1' stroke-width='0.5'/>";
html_s += "<line x1='0' y1='62.5' x2='150' y2='62.5' stroke='#f1f1f1' stroke-width='0.5'/><line x1='0' y1='81' x2='150' y2='81' stroke='#f1f1f1' stroke-width='0.5'/><line x1='0' y1='99.5' x2='150' y2='99.5' stroke='#f1f1f1' stroke-width='0.5'/><line x1='0' y1='118' x2='150' y2='118' stroke='#f1f1f1' stroke-width='0.5'/>";
html_s += "<polyline fill='none' stroke='" + tb_capteurs[0].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t1);
}
}
html_s += "'/>";
if(nb_capteur > 1){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[1].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t2);
}
}
html_s += "'/>";
}
if(nb_capteur > 2){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[2].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t3);
}
}
html_s += "'/>";
}
if(nb_capteur > 3){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[3].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t4);
}
}
html_s += "'/>";
}
if(nb_capteur > 4){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[4].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t5);
}
}
html_s += "'/>";
}
if(nb_capteur > 5){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[5].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t6);
}
}
html_s += "'/>";
}
if(nb_capteur > 6){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[6].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t7);
}
}
html_s += "'/>";
}
if(nb_capteur > 7){
html_s += "<polyline fill='none' stroke='" + tb_capteurs[7].v_coul + "' troke-width='0.7' points='";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr++){
if(tgr_temp[vadr].v_j){
html_s += " " + String(20 + (vadr*2)) + "," + String(100-tgr_temp[vadr].v_t8);
}
}
html_s += "'/>";
}
html_s += "</svg>";
html_s += "<div class='y-axis'><div class='y-tick'>100</div><div class='y-tick'>80</div><div class='y-tick'>60</div><div class='y-tick'>40</div><div class='y-tick'>20</div><div class='y-tick'>0</div><div class='y-tick'>-20</div></div>";
html_s += "<div class='x-axis'>";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr+=10){
html_s += "<div class='x-tick'>S:" + String(tgr_temp[vadr].v_s) + "</div>";
}
html_s += "</div><div class='x-axis2'>";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr+=10){
html_s += "<div class='x-tick'>M:" + String(tgr_temp[vadr].v_m) + "</div>";
}
html_s += "</div><div class='x-axis3'>";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr+=10){
html_s += "<div class='x-tick'>H:" + String(tgr_temp[vadr].v_h) + "</div>";
}
html_s += "</div><div class='x-axis4'>";
for(int vadr=0; vadr <= MAXTABTEMP-1; vadr+=10){
html_s += "<div class='x-tick'>J:" + String(tgr_temp[vadr].v_j) + "</div>";
}
html_s += "</div></div>";
html_s += "</div><br><br><br><br><br><br><br><br>";
html_s += "<table align='center'><tr>";
for(uint8_t i = 0; i < 8; i++){
html_s += "<td>" + String(v_ram.nom_s[i]) + " : <font color='" + tb_capteurs[i].v_coul + "'>=====</font></td>";
if(i==3) html_s += "</tr><tr>";
}
html_s += "</tr></table>";
html_s += "<br><br><p align='center'><a class='btn' href='/' target='_self'>Retour Accueil</a>";
html_s += "</body></html>";
return html_s;
}
String handleRoot() {
// Serve la page principale (HTML)
String html_s = "<html lang='fr'><head> <meta charset='UTF-8'><title>PAC Chauffage</title>";
html_s += "<style> " + v_css_body + v_css_lien + v_css_lien_vol + "</style>";
html_s += "</head><body><table width='100%'>";
html_s += "<caption><h1>Optimisation PAC</h1></caption>";
if(capteur_HS){
html_s += "<tr><td align='center'><br/><h1>PROBLEME INIT CIRCUIT HORLOGE ===>>>> FAIRE UN MARCHE ARRET !</h1><br/></td></tr>";
}
html_s += "<tr><td align='center' width='100%'>";
html_s += "Nous sommes le " + String(timeinfo.day()) + "/" + String(timeinfo.month()) + "/" + String(timeinfo.year());
html_s += " il est " + String(timeinfo.hour()) + " H " + String(timeinfo.minute());
html_s += "</td></tr>";
html_s += "<tr><td align='center'><br/><p><a class='btn' href='/dh' target='_self'>Modif date / heure</a></p><br/></td></tr>";
html_s += "<tr><td align='center'><br/><p><a class='btn' href='/aff_eeprom' target='_self'>Affichage données EEPROM</a></p><br/></td></tr>";
html_s += "<tr><td align='center'>Nb maximum valeurs mémorisées : " + String(MAXTABTEMP) + "</td></tr>";
html_s += "<tr><td align='center'>Délai entre deux mesures : " + String(nb_sec_inter_mesure) + " (secondes)</td></tr>";
html_s += "<tr><td align='center'><br><p align='center'><a class='btn' href='/modif_delai_m' target='_self'>Modifier délai entre 2 mesures</a></p></td></tr> ";
html_s += "<tr><td align='center'><br><p align='center'><a class='btn' href='/init_tab_val' target='_self'>Init tableau mesures</a></p></td></tr> ";
html_s += "<tr><td align='center'><br><br>Nb de capteur detecté : " + String(nb_capteur) + "</td></tr>";
html_s += "<tr><td align='center'><br><p align='center'><a class='btn' href='/capteur' target='_self'>Liste des capteurs</a></p></td></tr>";
html_s += "<tr><td align='center'>";
html_s += "<br><br><a class='btn' href='/page_graph' target='_self'>Graphique</a> ";
html_s += "<a class='btn' href='/page_valeurs' target='_self'>Liste des valeurs</a>";
html_s += "</td></tr>";
html_s += "<tr><td align='center'>";
html_s += "<br><br><a class='btn' href='/modif_PWM' target='_self'>Modif. vitesse moteur</a> ";
html_s += "</td></tr></table>";
html_s += "</body></html>";
return html_s;
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Capteur en erreur");
return;
}
Serial.print(" => ");
Serial.print(tempC);
Serial.println("°");
}
void memo_mesure(){
uint8_t vjour, vheure, vminute, vseconde;
// décallage vers le bas de tout le tableau
for(int vadr = MAXTABTEMP - 2; vadr >= 0; vadr--){
tgr_temp[vadr+1].v_j = tgr_temp[vadr].v_j;
tgr_temp[vadr+1].v_h = tgr_temp[vadr].v_h;
tgr_temp[vadr+1].v_m = tgr_temp[vadr].v_m;
tgr_temp[vadr+1].v_s = tgr_temp[vadr].v_s;
tgr_temp[vadr+1].v_t1 = tgr_temp[vadr].v_t1;
tgr_temp[vadr+1].v_t2 = tgr_temp[vadr].v_t2;
tgr_temp[vadr+1].v_t3 = tgr_temp[vadr].v_t3;
tgr_temp[vadr+1].v_t4 = tgr_temp[vadr].v_t4;
tgr_temp[vadr+1].v_t5 = tgr_temp[vadr].v_t5;
tgr_temp[vadr+1].v_t6 = tgr_temp[vadr].v_t6;
tgr_temp[vadr+1].v_t7 = tgr_temp[vadr].v_t7;
tgr_temp[vadr+1].v_t8 = tgr_temp[vadr].v_t8;
}
// Memo derniere valeur
vjour = timeinfo.day();
vheure = timeinfo.hour();
vminute = timeinfo.minute();
vseconde = timeinfo.second();
tgr_temp[0].v_j = vjour;
tgr_temp[0].v_h = vheure;
tgr_temp[0].v_m = vminute;
tgr_temp[0].v_s = vseconde;
tgr_temp[0].v_t1 = val_mesure[0];
tgr_temp[0].v_t2 = val_mesure[1];
tgr_temp[0].v_t3 = val_mesure[2];
tgr_temp[0].v_t4 = val_mesure[3];
tgr_temp[0].v_t5 = val_mesure[4];
tgr_temp[0].v_t6 = val_mesure[5];
tgr_temp[0].v_t7 = val_mesure[6];
tgr_temp[0].v_t8 = val_mesure[7];
}
void modif_param_post() {
if (server.hasArg("datetime")) {
String dateTime = server.arg("datetime"); // Récupère la valeur du formulaire
int year, month, day, hour, minute;
sscanf(dateTime.c_str(), "%d-%d-%dT%d:%d", &year, &month, &day, &hour, &minute);
// Met à jour l'horloge RTC
rtc.adjust(DateTime((uint16_t)year, (uint8_t)month, (uint8_t)day, (uint8_t)hour, (uint8_t)minute, 0));
timeinfo = rtc.now();
}
server.send(200, "text/html", handleRoot());
}
void setDelaiMesure() {
if (server.hasArg("v_d_mesure")) {
int v_d_mesure = server.arg("v_d_mesure").toInt(); // Récupère la valeur du formulaire
nb_sec_inter_mesure = v_d_mesure;
v_ram.delai_inter_mesure = nb_sec_inter_mesure;
temp_t = nb_sec_inter_mesure * 1000;
ecriture_eeprom();
}
server.send(200, "text/html", handleRoot());
}
void inc_PWM() {
if(val_PWM<255){
val_PWM += 10;
if(val_PWM>255) val_PWM = 255;
analogWrite(PinPWM, val_PWM);
}
server.send(200, "text/html", modif_PWM());
}
void dec_PWM() {
if(val_PWM>1){
val_PWM -= 10;
if(val_PWM<1) val_PWM = 1;
analogWrite(PinPWM, val_PWM);
}
server.send(200, "text/html", modif_PWM());
}
void setNomCapt() {
String v_nom;
if(server.hasArg("nom_capt_0")) {v_nom = server.arg("nom_capt_0"); v_nom.toCharArray(v_ram.nom_s[0], v_nom.length()+1);}
if(server.hasArg("nom_capt_1")) {v_nom = server.arg("nom_capt_1"); v_nom.toCharArray(v_ram.nom_s[1], v_nom.length()+1);}
if(server.hasArg("nom_capt_2")) {v_nom = server.arg("nom_capt_2"); v_nom.toCharArray(v_ram.nom_s[2], v_nom.length()+1);}
if(server.hasArg("nom_capt_3")) {v_nom = server.arg("nom_capt_3"); v_nom.toCharArray(v_ram.nom_s[3], v_nom.length()+1);}
if(server.hasArg("nom_capt_4")) {v_nom = server.arg("nom_capt_4"); v_nom.toCharArray(v_ram.nom_s[4], v_nom.length()+1);}
if(server.hasArg("nom_capt_5")) {v_nom = server.arg("nom_capt_5"); v_nom.toCharArray(v_ram.nom_s[5], v_nom.length()+1);}
if(server.hasArg("nom_capt_6")) {v_nom = server.arg("nom_capt_6"); v_nom.toCharArray(v_ram.nom_s[6], v_nom.length()+1);}
if(server.hasArg("nom_capt_7")) {v_nom = server.arg("nom_capt_7"); v_nom.toCharArray(v_ram.nom_s[7], v_nom.length()+1);}
ecriture_eeprom();
server.send(200, "text/html", handleRoot());
}
void setup() {
Serial.begin(115200);
#ifndef ESP8266
while (!Serial);
#endif
delay(500);
if (! rtc.begin()) {
Serial.println("On ne trouve pas le circuit Horloge RTC");
capteur_HS = true;
delay(2000);
if (! rtc.begin()) {
Serial.println("On ne trouve toujours pas le circuit Horloge RTC");
capteur_HS = true;
delay(1000);
}else{
capteur_HS = false;
}
}
Serial.println("Circuit Horloge RTC OK");
lecture_eeprom();
delay(1000);
analogWriteFreq(2000); // Frequence de PWM à 2 Khz
analogWrite(PinPWM, 255); // Moteur lancé à fond
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Date et heure compilation mettre en comment
Wire.begin();
WiFi.softAP(ap_ssid, ap_password); // ESP8266 en mode Point d'Accès
Serial.println("Point d'Accès démarré");
Serial.print("Adresse IP: ");
Serial.println(WiFi.softAPIP()); // L'adresse IP sera généralement 192.168.4.1
// Configurer les routes du serveur
server.on ( "/", [](){ server.send(200, "text/html", handleRoot()); });
server.on ( "/dh", [](){ server.send(200, "text/html", htmldateheure()); });
server.on ( "/page_valeurs", [](){ server.send(200, "text/html", page_valeurs()); });
server.on ( "/capteur", [](){ server.send(200, "text/html", page_capteurs()); });
server.on ( "/page_graph", [](){ server.send(200, "text/html", page_graph()); });
server.on ( "/modif_delai_m", [](){ server.send(200, "text/html", modif_delai_m()); });
server.on ( "/modif_PWM", [](){ server.send(200, "text/html", modif_PWM()); });
server.on ( "/aff_eeprom", [](){ server.send(200, "text/html", aff_eeprom()); });
server.on("/setDateTime", modif_param_post);
server.on("/setNomCapt", setNomCapt);
server.on("/setDelaiMesure", setDelaiMesure);
server.on("/inc_vit", inc_PWM);
server.on("/dec_vit", dec_PWM);
server.on("/init_tab_val", vinit_tab_val);
server.onNotFound(page_inexistante);
server.begin(); // Démarrer le serveur web
Serial.println("Serveur démarré");
sensors.begin();
nb_capteur = sensors.getDeviceCount();
Serial.print("Locating devices...");
Serial.print("Found ");
Serial.print(nb_capteur, DEC);
Serial.println(" devices.");
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
for (int i = 0; i < nb_capteur; i++)
{
if (sensors.getAddress(tempDeviceAddress, i))
{
Serial.print("Capteur ");
Serial.print(i, DEC);
tb_capteurs[i].v_n = i;
Serial.print(" adresse : ");
printAddress(tempDeviceAddress);
for (uint8_t n = 0; n < 8; n++){ tb_capteurs[i].v_ad[n] = tempDeviceAddress[n]; }
Serial.println();
Serial.print("Resolution ");
Serial.println(TEMPERATURE_PRECISION, DEC);
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
Serial.print("Resolution actually set to: ");
Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
Serial.println();
} else {
Serial.print("Capteur ");
Serial.print(i, DEC);
Serial.print(" pas d'adresse detectee.");
}
}
String v_defaut = "Sonde_x"; bool v_init = false;
for(uint8_t x=0; x<8; x++){ if(v_ram.nom_s[x][0]=='0'){ v_defaut.toCharArray(v_ram.nom_s[x], v_defaut.length()+1); v_init=true; }}
if(v_init) ecriture_eeprom();
tb_capteurs[0].v_coul = "Orange";
tb_capteurs[1].v_coul = "Yellow";
tb_capteurs[2].v_coul = "Green";
tb_capteurs[3].v_coul = "Purple";
tb_capteurs[4].v_coul = "Pink";
tb_capteurs[5].v_coul = "Blue";
tb_capteurs[6].v_coul = "Magenta";
tb_capteurs[7].v_coul = "Cyan";
timeinfo = rtc.now();
temps_qui_passe = millis();
nb_sec_inter_mesure = v_ram.delai_inter_mesure;
temp_t = nb_sec_inter_mesure*1000;
vinit_tab_val();
}
void loop() {
for(int x = 0; x < 8; x++){ val_mesure[x] = 0; }
timeinfo = rtc.now();
if((millis() - temps_qui_passe) >= temp_t){
sensors.requestTemperatures();
for (int i = 0; i < nb_capteur; i++){
if (sensors.getAddress(tempDeviceAddress, i)){
val_mesure[i] = sensors.getTempC(tempDeviceAddress);
//printTemperature(tempDeviceAddress);
}
}
memo_mesure();
temps_qui_passe = millis();
}
server.handleClient(); // Gérer les requêtes HTTP
}