Merci pour vos remarques,
J’avais lu quelques sujets au sujet des rebonds mais je ne m’y étais pas attardé et dans mon programme, j’ai résolu le problème en mettant un délai de 10ms. en fin de loop. si j’appuie de manière courte sur les boutons, j’incrémente facilement les unités et si je reste un peu trop longtemps appuyé, effectivement, j’en incrémente 2 ou 3 en même temps avec une possibilité de corriger avec le bouton voisin. Et si j’ai besoin d’aller de 20 à 100 cela ne me prend 7 secondes.
Je ne pense pas que mes boutons aient un dispositif anti-rebond cependant, ils sont neufs et réactifs. En vieillissant, des problèmes peuvent peut-être survenir.
En prenant conscience de vos remarques, j’ai lu cahiers-pratiques/gerer-rebonds-interrupteur et le tuto de pandaroux sur ce forum. Mais je n’ai rien trouvé sur l’utilisation de la bibliothèque Toggle.
J’y suis donc allé à tâtons pour écrire ce nouveau code en essayant d’utiliser Toggle.
#include <OneWire.h>
//#include <SPI.h> // dans certaines configurations, les capteurs utilisent SPI pour communiquer, SPI travaille avec Adafruit MAX31855
#include "Adafruit_MAX31855.h" // j'inclue Adafruit_MAX31855 pour gérer les thermocouples
#include <LiquidCrystal_I2C.h> // J'inclue LiquidCrystal-I2C pour gérer le LCD
#include <Toggle.h> // j'inclue Toggle pour gérer le bouton silence
LiquidCrystal_I2C lcd(0x27, 20, 5); // adresse du LCD i2c , nombre de colonnes, nombre de lignes de l'écran
#define MAXDO 2 // sortie DO du Max 31855
#define MAXCS 3 // sortie CS " " " "
#define MAXCLK 4 // sortie CLK " " " "
#define MAXCS2 5 // sortie CS 2 " " "
const int pinbtn1 = 6, pinbtn2 = 7, pinbtn3 = 8, pinbtn4 = 9, pinbuzzer = 10, pinledfourH = 11 , pinledfourB = 12, pinledfeu = 13, pinBoutonSilence = A0, pinLedSilence = A1 ; // le bouton n°1 est relié en broche 6 , ...
Toggle boutonSilence(pinBoutonSilence); //création d'une variable nommée bouton Silence, du type Toggle, qui est initialisée en utilisant le N° de la broche pinBoutonSilence (13)
Toggle btn1(pinbtn1);
Toggle btn2(pinbtn2);
Toggle btn3(pinbtn3);
Toggle btn4(pinbtn4);
int seuil_fourbas = 21; // 21° seuil de la sonde four - Basse (pour l'expérimentation) qui s'affiche lors de la réinitialisation, elle peut être incrémentée.
int seuil_fourhaut = 23; // 23° seiol de la sonde four - Haute (pour l'expérimentation) qui s'affiche lors de la réinitialisation, elle peut être incrémentée.
int seuil_feu = 25; // 25° seuil de la sonde placée en haut du conduit fumée pour détecter un incendie de cheminée (ne pourra pas s'incrémenter)
Adafruit_MAX31855 thermocouple1(MAXCLK, MAXCS, MAXDO); // création d'une variable nommée thermocouple1, du type Adafruit_MAX31855 , qui est initialisée en utilisant les N° des broches qui concernent le thermocouple 1
Adafruit_MAX31855 thermocouple2 (MAXCLK, MAXCS2, MAXDO); // création d'une variable nommée thermocouple2, du type Adafruit_MAX31855 , qui est initialisée en utilisant les N° des broches qui concernent le thermocouple 2
enum : uint8_t {AUCUNE_ALARME = 0, ALARME_FOUR_H = 1, ALARME_FOUR_B = 2, ALARME_FEU = 4};
uint8_t alarmesEnCours = AUCUNE_ALARME;
void setup() {
lcd.init(); // active le LCD
lcd.backlight(); // active le rétroéclairage
pinMode (pinbuzzer, OUTPUT) ; digitalWrite(pinbuzzer, LOW); // active la sortie 13 du buzzer
pinMode (pinledfourH, OUTPUT) ; digitalWrite(pinledfourH, LOW); // active la sortie 11 de la led alarme four Haut
pinMode (pinledfourB, OUTPUT) ; digitalWrite(pinledfourB, LOW); // active la sortie 11 de la led alarme four Bas
pinMode (pinledfeu, OUTPUT) ; digitalWrite(pinledfeu, LOW); // active la sortie 12 de la led alarme feu
pinMode (pinLedSilence, OUTPUT) ; digitalWrite(pinLedSilence, LOW); // active la sortie A1 de la led silence
boutonSilence.begin(pinBoutonSilence);
btn1.begin(pinbtn1);
btn2.begin(pinbtn2);
btn3.begin(pinbtn3);
btn4.begin(pinbtn4);
Serial.begin(115200);
Serial.println("PRET");
delay(1000); // pour stabiliser la lecture
}
void loop() {
double cfour = thermocouple1.readCelsius(); // Lecture en degrés Celcius du capteur 1
double cfeu = thermocouple2.readCelsius(); // Lecture en degrés Celcius du capteur 2
btn1.poll();
if (btn1.onPress()) { // si le bouton est appuyé on rentre dans ce if
seuil_fourbas--; // deg-- est équivalent à deg = deg -1 ;
}
btn2.poll();
if (btn2.onPress()) {
seuil_fourbas++;
}
btn3.poll();
if (btn3.onPress()) {
seuil_fourhaut--;
}
btn4.poll();
if (btn4.onPress()) {
seuil_fourhaut++;
}
//void animations() {
static bool modeSilence = false; // Variable persistante conservant l’état du mode silence entre deux appels de la fonction.
static uint32_t debutModeSilence = 0; // Instant, en millisecondes depuis le démarrage, auquel le mode silence a été activé.
static const uint32_t dureeModeSilence = 10000ul; // définition d'une constante pour la durée maximale du mode silence en millisecondes.
boutonSilence.poll();
if (boutonSilence.onPress()) { // si le bouton est appuyé on rentre dans ce if
modeSilence = not modeSilence; // Inversion explicite de l’état du mode silence à chaque appui.
digitalWrite(pinLedSilence, modeSilence ? HIGH : LOW); // La LED reflète directement l’état logique du mode silence. on interroge l'état du mode silence, s'il est "true" la pinledSilence devient HIGH sinon on retourne LOW ???
/*static uint32_t chrono = 0; // Référence temporelle persistante utilisée pour cadencer le clignotement….(le compteur est relevé)
if (millis() - chrono >= 100) { // Inversion de l’état de la LED toutes les 100 ms, ce qui fixe la fréquence de clignotement.
digitalWrite(pinLedSilence, digitalRead(pinLedSilence) == HIGH ? LOW : HIGH); // la led HP clignote… l'écriture de cette fonction s'appelle l'opérateur ternaire elle Inverse l'état en sortie pinLedHP… si pinLedHP est HIGH alors retourne LOW sinon retourne HIGH …on pourrait l'écrire digitalWrite(pinLedHP, !(digitalRead(pinLedHP)));
chrono = millis();
}*/
if (modeSilence) debutModeSilence = millis(); // Mémorisation de l’instant d’activation pour mesurer la durée écoulée.
}
if (modeSilence && millis() - debutModeSilence >= dureeModeSilence) { // si la durée maximale du mode silence est dépassée.(si le compteur continue moins le compte relevé au début du MS est supérieur ou égal à 10 secondes (dureeModeSilence) )
modeSilence = false; // le mode silence devient faux (est désactivé… le buzzer sonne.
digitalWrite(pinLedSilence, LOW); // et la led silence s'éteint
}
//**************************************************************
if (cfour >= seuil_fourhaut) { // si la dernière température du capteur four est supérieure à son seuil haut
static uint32_t chrono = 0; // Référence temporelle persistante utilisée pour cadencer le clignotement….(le compteur est relevé)
if (millis() - chrono >= 100) { // Inversion de l’état de la LED toutes les 100 ms, ce qui fixe la fréquence de clignotement.
digitalWrite(pinledfourH, digitalRead(pinledfourH) == HIGH ? LOW : HIGH); // la led HP clignote… l'écriture de cette fonction s'appelle l'opérateur ternaire elle Inverse l'état en sortie pinLedHP… si pinLedHP est HIGH alors retourne LOW sinon retourne HIGH …on pourrait l'écrire digitalWrite(pinLedHP, !(digitalRead(pinLedHP)));
chrono = millis(); // on se souvient du moment de la dernière inversion
}
alarmesEnCours |= ALARME_FOUR_H; // Activation du bit correspondant à l’alarme HP sans modifier les autres bits. |= est un OU bit à bit
} else { // sinon
digitalWrite(pinledfourH, LOW); // la led HP n'est pas alimentée
alarmesEnCours &= ~ALARME_FOUR_H; // Effacement du bit ALARME_HP par masquage binaire, les autres alarmes restent inchangées.
}
//**************************************************************
if (cfour <= seuil_fourbas) { // si la dernière température du capteur four est inférieure à son seuil bas
static uint32_t chrono = 0;
if (millis() - chrono >= 100) {
digitalWrite(pinledfourB, digitalRead(pinledfourB) == HIGH ? LOW : HIGH);
chrono = millis();
}
alarmesEnCours |= ALARME_FOUR_B;
} else {
digitalWrite(pinledfourB, LOW);
alarmesEnCours &= ~ ALARME_FOUR_B;
}
//**************************************************************
if (cfeu >= seuil_feu) { // si la dernière température du capteur feu est supérieure à son seuil
static uint32_t chrono = 0;
if (millis() - chrono >= 100) {
digitalWrite(pinledfeu, digitalRead(pinledfeu) == HIGH ? LOW : HIGH);
chrono = millis();
}
alarmesEnCours |= ALARME_FEU;
} else {
digitalWrite(pinledfeu, LOW);
alarmesEnCours &= ~ALARME_FEU;
}
//********************************************************************
if (not modeSilence && alarmesEnCours != AUCUNE_ALARME) {
// une alarme au moins est en cours et on n'est pas en mode silence
static uint32_t chrono = 0;
if (millis() - chrono >= 300) {
digitalWrite( pinbuzzer, digitalRead(pinbuzzer) == HIGH ? LOW : HIGH);
chrono = millis();
}
}
else
{
digitalWrite(pinbuzzer, LOW);
}
//Configuration du LCD
lcd.setCursor(4, 0); // sur la première colone de la quatrième ligne
lcd.print("Seuil bas = ");
lcd.print (seuil_fourbas); // le LCD imprime la valeur du seuil bas que l'on peut incrémenter
lcd.print((char)223);
lcd.setCursor(0, 1); // sur la première colone de la deuxième ligne
lcd.print("T");
lcd.print((char)223);
lcd.print("FOUR ");
lcd.print(cfour); // on imprime la température captée par le thermocouple du four // on imprime la température captée par le thermocouple du conduit de cheminée
lcd.setCursor(4, 2); // sur la première colone de la cinquième ligne
lcd.print("Seuil haut = ");
lcd.print (seuil_fourhaut); // le LCD imprime la valeur du seuil haut que l'on peut incrémenter
lcd.print((char)223);
lcd.setCursor(0, 3); // sur la première colone de la troisième ligne
lcd.print("T");
lcd.print((char)223);
lcd.print("CONDUIT ");
lcd.print(cfeu);
Serial.print ("alarmesEnCours") ; Serial.println(alarmesEnCours) ;
Serial.print ("T° FOUR") ; Serial.println(cfour) ;
Serial.print ("T° CONDUIT") ; Serial.println(cfeu) ;
}
Le code fonctionne, il faut appuyer environ une seconde sur un bouton pour incrémenter puis l’appui n’a plus d’effet donc, il n’y a pas de risque de rebond.
Cependant, l’appui long ne fonctionne pas.
Il y a certainement un moyen d’incrémenter rapidement sans rebond mais je n’ai pas trouvé.