aide programmation

Bonjour,

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;
}

#define Pous1On digitalRead(Pous1)==0

while(Pous1On)

Bonjour,

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 ...

#define Pous1On digitalRead(Pous1)==0

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:

enum etats { attenteBouton, bouton1, bouton2, attenteRelache}

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.

fdufnews:
L'utilisation d'enum pour nommer les états clarifie le code par exemple:

enum etats = { attenteBouton, bouton1, bouton2, attenteRelache}

ça va pas trop compiler écrit comme cela :slight_smile:

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.

postez votre code....

#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; 
 
       
 } }

hello
as tu testé :

if (Pous1On||Pous2On) { // entrée ou sortie de quelqu'un
if(Pous1On^Pous2On){ //pas les deux boutons en meme temps

ces 2 lignes deviennent :
if (Pous1On^Pous2On) { // entrée ou sortie de quelqu'un, mais pas les deux boutons en meme temps

Vous faites dans la boucle:

     ...
          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;
  }
}

Merci beaucoup!

Bonne soirée

      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...