probleme fonction " case "

bonjour a tous

je suis nouveau dans le monde de l'arduino j'essai temps bien que mal de réalisé mon projet mais je bloque

mon projet est un boitier qui contiens un arduino nano et quatre relais , ce boitier consiste a faire déclencher mon apn reflex via un câble , déplacer un chariot sur un rail disposant d'un moteur dc 5 volts , et a déclencher un téléphone portable via un module bluetooth '' perche a selfi "

sur la première version javais réalisé un code vraiment tout simple

après avoir déclarer les sorties javais ça

digitalWrite ( rail , HIGH );   
delay ( 200 ) ;                  
digitalWrite ( rail , LOW );   
delay  ( 1000 );
digitalWrite ( autofocus , HIGH );
delay( 1500 );
digitalWrite ( declencheur , HIGH );
delay ( 100 ) ;
digitalWrite ( autofocus , LOW);
digitalWrite ( declencheur , LOW );
delay ( 2000 );

aujourd'hui je voudrai pouvoir sélectionné chaque mode avec un bouton poussoir , en gros j'appuie
1 fois , j'ai le reflex qui fait sa boucle
2 fois le reflex plus le rail
3 fois le module bluetooth déclenche le smartphone
4 fois le module bluetooth plus le rail

j'ai trouvai un partie de code très intéressent sur le forum avec la fonction " case " mais le souci est qu'une fois dans la case je ne peux pas avoir de boucle , le programme s'exécute une seul fois puis plus rien

///////////////////////////////////////////////
//               declaration                 //
///////////////////////////////////////////////

int enfonce  = HIGH ;
int relache  = LOW ;
int etatBoutonPrecedant = relache;
int compteur      = 0;
int boutonPin     = 13 ;
int rail          = 2;   
int bluetooth     = 3;
int autofocus     = 4;
int declencheur   = 5;



unsigned long tempsAuRelachement = 0;

//////////////////////////////////////////////
//             initialisation               //
//////////////////////////////////////////////
 
void setup() {
       pinMode(rail,       OUTPUT); 
       pinMode(bluetooth,  OUTPUT);
       pinMode(autofocus,  OUTPUT);
       pinMode(declencheur,OUTPUT);
       pinMode(boutonPin,   INPUT);
       Serial.begin(19200);
     
}

/////////////////////////////////////////////
//             boucle infinie              // 
/////////////////////////////////////////////

void loop() {
      // Lecture du bouton et du temps
    int etatBouton = digitalRead(boutonPin);
    unsigned long tempsActuel = millis();
    

       if ( compteur > 4){

       compteur = 0 ;
       }
      
    // Si le bouton vient d'être enfoncé :
    if ( ( etatBouton == enfonce ) && ( etatBoutonPrecedant == relache ) ) {
        // On incrémente le compteur
        compteur++;
        etatBoutonPrecedant = enfonce; }
   
      
    // Si le bouton vient d'être relache :
    if ( ( etatBouton == relache ) && ( etatBoutonPrecedant == enfonce ) ) {
        // On note quand le bouton a été relache
        tempsAuRelachement = tempsActuel;
        etatBoutonPrecedant = relache; }

   
    
      // Si cela fait plus de 2000 ms que le bouton est relache :
    if ( ( etatBouton == relache ) && ( ( tempsActuel - tempsAuRelachement ) > 2000 ) && ( compteur > 0 ) ) {    
        // On gère les actions
        Serial.println(compteur);
        switch (compteur) {
          
            case 1:
                 digitalWrite(rail      ,HIGH);
                 digitalWrite(bluetooth  ,LOW);
                 digitalWrite(autofocus,  LOW);
                 digitalWrite(declencheur,LOW);
                 break;
                 
            case 2:
                digitalWrite(rail,       HIGH);
                digitalWrite(bluetooth,   LOW);
                digitalWrite(autofocus,  HIGH);
                digitalWrite(declencheur,HIGH);
                break;
                
            case 3:
                digitalWrite(rail,        LOW);
                digitalWrite(bluetooth,   LOW);
                digitalWrite(autofocus,  HIGH);
                digitalWrite(declencheur,HIGH);
                break;
                
            case 4:
                digitalWrite(rail,        LOW);
                digitalWrite(bluetooth,   LOW);
                digitalWrite(autofocus,   LOW);
                digitalWrite(declencheur, LOW); 

             
                     
        }
        // On remet le compteur à 0
        compteur = 0;
       
    }
      
    // Sauvegarde de l'état précédant avant de recommencer loop
    etatBoutonPrecedant = etatBouton;

Serial.println(compteur) ;


}

