/*
GESTION DE l'OUVERTURE ET DE LA FERMETURE DU VERIN
- Le verin est ouvert dès que la température atteint 26°
VERSIONS
V001 - 03/03/2024
. Version initiale
*/
const String VERSION = "V001";
//===========================================================================================================
// BIBLIOTHEQUES
//===========================================================================================================
#include <Wire.h>
//#include <LiquidCrystal_I2C.h>
#include <RTClib.h> // Bibliothèque pour le module Horloge RTC DS1307
#include <avr/wdt.h> //Watchdog Timer pour reset automatique
//===========================================================================================================
// OBJETS
//===========================================================================================================
//LiquidCrystal_I2C lcd(0x27, 16, 2); //Afficheur LCD (16 colonnes, 2 lignes)
RTC_DS1307 RTC; //Horloge RTC
//===========================================================================================================
// CONSTANTES DE BASE
//===========================================================================================================
const int LED_ALLUMEE = HIGH;
const int LED_ETEINTE = LOW;
const int RELAIS_ALLUME = LOW;
const int RELAIS_ETEINT = HIGH;
const int BOUTON_APPUYE = LOW;
const int BOUTON_RELEVE = HIGH;
//===========================================================================================================
// VARIABLES PROGRAMME
//===========================================================================================================
//Leds
const int PIN_LED_JAUNE = 12; //Clignote pour indiquer que l'arduino tourne
const int PIN_LED_ROUGE = 10;
const int PIN_LED_BLEUE = 8;
//Boutons
const int PIN_BOUTON_SELECT = 9; //Jaune
const int PIN_BOUTON_PLUS = 7; //Bleu
const int PIN_BOUTON_MOINS = 11; //Rouge
//Relais
const int PIN_RELAIS_OUVRE_VERIN = 4; //Blanc
const int PIN_RELAIS_FERME_VERIN = 2; //Marron
//Adresses des données NVRAM stockées dans l'horloge RTC
const int ADRESSE_MAX_POSITION_VERIN = 0;
const int ADRESSE_CURRENT_POSITION_VERIN = 1;
const int ADRESSE_TEMPERATURE_OUVERTURE_VERIN = 2;
//Gestion de l'heure
DateTime xNowCourante;
int xHeureCourante = 0;
int xMinuteCourante = 0;
String xHeure = "00h00";
//Gestion du décompte global de la loop pour appeler le traitement principal
int xNbSecondesDecompteGlobal = 25;
int xIntervalleSecondesDecompteGlobal = 30;
//Gestion de l'état du verin
const String ETAT_VERIN_OUVERT = "Ouvert";
const String ETAT_VERIN_OUVERTURE = "Ouverture";
const String ETAT_VERIN_FERME = "Fermé";
const String ETAT_VERIN_FERMETURE = "Fermeture";
String xEtatVerin = ETAT_VERIN_FERME;
//Gestion de la position du verin (exprimée en secondes)
int xMaxPositionVerin = 15;
int xCurrentPositionVerin = 0;
//Gestion de l'état global (déterminé par le bouton jaune SELECT)
const String ETAT_GLOBAL_AUTO = "Auto";
const String ETAT_GLOBAL_VERIN_MANUEL = "Manuel";
const String ETAT_GLOBAL_POSITION_MAX = "Max verin";
const String ETAT_GLOBAL_TEMPERATURE_DECLENCHEMENT = "Température";
String xEtatGlobal = ETAT_GLOBAL_AUTO;
//Getion de la température
int xTemperatureOuvertureVerin = 26;
//==========================================================================================
// SETUP
//==========================================================================================
void setup()
{
//Initialsation des pins leds
pinMode(PIN_LED_JAUNE, OUTPUT);
pinMode(PIN_LED_ROUGE, OUTPUT);
pinMode(PIN_LED_BLEUE, OUTPUT);
//Initialsation des pins bouton
pinMode(PIN_BOUTON_SELECT, INPUT_PULLUP);
pinMode(PIN_BOUTON_PLUS, INPUT_PULLUP);
pinMode(PIN_BOUTON_MOINS, INPUT_PULLUP);
//Liaison série
Serial.begin(9600);
delay(100);
Serial.println("======= SETUP ====================================");
delay(100);
//Activation du reset automatique par le watchdog toutes les 8 secondes si l'arduino ne répond pas
wdt_enable(WDTO_8S);
//Initialisation des objets IC2
RTC.begin(); //Horloge
//Initialisation du module horloge RTC => A NE FAIRE QU'EN MODE DEVELOPPEMENT !
//DateTime dt = DateTime(__DATE__, __TIME__); RTC.adjust(dt);
//Extinction des leds
digitalWrite(PIN_LED_JAUNE, LED_ETEINTE);
digitalWrite(PIN_LED_ROUGE, LED_ETEINTE);
digitalWrite(PIN_LED_BLEUE, LED_ETEINTE);
//Extinction des relais
digitalWrite(PIN_RELAIS_OUVRE_VERIN, RELAIS_ETEINT);
digitalWrite(PIN_RELAIS_FERME_VERIN, RELAIS_ETEINT);
//Récupération des données stockées en RAM
xMaxPositionVerin = RTC.readnvram(ADRESSE_MAX_POSITION_VERIN);
xCurrentPositionVerin = RTC.readnvram(ADRESSE_CURRENT_POSITION_VERIN);
xTemperatureOuvertureVerin = RTC.readnvram(ADRESSE_TEMPERATURE_OUVERTURE_VERIN);
//Ajustements si nécessaires
if (xMaxPositionVerin == 0)
{
xMaxPositionVerin = 15;
RTC.writenvram(ADRESSE_MAX_POSITION_VERIN, xMaxPositionVerin);
Serial.println("- Ajustement RAM de xMaxPositionVerin à 15");
}
if (xTemperatureOuvertureVerin == 0)
{
xTemperatureOuvertureVerin = 26;
RTC.writenvram(ADRESSE_TEMPERATURE_OUVERTURE_VERIN, xTemperatureOuvertureVerin);
Serial.println("- Ajustement RAM de xTemperatureOuvertureVerin à 26");
}
//Affichage
Serial.println("- Valeurs récupérées en RAM : ");
Serial.print(" . xMaxPositionVerin = ");
Serial.println(xMaxPositionVerin);
Serial.print(" . xCurrentPositionVerin = ");
Serial.println(xCurrentPositionVerin);
Serial.print(" . xTemperatureOuvertureVerin = ");
Serial.println(xTemperatureOuvertureVerin);
//Initialisation de l'état de départ du verin
if (xCurrentPositionVerin > 0)
{
xEtatVerin = ETAT_VERIN_OUVERT;
digitalWrite(PIN_LED_BLEUE, LED_ALLUMEE);
}
else
{
xEtatVerin = ETAT_VERIN_FERME;
digitalWrite(PIN_LED_ROUGE, LED_ALLUMEE);
}
//Initialisation de l'état global de départ
xEtatGlobal = ETAT_GLOBAL_AUTO;
}
//==========================================================================================
// LOOP
//==========================================================================================
void loop()
{
//Réinitialisation du timer du watchdog
wdt_reset();
//Récupération de l'heure
xNowCourante = RTC.now();
xHeureCourante = xNowCourante.hour();
xMinuteCourante = xNowCourante.minute();
xHeure = "";
if (xHeureCourante < 10) xHeure += " ";
xHeure += String(xHeureCourante);
xHeure += "h";
if (xMinuteCourante < 10) xHeure += "0";
xHeure += String(xMinuteCourante);
//Clignotement de la led jaune pour signifier que tout est OK
digitalWrite(PIN_LED_JAUNE, LED_ALLUMEE);
delay(500);
digitalWrite(PIN_LED_JAUNE, LED_ETEINTE);
delay(500);
//Gestion des boutons
ManageBoutons();
//Traitement automatique
if (xEtatGlobal == ETAT_GLOBAL_AUTO)
{
//Décompte pour le déclenchement
xNbSecondesDecompteGlobal += 1;
int reste = xIntervalleSecondesDecompteGlobal - xNbSecondesDecompteGlobal;
//Affichage sur le moniteur
Serial.print(VERSION);
Serial.print(" - ");
Serial.print(xHeure);
Serial.print(" - ");
Serial.print(xEtatVerin);
Serial.print(" - Reste avant traitement automatique : ");
Serial.print(reste);
Serial.println(" secondes");
//Déclenchement du traitement toutes les x secondes
if (xNbSecondesDecompteGlobal >= xIntervalleSecondesDecompteGlobal)
{
ManageVerin();
xNbSecondesDecompteGlobal = 0;
}
}
//Autres états
else
{
//Affichage sur le moniteur
Serial.print(VERSION);
Serial.print(" - ");
Serial.print(xHeure);
Serial.print(" - ");
Serial.print(xEtatGlobal);
Serial.println(" - Appuyer sur les boutons PLUS ou MOINS");
//Raz du décompte
xNbSecondesDecompteGlobal = 0;
}
}
//-----------------------------------------------------------------------------------------------------------
// Gestion du verin
//-----------------------------------------------------------------------------------------------------------
void ManageVerin()
{
//Message
Serial.println("=> MANAGE VERIN");
//Ouverture ou fermeture
if (xEtatVerin == ETAT_VERIN_FERME)
{
OuvreVerin();
}
else
{
FermeVerin();
}
//Extinction des relais
digitalWrite(PIN_RELAIS_OUVRE_VERIN, RELAIS_ETEINT);
digitalWrite(PIN_RELAIS_FERME_VERIN, RELAIS_ETEINT);
}
//-----------------------------------------------------------------------------------------------------------
// Ouverture du verin
//-----------------------------------------------------------------------------------------------------------
void OuvreVerin()
{
//Si le verin n'est pas fermé, on sort
if (xEtatVerin != ETAT_VERIN_FERME)
{
Serial.print(" + Ouverture impossible dans l'état '");
Serial.print(xEtatVerin);
Serial.println("'");
return;
}
//Basculement en état d'ouverture
digitalWrite(PIN_LED_ROUGE, LED_ETEINTE);
xEtatVerin = ETAT_VERIN_OUVERTURE;
digitalWrite(PIN_RELAIS_OUVRE_VERIN, RELAIS_ALLUME);
//On boucle sur l'ouverture jusqu'à ce que la position soit au max
while(xCurrentPositionVerin < xMaxPositionVerin)
{
//Réinitialisation du timer du watchdog
wdt_reset();
//Clignotement de la led bleue pour signifier l'ouverture en cours
digitalWrite(PIN_LED_BLEUE, LED_ALLUMEE);
delay(500);
digitalWrite(PIN_LED_BLEUE, LED_ETEINTE);
delay(500);
//Ajustement et sauvegarde de la position courante
xCurrentPositionVerin += 1;
RTC.writenvram(ADRESSE_CURRENT_POSITION_VERIN, xCurrentPositionVerin);
//Message d'avancement
int reste = xMaxPositionVerin - xCurrentPositionVerin;
Serial.print(" . Ouverture en cours - Reste ");
Serial.print(reste);
Serial.println(" secondes");
}
//L'ouverture est terminée
Serial.println(" . Ouverture terminée");
xEtatVerin = ETAT_VERIN_OUVERT;
digitalWrite(PIN_LED_BLEUE, LED_ALLUMEE);
}
//-----------------------------------------------------------------------------------------------------------
// Fermeture du verin
//-----------------------------------------------------------------------------------------------------------
void FermeVerin()
{
//Si le verin n'est pas ouvert, on sort
if (xEtatVerin != ETAT_VERIN_OUVERT)
{
Serial.print(" + Fermeture impossible dans l'état '");
Serial.print(xEtatVerin);
Serial.println("'");
return;
}
//Basculement en état de fermeture
digitalWrite(PIN_LED_BLEUE, LED_ETEINTE);
xEtatVerin = ETAT_VERIN_FERMETURE;
digitalWrite(PIN_RELAIS_FERME_VERIN, RELAIS_ALLUME);
//On boucle sur l'ouverture jusqu'à ce que la position soit à 0
while(xCurrentPositionVerin > 0)
{
//Réinitialisation du timer du watchdog
wdt_reset();
//Clignotement de la led rouge pour signifier la fermeture en cours
digitalWrite(PIN_LED_ROUGE, LED_ALLUMEE);
delay(500);
digitalWrite(PIN_LED_ROUGE, LED_ETEINTE);
delay(500);
//Ajustement et sauvegarde de la position courante
xCurrentPositionVerin -= 1;
RTC.writenvram(ADRESSE_CURRENT_POSITION_VERIN, xCurrentPositionVerin);
//Message d'avancement
Serial.print(" . Fermeture en cours - Reste ");
Serial.print(xCurrentPositionVerin);
Serial.println(" secondes");
}
//L'ouverture est terminée
Serial.println(" . Fermeture terminée");
xEtatVerin = ETAT_VERIN_FERME;
digitalWrite(PIN_LED_ROUGE, LED_ALLUMEE);
}
//-----------------------------------------------------------------------------------------------------------
// Gestion des boutons
//-----------------------------------------------------------------------------------------------------------
void ManageBoutons()
{
ManageBoutonSelect();
ManageBoutonMoins();
ManageBoutonPlus();
}
//-----------------------------------------------------------------------------------------------------------
// Gestion du bouton SELECT (jaune)
//-----------------------------------------------------------------------------------------------------------
void ManageBoutonSelect()
{
//Si le bouton n'est pas appuyé, on sort
if (digitalRead(PIN_BOUTON_SELECT) != BOUTON_APPUYE)
{
return;
}
//Passage à l'état suivant
SwitchToNextState();
//Message
Serial.println("=> APPUI SUR LE BOUTON SELECT");
Serial.print(" . Nouvel état = ");
Serial.println(xEtatGlobal);
}
//-----------------------------------------------------------------------------------------------------------
// Changement d'état global
//-----------------------------------------------------------------------------------------------------------
void SwitchToNextState()
{
if (xEtatGlobal == ETAT_GLOBAL_AUTO)
{
xEtatGlobal = ETAT_GLOBAL_VERIN_MANUEL;
return;
}
if (xEtatGlobal == ETAT_GLOBAL_VERIN_MANUEL)
{
xEtatGlobal = ETAT_GLOBAL_POSITION_MAX;
return;
}
if (xEtatGlobal == ETAT_GLOBAL_POSITION_MAX)
{
xEtatGlobal = ETAT_GLOBAL_TEMPERATURE_DECLENCHEMENT;
return;
}
if (xEtatGlobal == ETAT_GLOBAL_TEMPERATURE_DECLENCHEMENT)
{
xEtatGlobal = ETAT_GLOBAL_AUTO;
return;
}
}
//-----------------------------------------------------------------------------------------------------------
// Gestion du bouton MOINS (rouge)
//-----------------------------------------------------------------------------------------------------------
void ManageBoutonMoins()
{
//Si on est en état automatique, on ne fait rien
if (xEtatGlobal == ETAT_GLOBAL_AUTO)
{
return;
}
//Si le bouton n'est pas appuyé, on sort
if (digitalRead(PIN_BOUTON_MOINS) != BOUTON_APPUYE)
{
return;
}
//Message
Serial.println("=> APPUI SUR LE BOUTON MOINS");
if (xEtatGlobal == ETAT_GLOBAL_VERIN_MANUEL)
{
Serial.println(" . Fermeture forcée du verin");
xCurrentPositionVerin = xMaxPositionVerin;
xEtatVerin = ETAT_VERIN_OUVERT;
FermeVerin();
return;
}
}
//-----------------------------------------------------------------------------------------------------------
// Gestion du bouton PLUS (bleu)
//-----------------------------------------------------------------------------------------------------------
void ManageBoutonPlus()
{
//Si on est en état automatique, on ne fait rien
if (xEtatGlobal == ETAT_GLOBAL_AUTO)
{
return;
}
//Si le bouton n'est pas appuyé, on sort
if (digitalRead(PIN_BOUTON_PLUS) != BOUTON_APPUYE)
{
return;
}
//Message
Serial.println("=> APPUI SUR LE BOUTON PLUS");
if (xEtatGlobal == ETAT_GLOBAL_VERIN_MANUEL)
{
Serial.println(" . Ouverture forcée du verin");
xCurrentPositionVerin = 0;
xEtatVerin = ETAT_VERIN_FERME;
OuvreVerin();
return;
}
}