Pour ne pas polluer je redémarre ici.
Le projet décrit ici de manière pédagogique (j espère) consiste à piloter un relais qui allume un ampli avec micro-controleur (un ESP32). Il faut gérer un bouton poussoir et un trigger en entrée et faire quelques babioles supplémentaires.
Cela correspond très exactement à mon tout premier projet avec Arduino! Quand je le regarde aujourdh'ui je me dis que ça mérite que j'y revienne et j'en profite pour faire de la pédagogie à mon humble niveau

Pour bien faire, il faut du hardware! J'ai donc monté un banc de test rapide sur une breadboard avec une carte de dév ESP32, un bouton poussoir et une led rouge qui simulera le relais et quelques fils. La led bleue sur la carte servira pour diverses infos. Le trigger est simulé par un fil (le rouge) en l'air (trigger absent) ou au 0V (trigger présent).

Schéma

Sur l'image le trigger est présent (fil branché sur 0V) et la led rouge est allumée

J'utilise une carte ESP32 S2 mini que j'avais sous la main (carte que je ne recommande pas : trop de soucis de reconaissance sous arduino. Les cartes ESP32 wroom ou ESP32-S3 sont mieux)
Les specs pour la V1:
- Un appui sur le bouton active le relais. L'appui suivant le désactive.
- La led embarquée bleue est allumée pendant l'appui sur le bouton.
- Le relais suit l'entrée trigger, ie trigger présent=>relais activé et inversement
- Le bouton poussoir gagne sur le trigger: un appui bouton coupe le relais même si le trigger est présent, ou active le relais même si le trigger est absent.
Pour information, on mesure aussi la durée d'appui sur le bouton et durée de la boucle.
voilà le code de la v1
Code : Tout sélectionner
/*
Programme de gestion d'un bouton et d'un trigger pour piloter un relais.
Sur mon banc de test,
- une led rouge simule le relais.
- l'entréee trigger est simulée par un fil au 0V
La led bleue embarquée est utilisée comme témoin.
v1 08 juin 2024
Un appui sur le bouton active le relais. L'appui suivant le désactive.
La led embarquée bleue est allumée pendant l'appui sur le bouton.
Le relais suit l'entrée trigger, ie trigger présent=>relais activé et inversement
Le bouton poussoir gagne sur le trigger: il coupe le relais même si le trigger est présent,
ou active le relais même si le trigger est absent.
Pour information, donne la durée d'appui sur le bouton et durée de la boucle.
*/
#define FWVERSION "v1" // version du programme, pour que je m'y retrouve dans les copies d'écran!
// GPIOs utilisés
#define LED_ESP 15 // led embarquée sur la carte ESP32-S2. Elle est sur GPIO 15
#define RELAY 5 // sortie relais sur GPIO 03
const int PushButton = 16; // entrée PushButton sur GPIO 16. (Cette fois c'est défini avec une constante)
#define TRIGGER 39 // entrée trigger sur GPIO 39
// déclaration et initialisation des variables globales
bool relayState = LOW; // état du relais. HIGH = activé, LOW = non activé
bool prevButtonState = HIGH; // état précédent du bouton pour permetttre
// de tester si l'état a changé. Initialisé HIGH, càd 'BP ouvert'.
bool prevTriggerState = HIGH; // état précédent du trigger. initialisé HIGH, càd 'Trigger absent'.
ulong timeButtonPressed; // timestamp quand bouton appuyé. En ms. Peut etre très grand => unsigned long
int maxLoopTime = 0; // durée max de la boucle loop() en micro secondes
// *********************** SETUP ***********************************
void setup() {
// LED_ESP et RELAY declarés comme Output.
pinMode(LED_ESP, OUTPUT); // pin HIGH : Led allumée
pinMode(RELAY, OUTPUT); // pin HIGH : Relais activé
// PushButton et Trigger déclarés comme Input avec résistance pullup.
pinMode(PushButton, INPUT_PULLUP); // pin LOW : Bouton appuyé
pinMode(TRIGGER, INPUT_PULLUP); // pin LOW : Trigger présent
digitalWrite(LED_ESP, HIGH); // allume la led pendant le setup
Serial.begin(115200); // démarre la sortie série
delay(1000); // attends 1sec que le port Série démarre (lent sur ma carte)
Serial.println("Version " + String(FWVERSION));
Serial.println("Prêt. Appuyer sur le bouton ou mettre le trigger.");
Serial.println();
digitalWrite(LED_ESP, LOW); // éteins la led à la fin du setup
}
// *********************** LOOP ***********************************
void loop() {
unsigned long timeStartLoop = micros(); // mémorise le timestamp au début de la boucle en microsecodnes
// pour pouvoir mesurer la durée de la boucle
// Gestion du BOUTON POUSSOIR
int buttonState = digitalRead(PushButton); // LOW quand appuyé, HIGH sinon
if (buttonState != prevButtonState) {
// le bouton vient de changer d'état
if (buttonState) {
// bouton vient de passer à HIGH (ouvert)
digitalWrite(LED_ESP, LOW); // éteins la led embarquée
int delayButtonPressed = millis() - timeButtonPressed; // délai pendant lequel il est est resté appuyé
Serial.print("Bouton relaché (durée appui: ");
Serial.print(delayButtonPressed);
Serial.println(" ms).");
Serial.println(); // saut ligne pour bien distinguer les appuis successifs
} else {
// bouton vient de passer à LOW (appuyé)
digitalWrite(LED_ESP, HIGH); // allume la led embarquée
relayState = !relayState; // mémorise que l'état de la sortie Relais est inversé
digitalWrite(RELAY, relayState); // maj pin sortie relais
timeButtonPressed = millis(); // mémorise le timestamp du début de l'appui du bouton
Serial.println("Bouton appuyé.");
}
prevButtonState = buttonState; // met l'état précédent à l'état courant pour le prochain test
}
// Gestion de l'entrée TRIGGER
int triggerState = digitalRead(TRIGGER); // LOW si Trigger présent, HIGH sinon
if (triggerState != prevTriggerState) {
// le trigger vient de changer d'état
relayState = !triggerState; // l'état de la sortie Relais suit l'état du trigger mais en inversé.
// Pin trigger LOW => pin sortie relais HIGH, et inversement.
digitalWrite(RELAY, relayState); // maj pin sortie relais (ce qui allume ou éteins la led rouge sur mon bench)
Serial.print("Le trigger est ");
if (triggerState) Serial.println("ABSENT"); else Serial.println("PRESENT");
prevTriggerState = triggerState; // mémorise l'état du trigger pour le prochain test
}
// Mesure de la durée max de la boucle
int loopTime = micros() - timeStartLoop; // durée boucle courante en micro secondes
if (loopTime > maxLoopTime) { // compare avec la durée max mémorisée
maxLoopTime = loopTime; // cette boucle est plus longue: elle devient la durée max
Serial.println("duréee max boucle: " + String(loopTime) + " micros.");
}
} // end loop
et ce que cela donne sur la sortie série en utilisant le bouton. Dabord normalement puis quelques fois en appuyant le plus furtivement possible.
Code : Tout sélectionner
18:19.753 -> Version v1
18:19.753 -> Prêt. Appuyer sur le bouton ou mettre le trigger.
18:19.753 ->
18:19.753 -> Le trigger est PRESENT <--- trigger présent au départ
18:19.753 -> duréee max boucle: 204 micros.
18:55.475 -> Bouton appuyé.
18:55.648 -> Bouton relaché (durée appui: 201 ms) <--- aucun rebond sur le bouton !
18:55.648 ->
18:55.648 -> duréee max boucle: 220 micros.
18:57.722 -> Bouton appuyé.
18:57.859 -> Bouton relaché (durée appui: 112 ms).
18:57.859 ->
19:01.206 -> Bouton appuyé.
19:01.381 -> Bouton relaché (durée appui: 146 ms).
19:01.381 ->
19:03.898 -> Bouton appuyé.
19:03.991 -> Bouton relaché (durée appui: 102 ms).
19:03.991 ->
19:05.894 -> Bouton appuyé.
19:05.939 -> Bouton relaché (durée appui: 72 ms).
19:05.939 ->
19:05.939 -> duréee max boucle: 288 micros.
19:07.325 -> Bouton appuyé.
19:07.361 -> Bouton relaché (durée appui: 37 ms).
19:07.361 ->
19:08.945 -> Bouton appuyé.
19:08.945 -> Bouton relaché (durée appui: 9 ms).
19:08.945 ->
19:11.326 -> Bouton appuyé.
19:11.359 -> Bouton relaché (durée appui: 26 ms).
Bon, c'est raté

