Files
Arduino/ESP32_SERRE/ESP32_SERRE.ino
Jérôme Delacotte 7b30d6e298 first commit
2025-03-06 11:15:32 +01:00

624 lines
19 KiB
C++

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
#include <ArduinoOTA.h>
#include <math.h>
//////////////////////////////////////////
// WIFI
//////////////////////////////////////////
#ifndef STASSID
#define STASSID "Livebox-37cc"
#define STAPSK "8A6060920A8A86896F770F2C47"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
WebServer server(80);
//////////////////////////////////////////
// DALLAS
/////////////////////////////////////////
//#define DALLAS true
#ifdef DALLAS
#include <OneWire.h>
#include <DallasTemperature.h>
#define onewirepin 5 // DATA pin of DS18B20 wired to pin 10 of Arduino
OneWire oneWire(onewirepin);
DallasTemperature sensors(&oneWire);
// find the DeviceAddress of your DS18B20 with the sketch DS18B20_address_reporter
// then replace the 8-byte ID below with the reported one
DeviceAddress Probe = { 0x28, 0xFF, 0x61, 0x1D, 0x76, 0x04, 0x00, 0x34 };
#endif
#define moistPin 36
////////////////////////////////////////
// DHT
////////////////////////////////////////
#ifdef DHT
#include "DHT.h"
#define DHTPIN 5
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#endif
////////////////////////////////////////
// PINS
////////////////////////////////////////
#define LUM_PIN 33
#define LED_PIN 3
#define RELAY_PIN 26
#define BUTTON_PIN 12
const char* htmlCode = R"(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Courbe en HTML</title>
<style>
canvas {
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="lineChart" width="400" height="300"></canvas>
<script>
function drawChart(temperatures) {
// Obtenez le contexte du canevas
var canvas = document.getElementById('lineChart');
var context = canvas.getContext('2d');
// Largeur et hauteur du graphique
var chartWidth = canvas.width;
var chartHeight = canvas.height;
// Nombre de données
var n = temperatures.length;
// Largeur des barres
var barWidth = chartWidth / (n - 1);
// Dessiner la courbe
context.beginPath();
context.moveTo(0, chartHeight - temperatures[0]);
for (var i = 1; i < n; i++) {
var x = i * barWidth;
var y = chartHeight - temperatures[i];
context.lineTo(x, y);
}
// Styles de la courbe
context.strokeStyle = '#e74c3c'; // Couleur de la ligne
context.lineWidth = 2; // Largeur de la ligne
context.stroke();
context.closePath();
}
// Exemple d'utilisation avec un tableau statique
var exampleTemperatures = [20, 22, 25, 23, 30, 28, 27, 26, 24, 22];
drawChart(exampleTemperatures);
</script>
</body>
</html>
)";
void handleRoot();
// Tableau pour stocker les températures
const int capaciteTableau = 2000; // Ajustez selon vos besoins
float temperatures[capaciteTableau];
float illuminances[capaciteTableau];// Tableau pour stocker les illuminances
int indexTableau = 0;
float temperature = 0;
float humidity_air = 0;
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(9600);
// OTA
Serial.println("Booting");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Définissez les gestionnaires pour les différentes URL
server.on("/", HTTP_GET, handleRoot);
// server.on("/getData", HTTP_GET, handleData);
// Démarrer le serveur
server.begin();
Serial.println("Serveur Web démarré");
// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH) {
type = "sketch";
} else { // U_FS
type = "filesystem";
}
// NOTE: if updating FS this would be the place to unmount FS using FS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// END OTA
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(LUM_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT);
pinMode(moistPin, INPUT);
//pinMode(10, INPUT);
#ifdef DALLAS
sensors.begin (); // Initialize the sensor and set resolution level
sensors.setResolution(Probe, 10);
#endif
delay(1000);
Serial.println();
#ifdef DALLAS
Serial.print ("Number of Devices found on bus = ");
Serial.println (sensors.getDeviceCount());
Serial.print ("Getting temperatures... ");
Serial.println ();
#endif
#ifdef DHT
/** DHT **/
dht.begin();
#endif
// For sleep
// CLKPR = 0x80;
// CLKPR = 0x01;
stop();
// Initialisation du tableau avec des valeurs harmonieuses
for (int i = 0; i < capaciteTableau; i++) {
temperatures[i] = 5.0 * sin(2.0 * 3.14159 * i / capaciteTableau) + 20.0;
}
}
void loop() {
ArduinoOTA.handle();
server.handleClient();
// Reads the information from the CI
#ifdef DHT
/**
* DHT11 : Temperature
*/
temperature = dht.readTemperature();
humidity_air = dht.readHumidity();
#endif
#ifdef DALLAS
sensors.requestTemperatures(); // Command all devices on bus to read temperature
// Serial.print("Temperature is: ");
temperature = printTemperature(Probe);
//Serial.println();
#endif
// Stocker les valeurs dans les tableaux
int lum = analogRead(LUM_PIN);
int btn_status = digitalRead(BUTTON_PIN);
// int tmp = digitalRead(10);
int moistVal = analogRead(moistPin);
int percent = 2.718282 * 2.718282 * (.008985 * moistVal + 0.207762); //calculate percent for probes about 1 - 1.5 inches apart
//Serial.println(percent);
if (btn_status == 1) {
avance();
//delay(1000);
//stop();
}
else {
stop();
}
float lux = 100000 * lum / 4192;
// Stockage de la température dans le tableau
if (temperature < 60 && temperature > -20) {
// temperatures[indexTableau] = temperature;
storeValue(temperature, temperatures);
storeValue(lux, illuminances);
indexTableau = (indexTableau + 1) % capaciteTableau;
}
digitalWrite(LED_PIN, HIGH);
Serial.print("Humidite ");
Serial.print(humidity_air);
Serial.print(" température ");
Serial.print(temperature,2);
Serial.print(" luminosite ");
Serial.print(lum);
Serial.print(" lux ");
Serial.print(lux);
Serial.print(" bouton ");
Serial.print(btn_status);
Serial.print(" hum_sol ");
Serial.print(moistVal);
Serial.print(" %sol ");
Serial.println(percent);
// // Lire et imprimer l'état de tous les ports
// for (int i = 0; i < 41; i++) {
// int etatPort = digitalRead(i);
// Serial.print("Port ");
// Serial.print(i);
// Serial.print(" : ");
// float fvalue = analogRead(i);
//
// Serial.print(etatPort);
// Serial.print(" : ");
// Serial.println(fvalue,2);
// }
delay(2500);
digitalWrite(LED_PIN, LOW);
delay(2500);
//Serial.println("Goto sleep");
// set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// sleep_enable();
// sleep_cpu();
//Serial.println("Wake up");
}
void stop()
{
// Serial.println("stop");
digitalWrite(RELAY_PIN, LOW); // turn the LED on (HIGH is the voltage level)
delay(200);
// Serial.println("stop fin");
}
void avance() {
Serial.println("avance");
digitalWrite(RELAY_PIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(200);
//Serial.println("avance fin");
}
#ifdef DALLAS
float printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
// if (tempC == -127.00)
// {
// Serial.print ("Error getting temperature ");
// }
// else
// {
// Serial.print ("C: ");
// Serial.println (tempC);
// // Serial.print (" F: ");
// // Serial.print(DallasTemperature::toFahrenheit(tempC));
// }
return tempC;
}
#endif
void handleRoot() {
// Lecture de la température depuis le capteur DHT
//float temperature = dht.readTemperature();
// Stockage de la température dans le tableau
temperatures[indexTableau] = temperature;
indexTableau = (indexTableau + 1) % capaciteTableau;
// Construction de la page HTML avec le graphique
String html = "<html><head><title>Graphique de Temp&eacute;rature</title>";
html += "<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>";
html += "</head><body><div id='chart'></div><script>";
html += "var trace = {x: ["; // Les x sont les index du tableau
for (int i = 0; i < capaciteTableau; i++) {
html += i;
if (i < capaciteTableau - 1) {
html += ",";
}
}
html += "], y: [";
for (int i = 0; i < capaciteTableau; i++) {
html += temperatures[i];
if (i < capaciteTableau - 1) {
html += ",";
}
}
html += "], yaxis: 'y', type: 'line', name: 'Temperature'};";
html += "var trace2 = {x: ["; // Les x sont les index du tableau
for (int i = 0; i < capaciteTableau; i++) {
html += i;
if (i < capaciteTableau - 1) {
html += ",";
}
}
html += "], y: [";
for (int i = 0; i < capaciteTableau; i++) {
html += illuminances[i];
if (i < capaciteTableau - 1) {
html += ",";
}
}
html += "], yaxis: 'y2', type: 'line', name: 'Luminosite'};";
html += "var layout = { yaxis: { title: 'Temperature (°C)', autorange: true }, yaxis2: { title: 'Luminosite', overlaying: 'y', side: 'right' } };";
html += "Plotly.newPlot('chart', [trace, trace2], layout);";
html += "</script></body></html>";
//String htmlContent = generateHTMLChart(temperatures, capaciteTableau);
String htmlCode = "<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"<head>\n"
" <meta charset=\"UTF-8\">\n"
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
" <title>Courbe en HTML</title>\n"
" <style>\n"
" canvas {\n"
" border: 1px solid #000;\n"
" }\n"
" </style>\n"
"</head>\n"
"<body>\n";
htmlCode += generateHTMLChart(temperatures, capaciteTableau, "temperatureChart", "#e74c3c", "Temps", "Températures (°C)");
htmlCode += generateHTMLChart(illuminances, capaciteTableau, "illuminanceChart", "#3498db", "Temps", "Illuminance (lux)");
htmlCode += "</body></html>";
// Envoi de la réponse HTTP
server.send(200, "text/html", htmlCode);
}
// Fonction pour générer la page HTML avec le graphique
String generateHTML() {
String html = "<!DOCTYPE html>";
html += "<html><head><script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script></head><body>";
// Ajouter le script JavaScript pour le graphique
html += "<script>";
html += "var trace1 = { x: [...Array(100).keys()], y: [" + arrayToString(temperatures) + "], yaxis: 'y', type: 'scatter', name: 'Temperature' };";
html += "var trace2 = { x: [...Array(100).keys()], y: [" + arrayToString(illuminances) + "], yaxis: 'y2', type: 'scatter', name: 'Luminosite' };";
html += "var layout = { yaxis: { title: 'Temperature (°C)', autorange: true }, yaxis2: { title: 'Luminosite', overlaying: 'y', side: 'right' } };";
html += "Plotly.newPlot('myDiv', [trace1, trace2], layout);";
html += "</script>";
html += "<div id=\"myDiv\"></div></body></html>";
return html;
}
// Fonction pour convertir un tableau en chaîne de caractères
String arrayToString(float array[]) {
String result = "";
for (int i = 0; i < 100; i++) {
result += String(array[i], 2);
if (i < 99) {
result += ", ";
}
}
return result;
}
// Fonction pour stocker une nouvelle valeur dans le tableau circulaire
void storeValue(float newValue, float array[]) {
array[indexTableau] = newValue;
//index = (index + 1) % capaciteTableau; // Taille maximale du tableau
}
//String generateHTMLChart(float temperatures[], int n) {
// String htmlCode = "<!DOCTYPE html>\n"
// "<html lang=\"en\">\n"
// "<head>\n"
// " <meta charset=\"UTF-8\">\n"
// " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
// " <title>Courbe en HTML</title>\n"
// " <style>\n"
// " canvas {\n"
// " border: 1px solid #000;\n"
// " }\n"
// " </style>\n"
// "</head>\n"
// "<body>\n"
// " <canvas id=\"lineChart\" width=\"600\" height=\"400\"></canvas>\n"
// "\n"
// " <script>\n"
// " function drawChart(temperatures) {\n"
// " var canvas = document.getElementById('lineChart');\n"
// " var context = canvas.getContext('2d');\n"
// "\n"
// " var chartWidth = canvas.width;\n"
// " var chartHeight = canvas.height;\n"
// "\n"
// " var n = temperatures.length;\n"
// " var barWidth = chartWidth / (n - 1);\n"
// "\n"
// " context.beginPath();\n"
// " context.moveTo(0, chartHeight - temperatures[0]);\n"
// "\n"
// " for (var i = 1; i < n; i++) {\n"
// " var x = i * barWidth;\n"
// " var y = chartHeight - temperatures[i];\n"
// " context.lineTo(x, y);\n"
// " }\n"
// "\n"
// " context.strokeStyle = '#e74c3c';\n"
// " context.lineWidth = 2;\n"
// " context.stroke();\n"
// " context.closePath();\n"
// " }\n"
// "\n"
// " var receivedTemperatures = " + String("[") + temperatures[0];
//
// for (int i = 1; i < n; i++) {
// htmlCode += String(",") + temperatures[i];
// }
//
// htmlCode += "];\n"
// " drawChart(receivedTemperatures);\n"
// " </script>\n"
// "</body>\n"
// "</html>";
//
// return htmlCode;
//}
#include <Arduino.h>
String generateHTMLChart(float data[], int n, const char* chartId, const char* chartColor, const char* xLabel, const char* yLabel) {
String htmlCode = "<script>\n"
" function drawChart(data, chartId, chartColor, xLabel, yLabel) {\n"
" var canvas = document.getElementById(chartId);\n"
" var context = canvas.getContext('2d');\n"
"\n"
" var chartWidth = canvas.width;\n"
" var chartHeight = canvas.height;\n"
"\n"
" var n = data.length;\n"
" var barWidth = chartWidth / (n - 1);\n"
" var maxValue = Math.max.apply(null, data);\n"
"\n"
" // Dessiner l'axe y\n"
" context.beginPath();\n"
" context.moveTo(40, 0);\n"
" context.lineTo(40, chartHeight);\n"
" context.strokeStyle = '#000';\n"
" context.lineWidth = 2;\n"
" context.stroke();\n"
" context.closePath();\n"
"\n"
" // Dessiner l'axe x\n"
" context.beginPath();\n"
" context.moveTo(40, chartHeight);\n"
" context.lineTo(chartWidth, chartHeight);\n"
" context.stroke();\n"
" context.closePath();\n"
"\n"
" context.font = '12px Arial';\n"
" context.fillStyle = '#000';\n"
" context.fillText(yLabel, 10, 10);\n"
" context.fillText(xLabel, chartWidth - 40, chartHeight + 15);\n"
"\n"
" context.beginPath();\n"
" context.moveTo(40, chartHeight - data[0] * chartHeight / maxValue);\n"
"\n"
" for (var i = 1; i < n; i++) {\n"
" var x = i * barWidth + 40;\n"
" var y = chartHeight - data[i] * chartHeight / maxValue;\n"
" context.lineTo(x, y);\n"
" }\n"
"\n"
" context.strokeStyle = chartColor;\n"
" context.lineWidth = 2;\n"
" context.stroke();\n"
" context.closePath();\n"
" }\n"
"</script>\n"
"\n"
"<canvas id='" + String(chartId) + "' width='600' height='300'></canvas>\n"
"\n"
"<script>\n"
" var " + String(chartId) + "Data = " + String("[") + data[0];
for (int i = 1; i < n; i++) {
htmlCode += String(",") + data[i];
}
htmlCode += "];\n"
" drawChart(" + String(chartId) + "Data, '" + String(chartId) + "', '" + String(chartColor) + "', 'Temps', 'Valeurs');\n"
"</script>\n";
return htmlCode;
}