sequence

bonjour,

je viens vers la communauté car je bloque sur un programme et je cherche quelques pistes. Ayant déjà été éclairé par certains d entre vous lors d un autre sujet je me tourne à nouveau vers vous afin que vous m éclairiez.

mon projet est simple en apparence mais en programmation me voila complètement perdu.

je souhaite simplement réaliser un "séquenceur" , je m explique:

j' ai trois boutons poussoir et il faut appuyer dessus dans un certain ordre pour déclencher un relais, d'ou la séquence.

exemple: il faut appuyer d abord sur le bouton 1 puis le bouton 2 et enfin le bouton 3 pour que le relais déclenche.

toute autre combinaison ne fonctionne pas c est a dire qui ne doit rien se passer et il faut donc recommencer toute la séquence d appuie.

je me demande donc si la "machine a état" serait la bonne méthode, et comme j ai pas encore saisie tout le potentiel de ce type de programme je me tourne donc vers vous.

j espère m être bien expliqué et j espère que vous pourrez me guider, merci d avance.

Une machine à état est parfaitement adaptée à ce besoin. Son intérêt c'est justement de coder un enchaînement d'états déclenchés par des évènements.

merci pour la confirmation de mon idée de machine a état y a plus qu a synthétiser un code. faut que je comprenne exactement le fonctionnement de la machine a état pour l instant c est le vague et flou artistique dans ma tête je ne sais même pas par ou commencer lol . je reviendrai vers vous avec une première esquisse. en tout cas merci pour la réponse.

int const relais =5 ;
int const bouton1 =2 ;
int const bouton2 =3 ;
int const bouton3 =4 ;


void setup() {                
 
  pinMode(relais, OUTPUT); 
  pinMode(bouton1, INPUT);
  pinMode(bouton2, INPUT);
  pinMode(bouton3, INPUT);
  
 
}


void loop() {

  switch (bonCode) {  

      case 1:

       digitalread(bouton1);

      if (bouton1 == HIGH){

          digitalread (bouton2);

          delay(20);

          break;
      }
      
      case 2:

      if (bouton2 == HIGH){

          digitalread (bouton3);

          delay(20);

          break;
      }
      

      case 3:

      if (bouton3 == HIGH){

      delay(200);

      digitalwrite(relais, HIGH);

      delay(1000);

      break;

      }
      
      
}

bonjour ,

suite a votre réponse je poste donc un code que j ai écris pour mon séquenceur , je doute qu il marche car je n ai pas encore eu l occasion de l essayer ( j attends ma carte arduino qui va être livrée d ici peu).

je suis un super débutant donc je pense avoir fait plein de fautes dans ce code, il me parait trop simple pour fonctionner a moins que je sois devenu un petit génie en deux nuits lol.

je cherche en fait a me faire un petit peu aiguillé , juste savoir si je suis sur la bonne voie et si j ai bien compris le concept du SWITCH/CASE.

merci d avance pour vos réponses qui me fond avancer dans mon apprentissage de l arduino.

Bonjour,

Comme tu le dis toi même c'est une sequence de touche que tu veux tester. Donc il faut que tu mémorise chaque touche sur laquelle tu appuie et ensuite tu compares au code.

Pour faire une machine à états, le swicth … case doit gérer tous les états possible de la machine. Et on fait avancer le “compteur d’états” en fonction d’évènements.

Un morceau de code non fonctionnel mais qui explique comment ça marche
On présuppose l’existence d’une fonction qui retourne la valeur entrée par l’appui sur une touche d’un clavier numérique, ainsi que la présence d’une fonction qui met l’affichage à jour.

//On définit les différents états de la machine
enum mesEtats{E_INIT, E_ATTENT_T1, E_ATTENT_T2, E_ATTENT_T3, E_ATTENT_T4, E_VERIFIE, E_OK, E_KO};

//On définit une variable qui va contenir l'état courant de la machine
int etatCourant=E_INIT; // on démarre dans l'état INIT

//Dans le corps du programme on va aiguiller le programme en fonction de l'état courant de la machine

switch (etatCourant){
    case E_INIT:
        // ici tu places le code utilisé à chaque fois que tu recommences du début
        code=0; //on démarre avec un code vierge
        mise_a_jour_affichage();
        etatCourant = E_ATTENT_T1;
        break;
    case E_ATTENT_T1;
        // ici tu places le code utilisé lorsque tu es en attente de la première touche
        code= lecture_clavier();
        mise_a_jour_affichage();
        etatCourant = E_ATTENT_T2;
        break;
    case E_ATTENT_T2;
        // ici tu places le code utilisé lorsque tu es en attente de la deuxième touche
        code= code*10+lecture_clavier();
        mise_a_jour_affichage();
        etatCourant = E_ATTENT_T3;
        break;
    case E_ATTENT_T3;
        // ici tu places le code utilisé lorsque tu es en attente de la troisième touche
        code= code*10+lecture_clavier();
        mise_a_jour_affichage();
        etatCourant = E_ATTENT_T4;
        break;
    case E_ATTENT_T4;
        // ici tu places le code utilisé lorsque tu es en attente de la quatrième touche
        code= code*10+_clavier();
        mise_a_jour_affichage();
        etatCourant = E_VERIFIE;
        break;
    case E_VERIFIE;
        if(verification_code(code)){
            // si le code est bon
            etatCourant = E_OK;
        }
        else {
            // si le code est faux
            etatCourant = E_OK;
        }
        break;
    case E_OK;
        // le code est bon
        mise_a_jour_affichage();
        deverouille_la_porte();
        etatCourant = E_INIT;
        break;
    case E_KO;
        // le code est faux
        mise_a_jour_affichage();
        message_d_insulte();
        etatCourant = E_INIT;
        break;
    default:
        // cas non géré. On ne devrait jamais arriver ici
        Serial.println("Y'a un bug");
}

La machine déroule la séquence de pas quasi linéairement. Mais on pourrait très bien imaginer que la fonction lecture-clavier() retourne un code qui indique l’appui d’une touche pour corriger la saisie et qui ferait donc rebrousser la machine d’un pas en arrière ou alors l’appui sur une touche qui permettrait d’abandonner la saisie et retournerait à l’état E_INIT.

ok merci pour tous ces détails je vais m y atteler , je reviendrai vers vous pour vous monter le code final. juste une question, si je remplace les boutons par des capteurs qui doivent rester à l état HIGH pour passer a l étape suivante y a t il une commande spéciale?

exemple :

capteur 1 état HIGH

lire état capteur 2, si capteur 2 HIGH

lire capteur 3 et si capteur 3 HIGH ( donc capteur 1 ,2 et 3 allumé dans l ordre)

alors je déclenche mon relais

merci pour tout.

Dans chaque case, il y a 2 parties distinctes. 1) une portion de code qui effectue l'action prévue pour l'état courant 2) une portion de code qui détermine l'état suivant en fonction d’événements. Lesdits événements pouvant être une action externe (action sur un bouton, état d'un capteur) ou simplement l'exécution de l'état courant.

