#include <OneButton.h>
#include <U8g2lib.h>
#include <Wire.h>
// Initialisation de l'écran OLED avec la bibliothèque U8G2
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const byte in1Pin = 4;
const byte in2Pin = 5;
const byte sleepPin = 6;
const byte buttonPin = 2;
const byte ledPin = 13;
const byte switchPin1 = 8;
const byte switchPin2 = 9;
const byte switchPin3 = 10;
const unsigned long seuilTemps = 1500;
const int buttonPinNL = 3; // Pin du bouton poussoir de la NavLight
const uint8_t NLledPin = 7; // Pin de la NavLight
// Variables pour stocker l'état du bouton et de la NavLight
int buttonState = 0;
int lastButtonState = 0; // Stocke l'état précédent du bouton
bool ledState = false; // Garde la trace de l'état actuel de la NavLight (allumée/éteinte)
// Pour l'anti-rebond du BP de la NavLight
unsigned long lastDebounceTime = 0; // Temps du dernier changement d'état du bouton
unsigned long debounceDelay = 50; // Délai pour éviter les rebonds (en millisecondes)
// Paramètres du pont diviseur de tension :
const float R1 = 4558; // Résistance 1 (4kΩ)
const float R2 = 992; // Résistance 2 (1kΩ)
// Pin pour la mesure de la tension :
const int voltagePin = A0;
// Résolution ADC de l'ESP32 :
const int ADC_RESOLUTION = 4095; // ADC 12 bits
const float REFERENCE_VOLTAGE = 3.3; // Tension de référence de l'ESP32 (3.3V)
// Variables pour le rafraîchissement sans delay()
unsigned long previousMillis2 = 0;
const long interval2 = 500; // Intervalle d'une seconde
OneButton bouton(buttonPin);
enum {moteurEtatArrete, moteurEtatDoitDemarrer, moteurEtatMarche, moteurEtatCycleArret, moteurEtatDoitArreter};
int moteurEtat = moteurEtatArrete;
// Les temporisations en millisecondes (2 minutes, 10 minutes, 30 minutes)
const unsigned long cycleDurations[] = {120000, 600000, 1800000}; // 2 minutes, 10 minutes, 30 minutes
unsigned long moteurMarcheTempo = cycleDurations[0];
unsigned long moteurMarcheMillis = 0;
void simpleClick() {
if (moteurEtat == moteurEtatArrete) {
Serial.println(F("Moteur doit demarrer"));
moteurEtat = moteurEtatDoitDemarrer;
} else {
Serial.println(F("Moteur deja en marche"));
}
}
void clickLong() {
Serial.println(F("Moteur cycle doit arreter"));
moteurEtat = moteurEtatCycleArret;
}
void updateCycleDuration() {
u8g2.setFont(u8g2_font_timB24_tf);
if (digitalRead(switchPin1) == LOW) {
moteurMarcheTempo = cycleDurations[0];
Serial.println(F("Cycle: 2 minutes"));
u8g2.drawStr(5, 46, " 2'");
} else if (digitalRead(switchPin2) == LOW) {
moteurMarcheTempo = cycleDurations[1];
Serial.println(F("Cycle: 10 minutes"));
u8g2.drawStr(5, 46, "10'");
} else if (digitalRead(switchPin3) == LOW) {
moteurMarcheTempo = cycleDurations[2];
Serial.println(F("Cycle: 30 minutes"));
u8g2.drawStr(5, 46, "30'");
}
}
void setup() {
Serial.begin(115200);
Wire.begin();
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_timB24_tf);
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
pinMode(sleepPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(switchPin1, INPUT_PULLUP);
pinMode(switchPin2, INPUT_PULLUP);
pinMode(switchPin3, INPUT_PULLUP);
pinMode(buttonPinNL, INPUT_PULLUP);
pinMode(NLledPin, OUTPUT);
digitalWrite(NLledPin, LOW); // On éteint la LED au départ
bouton.setPressMs(seuilTemps);
bouton.attachClick(simpleClick);
bouton.attachLongPressStop(clickLong);
moteurEtat = moteurEtatDoitArreter;
}
// Fonction pour lire la tension de la batterie
float lireTensionBatterie() {
int analogValue = analogRead(voltagePin); // Lire la valeur analogique de l'ESP32 (0 - 4095)
float voltageESP = (analogValue / (float)ADC_RESOLUTION) * REFERENCE_VOLTAGE; // Convertir la valeur analogique en tension (V)
float batteryVoltage = voltageESP * ((R1 + R2) / R2); // Calculer la tension réelle de la batterie en utilisant le pont diviseur de tension
return batteryVoltage;
}
// Fonction pour afficher la tension de la batterie sur l'écran OLED
void tensionBattery() {
float batteryVoltage = lireTensionBatterie();
u8g2.clearBuffer();
u8g2.setCursor(90, 64);
u8g2.print(batteryVoltage, 1);
u8g2.print(" V");
}
void loop() {
bouton.tick();
// Lecture de l'état actuel du bouton poussoir pour la NavLight
int reading = digitalRead(buttonPinNL);
// Vérification si l'état du bouton a changé par rapport à l'état précédent
if (reading != lastButtonState) {
// Reset du timer anti-rebond
lastDebounceTime = millis();
}
// Si le changement d'état est stable (le délai anti-rebond est écoulé)
if ((millis() - lastDebounceTime) > debounceDelay) {
// Si l'état du bouton a réellement changé
if (reading != buttonState) {
buttonState = reading;
// Si le bouton est pressé (LOW)
if (buttonState == LOW) {
// Inverser l'état de la LED
ledState = !ledState;
digitalWrite(NLledPin, ledState ? HIGH : LOW); // Allume ou éteint la LED
}
}
}
// Mémorisation de l'état actuel pour la prochaine vérification
lastButtonState = reading;
// Gestion des états du moteur et autres affichages
if (moteurEtat == moteurEtatArrete) {
Serial.println(F("Arret"));
u8g2.setFont(u8g2_font_timB10_tf);
//u8g2.drawStr(90, 10, "Arret");
unsigned long currentMillis2 = millis(); // Obtenir le temps actuel
// Si l'intervalle d'une seconde s'est écoulé
if (currentMillis2 - previousMillis2 >= interval2) {
previousMillis2 = currentMillis2; // Mettre à jour le temps
// Lire la tension de la batterie
tensionBattery();
}
updateCycleDuration();
}
if (moteurEtat == moteurEtatDoitDemarrer) {
u8g2.clearBuffer();
Serial.println(F("Marche"));
Serial.print(F("Durée du cycle: "));
Serial.print(moteurMarcheTempo / 60000);
Serial.println(F(" minutes"));
u8g2.setFont(u8g2_font_timB10_tf);
//u8g2.drawStr(80, 10, "Marche");
tensionBattery();
moteurMarcheMillis = millis();
moteurDemarrage();
moteurEtat = moteurEtatMarche;
}
if (moteurEtat == moteurEtatDoitArreter) {
Serial.println(F("Moteur Arret"));
moteurArret();
moteurEtat = moteurEtatArrete;
}
if (moteurEtat == moteurEtatCycleArret) {
Serial.println(F("Moteur Arret du cycle"));
moteurArret();
moteurEtat = moteurEtatDoitArreter;
}
if (moteurEtat == moteurEtatMarche) {
unsigned long currentMillis = millis();
unsigned long elapsed = currentMillis - moteurMarcheMillis;
unsigned long remaining = moteurMarcheTempo - elapsed;
static unsigned long lastUpdateMillis = 0;
if (remaining > 0) {
if (currentMillis - lastUpdateMillis >= 1000) {
lastUpdateMillis = currentMillis;
unsigned long remainingMinutes = remaining / 60000;
unsigned long remainingSeconds = (remaining % 60000) / 1000;
Serial.print(F("Temps restant: "));
Serial.print(remainingMinutes);
Serial.print(F("' "));
Serial.print(remainingSeconds);
Serial.println(F("''"));
char countdownBuffer[20];
snprintf(countdownBuffer, sizeof(countdownBuffer), "%lu' %02lu''", remainingMinutes, remainingSeconds);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_timB10_tf);
//u8g2.drawStr(80, 10, "Marche");
tensionBattery();
u8g2.setFont(u8g2_font_timB24_tf);
u8g2.drawStr(5, 46, countdownBuffer);
u8g2.sendBuffer();
}
}
if (elapsed >= moteurMarcheTempo) {
Serial.println(F("Moteur Fin cycle"));
moteurEtat = moteurEtatDoitArreter;
}
}
u8g2.sendBuffer();
}
void moteurDemarrage() {
digitalWrite(ledPin, HIGH);
digitalWrite(sleepPin, HIGH);
digitalWrite(in1Pin, HIGH);
digitalWrite(in2Pin, LOW);
}
void moteurArret() {
digitalWrite(ledPin, LOW);
digitalWrite(sleepPin, LOW);
digitalWrite(in1Pin, LOW);
digitalWrite(in2Pin, LOW);
}