que faire pour avoir une boucle dans chaque case ?

merci d'avance pour votre aide :slight_smile:

a bientôt

Bonjour,

Mets ton code entre balises code
Si j'ai bien compris tu veux
1 click sur le bouton -> action 1
double click -> action 2
triple click -> action 3
quadruple click -> action 4;

C'est bien ça?

      // Si cela fait plus de 2000 ms que le bouton est relache :

ça va être long d'attendre 2 secondes après avoir pressé sur le boutons 1,2,3 ou 4 fois pour que quelque chose se passe.

ce qu'il faut faire c'est écrire 4 fonctions qui font ce que vous voulez faire dans le cas 1,2,3,4 les appeler dans le case et continuer à les appeler dans la boucle si elles n'ont pas fini leur action --> voir les machines à états

Dans un while sur un intervalle e temps, je compterais les fronts descendants et en fonction, j'executerai l'action
http://www.chambeyron.fr/index.php/arduino-raspberry-py/61-arduino-gestion-d-un-front
https://www.arduino.cc/en/Reference/While
https://www.arduino.cc/en/Reference/SwitchCase
Et pour le temps

Voilà, il suffit d'assembler tout ça

Kamill je suis sur mobile actuellement mais je m'en occupe pour la balise

Sinon effectivement c'est ce que je veux mais en mettant la fonction loop dans la case j'ai un blocage de bouton, il ne reviens pas à zéro

J-m-l les 2000ms c'est le retour à zéro du compteur

Zigomatos merci pour les liens j"ai vu le premier, alors si j'ai bien compris pour le premier cas je met juste un delay à la fin de ma boucle principale et normalement c'est bon ?

Ton problème n'a rien à voir avec la fonction case.

Il y avait de l'idée dans ce que tu as fait, mais en fait il n'y a pas à traiter le relachement. Il faut que tu comptes le nombre d'appuis avant le time out.
Cequi donne quelque chose comme ça:

///////////////////////////////////////////////
//               declaration                 //
///////////////////////////////////////////////
const int boutonPin     = 13 ;
const int rail          = 2;
const int bluetooth     = 3;
const int autofocus     = 4;
const int declencheur   = 5;
const int enfonce  = HIGH ;
const int relache  = LOW ;
const unsigned long timeOutAppui = 1000;

int etatBoutonPrecedant = relache;
int compteur      = 0;
bool compteurValide = false;
unsigned long premierAppui = 0;

//////////////////////////////////////////////
//             initialisation               //
//////////////////////////////////////////////

void setup() {
 pinMode(rail,       OUTPUT);
 pinMode(bluetooth,  OUTPUT);
 pinMode(autofocus,  OUTPUT);
 pinMode(declencheur, OUTPUT);
 pinMode(boutonPin,   INPUT);
 Serial.begin(19200);

}

/////////////////////////////////////////////
//             boucle infinie              //
/////////////////////////////////////////////

void loop() {
 // Lecture du bouton et du temps
 int etatBouton = digitalRead(boutonPin);
 unsigned long tempsActuel = millis();

 // Si le bouton vient d'être enfoncé :
 if (( etatBouton == enfonce ) && ( etatBoutonPrecedant == relache )) {
   // On incrémente le compteur
   if (compteur == 0)
     // on mémorise le temps du premier appui
     premierAppui = millis();
   compteur++;
   if (compteur == 4)
     compteurValide = true;    // on ne peut pas aller à plus que 4
 }
 etatBoutonPrecedant = etatBouton;

 if (compteur > 0 && millis() - premierAppui >= timeOutAppui)
 {
   compteurValide = true;    // le time out pour appuyé est terminé -> on valide le compteur
 }

 if (compteurValide)
 {
   Serial.println(compteur);
   switch (compteur) {

     case 1:
       digitalWrite(rail      , HIGH);
       digitalWrite(bluetooth  , LOW);
       digitalWrite(autofocus,  LOW);
       digitalWrite(declencheur, LOW);
       break;

     case 2:
       digitalWrite(rail,       HIGH);
       digitalWrite(bluetooth,   LOW);
       digitalWrite(autofocus,  HIGH);
       digitalWrite(declencheur, HIGH);
       break;

     case 3:
       digitalWrite(rail,        LOW);
       digitalWrite(bluetooth,   LOW);
       digitalWrite(autofocus,  HIGH);
       digitalWrite(declencheur, HIGH);
       break;

     case 4:
       digitalWrite(rail,        LOW);
       digitalWrite(bluetooth,   LOW);
       digitalWrite(autofocus,   LOW);
       digitalWrite(declencheur, LOW);
   }
   // On remet le compteur à 0
   compteur = 0;
   compteurValide = false;

 }
 delay(10); // pour anti rebond
}

