1 – Déclaration variables
#include <lib.h>
// todo--------------------------------------Variables générales ----------------------------
const char *PARAM_INPUT_1 = "output";
const char *PARAM_INPUT_2 = "state";
int led = LED_BUILTIN; // led interne au ESP8266 fonction sur recherche connexion WIFI
int cpt = 0;
uint8_t wifi_ok = 1;
int Mode_AM = false;
String inputMessage1;
String inputMessage2;
int val_out = 0;
int val_state = 0;
int AutoManu = 0;
String T1M, T2M; // Ajout 0 si les Mn plage horaire
String mode_am = "";
AsyncWebServer server(80); // Create AsyncWebServer object on port 80
//----------------------------------------- Afficheur LCD ---------------------------------------
#define SCREEN_WIDTH 128 // OLED largeur écran en pixels
#define SCREEN_HEIGHT 32 // OLED hauteur écran en pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // L'adresse i2c -> 0x3C de l'écran oled 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
uint16_t EcritureTexteBlanc = SSD1306_WHITE; // Affichage du texte en "blanc"
uint16_t EcritureTexteNoir = SSD1306_BLACK; // Affichage du texte en "noir"
uint16_t FondTexteBlanc = SSD1306_WHITE; // Affichage du fond texte en "blanc"
uint16_t FondTexteNoir = SSD1306_BLACK; // Affichage du fond texte en "noir"
unsigned long timer_ecran = millis(); // Compteur gestion marche arrêt écran
unsigned long tempo_ecran = 100000; // valeur de la durée avec extinction écran
int ecran = 0; // Drapeau bascule ecran
#define input_ecran 15 // (D8) BP cde allumage ecran
// important -------------------------------------- Gestion PCF8574 -------------------------------
PCF8574 PCF_21(0x21); // Ajout entrées sorties avec module PCF8574 à l'adresse 0X21
// *** les interrupteurs de commande
uint8_t I_EV1; // Goutte a goutte avant
uint8_t I_EV2; // Goutte a goutte arrière
uint8_t I_EV3; // Circuit tuyeres
uint8_t I_EV4; // Circuit turbines
// *** les sorties relais
int S_EV1 = 3; // Sortie relais
int S_EV2 = 2; // Sortie relais
int S_EV3 = 1; // Sortie relais
int S_EV4 = 0; // Sortie relais
//--------------------------------------Variables gestion horaire ----------------------
//***** Gestion Heures minutes EV1 tranche 1 *****
String T1_Debut_EV1, T1_Debut_M_EV1, T1_Nb_Cycle_EV1, T1_Periode_Cycle_EV1, T1_Duree_Cycle_EV1; // Déclaration des variables pour la page web
int T1_Total_Debut_EV1, T1_Total_Fin_Cycle_EV1, T1_Cpt_Nb_Cycle_EV1;
int T1_Debut_EV1_Int, T1_Debut_M_EV1_Int, Nb_Cycle_EV1_Int, T1_Periode_Cycle_EV1_Int, T1_Duree_Cycle_EV1_Int;
//------------------------ Variables température & humidité ATH10----------------------------
Adafruit_AHTX0 aht; // SCL -> D1 - SDA -> D2
int humidite; //
sensors_event_t humidity, temp;
//--------------------------------- Variables GPS --------------------------------------
#define SerialGPS Serial // Définir les entrées TX & RX du gps
TinyGPSPlus gps; // Lib TinyGPS et SoftwareSerial sont l'œuvre de Mikal Hart
time_t prevDisplay = 0; // lorsque l'horloge numérique était affichée
float Latitude, Longitude; // variables GPS
int Year, Month, Day, Hour, Minute, Second; // Mois, jour, heure, minute, seconde GPS
int changement_heure = 2; // Décalage des heures par rapport à l'heure GPS (UTC)
//--------------------------Variables Heure & date ------------------------------------------
String zs; // pour ajout 0 formatage ex seconde 02
String zmn; // pour ajout 0 formatage ex minute 02
String zh; // pour ajout 0 formatage ex heure 02
String zmois; // pour ajout 0 formatage ex mois 05
String val_heure, val_date; // calcul de l'heure au format String"02:05:05" ou "10:15:25"
int total_mn_gps; // Calcul le total en minute de l'heure réelle.
// String Val_T1EV1; //= "test pour verification bon fonctionnement "; // Création d'une variable pour affichage WEB de la plage horaire de EV1 (début fin matin )
// String Plage_horaire_EV2; // Création d'une variable pour affichage WEB de la plage horaire de EV2 (début fin matin )
String EtatWeb_EV1, EtatWeb_EV2; // envois sur web état inter marche forcée
// ---------------------------------- Variables sonde pluie -----------------------------------
String EtatPluie;
int presence_pluie; // si detection pluie alors "presence_pluie" = 1 (microswitch "NO" sur la sonde )
//-------------------------------------- Sous programmes -------------------------------
void ecriture_json()
{ // Créer un document JSON avec la capacité définie
JsonDocument doc;
// Assigner des valeurs aux variables
doc["T1_Debut_EV1"] = T1_Debut_EV1;
doc["T1_Debut_M_EV1"] = T1_Debut_M_EV1;
doc["T1_Nb_Cycle_EV1"] = T1_Nb_Cycle_EV1;
doc["T1_Periode_Cycle_EV1"] = T1_Periode_Cycle_EV1;
doc["T1_Duree_Cycle_EV1"] = T1_Duree_Cycle_EV1;
// Convertir le document JSON en chaîne JSON
String output;
serializeJson(doc, output);
// Enregistrer la chaîne JSON dans l'EEPROM
for (size_t i = 0; i < output.length(); ++i)
{
EEPROM.write(i, output[i]);
}
EEPROM.commit(); // N'oubliez pas de faire un commit après avoir écrit dans l'EEPROM
Serial.println("Données enregistrées dans l'EEPROM !");
}
void lecture_json()
{
// Lire la chaîne JSON enregistrée dans l'EEPROM
String input;
for (int i = 0; i < 200; ++i)
{
input += char(EEPROM.read(i));
}
// Convertir la chaîne JSON en document JSON
JsonDocument doc;
DeserializationError error = deserializeJson(doc, input);
if (error)
{
Serial.print("Erreur lors de la lecture du JSON : ");
Serial.println(error.c_str());
return;
}
// Extraire les valeurs du document JSON
T1_Debut_EV1 = doc["T1_Debut_EV1"].as<String>();
T1_Debut_M_EV1 = doc["T1_Debut_M_EV1"].as<String>();
T1_Nb_Cycle_EV1 = doc["T1_Nb_Cycle_EV1"].as<String>();
T1_Periode_Cycle_EV1 = doc["T1_Periode_Cycle_EV1"].as<String>();
T1_Duree_Cycle_EV1 = doc["T1_Duree_Cycle_EV1"].as<String>();
Serial.print(" lecture du JSON ok ");
}
String readHeure()
{
if (val_heure == "")
{
val_heure = "En attente signal GPS";
return val_heure;
}
else
{
// Serial.println(val_heure);
return val_heure;
}
}
String readDate()
{
// Serial.println(val_date);
return val_date;
}
String readAHTTemperature()
{
aht.getEvent(&humidity, &temp);
float temperatureInt = temp.temperature;
if (isnan(temperatureInt))
{
Serial.println("Echec de la lecture du capteur AHT!");
return "--";
}
else
{
// Serial.print("température :");
// Serial.println(temperatureInt);
return String(temperatureInt);
}
}
String readAHTHumidity()
{
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
aht.getEvent(&humidity, &temp);
humidite = humidity.relative_humidity;
if (isnan(humidite))
{
Serial.println("Echec de la lecture du capteur AHT");
return "--";
}
else
{
// Serial.print("Humidité :");
// Serial.println(humidite);
return String(humidite);
}
}
String outputState(int output)
{
if (digitalRead(output))
{
return "checked";
}
else
{
return "";
}
}
void GestionZero()
{
zh = "";
if (Hour < 10)
{
zh = "0";
}
zmn = "";
if (Minute < 10)
{
zmn = "0";
}
zs = "";
if (Second < 10)
{
zs = "0";
}
zmois = "";
if (Month < 10)
{
zmois = "0";
}
}
void Affiche_gpio()
{
Serial.print("GPIO: ");
Serial.print(inputMessage1);
Serial.print(" - Etat: ");
Serial.println(inputMessage2);
Serial.print(" - Mode Am ");
Serial.println(Mode_AM);
}
void Clignotement(int temps)
{
digitalWrite(led, LOW); // led clignote en attende de synchronisation avec le WIFI
delay(temps);
digitalWrite(led, HIGH);
delay(temps);
}
void affiche_ecran()
{
display.setCursor(0, 0);
display.clearDisplay();
display.print(val_date);
display.print(" ");
display.println(val_heure);
display.setCursor(0, 24);
display.print("Mem libre:");
display.print(ESP.getFreeHeap()); // Imprimez la quantité de mémoire libre
// display.println(" octets");
display.display();
}
String readOut()
{
String output = String(val_out);
String state = String(val_state);
return output + "&" + state;
}
// Replaces placeholder with button section in your web page
String processor(const String &var)
{
if (var == "T1_Debut_EV1")
{
return T1_Debut_EV1;
}
if (var == "T1_Debut_M_EV1")
{
return T1_Debut_M_EV1;
}
if (var == "T1_Nb_Cycle_EV1")
{
return T1_Nb_Cycle_EV1;
}
if (var == "T1_Periode_Cycle_EV1")
{
return T1_Periode_Cycle_EV1;
}
if (var == "T1_Duree_Cycle_EV1")
{
return T1_Duree_Cycle_EV1;
}
if (var == "HEURE")
{
return readHeure();
}
if (var == "DATE")
{
return readDate();
}
if (var == "TEMPERATURE")
{
return readAHTTemperature();
}
else if (var == "HUMIDITY")
{
return readAHTHumidity();
}
if (var == "BUTTONPLACEHOLDER")
{
String buttons = "";
// buttons += "<h4>Manu/Auto</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleMode(this)\" id=\"modeSwitch\" " + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Manu/Auto</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"4\" id=\"modeSwitch\"" + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "<div id=\"manualControls\">";
buttons += "<h4>Arret/Marche EV1</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"3\" " + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Arret/Marche EV2</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"2\" " + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Arret/Marche EV3</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"1\" " + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "<h4>Arret/Marche EV4</h4><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"0\" " + outputState(1) + "><span class=\"slider\"></span></label>";
buttons += "</div>";
return buttons;
}
return String();
}
Void (setup)
void setup()
{
// Serial port for debugging purposes
Serial.begin(9600);
EEPROM.begin(512);
PCF_21.begin(); // Entrées sortie sup.
//-------------------------------------- Gestion AHT10 -------------------------------
aht.begin();
//---------------------------------------- Gestion GPS -------------------------------
SerialGPS.begin(9600);
//--------------------------- Gestion écran OLED -----------------------------
pinMode(input_ecran, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS))
{
Serial.println(F("SSD1306 allocation erreur"));
for (;;)
; // Ne continuez pas, bouclez pour toujours
}
display.clearDisplay();
display.drawBitmap(0, 0, logo_arrosage, 128, 64, 1); // affiche le logo arrosage sur l'écran Oled
display.display();
delay(1000); // Pause de 1 secondes
display.setCursor(0, 0); // Déplacement du curseur en position (0,0), angle supérieur gauche
display.clearDisplay();
display.setTextColor(EcritureTexteBlanc, FondTexteNoir);
display.println("Recherche borne Wifi");
//-------------------------------------- Gestion Wi-Fi -------------------------------
WiFi.begin(ssid, password);
Serial.print("Recherche borne Wifi");
while (WiFi.status() != WL_CONNECTED)
{
Clignotement(500);
Serial.print(".");
display.print(".");
display.display();
cpt++;
if (cpt == 1000)
{
wifi_ok = 0;
return; // Sortir de la boucle si non connexion au bout de x tentatives}
}
}
Serial.print("Connection à l'adresse IP: ");
Serial.println(WiFi.localIP());
WiFi.printDiag(Serial); // imprimer les principales informations du wifi
Serial.println();
// ---------- Etat connection du wifi sur ecran Oled -------------
display.setCursor(0, 0);
display.clearDisplay();
display.display();
display.println(WiFi.localIP());
display.display();
lecture_json(); // lire les valeurs des heure et incorporer dans les variables
// ---- Page web bouton & varables (heure/date ...) Initialisation du serveur Web ------------------
server.on("/", HTTP_POST, [](AsyncWebServerRequest *request) { // HTTP POST ssid value
});
server.on("/get_out", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", readOut().c_str()); });
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/html", index_html, processor); });
server.on("/val_heure", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", readHeure().c_str()); });
server.on("/val_date", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", readDate().c_str()); });
server.on("/temperatureInt", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", readAHTTemperature().c_str()); });
server.on("/humidite", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/plain", readAHTHumidity().c_str()); });
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request)
{
if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2))
{
inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
}
Affiche_gpio();
request->send(200, "text/plain", "OK"); });
// ----------------------------- Formulaire -------------------------------
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{
request->send_P(200, "text/html", index_html); // Envoyer la page HTML depuis le fichier index_html.h
});
server.on("/submit", HTTP_POST, [](AsyncWebServerRequest *request)
{
if (request->hasParam("T1_Debut_EV1", true)) {
T1_Debut_EV1 = request->getParam("T1_Debut_EV1", true)->value();
}
if (request->hasParam("T1_Debut_M_EV1", true)) {
T1_Debut_M_EV1 = request->getParam("T1_Debut_M_EV1", true)->value();
}
if (request->hasParam("T1_Nb_Cycle_EV1", true)) {
T1_Nb_Cycle_EV1 = request->getParam("T1_Nb_Cycle_EV1", true)->value();
}
if (request->hasParam("T1_Periode_Cycle_EV1", true)) {
T1_Periode_Cycle_EV1 = request->getParam("T1_Periode_Cycle_EV1", true)->value();
}
if (request->hasParam("T1_Duree_Cycle_EV1", true)) {
T1_Duree_Cycle_EV1 = request->getParam("T1_Duree_Cycle_EV1", true)->value();
}
String response = "<!DOCTYPE html><html lang=\"fr\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Résultat de l'Arrosage</title></head><body>";
response += "<div style=\"background-color: blue; padding: 10px;\">";
response += "<h3 style=\"color: white;\">Zone 1</h3>";
response += "<p style=\"color: white;\">Heure de démarrage: " + T1_Debut_EV1 + "</p>";
response += "<p style=\"color: white;\">Minute de démarrage: " + T1_Debut_M_EV1 + "</p>";
response += "<p style=\"color: white;\">Nombre d'arrosage: " + T1_Nb_Cycle_EV1 + "</p>";
response += "<p style=\"color: white;\">Intervalle d'arrosage: " + T1_Periode_Cycle_EV1 + "</p>";
response += "<p style=\"color: white;\">Durée d'arrosage: " + T1_Duree_Cycle_EV1 + "</p>";
response += "</div>";
response += "<br><br><a href=\"/\" style=\"background-color: white; color: blue; padding: 10px 20px; text-decoration: none; border: 1px solid blue;\">Retour</a>";
response += "</body></html>";
ecriture_json();
request->send(200, "text/html", response); });
// Start server
server.begin();
}
Void (loop)
void loop()
{
while (SerialGPS.available() > 0)
{
if (gps.encode(SerialGPS.read()))
{
if (gps.date.isValid())
{
Day = gps.date.day();
Month = gps.date.month();
Year = gps.date.year();
}
if (gps.time.isValid())
{
Hour = gps.time.hour() + changement_heure; // ajuste UTC (heure hivers +1 - heure été +2)
Minute = gps.time.minute();
Second = gps.time.second();
}
GestionZero(); // Ajout 0 si var < 10
val_heure = zh + String(Hour) + ":" + zmn + String(Minute) + ":" + zs + String(Second);
val_date = String(Day) + "/" + zmois + String(Month) + "/" + String(Year);
total_mn_gps = (Hour) * 60 + Minute; // calcul nb total en minutes des heures du GPS
}
}
// ------------------------- Conversion des heures en minutes & calcul tranche début fin --------------------------
if (T1_Debut_EV1 != "")
{
T1_Debut_EV1_Int = T1_Debut_EV1.toInt();
}
if (T1_Debut_M_EV1 != "")
{
T1_Debut_M_EV1_Int = T1_Debut_M_EV1.toInt();
}
if (T1_Nb_Cycle_EV1 != "")
{
Nb_Cycle_EV1_Int = T1_Nb_Cycle_EV1.toInt();
}
if (T1_Periode_Cycle_EV1 != "")
{
T1_Periode_Cycle_EV1_Int = T1_Periode_Cycle_EV1.toInt();
}
if (T1_Duree_Cycle_EV1 != "")
{
T1_Duree_Cycle_EV1_Int = T1_Duree_Cycle_EV1.toInt();
}
// ----------------------------------- traitement des tranches à afficher sur la page web -----------------------------
T1M = ""; // Ajout 0 si mn entre 0et 9
if (T1_Debut_M_EV1_Int < 10)
{
T1M = "0";
}
T1_Total_Debut_EV1 = T1_Debut_EV1_Int * 60 + T1_Debut_M_EV1_Int + T1_Periode_Cycle_EV1_Int * T1_Cpt_Nb_Cycle_EV1; // Conversion des heures en minutes
T1_Total_Fin_Cycle_EV1 = T1_Total_Debut_EV1 + T1_Duree_Cycle_EV1_Int; // Calcul de la fin des cycles
if (T1_Total_Fin_Cycle_EV1 == total_mn_gps && T1_Cpt_Nb_Cycle_EV1 < Nb_Cycle_EV1_Int) // A la fin du cycle calcul le cycle suivant
{
T1_Cpt_Nb_Cycle_EV1++;
}
if (T1_Cpt_Nb_Cycle_EV1 == Nb_Cycle_EV1_Int)
{
T1_Cpt_Nb_Cycle_EV1 = 0;
}
//------------------------------Gestion des cde de sortie électrovannes (PCF8475) -----------------------------
I_EV1 = PCF_21.read(7); // inter marche/arrêt forcée EV1
I_EV2 = PCF_21.read(6); // inter march/arrête forcée EV2
I_EV3 = PCF_21.read(5); // inter marche/arrêt forcée EV3
I_EV4 = PCF_21.read(4); // inter marche/arrêt forcée EV4
if (inputMessage1 == "4" && inputMessage2 == "0")
{
Mode_AM = 0;
inputMessage1 == "";
}
if (inputMessage1 == "4" && inputMessage2 == "1")
{
Mode_AM = 1;
inputMessage1 == "";
}
//* ----------------------- Marche/Arrêt mode manuel -----------------------
if (Mode_AM == 0)
{
val_out = 5; //! permet de na pas activer les sortie de 0 à 4 (essai)
val_state = 0;
if (inputMessage1 == "3")
{
if (I_EV1 == 1 || inputMessage2 == "1")
{
PCF_21.write(S_EV1, 0); // Marche EV1
}
else if (I_EV1 == 0 || inputMessage2 == "0")
{
PCF_21.write(S_EV1, 1); // Arrêt EV1
}
}
if (inputMessage1 == "2")
{
if (I_EV2 == 1 || inputMessage2 == "1")
{
PCF_21.write(S_EV2, 0); // Marche EV2
}
else if (I_EV2 == 0 || inputMessage2 == "0")
{
PCF_21.write(S_EV2, 1); // Arrêt EV2
}
}
if (inputMessage1 == "1")
{
if (I_EV3 == 1 || inputMessage2 == "1")
{
PCF_21.write(S_EV3, 0); // Marche EV3
}
else if (I_EV3 == 0 || inputMessage2 == "0")
{
PCF_21.write(S_EV3, 1); // Arrêt EV3
}
}
if (inputMessage1 == "0")
{
if (I_EV4 == 1 || inputMessage2 == "1")
{
PCF_21.write(S_EV4, 0); // Marche EV4
}
else if (I_EV4 == 0 || inputMessage2 == "0")
{
PCF_21.write(S_EV4, 1); // Arrêt EV4
}
}
}
//* ----------------------- Marche/Arrêt mode automatique -----------------------
if (Mode_AM == 1)
{
// if (((total_mn_gps >= T1_Total_Debut_EV1) && (total_mn_gps < T1_Total_Fin_Cycle_EV1)))
if (total_mn_gps >= T1_Total_Debut_EV1 && total_mn_gps < T1_Total_Fin_Cycle_EV1)
{
PCF_21.write(S_EV1, 0); // marche auto
val_out = 3;
val_state = 1;
}
else
{
PCF_21.write(S_EV1, 1); // arrêt auto
val_out = 3;
val_state = 0;
}
}
affiche_ecran();
}