Je sollicite un peu d'aide pour ce programme. Je suis un cours en ligne mais je ne comprends pas mon erreur. Le pitch : on appuie sur un bouton ça compte. Lorsqu'on appuie sur l'autre on soustrait. Lorsqu'on depasse 15 personne la LED 1 s'allume. Quand il n'y a plus personne la led 2 s'allume. Mais ma led2 ne s'allume pas.
L'un d entre vous entrevoit mon erreur ?
D'avance merci pour les pistes.
#define Led1 4
#define Led2 5
#define Pous1 2
#define Pous2 3
#define Led1On digitalWrite(Led1,HIGH)
#define Led1Off digitalWrite(Led1,LOW)
#define Led2On digitalWrite(Led2,HIGH)
#define Led2Off digitalWrite(Led2,LOW)
#define Pous1On digitalRead(Pous1)==0
#define Pous2On digitalRead(Pous2)==0
int compteur = 0;
void setup() {
pinMode(Pous1, INPUT_PULLUP);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
Led2On;
}
int etat=1;
void loop() {
switch (etat) {
case 1: // on attend
if (Pous1On||Pous2On) {
if(Pous1On^Pous2On){
if(Pous1On){
etat = 2;
}else
{etat =3;}}
else{etat=6;}}
break;
case 2:
compteur++ ;
if(compteur>14){Led1On;}
if(compteur>0){Led2Off;}
etat = 4;
break;
case 3:
compteur-- ;
if(compteur<1){digitalWrite(Led2,HIGH);}
if(compteur<15){Led1Off;}
etat = 5;
break;
case 4:
//on attend le relâchement
if (!Pous1On) {
etat = 1;
}
case 5:
//on attend le relâchement
if (!Pous2On) {
etat = 1;
}
case 6:
if(!Pous2On&&!Pous1On)
{etat=1;}
} }
pas certain que les #define avec un bout de code aident à la compréhension ... moi ça me perturbe, mais c'est peut-être une question d'habitude
tu pourrais pour mieux comprendre ce qui se passe dans ton code ajouter des serial.Print() avec les valeurs de tes variables, par exemple juste avant le switch faire afficher la valeur de etat ça risque d'aider à comprendre ce qui se passe.
pourquoi autant d'états différents ? ça me semble bien compliqué pour une fonction au départ bien plus simple.
sinon dans ton setup() tu ne définis pas la fonction de la pin pour le bouton 2, il manque un pinMode(Pous2, INPUT_PULLUP); du coup il est probable que ton bouton 2 ne soit pas pris en compte
sinon pour faire plus simple que la multitude d'états avec ses possibilités de se planter assez importantes, tu pourrais utiliser des while(Pous1On){} pour rester en attente du relachement, ça simplifierait grandement je pense.
par exemple :
#define Led1 4
#define Led2 5
#define Pous1 2
#define Pous2 3
#define Led1On digitalWrite(Led1,HIGH)
#define Led1Off digitalWrite(Led1,LOW)
#define Led2On digitalWrite(Led2,HIGH)
#define Led2Off digitalWrite(Led2,LOW)
#define Pous1On digitalRead(Pous1)==0
#define Pous2On digitalRead(Pous2)==0
#define Antirebond 5 //delai pour éviter de prendre en compte les rebonds du contact
int compteur = 0;
void setup() {
pinMode(Pous1, INPUT_PULLUP);
pinMode(Pous2, INPUT_PULLUP);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
}
void loop() {
////////////////////prise en compte des appuis sur les boutons////////////////////////////////////////////
if(Pous1On) {
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à la fermeture
//ici le contact est appuyé, on va doc attendre qu'il soit relaché
while(Pous1On) {
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
//ici on est sorti de la boucle while donc le contact est désormais relaché, on peut prendre en compte l'appui qui a été fait
compteur++;
}
if(Pous2On) {
delay(Antirebond);
while(Pous1On) {
delay(Antirebond);
}
compteur--;
}
////////////////////limitations de la valeur du compteur////////////////////////////////////////////
if(compteur>15) compteur=15;
if(compteur<0) compteur=0;
////////////////////Affichage sur les leds//////////////////////////////////////////////////////////
if(compteur==15) Led1On;
else Led1Off;
if(compteur==0) Led2On;
else Led2Off;
}
petite remarque : la fonction digitalRead() ne renvoie que 2 valeurs : HIGH ou LOW
il est donc correct d'écrire : #define Pous1On digitalRead(Pous1)==LOW
(de plus cela facilite aux débutants la compréhension des types de variable)
et tout à fait sans importance : je trouve que Pous1On n'est pas facile à lire, j'aurais préféré Pous1on ...
Prendre l'habitude de mettre les définitions entre parenthèses cela évite des mauvaises surprises lorsque tu concatènes les expressions avec d'autres opérateurs (problème difficile à détecter de priorité des opérateurs)
#define Pous1On (digitalRead(Pous1)==0)
L'utilisation d'enum pour nommer les états clarifie le code par exemple:
Dans la mesure où c'est l'état des boutons qui pilote la machine à états, tu aurais pu concaténer l'état des 2 boutons dans la variable utilisée par le switch je pense que fonctionnement de la machine aurait été plus simple à comprendre.
Merci merci merci. Impressionné par le nombre d'intervention et d'aide constructive de ce forum. Je prends note des conseils d'écriture et de convention.
J'ai fait les corrections. en rajoutant pinMode dans mon programme pour le poussoir 2 ou en utilisant l'aide de bricofoy j'ai toujours le soucis que la lampe ne s'allume pas lorsque le compteur est à zéro.
#define Led1 4// allumé lorsque plus de 15 personnes
#define Led2 5// allumé lorsque piece vide
#define Pous1 2// lorsque 1 appuyé on entre
#define Pous2 3// Lorsque 2 appuyé on sort
#define Led1On (digitalWrite(Led1,HIGH))
#define Led1Off (digitalWrite(Led1,LOW))
#define Led2On (digitalWrite(Led2,HIGH))
#define Led2Off (digitalWrite(Led2,LOW))
#define Pous1On (digitalRead(Pous1)==0)
#define Pous2On (digitalRead(Pous2)==0)
#define Antirebond 20 //delai pour éviter de prendre en compte les rebonds du contact
int compteur = 0;
void setup() {
pinMode(Pous1, INPUT_PULLUP);
pinMode(Pous2, INPUT_PULLUP);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
Led2On; // Alllumage car piece vide
}
int etat=1;
void loop() {
switch (etat) {
case 1: // on attend
if (Pous1On||Pous2On) { // entrée ou sortie de quelqu'un
if(Pous1On^Pous2On){ //pas les deux boutons en meme temps
if(Pous1On){
etat = 2; //entrée
}else
{etat =3;}}//sortie
else{etat=4;}}// cas où entrée et sortie en meme temps
break;
case 2: //entrée traitement
while(Pous1On) { //attente du relachement du bouton
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
compteur++ ; //incremente
if(compteur>14){Led1On;} // allume lampe si trop de monde
if(compteur>0){Led2Off;} //eteint lampe2 si la piece etait vide juste avant
etat = 1; //retour attente
break;
case 3: //sortie traitement
while(Pous2On) {
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
compteur-- ; // depart de quelqu'un
if(compteur==0){Led2On;}
if(compteur<15){Led1Off;}
etat = 1; //retour attente
break;
case 6:// cas où entrée et sortie en meme temps
while(Pous2On||Pous1On){
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
etat=1;
} }
Bon.... En enlevant la partie "appuie des deux boutons en même temps le programme est validé par le cours en ligne. Mais bon. J'aimais bien la partie sortie et entrée en même temps. Improbable vu la rapidité du programme et la probabilité que exactement en même entrée et sortie ?
voici le programme final validé :
#define Led1 4// allumé lorsque plus de 15 personnes
#define Led2 5// allumé lorsque piece vide
#define Pous1 2// lorsque 1 appuyé on entre
#define Pous2 3// Lorsque 2 appuyé on sort
#define Led1On (digitalWrite(Led1,HIGH))
#define Led1Off (digitalWrite(Led1,LOW))
#define Led2On (digitalWrite(Led2,HIGH))
#define Led2Off (digitalWrite(Led2,LOW))
#define Pous1On (digitalRead(Pous1)==0)
#define Pous2On (digitalRead(Pous2)==0)
#define Antirebond 20 //delai pour éviter de prendre en compte les rebonds du contact
int compteur = 0;
void setup() {
pinMode(Pous1, INPUT_PULLUP);
pinMode(Pous2, INPUT_PULLUP);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
Led2On; // Alllumage car piece vide
}
int etat=1;
void loop() {
switch (etat) {
case 1: // on attend
if(Pous1On){
etat = 2; //entrée
}
if(Pous2On){{etat =3;}}//sortie
break;
case 2: //entrée traitement
while(Pous1On) { //attente du relachement du bouton
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
compteur++ ; //incremente
if(compteur==14){Led1On;} // allume lampe si trop de monde
if(compteur==1){Led2Off;} //eteint lampe2 si la piece etait vide juste avant
etat = 1; //retour attente
break;
case 3: //sortie traitement
while(Pous2On) {
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
}
compteur-- ; // depart de quelqu'un
if(compteur==0){Led2On;}
if(compteur==14){Led1Off;}
etat = 1; //retour attente
break;
} }
...
etat = [color=red]4[/color]; // cas où entrée et sortie en meme temps
mais plus loin ça c'est un soucis...
case [color=red]6[/color]:// cas où entrée et sortie en meme temps
sinon j'ai un peu cleané le code, histoire qu'il se lise plus facilement et j'ai mis un enum pour justement éviter les bêtises comme au dessus
const byte Led1 = 4; // allumé lorsque plus de 15 personnes
const byte Led2 = 5; // allumé lorsque piece vide
const byte Pous1 = 2; // lorsque 1 appuyé on entre
const byte Pous2 = 3; // Lorsque 2 appuyé on sort
#define Led1On (digitalWrite(Led1,HIGH))
#define Led1Off (digitalWrite(Led1,LOW))
#define Led2On (digitalWrite(Led2,HIGH))
#define Led2Off (digitalWrite(Led2,LOW))
#define Pous1On (digitalRead(Pous1)==LOW)
#define Pous2On (digitalRead(Pous2)==LOW)
#define Antirebond 20 //delai pour éviter de prendre en compte les rebonds du contact
int compteur = 0;
enum : byte {onAttend, onEntre, onSort, entreEtSortEnMemeTemps} etat;
void setup() {
pinMode(Pous1, INPUT_PULLUP);
pinMode(Pous2, INPUT_PULLUP);
pinMode(Led1, OUTPUT);
pinMode(Led2, OUTPUT);
Led2On; // Alllumage car piece vide
etat = onAttend;
}
void loop() {
switch (etat) {
// -------------------------------------------
case onAttend: // on attend
if (Pous1On || Pous2On) { // entrée ou sortie de quelqu'un
if (Pous1On ^ Pous2On) { //pas les deux boutons en meme temps
if (Pous1On) etat = onEntre; //entrée
else etat = onSort; //sortie
} else etat = entreEtSortEnMemeTemps; // cas où entrée et sortie en meme temps
}
break;
// -------------------------------------------
case onEntre://entrée traitement
while (Pous1On); //attente du relachement du bouton
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
compteur++ ; //incremente
if (compteur > 14) Led1On; // allume lampe si trop de monde
if (compteur > 0) Led2Off; //eteint lampe2 si la piece etait vide juste avant
etat = onAttend; //retour attente
break;
// -------------------------------------------
case onSort: //sortie traitement
while (Pous2On);//attente du relachement du bouton
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
compteur-- ; // depart de quelqu'un
if (compteur == 0) Led2On;
if (compteur < 15) Led1Off;
etat = onAttend; //retour attente
break;
// -------------------------------------------
case entreEtSortEnMemeTemps:// cas où entrée et sortie en meme temps
while (Pous1On || Pous2On);//attente du relachement des 2 boutons
delay(Antirebond); //on attends le delai pour être sur que le contact à fini de rebondir à l'ouverture
etat = onAttend;
}
}
if (compteur > 0) Led2Off; //eteint lampe2 si la piece etait vide juste avantce truc là me semble très louche car vous faites un compteur++ ; //incrementejuste avant...