Hello petit retour sur le code que tu as modifier

Déjà merci pour ton aide :slight_smile:

J'ai perdu l'état du bouton dans le com :-/
Et quand je sélectionne l'une des 4 casse l'équipement fonctionne mais qu'une seule fois, je sais pas quoi faire

J'ai changé le code dans la case 1 pour voir si il y aurai du changement mais ça fonctionne pas

case 1:
digitalWrite ( rail, HIGH) ;
delay ( 100);
digitalWrite ( rail, LOW) ;
delay ( 1000);
break;

En faite je veux obtenir une boucle dans chaque case,
Si case 1 sélectionné, boucle de celui si
Si case 2 sélectionné, boucle de celui si

Et ainsi de suite

Bonjour,

Il suffit de ne pas réinitialiser le compteurValide après l'action

///////////////////////////////////////////////
//               declaration                 //
///////////////////////////////////////////////
const int boutonPin     = 13 ;
const int rail          = 2;
const int bluetooth     = 3;
const int autofocus     = 4;
const int declencheur   = 5;
const int enfonce  = HIGH ;
const int relache  = LOW ;
const unsigned long timeOutAppui = 1000;

int etatBoutonPrecedant = relache;
int compteur      = 0;
int compteurValide = -1;
unsigned long premierAppui = 0;

//////////////////////////////////////////////
//             initialisation               //
//////////////////////////////////////////////

void setup() {
 pinMode(rail,       OUTPUT);
 pinMode(bluetooth,  OUTPUT);
 pinMode(autofocus,  OUTPUT);
 pinMode(declencheur, OUTPUT);
 pinMode(boutonPin,   INPUT);
 Serial.begin(19200);
}

/////////////////////////////////////////////
//             boucle infinie              //
/////////////////////////////////////////////

void loop() {
 // Lecture du bouton et du temps
 int etatBouton = digitalRead(boutonPin);
 unsigned long tempsActuel = millis();

 // Si le bouton vient d'être enfoncé :
 if (( etatBouton == enfonce ) && ( etatBoutonPrecedant == relache )) {
   // On incrémente le compteur
   if (compteur == 0)
     // on mémorise le temps du premier appui
     premierAppui = millis();
   compteur++;
   if (compteur == 4)
   {
     compteurValide = compteur;    // on ne peut pas aller à plus que 4
     Serial.println(compteurValide);
     compteur = 0;
   }
 }

 etatBoutonPrecedant = etatBouton;

 if (compteur > 0 && millis() - premierAppui >= timeOutAppui)
 {
   compteurValide = compteur;    // le time out pour appuyé est terminé -> on valide le compteur
   Serial.println(compteurValide);
   compteur = 0;
 }
 switch (compteurValide) {
   case 1:
     digitalWrite(rail      , HIGH);
     digitalWrite(bluetooth  , LOW);
     digitalWrite(autofocus,  LOW);
     digitalWrite(declencheur, LOW);
     break;

   case 2:
     digitalWrite(rail,       HIGH);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,  HIGH);
     digitalWrite(declencheur, HIGH);
     break;

   case 3:
     digitalWrite(rail,        LOW);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,  HIGH);
     digitalWrite(declencheur, HIGH);
     break;

   case 4:
     digitalWrite(rail,        LOW);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,   LOW);
     digitalWrite(declencheur, LOW);
 }
 delay(10);        // pour anti rebond
}

Question;: comment tu vas arrêter?

Merci pour t'as réponse :slight_smile: je vais faire un test

En choisissant une autre case,

Comme la case 4 par exemple ou en arrêtant l'alimentation de l"arduino

merci Kamill , ton code fonctionne , j'ai bien la boucle dans la case choisis , par-contre mon compteur ne revient pas a zéro , du coup impossible de choisir une autre case ou déteindre avec la case 4 qui a pour fonction de mettre les équipements hors tension , je te poste le code en entier pour que tu puisse voir

///////////////////////////////////////////////
//               declaration                 //
///////////////////////////////////////////////
const int boutonPin     = 13 ;
const int rail          = 2;
const int bluetooth     = 3;
const int autofocus     = 4;
const int declencheur   = 5;
const int enfonce  = HIGH ;
const int relache  = LOW ;
const unsigned long timeOutAppui = 1000;

int etatBoutonPrecedant = relache;
int compteur      = 0;
int compteurValide = -1;
unsigned long premierAppui = 0;

//////////////////////////////////////////////
//             initialisation               //
//////////////////////////////////////////////