Concernant les capteurs, au lieu de faire appel à une fonction qui retourne l'état d'une touche, tu peux très bien lire l'état d'un capteur externe et agir en conséquence. Par exemple

if (digitalRead(capteur1)==HIGH){
       etatCourant = E_LIT_CAPTEUR2; // on passe au capteur suivant
} else {
       etatCourant = E_INIT; // erreur on recommence depuis le début
}
int const relais =5 ;
int const bouton1 =2 ;
int const bouton2 =3 ;
int const bouton3 =4 ;

 enum etatCode{etatZero, etape1, etape2, etape3};


void setup() {                

  pinMode(relais, OUTPUT); 
  pinMode(bouton1, INPUT);
  pinMode(bouton2, INPUT);
  pinMode(bouton3, INPUT);
}

void loop() {
  switch (etatCode) {  
      case etatZero:
       
      if (digitalRead (bouton1) == HIGH){
          etatCode = etape1;}
          
          else{etatCode = etatZero; }
  
          break;
      
      
      case etape1:
      
      if (digitalRead (bouton2) == HIGH){
          etatCode = etape2;}
          
       else {etatCode = etape1;}
       
          break;
      
      
      case etape2:
      
      if(digitalRead (bouton3) == HIGH){
      etatCode = etape3;
      delay(200);
      digitalwrite(relais, HIGH);
      delay(1000);}
      
       else {etatCode = etape2;}
       
      break;
      }
}

re bonjour, après tout vos conseils et explications voila le code finale que j ai réussi à pondre , j espère qu il est bon , je reçois ma carte lundi je pourrais donc tester. comme promis dans un poste précédant je vous présente donc mon code n hésitez pas a faire des critiques, grace a elles je progresse , en tout cas merci a tout ceux qui m ont aidé en me conseillant.

Bonjour,

Il y a de l'idée, mais l'algorithme utilisé fait que quel que soit le code si tu tapes trois fois (maximum) 1 2 3, tu actives le relais.

Ta variable etatCode n'est pas définie. Il faut la définir comme suit:

 enum ETATCODE{etatZero, etape1, etape2, etape3} etatCode;
int const relais =5 ;
int const bouton1 =2 ;
int const bouton2 =3 ;
int const bouton3 =4 ;
int const ledDefaut = 6;
 enum ETATCODE{etatZero, etape1, etape2, etape3, etapeInit};

boolean capteur1=false;
boolean capteur2=false;
boolean capteur3=false; 

int etatCode = etatZero;

void setup() {                
 pinMode(ledDefaut,OUTPUT);
  pinMode(relais, OUTPUT); 
  pinMode(bouton1, INPUT);
  pinMode(bouton2, INPUT);
  pinMode(bouton3, INPUT);
}

void loop() {
  switch (etatCode){   
      case etatZero:
         
      if (digitalRead (bouton1) == HIGH && digitalRead (bouton2)==LOW && digitalRead(bouton3)==LOW){
          digitalWrite (ledDefaut, HIGH);
          etatCode = etape1;}
          else{etatCode = etatZero; }
          
          break;
      
      
      case etape1:
      
      if (digitalRead (bouton2) == HIGH && digitalRead (bouton1)==HIGH && digitalRead(bouton3)==LOW){
        digitalWrite (ledDefaut, HIGH);
          capteur2 = true;
          etatCode = etape2;}
          
       else {etatCode = etape1;}
       
          break;
      
      
      case etape2:
      
      if(digitalRead (bouton3) == HIGH && digitalRead (bouton1)==HIGH && digitalRead(bouton2)==HIGH){
        digitalWrite (ledDefaut, HIGH);
      capteur2 = true; 
      etatCode = etape3;
      delay(200);}
     
       else {etatCode = etape2;}
       
      break;
      
      case etape3:
      digitalWrite(relais, HIGH);
      digitalWrite (ledDefaut, LOW);
      delay(1000);
      etatCode= etapeInit;
      
      break;
      
      case etapeInit:
      
      if (digitalRead (bouton3) == LOW && digitalRead (bouton1)==LOW && digitalRead(bouton2)==LOW){
      digitalWrite (relais,LOW);
      delay(500);
      
      etatCode = etatZero;}
      
      }       
}

bonjour ,

un grand merci a tous pour vos conseils et astuces , j ai réussi a faire mon programme et il fonctionne comme je le désire. Comme promis je le poste donc

a bientot !! :D :D :D :D