Dans le programme que j'ai créé, il y a deux 2 fonctions différentes mais utilisant un bloc de code similaire (voir code ci-dessous).
Dans la 1ère fonction, ce bloc de code fonctionne parfaitement.
J'ai donc fait un copier-coller dans la 2ème fonction et modifié les valeurs des constantes (valeurs en majuscules).
Et là, bizarrement, le code ne fonctionne plus.
Pour rechercher le bug, j'ai donc inséré des Serial.print() pour voir ce qui se passait.
Cette fois, la 2ème fonction travaille comme attendu.
Mais le fait de retirer le dernier Serial.print() fait que ce code ne fonctionne alors plus !
La modification du délai ne change rien (je pensais que c'était dû à une question de temps de boucle).
J'ai déjà eu le même problème il y a quelques temps, mais je ne me souviens plus de la solution apportée.
Quelqu'un a-t-til une idée ?
Pour ma part, je sèche vraiment.
while (menuSelector == RANDOM_REPLAY_MODE) {
// Du code ici, inutile pour l'explicatif.
while( (menuSelector == RANDOM_REPLAY_MODE) && digitalRead(JOY_BP_PIN) == HIGH) {
Serial.println(""); // Le code ne fonctionne pas sans cette instruction !
delay(50);
}
if (digitalRead(JOY_BP_PIN) == LOW) {
menuSelector = STDBY_MODE;
delay(10);
return;
}
else {
menuSelector = RANDOM_MODE;
delay(10);
return;
}
Pas facile sans voir l'ensemble du code, il y a peut-être un dépassement d'indice de tableau ou une variable mal définie...
Par ailleurs, tu as posté dans la mauvaise section 'tutoriels et cours', il faudrait avertir le modérateur, mais je ne sais pas comment faire avec le nouveau forum...
Je n’ai pas réussi à trouver la bonne section avec ce nouveau forum…
Pas évident en effet ! La bonne zone c'est comme avant en dehors des 3 'sous-forum'= 3 'catégories spéciales' , donc en dessous de celles-ci.
En postant dans la zone dédiée aux cours et tutoriels tu n'accordes pas beaucoup de visibilité à ta demande .....et tu encombres la liste de cours et tutoriels
Pour demander le déplacement , cliques sur les trois petits points puis sur le drapeau et enfin sur 'Something else' pour expliquer la demande.
En sortie du while qui ne fonctionne pas digitalRead(JOY_BP_PIN) ne peut être que LOW (sauf malchance si rebond) donc le else du if suivant ne sert à rien
Ce serait bien de voir Du code ici, inutile pour l'explicatif
@J_M_L : exact pour le "else" ; il avait été rajouté en désespoir de cause. Quant au rebond, un trigger de Schmitt retourne un signal propre exempt de rebonds.
@ al1fch : je fais le nécessaire pour déplacer ce post.
Merci à lesept, J_M_L et à al1fch pour s'être intéressés à mon problème. Ne trouvant pas la cause, j'ai modifié le code comme suit. Ce n'est pas "intellectuellement propre", mais ça à l'avantage de fonctionner...
while (menuSelector == RANDOM_REPLAY_MODE) {
while (digitalRead(MENU_SELECTOR_PIN) == LOW && digitalRead(JOY_BP_PIN) == HIGH ) {
delay(50);
}
if (digitalRead(JOY_BP_PIN) == LOW) { // User quits the game (KO).
menuSelector = STDBY_MODE;
delay(50);
return;
}
if (digitalRead(MENU_SELECTOR_PIN) == HIGH) { // User continues the game (OK).
menuSelector = RANDOM_MODE;
delay(50);
return;
}
vous avouerez que le nom JOY_BP_PIN fait plus penser à un bouton pression momentané qu'à un trigger de Schmitt
le nouveau code n'est pas équivalent à l'ancien. Quand vous faisiez
while( (menuSelector == RANDOM_REPLAY_MODE) && digitalRead(JOY_BP_PIN) == HIGH) {
Serial.println(""); // Le code ne fonctionne pas sans cette instruction !
delay(50);
}
rien ne modifie menuSelector dans la boucle donc il ne servait à rien et on savait qu'il valait RANDOM_REPLAY_MODE puisqu'on était entré dans le while juste au dessus. Je ne vois pas pourquoi un while( (digitalRead(JOY_BP_PIN) == HIGH) ; // on attend qu'il passe LOW
n'aurait pas fonctionné
J'aurais juste écrit
while (true) {
if (digitalRead(JOY_BP_PIN) == LOW) { // User quits the game (KO).
menuSelector = STDBY_MODE;
break;
}
if (digitalRead(MENU_SELECTOR_PIN) == HIGH) { // User continues the game (OK).
menuSelector = RANDOM_MODE;
break;
}
}
@ J-M-L
Merci d'avoir pris le temps de considérer mon problème !
vous avouerez que le nom JOY_BP_PIN fait plus penser à un bouton pression momentané qu’à un trigger de Schmitt
Exact, mais chaque BP (joystick, BP normal) étant systématiquement connecté à un trigger, cela simplifie la désignation de la pin concernée.
Le code final
Votre solution étant nettement plus futée que la mienne, je l'ai donc incluse dans mon programme. La fonction finale est de ce fait conforme à votre suggestion :
/************************************************************
* Purpose :
* - Display "Random mode" with "Replay" option on the LCD.
* - Deactivates the 2 servos.
* - Switch the laser beam Off.
* Input : no parameter required.
* Output :
* - Updates the static variable 'menuSelector".
* - Updates the LCD with the choices.
* Used components : joystick push button, 'Mode' pushbutton.
* Drived components : 2 servos, laser, LCD.
*/
void randomReplayMode() {
digitalWrite (LASER_DRIVER_PIN, LOW); // Switch off the laser.
lowerServoX.detach();
upperServoY.detach();
buzzerBeeps(6); // Emit 6 beeps.
refreshAndDisplayMenu
(refreshDisplay, randomModeReplayMenu_Msgs); // LCD update.
while (true) { // Loop waiting user's action.
if (digitalRead(JOY_BP_PIN) == LOW) { // User quits the game (KO).
menuSelector = STDBY_MODE;
delay(50);
break;
}
if (digitalRead(MENU_SELECTOR_PIN) == HIGH) { // User continues the game (OK).
menuSelector = RANDOM_MODE;
delay(50);
break;
}
}
}
PS : je n'ai toujours pas trouvé le chemin de modification du post indiqué par al1fch...
Ca y est. Je pense avoir localisé l'erreur qui faisait que mon programme initial fonctionnait dans une autre fonction, mais pas dans celle proposée à votre sagacité.
Le problème venait de la variable dénommée menuSelector qui a été (mal) définie comme étant de type int, alors qu'elle est modifiée par une interruption, chose que j'avais oubliée dans le cours du développement.
Je l'ai donc déclarée cette fois comme elle aurait dû l'être, à savoir :