je comptais me servir de cet exemple pour illustrer un phénomène de rebond (bouncing) qui se passe avec les boutons poussoir si on n'y prend pas garde mais ce BP fonctionne trop bien.
Heureusement le trigger est là ! Comme il s'agit d'une fiche à enfoncer ou à retirer dans la breadboard, le contact sera bien moins franc.
Voyons ce qui se passe si je retire et remets le trigger :
Code : Tout sélectionner
19:30.146 -> Le trigger est ABSENT <--- retrait trigger
19:30.146 -> Le trigger est PRESENT <--- 20 rebonds en 109ms !!!
19:30.222 -> Le trigger est ABSENT
19:30.222 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:30.255 -> Le trigger est PRESENT
19:30.255 -> Le trigger est ABSENT
19:45.000 -> Le trigger est PRESENT <--- remise trigger
19:45.000 -> Le trigger est ABSENT 12 rebonds en 89ms !!!
19:45.000 -> Le trigger est PRESENT
19:45.043 -> Le trigger est ABSENT
19:45.043 -> Le trigger est PRESENT
19:45.089 -> Le trigger est ABSENT
19:45.089 -> Le trigger est PRESENT
19:45.089 -> Le trigger est ABSENT
19:45.089 -> Le trigger est PRESENT
19:45.089 -> Le trigger est ABSENT
19:45.089 -> Le trigger est PRESENT
19:45.089 -> Le trigger est ABSENT
19:45.089 -> Le trigger est PRESENT
Là on voit bien que le programme lit 20 ou 12 changements d'états là ou je n'en voudrai qu'un seul.
Il faut faire un anti-rebond (debounce).
Tout ça pour justifier une V2

a suivre...