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

1230 lines
35 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//#include <ArduinoJson.h>
#include <EEPROM.h>
#include <Ticker.h>
#include <ArduinoJson.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "style.h"
#include "js.h"
void tickA();
void tickB();
void blink();
Ticker timerA(tickA, 1000);
Ticker timerB(tickB, 1000);
#define MA 1
#define MB 0
const int LATITUDE = 47.726682;
const int LONGITUDE = -2.131774;
const int ANGLE_AZIMUT_MIN = 100;
const int ANGLE_AZIMUT_MAX = 260;
// A 14 heures : Hiver max 18 / Ete max 65
const int ANGLE_ALTITUDE_MIN = 20;
const int ANGLE_ALTITUDE_MAX = 65;
const int DECALAGE_GMT = 2;
const int NB_BOUCLE_FIN_WIFI = 30;
// Adresse de départ dans l'EEPROM pour stocker la variable
#define EEPROM_ADDRESS 0
#define MAX_TIME 30
struct To_Store {
int max_time[2];
int theorique_position[2];
int min[2] = {ANGLE_ALTITUDE_MIN, ANGLE_AZIMUT_MIN};
int max[2] = {ANGLE_ALTITUDE_MAX, ANGLE_AZIMUT_MAX};
float speed[2] {1.4, 1.4};
};
To_Store to_store;
// Time to sleep (in seconds):
const int sleepTimeS = 10;
const int LONGUEUR_UTILE[2] = {25, 25}; // cm
const int SPEED = 1.4; //cm/s
int positionAttendue[2];
// =======================
// WIFI
// =======================
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
// Your WiFi credentials.
// Set password to "" for open networks.
const char* ssid_m = "MOTORS";
const char* pass_m = "MOTORS";
const char* ssid = "Livebox-37cc";
const char* pass = "8A6060920A8A86896F770F2C47";
IPAddress local_IP(192, 168, 4, 22);
IPAddress gateway(192, 168, 4, 9);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer server(80);
unsigned long lastUpdateTime = 0;
unsigned long updateInterval = 1 /*5*/ * 60 * 1000; // 5 minutes en millisecondes
String currentTime = "";
String sunriseTime = "";
String sunsetTime = "";
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 3 /* Time ESP32 will go to sleep (in seconds) */
// =======================
// MOTOR
// =======================
bool motor_is_running[2] = {false, false};
String sens[2] = {"", ""};
int mmin = 0;
String error = "";
String date = "";
String heure = "";
// =======================
// SOLEIL
// =======================
#include <Ephem_Soleil.h>
double ha;
double az;
String lS, mS, cS;
int amplitudeHoraire = 5;
int minH = 0;
int maxH = 0;
int minM = 0;
int maxM = 0;
double minAz = 0;
double maxAz = 0;
double minHa = 0;
double maxHa = 0;
String tableau;
// PINS
#define RTC_CLOCK D6
#define RTC_DATA D7
#define RTC_RESET D8
#define PWMA D1 //5 //=D6 was D3
#define PWMB D2 //4 //=D7 was D4
#define PIN_DA D3 //0
#define PIN_DB D4 //2
#define PIN_LED 2
//#define PWMA 17 //=D6 was D3
//#define PWMB 18 //=D7 was D4
//#define PIN_DA 19
//#define PIN_DB 20
// =======================
// RTC
// =======================
// Load the virtuabotixRTC library
#include "virtuabotixRTC.h"
// Determine the pins connected to the module
// myRTC (clock, data, RST)
virtuabotixRTC myRTC (RTC_CLOCK, RTC_DATA, RTC_RESET);
// Lire les valeurs RTC
int year = 2024; //myRTC.year;
int month = 9; //myRTC.month;
int day = 7; //myRTC.dayofmonth;
int hours = 14; //myRTC.hours;
int minutes = 0; //myRTC.minutes;
int seconds = 0; //myRTC.seconds;
// TIME
unsigned long lastSyncMillis;
int getValueFromParam(String param_key);
void setup() {
// initialize digital pin LED_BUILTIN as an output.
Serial.begin(115200);
pinMode(PWMA, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(PIN_DA, OUTPUT);
pinMode(PIN_DB, OUTPUT);
// pinMode(PIN_LED, OUTPUT);
stop(MA);
stop(MB);
Serial.println("Motors initialized.");
delay(10);
// // Connectez-vous au réseau WiFi
// WiFi.begin(ssid, pass);
// Serial.println("Connexion au WiFi en cours.");
// int essai = 0;
// while (WiFi.status() != WL_CONNECTED && essai < 15) {
//// digitalWrite(PIN_LED, LOW);
//
// delay(1000);
// Serial.print(".");
//// digitalWrite(PIN_LED, HIGH);
//
// essai ++;
// }
Serial.println("");
Serial.println("Connecté au réseau WiFi");
Serial.println(WiFi.localIP());
Serial.print("Setting soft-AP configuration ... ");
Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP(ssid_m, pass_m) ? "Ready" : "Failed!");
//WiFi.softAP(ssid);
//WiFi.softAP(ssid, password, channel, hidden, max_connection)
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
// Définissez les gestionnaires pour les différentes URL
server.on("/", HTTP_GET, handleRoot);
server.on("/forward", HTTP_GET, handleForward);
server.on("/backward", HTTP_GET, handleBackward);
server.on("/stop", HTTP_GET, handleStop);
server.on("/reset", HTTP_GET, handleReset);
server.on("/setFinCourse", HTTP_GET, handleFinCourse);
server.on("/add", HTTP_GET, handleAdd);
server.on("/sub", HTTP_GET, handleSub);
server.on("/data", HTTP_GET, handleData);
server.on("/save", HTTP_POST, handleSave);
server.on("/settings", HTTP_GET, handleSettings);
server.on("/saveDate", HTTP_POST, handleSaveDate);
server.on("/setDate", HTTP_GET, handleSetDate);
server.on("/gotoPosition", HTTP_GET, handleGotoPosition);
// Démarrer le serveur
server.begin();
Serial.println("Serveur Web démarré");
lastSyncMillis = millis() - 5001;
// Initialisation de l'EEPROM
EEPROM.begin(sizeof(To_Store));
// Lire la valeur stockée dans l'EEPROM
EEPROM.get(EEPROM_ADDRESS, to_store);
for (int button = 0; button < 2; button ++) {
if (to_store.max_time[button] == 0) {
to_store.max_time[button] = MAX_TIME;
}
if (to_store.theorique_position[button] == 0) {
to_store.theorique_position[button] = 0;
}
if (to_store.min[button] < 0) {
to_store.min[button] = ANGLE_ALTITUDE_MIN;
}
if (to_store.max[button] < 0) {
to_store.max[button] = ANGLE_ALTITUDE_MAX;
}
}
///////////////////////////////////
// UPDATE OTA
///////////////////////////////////
// Port defaults to 8266
ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
ArduinoOTA.setHostname("ESP8266_MOTEUR_SOLAIRE");
// 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([]() {
Serial.println("Start");
});
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();
// After to set the entire information, comment the following line
// (seconds, minutes, hours, day of week, day of month, month, year)
// myRTC.setDS1302Time (0, 34, 18, 2, 7, 9, 2024);
}
void tickA() {
tick_button(MA);
}
void tickB() {
tick_button(MB);
}
void tick_button(int button)
{
if (motor_is_running[button]) {
Serial.print(button);
Serial.print(" ");
//Serial.println("La méthode est appelée toutes les 1 seconde !");
if (to_store.theorique_position[button] != positionAttendue[button]) {
if (sens[button] == "backward") {
to_store.theorique_position[button] --;
Serial.println("Backward is running " + String(to_store.theorique_position[button]));
}
else {
to_store.theorique_position[button] ++;
Serial.println("Forward is running " + String(to_store.theorique_position[button]));
}
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
}
if (to_store.theorique_position[button] == positionAttendue[button] || to_store.theorique_position[button] < 0 || to_store.theorique_position[button] > to_store.max_time[button]) {
Serial.println("Stop running " + String(button) + " " + String(to_store.theorique_position[button]) + " / " + String(to_store.max_time[button]));
stop(button);
// motor_is_running[button] = false;
}
}
myRTC.updateTime();
}
int boucle = 0;
void loop() {
// getJson();
ArduinoOTA.handle();
// Gérez les requêtes du serveur
server.handleClient();
if ((!motor_is_running[0] && !motor_is_running[1]) &&
(millis() - lastUpdateTime >= updateInterval || lastUpdateTime == 0)
) {
boucle ++;
blink();
myRTC.updateTime();
printTime();
// Lire les valeurs RTC
year = myRTC.year;
month = myRTC.month;
day = myRTC.dayofmonth;
hours = myRTC.hours;
minutes = myRTC.minutes;
seconds = myRTC.seconds;
// Valider les valeurs RTC
bool valid = validateRTC(year, month, day, hours, minutes, seconds);
if (!valid) {
year = 2024;
month = 8;
day = 3;
hours = 10;
minutes = 40;
seconds = 00;
myRTC.setDS1302Time (0, minutes, hours, 2, day, month, year);
}
lastSyncMillis = millis();
// "ha" est la hauteur du soleil au-dessu de l'horizon.
// "az" est l'azimut du soleil compté positivement dans le sens des aiguilles d'une motre à partir du Nord
posSoleil(
year, month, day,
hours, minutes, seconds,
DECALAGE_GMT, LATITUDE, LONGITUDE,
&ha, &az); // Même calcul que ci-dessus mais avec date et heure sous form d'entiers
Serial.println(" hauteur : " + String(ha, 1) + " azimut : " + String(az, 1));
//Serial.println("Glenac; lever, zenith et coucher : 19 m");
// if (true || ha < -4) {
// ESP.deepSleep(60 * 1000000L);
// }
//lmvSoleil("28/05/2021", 2, 0, LATITUDE, LONGITUDE, &lS, &mS, &cS, 19);
lmvSoleil(
year, month, day,
DECALAGE_GMT, 0,
LATITUDE, LONGITUDE,
&lS, &mS, &cS, 19);
int hlS = lS.substring(0, 2).toInt();
int mnlS = lS.substring(3, 5).toInt();
int hcS = cS.substring(0, 2).toInt();
int mncS = cS.substring(3, 5).toInt();
int hmS = mS.substring(0, 2).toInt();
int mnmS = mS.substring(3, 5).toInt();
double ignore;
posSoleil(
/*2021, 12, 21, */ year, month, day,
hlS, mnlS, 0,
DECALAGE_GMT, LATITUDE, LONGITUDE,
&minHa, &minAz); // Même calcul que ci-dessus mais avec date et heure sous form d'entiers
posSoleil(
/*2021, 12, 21, */ year, month, day,
hmS, mnmS, 0,
DECALAGE_GMT, LATITUDE, LONGITUDE,
&maxHa, &ignore); // Même calcul que ci-dessus mais avec date et heure sous form d'entiers
posSoleil(
/*2021, 12, 21, */ year, month, day,
hcS, mncS, 0,
DECALAGE_GMT, LATITUDE, LONGITUDE,
&ignore, &maxAz); // Même calcul que ci-dessus mais avec date et heure sous form d'entiers
amplitudeHoraire = (hcS * 60 + mncS) - (hlS * 60 + mnlS);
Serial.println("amplitudeHoraire : "
+ String(minH) + ":" + String(minM) + " "
+ String(maxH) + ":" + String(maxM) + " "
+ String(minAz) + " "
+ String(maxAz) + " amplitude=" + amplitudeHoraire);
//}
Serial.println(" lever : " + lS + " zenith : " + mS + " coucher : " + cS);
// if (to_store.theorique_position[MA] == -1) {
// retourEnZero(0);
// }
// if (to_store.theorique_position[MB] == -1) {
// retourEnZero(1);
// }
//
double ha_tmp;
double az_tmp;
tableau = "<table><tr>";
tableau += "<td>Heure</td>";
for (int h = 0; h <= 23; h++) {
tableau += "<td>" + String(h) + "</td>";
}
tableau += "</tr>";
for (int button = 0; button < 2; button ++) {
tableau += "<tr>";
tableau += "<td>Motor " + String(button) + "</td>";
for (int h = 0; h <= 23; h++) {
// for (int m = 0; m <= 50; m += 10) {
Serial.print("Calcul pour h="); Serial.println(h);
posSoleil(
year, month, day,
h, 0, 0,
DECALAGE_GMT, LATITUDE, LONGITUDE,
&ha_tmp, &az_tmp); // Même calcul que ci-dessus mais avec date et heure sous form d'entiers
tableau += "<td>" + String(calculatePosition(button, ha_tmp, az_tmp)) + "</td>";
blink();
}
tableau += "</tr>";
}
tableau += "</table>";
Serial.println("Fin de tableau");
if (lastUpdateTime == 0) {
to_store.theorique_position[MA] = to_store.max_time[MA];
to_store.theorique_position[MB] = to_store.max_time[MB];
retourEnZero(MA);
retourEnZero(MB);
}
else {
Serial.println("Calcul position pour heure " + heure + " hauteur=" + String(ha, 2) + " azimuth=" + String(az, 2));
int positionTogo = calculatePosition(MA, ha, az);
gotoPosition(MA, positionTogo);
positionTogo = calculatePosition(MB, ha, az);
gotoPosition(MB, positionTogo);
}
// Mettre à jour le temps de la dernière mise à jour
lastUpdateTime = millis();
if (boucle > NB_BOUCLE_FIN_WIFI) {
Serial.println("Wifi desactivé");
WiFi.forceSleepBegin();
}
}
timerA.update();
timerB.update();
// Serial.print("Go to sleep ");
// delay(20);
//
// ESP.deepSleep(3600 * 1000000L); // Infini
// WiFi.forceSleepBegin();
// if (boucle == 4) {
// WiFi.mode(WIFI_OFF);
// //updateInterval *= 10;
// }
}
void handleRoot() {
// Générer la page HTML avec CSS
String html = "<html><head>";
html += "<meta charset='UTF-8'>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += js;
// html += "<link type='text/css' rel='stylesheet' href='http://192.168.1.3:81/velux/velux.css'>";
// html += "<script src='http://192.168.1.3:81/velux/jquery.min.js'></script>";
// html += "<script src='http://192.168.1.3:81/velux/velux.js'></script>";
html += "<style>";
html += css;
html += "</style>";
html += "</head><body>";
html += "<h1>Controle AZIMUTH " + String(to_store.theorique_position[MA]) + "/" + String(to_store.max_time[MA]) + "</h1>";
html += "<h1>Controle HAUTEUR " + String(to_store.theorique_position[MB]) + "/" + String(to_store.max_time[MB]) + "</h1>";
html += "<h2>" + String(WiFi.softAPIP().toString()) + "</h2>";
html += "<h2>Date " + String(day) + "/" + String(month) + " " + heure + "</h2>";
html += "<h2>Levé " + String(lS) + " - couché " + String(cS) + "</h2>";
html += "<h2>Hauteur : " + String(ha) + " azimuth=" + String(az) + "</h2>";
html += "<div class='button' onclick='showNotification()'><form action='/settings' method='get'>";
html += "<input type='submit' value='Param&ecirc;tres'>";
html += "</form>";
html += "<form action='/setDate' method='get'>";
html += "<input type='submit' value='Date'>";
html += "</form></div>";
for (int button = 0; button < 2; button ++) {
html += "<ul class='buttons'>";
html += "<li class='button' onclick='showNotification()'><form action='/reset?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Reset'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/setFinCourse?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Set Bas'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/forward?button=" + String(button) + "' method='get'>";
// html += "<input type='hidden' id='time' name='time' value='" + String(to_store.max_time - to_store.theorique_position) + "'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Descendre'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/backward?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Monter'>";
html += "</form></li>";
html += "<li class='button' onclick='showNotification()'><form action='/stop?button=" + String(button) + "' method='get'>";
html += "<input type='input' hidden name='button' value='" + String(button) + "'>";
html += "<input type='submit' value='Arr&ecirc;ter'>";
html += "</form></li>";
html += "<li class='button'><button onclick='handleButtonClick(" + String(button) + ")'>Aller à</button></li>";
html += "</ul>";
}
if (error != "") {
html += "<p>" + error + "</p>";
}
html += tableau;
html += "<div id='notification' class='notification'></div>";
html += "</body></html>";
// Envoyer la page HTML au client
server.send(200, "text/html", html);
}
void handleReset() {
mmin = 0;
int button = getValueFromParam("button");
retourEnZero(button);
// to_store.theorique_position[button] = 0;
to_store.max_time[button] = LONGUEUR_UTILE[button];
to_store.theorique_position[button] = LONGUEUR_UTILE[button];
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleFinCourse() {
int button = getValueFromParam("button");
to_store.max_time[button] = to_store.theorique_position[button];
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleForward() {
int button = getValueFromParam("button");
positionAttendue[button] = to_store.max_time[button];
avance(button);
//Serial.println(readVcc());
Serial.println("avance fin");
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void avance(int button) {
stop(button);
error = "";
if (to_store.theorique_position[button] >= to_store.max_time[button]) {
error = "La position actuelle est maximale";
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
return;
}
motor_is_running[button] = true;
sens[button] = "forward";
Serial.println("avance " + String(button));
if (button == MA) {
digitalWrite(PWMA, HIGH);
digitalWrite(PIN_DA, HIGH);
timerA.start();
}
if (button == MB) {
digitalWrite(PWMB, HIGH);
digitalWrite(PIN_DB, HIGH);
timerB.start();
}
delay(200);
}
void recule(int button) {
stop(button);
error = "";
if (to_store.theorique_position[button] <= mmin) {
error = "La position actuelle est minimale";
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
return;
}
motor_is_running[button] = true;
sens[button] = "backward";
Serial.println("recule");
if (button == MA) {
digitalWrite(PWMA, HIGH);
digitalWrite(PIN_DA, LOW);
timerA.start();
}
if (button == MB) {
digitalWrite(PWMB, HIGH);
digitalWrite(PIN_DB, LOW); // turn the LED on (HIGH is the voltage level)
timerB.start();
}
delay(200);
//Serial.println(readVcc());
Serial.println("recule fin");
}
void handleBackward() {
int button = getValueFromParam("button");
positionAttendue[button] = 0;
recule(button);
// Vous pouvez ajouter ici le code pour traiter la vitesse comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleStop() {
Serial.println("Arrêt");
int button = getValueFromParam("button");
stop(button);
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleAdd() {
int button = getValueFromParam("button");
Serial.println("Arrêt");
stop(button);
to_store.max_time[button] ++;
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void handleData() {
// Création d'un objet JSON
StaticJsonDocument<200> jsonDoc;
jsonDoc["sensor"] = "temperature";
jsonDoc["value"] = 25.5;
// Conversion de l'objet JSON en chaîne JSON
String jsonString;
serializeJson(jsonDoc, jsonString);
// Configuration de la réponse HTTP
server.sendHeader("Content-Type", "application/json");
server.send(200, "application/json", jsonString);
}
void handleSub() {
int button = getValueFromParam("button");
Serial.println("Arrêt");
stop(button);
to_store.max_time[button] --;
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
// Vous pouvez ajouter ici le code pour gérer l'arrêt comme vous le souhaitez
// Rediriger vers la page principale après le traitement
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void stop(int button)
{
motor_is_running[button] = false;
sens[button] = "";
if (to_store.theorique_position[button] < 0) {
to_store.theorique_position[button] = 0;
}
if (to_store.theorique_position[button] > to_store.max_time[button]) {
to_store.theorique_position[button] = to_store.max_time[button];
}
if (button == MB) {
Serial.println("stop B");
digitalWrite(PWMB, LOW);
digitalWrite(PIN_DB, LOW);
timerB.stop();
}
if (button == MA) {
Serial.println("stop A");
digitalWrite(PWMA, LOW);
digitalWrite(PIN_DA, LOW);
timerA.stop();
}
delay(200);
// Serial.println("stop fin");
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------
String readVcc() {
// most exact output
uint16_t v = ESP.getVcc();
float_t v_cal = ((float) v / 1024.0f);
char v_str[10];
dtostrf(v_cal, 5, 3, v_str);
sprintf(v_str, "%s", v_str);
Serial.print("Tension lue ");
Serial.println(String(v_str));
return String(v_str); //ESP.getVcc() / 1024.0f; // Vcc in millivolts
}
int getValueFromParam(String param_key)
{
String message = "Number of args received:";
message += server.args();
for (int i = 0; i < server.args(); i++) {
message = message + ("Arg nº" + String(i) + " > ");
message = message + (server.argName(i) + ": ");
message = message + (server.arg(i) + "\n");
if (param_key.equals(server.argName(i))) {
Serial.println(message);
return String(server.arg(i)).toInt();
}
}
Serial.println(message);
return 0;
}
void printTime()
{
// Print the details in serial monitor
Serial.print
("Data "); // Call the routine that prints the day of the week
jourSemaine (myRTC.dayofweek);
Serial.print (", ");
date = (day < 10 ? "0" : "") + String(day) + "/"
+ (month < 10 ? "0" : "") + String(month)
+ "/" + String(year);
Serial.print (date);
heure = (hours < 10 ? "0" : "") + String(hours) + ":"
+ (minutes < 10 ? "0" : "") + String(minutes) + ":"
+ (seconds < 10 ? "0" : "") + String(seconds);
Serial.println(" Time " + heure); // Adds a 0 if the time value is <10
}
void handleGotoPosition() {
int button = getValueFromParam("button");
int value = getValueFromParam("value");
stop(button);
gotoPosition(button, value);
Serial.println("goto position " + String(button) + " value=" + value);
server.sendHeader("Location", "/");
server.send(302, "text/plain", "Redirection vers la page principale");
}
void retourEnZero(int button) {
Serial.println("retour en zero " + String(button));
to_store.theorique_position[button] = LONGUEUR_UTILE[button];
stop(button);
recule(button);
Serial.println("Fin retour en zero");
}
void gotoPosition(int button, int positionTogo) {
//Serial.println("gotoPosition " + String(button) + ' ' + String(positionTogo));
float real_positionTogo = positionTogo / to_store.max[button];
positionAttendue[button] = real_positionTogo;
if (to_store.theorique_position[button] != real_positionTogo) {
if (real_positionTogo > to_store.theorique_position[button]) {
avance(button);
}
else if (real_positionTogo < to_store.theorique_position[button]) {
recule(button);
}
}
}
int calculatePosition(int button, double ha, double az)
{
int position = 0;
if (button == MA) {
Serial.println("Calcul position min=" + String(to_store.min[MA]) + " max=" + String(to_store.max[MA]));
if ( az > 0) {
if (az <= to_store.min[MA]) {
position = 0;
}
else if (az > to_store.min[MA] && az <= to_store.max[MA]) {
position = map(az, to_store.min[MA], to_store.max[MA], 0, to_store.max_time[button]);
}
else if (az > to_store.max[MA]) {
position = to_store.max_time[button];
}
} else {
position = to_store.max_time[button] / 2;
}
Serial.println("Calcul position axe AZIMUTH az=" + String(az) + " minAz=" + String(to_store.min[MA]) + " maxAz=" + String(to_store.min[MA]) + " pos=" + String(position));
}
else {
//
Serial.println("Calcul position min=" + String(to_store.min[MB]) + " max=" + String(to_store.max[MB]));
int ha_loc = 90 - ha;
if ( ha > 0) {
if (ha <= to_store.min[MB] || az <= to_store.min[MA]) {
position = 0;
}
else if (ha > to_store.min[MB]) { // && ha <= to_store.max[MB]) {
position = map(ha, to_store.min[MB], to_store.max[MB], 0, to_store.max_time[button]);
}
else if (ha > to_store.max[MB] || az > to_store.max[MA]) {
position = 0; //to_store.max_time[button];
}
} else {
position = 0; //to_store.max_time[button] / 2;
}
Serial.println("Calcul position axe ALTITUDE ha=" + String(ha) + " ha_loc=" + String(ha_loc) + " az=" + String(az) + " minHa=" + String(to_store.min[MB]) + " maxHa=" + String(to_store.max[MB]) + " pos=" + String(position));
}
return position;
}
void jourSemaine (int day)
{
switch (day)
{
case 1:
Serial.print("Lundi");
break;
case 2:
Serial.print("Mardi");
break;
case 3:
Serial.print("Mercredi");
break;
case 4:
Serial.print("Jeudi");
break;
case 5:
Serial.print("Vendredi");
break;
case 6:
Serial.print("Samedi");
break;
case 7:
Serial.print("Dimanche");
break;
}
}
void handleSettings() {
String html = "<html>\
<head>\
<style>\
body {\
font-family: Arial, sans-serif;\
background-color: #f4f4f4;\
display: flex;\
justify-content: center;\
align-items: center;\
height: 100vh;\
margin: 0;\
}\
.form-container {\
background-color: #fff;\
padding: 20px;\
border-radius: 8px;\
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\
width: 600px;\
}\
h2 {\
color: #333;\
text-align: center;\
}\
.form-content {\
display: flex;\
justify-content: space-between;\
}\
.column {\
display: flex;\
flex-direction: column;\
width: 48%;\
}\
label {\
margin-bottom: 5px;\
font-weight: bold;\
color: #555;\
}\
input[type='text'] {\
padding: 10px;\
margin-bottom: 15px;\
border: 1px solid #ccc;\
border-radius: 4px;\
font-size: 16px;\
}\
input[type='submit'] {\
background-color: #28a745;\
color: white;\
border: none;\
padding: 10px;\
border-radius: 4px;\
cursor: pointer;\
font-size: 16px;\
margin-top: 10px;\
width: 100%;\
}\
input[type='submit']:hover {\
background-color: #218838;\
}\
</style>\
</head>\
<body>\
<div class=\"form-container\">\
<h2>Configuration</h2>\
<form action=\"/save\" method=\"POST\">\
<div class=\"form-content\">\
<div class=\"column\">\
<label for=\"max_time_MA\">MAX Time A :</label>\
<input type=\"text\" id=\"max_time_MA\" name=\"max_time_MA\" value=\"" + String(to_store.max_time[MA]) + "\">\
<label for=\"theorique_position_MA\">Position A :</label>\
<input type=\"text\" id=\"theorique_position_MA\" name=\"theorique_position_MA\" value=\"" + String(to_store.theorique_position[MA]) + "\">\
<label for=\"speed_MA\">Speed A :</label>\
<input type=\"text\" id=\"speed_MA\" name=\"speed_MA\" value=\"" + String(to_store.speed[MA]) + "\">\
<label for=\"min_MA\">MIN angle A :</label>\
<input type=\"text\" id=\"min_MA\" name=\"min_MA\" value=\"" + String(to_store.min[MA]) + "\">\
<label for=\"max_MA\">MAX angle A :</label>\
<input type=\"text\" id=\"max_MA\" name=\"max_MA\" value=\"" + String(to_store.max[MA]) + "\">\
</div>\
<div class=\"column\">\
<label for=\"max_time_MB\">MAX Time B :</label>\
<input type=\"text\" id=\"max_time_MB\" name=\"max_time_MB\" value=\"" + String(to_store.max_time[MB]) + "\">\
<label for=\"theorique_position_MB\">Position B :</label>\
<input type=\"text\" id=\"theorique_position_MB\" name=\"theorique_position_MB\" value=\"" + String(to_store.theorique_position[MB]) + "\">\
<label for=\"speed_MB\">Speed B :</label>\
<input type=\"text\" id=\"speed_MB\" name=\"speed_MB\" value=\"" + String(to_store.speed[MB]) + "\">\
<label for=\"min_MB\">MIN angle B :</label>\
<input type=\"text\" id=\"min_MB\" name=\"min_MB\" value=\"" + String(to_store.min[MB]) + "\">\
<label for=\"max_MB\">MAX angle B :</label>\
<input type=\"text\" id=\"max_MB\" name=\"max_MB\" value=\"" + String(to_store.max[MB]) + "\">\
</div>\
</div>\
<input type=\"submit\" value=\"Save\">\
</form>\
</div>\
</body>\
</html>";
server.send(200, "text/html", html);
}
void handleSave() {
if (server.hasArg("max_time_MA") && server.hasArg("max_time_MB")) {
to_store.max_time[MA] = String(server.arg("max_time_MA").c_str()).toInt();
to_store.max_time[MB] = String(server.arg("max_time_MB").c_str()).toInt();
to_store.theorique_position[MA] = String(server.arg("theorique_position_MA").c_str()).toInt();
to_store.theorique_position[MB] = String(server.arg("theorique_position_MB").c_str()).toInt();
to_store.min[MA] = String(server.arg("min_MA").c_str()).toInt();
to_store.max[MA] = String(server.arg("max_MA").c_str()).toInt();
to_store.min[MB] = String(server.arg("min_MB").c_str()).toInt();
to_store.max[MB] = String(server.arg("max_MB").c_str()).toInt();
to_store.cl[MA] = String(server.arg("speed_MA").c_str()).toFloat();
to_store.speed[MB] = String(server.arg("speed_MB").c_str()).toFloat();
// Sauvegarde des paramètres dans l'EEPROM
EEPROM.put(EEPROM_ADDRESS, to_store);
EEPROM.commit();
server.send(200, "text/plain", "Configuration saved");
} else {
server.send(400, "text/plain", "Invalid request");
}
}
void handleSetDate() {
// year, month, day,
String html = "<html>\
<head>\
<style>\
body {\
font-family: Arial, sans-serif;\
background-color: #f4f4f4;\
display: flex;\
justify-content: center;\
align-items: center;\
height: 100vh;\
margin: 0;\
}\
.form-container {\
background-color: #fff;\
padding: 20px;\
border-radius: 8px;\
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\
}\
h2 {\
color: #333;\
}\
form {\
display: flex;\
flex-direction: column;\
}\
label {\
margin-bottom: 5px;\
font-weight: bold;\
color: #555;\
}\
input[type='text'] {\
padding: 10px;\
margin-bottom: 15px;\
border: 1px solid #ccc;\
border-radius: 4px;\
font-size: 16px;\
}\
input[type='submit'] {\
background-color: #28a745;\
color: white;\
border: none;\
padding: 10px;\
border-radius: 4px;\
cursor: pointer;\
font-size: 16px;\
}\
input[type='submit']:hover {\
background-color: #218838;\
}\
</style>\
</head>\
<body>\
<div class=\"form-container\">\
<h2>Date</h2>\
<form action=\"/saveDate\" method=\"POST\">\
<label for=\"year\">Ann&eacute;e :</label>\
<input type=\"text\" id=\"year\" name=\"year\" value=\"" + String(year) + "\">\
<label for=\"month\">Mois :</label>\
<input type=\"text\" id=\"month\" name=\"month\" value=\"" + String( month) + "\">\
<label for=\"day\">Jour :</label>\
<input type=\"text\" id=\"day\" name=\"day\" value=\"" + String(day) + "\">\
<label for=\"hours\">Heures :</label>\
<input type=\"text\" id=\"hours\" name=\"hours\" value=\"" + String(hours) + "\">\
<label for=\"minutes\">Minutes :</label>\
<input type=\"text\" id=\"minutes\" name=\"minutes\" value=\"" + String(minutes) + "\">\
<input type=\"submit\" value=\"Enregistrer la date\">\
</form>\
</div>\
</body>\
</html>";
server.send(200, "text/html", html);
}
void handleSaveDate() {
myRTC.setDS1302Time (0,
String(server.arg("minutes").c_str()).toInt(),
String(server.arg("hours").c_str()).toInt(),
2,
String(server.arg("day").c_str()).toInt(),
String(server.arg("month").c_str()).toInt(),
String(server.arg("year").c_str()).toInt());
myRTC.updateTime();
printTime();
server.send(200, "text/plain", "Date saved");
}
bool validateRTC(int year, int month, int day, int hour, int minute, int second) {
if (month < 1 || month > 12) return false;
if (day < 1 || day > 31) return false;
if (hour < 0 || hour > 23) return false;
if (minute < 0 || minute > 59) return false;
if (second < 0 || second > 59) return false;
// Vérification des jours dans le mois
if (month == 2) {
if (isLeapYear(year)) {
if (day > 29) return false;
} else {
if (day > 28) return false;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day > 30) return false;
}
return true;
}
bool isLeapYear(int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0) {
return true;
} else {
return false;
}
} else {
return true;
}
} else {
return false;
}
}
void blink()
{
digitalWrite(PIN_LED, HIGH);
delay(10);
digitalWrite(PIN_LED, LOW);
delay(10);
}