void setup() {
 pinMode(rail,       OUTPUT);
 pinMode(bluetooth,  OUTPUT);
 pinMode(autofocus,  OUTPUT);
 pinMode(declencheur, OUTPUT);
 pinMode(boutonPin,   INPUT);
 Serial.begin(19200);
}

/////////////////////////////////////////////
//             boucle infinie              //
/////////////////////////////////////////////

void loop() {
 // Lecture du bouton et du temps
 int etatBouton = digitalRead(boutonPin);
 unsigned long tempsActuel = millis();

 // Si le bouton vient d'être enfoncé :
 if (( etatBouton == enfonce ) && ( etatBoutonPrecedant == relache )) {
   // On incrémente le compteur
   if (compteur == 0)
     // on mémorise le temps du premier appui
     premierAppui = millis();
   compteur++;
   if (compteur == 4)
   {
     compteurValide = compteur;    // on ne peut pas aller à plus que 4
     Serial.println(compteurValide);
     compteur = 0;
   }
 }

 etatBoutonPrecedant = etatBouton;

 if (compteur > 0 && millis() - premierAppui >= timeOutAppui)
 {
   compteurValide = compteur;    // le time out pour appuyé est terminé -> on valide le compteur
   Serial.println(compteurValide);
   compteur = 0;
 }
 switch (compteurValide) {
   case 1:
     digitalWrite(rail      , HIGH);
     delay(100);
     digitalWrite(rail,LOW);
     delay( 1000);
     digitalWrite(bluetooth  , LOW);
     digitalWrite(autofocus,  LOW);
     digitalWrite(declencheur, LOW);
     break;

   case 2:
     digitalWrite(rail,       HIGH);
     delay(200);
     digitalWrite( rail , LOW);
     delay (1000);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,  HIGH);
     delay(1500);
     digitalWrite(declencheur, HIGH);
     delay(200);
     digitalWrite(autofocus , LOW);
     digitalWrite(declencheur,LOW);
     delay(3500);
     break;

   case 3:
     digitalWrite(rail,        LOW);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,  HIGH);
     delay(1500);
     digitalWrite(declencheur, HIGH);
     delay(200);
     digitalWrite(autofocus , LOW);
     digitalWrite(declencheur,LOW);
     delay(8500);
     break;

   case 4:
     digitalWrite(rail,        LOW);
     digitalWrite(bluetooth,   LOW);
     digitalWrite(autofocus,   LOW);
     digitalWrite(declencheur, LOW);
 }
 delay(10);        // pour anti rebond
}

en tout cas un grand merci tu me retire une grosse épine du pied :slight_smile:

Le gros problème c'est que la lecture correcte du bouton poussoir est complètement incompatible avec les delay() que tu as mis.

Tu as deux solutions:

  • supprimer les délais et les remplacer par millis(), ce qui t'oblige à faire une sorte d'automate d'état (à mon avis c'est la meilleure solution)
  • traiter ton bouton en interruption (peut être plus simple à implémenter)

Au fait - vous ne semblez pas utiliser de pullup / down interne - comment est câblé le bouton sur la pin13?

Si vous lisez la doc, pour cette pin 13 il note qu'il faut faire attention

NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins because it has an LED and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7V instead of the expected 5V because the onboard LED and series resistor pull the voltage level down, meaning it always returns LOW. If you must use pin 13 as a digital input, set its pinMode() to INPUT and use an external pull down resistor.

kamill:

  • supprimer les délais et les remplacer par millis(), ce qui t'oblige à faire une sorte d'automate d'état (à mon avis c'est la meilleure solution)

oui c'est l'approche à recommander

J-M-L:
Si vous lisez la doc, pour cette pin 13 il note qu'il faut faire attention

Cette remarque est valable sur les anciennes cartes.
A partir des cartes R3 (uno et mega), la pin 13 est reliée à un ampli op monté en suiveur de tension et la led est sur la sortie de l'ampli op. Donc l'influence sur la pin 13 est complètement négligeable.

kamill:
Cette remarque est valable sur les anciennes cartes.

quoi, vous insinuez que j'ai du vieux matos pourri? :slight_smile:

blague à part - merci j'étais resté sur de vielles infos sans regarder les specs des nouvelles cartes de ce côté là

J-M-L:
Au fait - vous ne semblez pas utiliser de pullup / down interne - comment est câblé le bouton sur la pin13?

Si vous lisez la doc, pour cette pin 13 il note qu'il faut faire attention

j'utilise pas le pullup interne , j'ai câblé comme vu sur le tuto d'eskimon ""Récupérer l’appui du bouton"" mais en pin 13 sans condensateur car j'ai pas de soucis de rebond