Tout d'abord, je vous présente tous mes voeux pour cette nouvelle année.
Je viens demander de l'aide car je tourne en rond sur des boucles. Mon appareil est constitué d'un capteur (sonde de pH), de 2 boutons (branchés en pull-up interne) branchés sur une carte UNO.
J'étalonne le capteur avec 2 points de mesure (pH=7 et pH=4). A la fin de la procédure, je fais afficher la valeur du pH mesuré et demande à l'utilisateur s'il est content de son étalonnage ou non : s'il est content, le programme se poursuit sinon on réitère la procédure d'étalonnage.
Le choix de l'utilisateur se fait via les 2 boutons (ils fonctionnent correctement car la fonction etalonnage qui les utilise fonctionne parfaitement)
Avec ce code, j'arrive bien à l'écran qui me demande si l'étalonnage est bon mais le programme reste figé dessus, l'appui sur les boutons ne fait plus rien.
J'imagine que mon problème vient des boucles qui sont inadaptées ou pas correctement placées mais j'ai beau avoir fait plusieurs essais, je n'arrive pas à obtenir ce que je souhaite.
Le code de la fonction etalonnage qui effectivement modifie le valeur de testEtalonnage à l'issue de la procédure :
void etalonnage(byte valtampon) //fonction qui lance la procédure d'étalonnage du capteur
{
//Affichage sur LCD par fonction
affiche_texte_lcd(5, 0, "ETALONNAGE");
delay(1000);
affiche_texte_lcd(0, 1, "Plonger sonde dans");
affiche_texte_lcd(0, 2, "sol. tampon pH= ");
if (valtampon == 7)
affiche_texte_lcd(15, 2, "7");
else
affiche_texte_lcd(15, 2, "4");
affiche_texte_lcd(0, 3, "Appuyer ENTER si OK");
//temperature = readTemperature(); // mesure de la température via la fonction readTemperature dédiée
// on teste si le bouton ENTER est pressé
etatBoutonEnter = digitalRead(pinBoutonEnter); //si enter est presse etatBoutonEnter=LOW=0 car pin en mode pull up interne
if (etatBoutonEnter == LOW ) //si le bouton était précédemment non appuyé alors lastBoutonEnter=1=HIGH
{
testBoutonEnter = 1;
voltage = analogRead(PH_PIN) / 1024.0 * 5000; // read the voltage
phValue = ph.readPH(voltage, temperature); // convert voltage to pH with temperature compensation
ph.calibration(voltage, temperature, Enter); // on envoie la commande ENTEREC au module pour commencer la calibration
lcd.backlight();
lcd.clear();
affiche_texte_lcd(0, 0, "ETALONNAGE");
int i = 6;
while (i >= 0)
{
lcd.setCursor(0, 2);
lcd.print(F("Attendre "));
lcd.setCursor(9, 2);
lcd.print(i);
lcd.setCursor(10, 2);
lcd.print(F(" sec "));
delay(1000);
i = i - 1;
}
lcd.clear();
affiche_texte_lcd(5, 0, "ETALONNAGE");
affiche_texte_lcd(0, 2, "CAL pour valider ");
if (lastBoutonCal == HIGH) // on teste si Cal n'est pas appuyé après que le bouton Enter ait été appuyé
while (testBoutonEnter == 1)
{ // on teste si le bouton CAL est pressé --> si oui, on valide l'étalonnage
etatBoutonCal = digitalRead(pinBoutonCal); //on lit l'état du bouton Cal
if (etatBoutonCal == 0) //si le bouton Cal est pressé alors etatBoutonCal=LOW=0 car pin en mode pull up interne
{
//lcd.backlight();
lcd.clear();
ph.calibration(voltage, temperature, Cal); // calibration process by Serail CMD
//lcd.backlight();
affiche_texte_lcd(0, 0, "->Etalonnage reussi ");
affiche_texte_lcd(0, 1, "EXIT pour sauvegarde");
affiche_texte_lcd(0, 2, "et pour quitter ");
testBoutonCal = 1;
}
if (lastBoutonExit == HIGH) // Appui sur Exit après appui sur Enter
while (testBoutonCal == 1)
{
etatBoutonExit = digitalRead(pinBoutonExit);
if (etatBoutonExit == 0)
{
//lcd.backlight();
lcd.clear();
ph.calibration(voltage, temperature, Exit); // calibration process by Serail CMD
//lcd.backlight();
affiche_texte_lcd(0, 0, "->Etalonnage termine");
delay(1000);
lcd.clear();
testBoutonEnter = 0;
testBoutonCal = 0;
testEtalonnage = 1;
break;
}
}
}
}
else
{
etatBoutonCal = digitalRead(pinBoutonCal);
etatBoutonExit = digitalRead(pinBoutonExit);
if (etatBoutonExit > lastBoutonExit && etatBoutonCal == 0)
{
ph.calibration(voltage, temperature, Exit); // calibration process by Serail CMD
//lcd.backlight();
lcd.clear();
affiche_texte_lcd(0, 0, "->Etalonnage arrete");
delay(2000);
lcd.clear();
}
}
lastBoutonEnter = etatBoutonEnter;
lastBoutonCal = etatBoutonCal;
lastBoutonExit = etatBoutonExit;
}
Pour moi, testBoutonEnter n'est jamais mis à jour dans le code du while donc boucle infinie.
Erreur de ma part, je n'avais pas vu l'affectation un peu plus bas.
cette condition est vrai tant que les 2 boutons ne sont pas appuyés ensembles.
Toi, tu veux sortir si l'un des 2 est appuyé, il faut faire
while (etatBoutonEnter == HIGH && etatBoutonExit == HIGH )
Cette condition reste vrai tant qu'aucun des boutons n'a été appuyé
A noter, la lecture de l'état des boutons avant d'entrer dans le while peut empêcher d'entrer dans la boucle, si l'un des boutons est déjà appuyé. Il faut supprimer ces lignes et ne conserver que la lecture à l'intérieur de la boucle.
Si je ne me trompe pas, on appui sur exit en quittant etalonnage().
Il faudrait alors faire un
while(digitalRead(pinBoutonExit) == LOW);
avant d'entrer dans la boucle de validation pour être certain que le bouton a été relâché.
Si je change la boucle while (etatBoutonEnter != LOW || etatBoutonExit != LOW )
en while (etatBoutonEnter == HIGH && etatBoutonExit == HIGH )
soit je boucle infiniment sur l'étalonnage 4 (dès que je valide l'étalonnage 4, je reviens à l'étalonnage 4 sans rien toucher) si je supprime la lecture de l'état des boutons avant d'entrer dans la bouche while
soit j'arrive à l'écran qui demande si l'étalonnage est bon (à valider par l'utilisateur en pressant ENTER ou EXIT) mais où cela reste fixe, l'appui d'un bouton ne change rien
Oui parce que la touche exit est utilisée comme acceptation à la fin d'etalonnage() et dans la validation finale d'où l'ajout du test du relâchement du bouton pour ne pas sortir directement après etalonnage(). Par contre, il faut effectivement conserver la mise à jour de l'état des 2 boutons avant d'entrer dans le while.
Tu as des boucles imbriquées avec des variables qui définissent des états et qui sont réutilisées dans les différents blocs elles ne sont peut-être pas bien mise à jours. Peut-être utiliser des variables locales pour gérer ça.
Avec quelques Serial.print placés judicieusement dans ton code tu verrais mieux son déroulement.
En fait, il n'y avait plus de problème suite à tes remarques ! C'est tout simplement que j'ai oublié de supprimer l'affichage de la demande à l'utilisateur qui paraissait bloquer le programme alors que les mesures étaient bien faites.
while (EtalonnageValide == 0)
{
while (testEtalonnage == 0)
{
etalonnage(7);
}
testEtalonnage = 0;
while (testEtalonnage == 0)
{
etalonnage(4);
}
etatBoutonEnter = digitalRead(pinBoutonEnter); //si enter est presse etatBoutonEnter=LOW=0 car pin en mode pull up interne
etatBoutonExit = digitalRead(pinBoutonExit); //si enter est presse etatBoutonEnter=LOW=0 car pin en mode pull up interne
while (etatBoutonEnter == HIGH && etatBoutonExit == HIGH )
{
mesure_simple();
affiche_texte_lcd(0, 0, "Etalonnage bon ?");
affiche_texte_lcd(0, 1, "oui --> EXIT");
affiche_texte_lcd(0, 2, "non --> ENTER");
//delay(2000);
etatBoutonEnter = digitalRead(pinBoutonEnter); //si enter est presse etatBoutonEnter=LOW=0 car pin en mode pull up interne
etatBoutonExit = digitalRead(pinBoutonExit); //si enter est presse etatBoutonEnter=LOW=0 car pin en mode pull up interne
if (etatBoutonEnter == LOW) //si le bouton était précédemment non appuyé alors lastBoutonEnter=1=HIGH
{
EtalonnageValide = 0;
testEtalonnage = 0;
lcd.clear();
}
//delay(5000);
if (etatBoutonExit == LOW) //si le bouton était précédemment non appuyé alors lastBoutonEnter=1=HIGH
{
EtalonnageValide = 1;
lcd.clear();
}
}
}