#include <LiquidCrystal_I2C.h> // Bibliothèque pour l'écran LCD fonctionnant avec I2C.
LiquidCrystal_I2C lcd(0x27, 20, 4); // Définitions des paramètres de lcd 2004 à l'adresse 0x27.
LiquidCrystal_I2C lcd1(0x26, 20, 4); // Définitions des paramètres de lcd1 2004 à l'adresse 0x26.
unsigned long currentTime = 0; // Variable utilisée pour récupérer la valeur de millis()
unsigned long previousTime = 0; // Variable utilisée pour stocker la valeur de millis() pour le prochain "loop"
// valeurs du temps de départ
long TempsEcoule, Milliseconde, heure, minute, seconde ;
const int buzzer = 13; // Buzzer relié à la broche 13
// DÉCLARATION DES BOUTONS POUSSOIRS
const int btn_StartStop = 2; bool etat_btn_StartStop, etat_BoutonAppuyer, etat_ChronoOnOFF;
const int btn_Reset = 3; bool etat_btn_Reset;
const int btn_Mute = 4; bool etat_btn_Mute, etat_Mute;
const int btn_TimeOn = 5; bool etat_btn_TimeOn;
const int btn_TimeOff = 6; bool etat_btn_TimeOff;
const int btn_Set = 7; bool etat_btn_Set;
const int SSR_relais = 12; bool etat_SSRrelais = LOW;
bool FlagON = false;
char Chrono[20], TimeOn[20], TimeOff[20],MinuteurON[20], MinuteurOFF[20];
long onTime, offTime;
long MyTimeON, H_ON = 0, M_ON = 0, S_ON = 0, MS_ON = 0;
long MyTimeOFF, H_OFF = 0, M_OFF = 0, S_OFF = 0, MS_OFF = 0;
long minutes_OFF = 0, minutes_ON = 0;
// Tableaux de type String
String Start_Stop[] = {"START | RESET |", "STOP | RESET |" };
String Mute[] = {"OFF", "ON "};
String Mark[11] = {" ",
"**",
"****",
"******",
"********",
"**********",
"************",
"**************",
"****************",
"******************",
"********************"
};
int index = 0;
int Record, Start;
bool etatRecord = false;
void setup(void) { // Initialisation
lcd.init(); lcd.backlight(); // Initialisation de l'écran LCD, et active le rétroéclairage de l'écran LCD
lcd1.init(); lcd1.backlight(); // Initialisation de l'écran LCD1, et active le rétroéclairage de l'écran LCD1
lcdPrintCenter("Chronometre", 0); // écran de démarrage
lcd1PrintCenter("Minuteur Cyclique", 0); // écran de démarrage
lcd1.setCursor(0, 3); lcd1.print("Time ON | OFF | Set"); // écran de démarrage
Fn_Display();
pinMode(btn_StartStop, INPUT_PULLUP); // Assigne le mode ENTREE et résistance PULL UP
pinMode(btn_Reset, INPUT_PULLUP); // Assigne le mode ENTREE et résistance PULL UP
pinMode(btn_Mute, INPUT_PULLUP);
pinMode(btn_TimeOn, INPUT_PULLUP);
pinMode(btn_TimeOff, INPUT_PULLUP);
pinMode(btn_Set, INPUT_PULLUP);
pinMode(buzzer, OUTPUT); // Assigne le mode SORTIE à la broche 13.
pinMode(SSR_relais, OUTPUT); // Assigne le mode SORTIE à la broche 12
lcd.setCursor(0, 3); lcd.print(Start_Stop[0]);
lcd.setCursor(17, 3); lcd.print(Mute[0]);
}
void loop(void) {
Fn_Scan_Buttons(); // Fonction de balayage de l'état de tous les boutons poussoirs
///Fn_boutons();
Fn_Chronometre(); // Fonction de gestion du temps qui passe lorsque le chrono est à ON
} // fin de loop()
// fonction perso beep pour Émettre une tonalité de x kHz pendant x ms
void beep() {
if (!etat_Mute) {
tone(buzzer, 2500, 100); // Émet une tonalité de 2,5kHz pendant 100 ms
}
}
void tick() { // fonction perso pour Émettre une très brèvetonalité de 5kHz pendant 1 ms
if (!etat_Mute) {
tone(buzzer, 5000, 4); // Émet un son de 5 kHz pendant 1 ms
}
}
void Fn_Scan_Buttons() { //balayage de l'état de tous les boutons poussoirs
etat_btn_StartStop = digitalRead(btn_StartStop); // État Bouton Start/Stop
etat_btn_Reset = digitalRead(btn_Reset); // État Bouton Start/Stop
etat_btn_Mute = digitalRead(btn_Mute);
etat_btn_TimeOn = digitalRead(btn_TimeOn);
etat_btn_TimeOff = digitalRead(btn_TimeOff);
etat_btn_Set = digitalRead(btn_Set);
if (etat_btn_StartStop == LOW && etat_BoutonAppuyer == 0) { // Test pression bouton START/STOP
etat_BoutonAppuyer = 1; beep(); delay(500); // Evite l'effet rebond
etat_ChronoOnOFF = !etat_ChronoOnOFF; // Inverse l'état du chronomètre
lcd.setCursor(0, 3); lcd.print(Start_Stop[0]);
while (etat_btn_StartStop)etat_btn_StartStop = digitalRead(btn_StartStop); // fonction anti rebond
}
if (etat_btn_Reset == LOW && etat_ChronoOnOFF == 0 && etat_BoutonAppuyer == 0) { // Test pression bouton RESET
etat_BoutonAppuyer = 1; beep(); delay(500); // Evite l'effet rebond
seconde = 0; minute = 0; heure = 0; Milliseconde = 0; // Remet toutes les variables de temps à 0.
index = 0;
while (etat_btn_Reset)etat_btn_Reset = digitalRead(btn_Reset); // fonction anti rebond
Fn_Display(); // Mise à zéro du contenu de l'écran LCD
}
if (etat_btn_Mute == LOW ) {
tone(buzzer, 2500, 100); delay(500);
etat_Mute = !etat_Mute; // Inverse l'état Mute (ON/OFF)
lcd.setCursor(17, 3); lcd.print(Mute[etat_Mute]);
while (etat_btn_Mute)etat_btn_Mute = digitalRead(btn_Mute); // fonction anti rebond
}
if (etat_btn_TimeOn == LOW) { // Réglage du temps ON
minutes_ON = minutes_ON + 1; // Incrémente de 1 à chaque pression du bouton bleu.
if (minutes_ON > 59) { // si dépassement de 59, remet à 0.
minutes_ON = 0;
}
S_ON = minutes_ON; Fn_Display();
delay(10); // Délais de 10 ms entre chaque pression du bouton
// Empêche les rebonds des boutons poussoirs
while (etat_btn_TimeOn) etat_btn_TimeOn = digitalRead(btn_TimeOn);
}
if (etat_btn_TimeOff == LOW) { // Réglage du temps OFF
minutes_OFF = minutes_OFF + 1; //Incrémente de 1 à chaque pression du bouton jaune.
if (minutes_OFF > 59) { // si dépassement de 59, remet à 0.
minutes_OFF = 0;
}
S_OFF = minutes_OFF;
Fn_Display(); // Rafraîchi l'affichage.
delay(10); // Délais de 10 ms entre chaque pression du bouton
// Empêche les rebonds des boutons poussoirs
while (etat_btn_TimeOff) etat_btn_TimeOff = digitalRead(btn_TimeOff);
}
// Enregitrement des temps ON/OFF du minuteur
if (etat_btn_Set == LOW) {
Record = Record + 1; // Nombre de fois que le bouton gris est pressé.
if (Record == 1) { // S'il est égale à 1, exécute les instructions entre ses accolades.
lcd1.setCursor(17, 1); lcd1.print("SET");// Set indique que la valeur du temps ON est stocké.
onTime = minutes_ON; MyTimeON = onTime; S_ON = MyTimeON; // Enregistre les variables.
Fn_Display(); // Rafraîchi l'affichage.
}
if (Record == 2) { // S'il est égale à 2, exécute les instructions entre ses accolades.
lcd1.setCursor(17, 2); lcd1.print("SET"); // Set indique que la valeur du temps OFF est stocké.
offTime = minutes_OFF; MyTimeOFF = offTime; S_OFF = MyTimeOFF; // Enregistre les variables.
Fn_Display(); // Rafraîchi l'affichage.
etatRecord = true; // Confirme que les valeurs sélectionnées on été engeristrées.
delay(1000); // Délais de 1 secondes avant d'afficher les messages qui suivent...
lcd1.setCursor(14, 1); lcd1.print("Ready!"); // Ready! indique que le minuteur ON est programmé et prêt à être lancé.
lcd1.setCursor(14, 2); lcd1.print("Ready!"); // Ready! indique que le minuteur OFF est programmé et prêt à être lancé.
delay(1000);// Délais de 1 secondes avant d'afficher les messages qui suivent..
lcd1.setCursor(14, 1); lcd1.print("Relais");
lcd1.setCursor(14, 2); lcd1.print(" OFF "); // État actuel du relais. Prêt à être lancé avec le chronomètre (bouton rouge Start/Stop).
}
delay(10); // Délais de 10 ms entre chaque pression du bouton
// Empêche les rebonds des boutons poussoirs
while (etat_btn_Set) etat_btn_Set = digitalRead(btn_Set);
}
}
void Fn_Chronometre() {// Fonction pricipale de la gestion de l'horloge du chrono
// Incrémentation du compteur de chrono en utilisant la fonction millis()
currentTime = millis(); // Le temps courant = l'horloge interne en ms.
TempsEcoule = currentTime - previousTime; // Le temps écoulée = au temps courant - le temps précédant
previousTime = millis(); // nouveau temps précédant = l'horloge interne en ms.
// Fonction compteur d'incrémentation des variables Seconde, Minute, Heure
if (etat_ChronoOnOFF == 1) { // Si Etat_ChronoOnOff = true exécute le code entre {}.
lcd.setCursor(0, 3); lcd.print(Start_Stop[1]);
Milliseconde = Milliseconde + TempsEcoule; // Incrémentation des millisecondes
if (Milliseconde > 999) { // Si Milliseconde est supérieure à 999... (1000ms)
Milliseconde = Milliseconde - 1000; // ...Remise à 0 de la variable Milliseconde
seconde++; // Incrémentation de 1 seconde toutes les 1000 Millisecondes
index++; // Index de 0 à 10 pour le tableau nommé Mark[11].
tick(); // Émet un tic toutes les secondes
if (MyTimeON > 0) {
FlagON = true;//*****************
etat_SSRrelais = FlagON; // État du relais selon la valeur de FlagOn (On/OFF ou 1/0 ou true/false)
digitalWrite(SSR_relais, FlagON); // Mettre à jour le relais selon la valeur de FlagOn (On/OFF ou 1/0 ou true/false)
lcd1.setCursor(14, 2); lcd1.print(" ON ");
MyTimeON--;
S_ON = MyTimeON;
}
if ((MyTimeOFF > 0) && (MyTimeON == 0)) {
FlagON = false ;//**********************
lcd1.setCursor(14, 2); lcd1.print(" OFF ");
etat_SSRrelais = FlagON; // État du relais selon la valeur de FlagOn (On/OFF ou 1/0 ou true/false)
digitalWrite(SSR_relais, FlagON); // Mettre à jour le relais selon la valeur de FlagOn (On/OFF ou 1/0 ou true/false)
MyTimeOFF--; S_OFF = MyTimeOFF;
if ((MyTimeOFF == 0) && (MyTimeON == 0)) {
MyTimeON = onTime;
MyTimeOFF = offTime;
}
}
}
if (seconde > 59) { // Si Seconde est supérieure à 59... (60sec)
seconde = 0; // ...Remise à 0 de la variable Seconde
beep(); // Émet un beep par minute
minute++; // Incrémentation de 1 Minute toutes les 60 Secondes
}
if (minute > 59) { // Si Minute est supérieure à 59... (60 minutes)
minute = 0; // ...Remise à 0 de la variable Minute
heure++; // Incrémentation de 1 Heure toutes les 60 Minutes
}
}
if (etat_btn_StartStop == HIGH && etat_btn_Reset == HIGH) {
etat_BoutonAppuyer = 0; // réinitialise la variable "etat_BoutonAppuyer" à "0" cequi évite l'effet rebond
}
Fn_Display(); // Fonction principale d'Affichage en temps réel.
}
// fonction perso pour centrer le texte à afficher sur lcd.
void lcdPrintCenter(String text, int ligne) {
int len = text.length(); // défini la longeur de la variable text
lcd.setCursor((20 - len) / 2, ligne); // positionne le curseur au centre de la ligne choisie et soustrait la longeur du text à afficher
lcd.print(text); // affiche le text centré
}
// fonction perso pour centrer le texte à afficher sur lcd1.
void lcd1PrintCenter(String text, int ligne) {
int len = text.length(); // défini la longeur de la variable text
lcd1.setCursor((20 - len) / 2, ligne); // positionne le curseur au centre de la ligne choisie et soustrait la longeur du text à afficher
lcd1.print(text); // affiche le text centré
}
void Fn_Display() { // rafraîchi l'Affichage en temps réel toutes les secondes.
lcdPrintCenter(Mark[index], 2);
sprintf(MinuteurON, "T-ON: %02ld:%02ld", M_ON, S_ON); //Formate l'affichage.
sprintf(MinuteurOFF, "T-OFF: %02ld:%02ld", M_OFF, S_OFF); //Formate l'affichage.
sprintf(Chrono, "%02ld:%02ld:%02ld:%03ld ", heure, minute, seconde, Milliseconde ); //Formate l'affichage.
lcdPrintCenter(Chrono, 1); // Affiche le temps écoulé.
lcd1.setCursor(0, 1); lcd1.print(MinuteurON); // Afffiche le minuteur ON sur la 3e ligne du lcd.
lcd1.setCursor(0, 2); lcd1.print(MinuteurOFF);// Afffiche le minuteur OFF sur la 4e ligne du lcd.
if (index >= 10)index = 0;
}