1230 lines
35 KiB
C++
1230 lines
35 KiB
C++
//#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ê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ê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é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);
|
||
}
|