IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Problème avec boucle for


Sujet :

Arduino

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut Problème avec boucle for
    bonjour à vous,
    voila quasiment 1 heure que je galère avec une boucle

    le but final de la programmation est de configurer le temps d'un compte à rebours, format hh/mm/ss
    du coup 6 variables h1,h2.....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //declaration des variables pour le compteur
    int h1=0;
    int h2=0;
    int m1=0;
    int m2=0;
    int s1=0;
    int s2=0;
    je déclare le clavier et configuration

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    #include <Keypad.h>
    const byte ROWS = 4; //4 lignes
    const byte COLS = 4; //4 colonnes
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    //Brancher le clavier sur 9 10 11 12 (colonnes) et 5 6 7 8 (lignes)
    byte rowPins[ROWS] = {5, 6,7, 8}; //Lignes
    byte colPins[COLS] = {9,10, 11, 12}; //Colonnes
     
     
    // Initialiser une instance de la classe keypad
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Test de clavier 16 touches");
     
      // Pour activer l'état HOLD
      unsigned int time_hold = 4;
      keypad.setHoldTime(time_hold);
     
      //Anti rebond
      unsigned int time_anti_rebond = 4;  //4 ms
      keypad.setDebounceTime(time_anti_rebond);
    }
    viens le moment où ça ne fonctionne plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void loop()
    {
      for (int i = 1; i < 7; i++) 
    {
      char key = keypad.getKey();
      if (key != NO_KEY)
      {   
       Serial.print(i);
      }
     }
     
    }
    quand je lance le programme, dans l'écran ça met un chiffre hasardeux et non croissant.
    si je déplace "char key = keypad.getKey();" avant le for,
    alors j'obtiens la suite 123456 sans avoir d'action sur le clavier.

    idéalement, je voudrais que quand i==1 alors h1 prend la valeur de key, puis i==2 alors h2=key…..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (i==1)
    {
    h1==key;
    }
    je n'y comprends rien, merci pour votre aide
    PS, les branchements du clavier sont ok, sans la boucle for, j'obtiens les bonnes touches

  2. #2
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 335
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 335
    Points : 4 158
    Points
    4 158
    Par défaut Déclaration ou déclarations
    Bonjour,

    Et comme cela, ça marche ? Il faut ralentir tout ça sinon soit 1234567 (si une touche détectée initialement) ou rien. C'est pourquoi je ne compte que les pressions effectives : au diable les passage pour rien, même ralenties au 1/20 s, 7 itérations ne prendraient qu'un tiers de seconde.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    void loop()
    {
       char key;
       for (int i = 1; i < 7;) 
       {
       key = keypad.getKey();
       if (key != NO_KEY)
       {   
          Serial.print(i);
          Serial.print(" : ");
          Serial.println(key);
          ++i;                                    // 7 touches effectives
          do {
               delay(50)                          // au moins une fois pour d'éventuels rebonds (sauf si la lib les gère)
          while(keypad.getKey() == key) ;         // attendre que cela change
       }
       else delay(50);                            // 1/20 s entre scrutation paraissent suffisants
    }
    Par ailleurs, pourquoi 7 itérations ? Sachant que loop en fera 7 autres de suite après et ainsi de suite...

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    Bonjour, merci pour ta réponse.
    Très honnêtement, je ne comprends pas ce que tu dis.
    😭

  4. #4
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 725
    Points : 5 415
    Points
    5 415
    Par défaut
    Il ne faut pas ralentir tout, il faut juste pas essayer de deviner quand votre utilisateur va appuyer sur la touche.

    Ce que vous n’avez peut être pas compris c’est que getkey() n’est pas bloquant, ça teste juste si on en a reçu une

    Donc votre i ne devrait pas être l’index d’une boucle for, il devrait juste s’incrémenter quand vous avez reçu une touche adéquate

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    byte indicateur = 1;  // on attend h1
     
    void setup() {}
     
    void loop()
    {
      if (indicateur < 7) { // on attend toujours une entrée 
        char key = keypad.getKey();
        if ((key != NO_KEY) && (key >= ‘0) && (key <= ‘9)) {
          // on a reçu un appui et c’est un chiffre
          switch(indicateur) {
            case 1: h1 = key - ‘0’; break;
            case 2: h2 = key - ‘0’; break;
            case 3: m1 = key - ‘0’; break;
            case 4: m2 = key - ‘0’; break;
            case 5: s1 = key - ‘0’; break;
            case 6: s2 = key - ‘0’; break;
            default: break;// ne devrait pas arriver 
          }
          indicateur++;
        }
      }
      ...
    }
    Ce n’est pas la manière la plus élégante mais correspond ( aux fautes près, j’ai tapé ça ici) à l’approche que vous évoquez

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    salut Jay M,
    merci pour ton retour

    effectivement quelques petites erreurs le guillemets

    et aussi , dans les conditions, si on laisse 0 et 9 ça ne fonctionne pas car il y a une différence entre la valeur de la touche et son code (c'est mont avis).
    du coup voilà le code pour que ça fonctionne.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     if (indicateur < 7) { // on attend toujours une entrée 
        char key = keypad.getKey();
        if ((key != NO_KEY) and (key >= 48) and (key <= 57 )) {
          // on a reçu un appui et c’est un chiffre
          Serial.print(key);
          switch(indicateur) {
            case 1: 
           if(key==48){h1=0;}
           if(key==49){h1=1;}
           if(key==50){h1=2;}
           if(key==51){h1=3;}
           if(key==52){h1=4;}
           if(key==53){h1=5;}
           if(key==54){h1=6;}
           if(key==55){h1=7;}
           if(key==56){h1=8;}
           if(key==57){h1=9;} 
           break;
    ...
    aurais tu une idée pour que m1<6 et s1 car il n'y a que soixante minutes et secondes?

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 725
    Points : 5 415
    Points
    5 415
    Par défaut
    Comme j’ai tapé sur mon tel il a mis des apostrophes françaises et pas de guillemet simple, pas besoin de mettre les codes en numérique ça rend le code moins compréhensible vous pouvez taper ‘0’ et ça doit être le bon code ascii pas besoin de mettre 48, c’est pareil

    Sinon pour votre question il suffit de tester dans cahque «case» ce qui correspond à une valeur correcte

    Dans ce cas bien sûr on ne peut plus partager le passage à la valeur d’après, il faut le mettre dans le test quand le code entré était acceptable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void loop()
    {
      if (indicateur < 7) { // si on attend toujours une entrée 
        char key = keypad.getKey();
        if ((key != NO_KEY) && (key >= ‘0) && (key <= ‘9)) {
          // on a reçu un appui et c’est un chiffre
          switch(indicateur) {
            case 1: 
                 if (key >= ‘0’ && key <= ‘2) { // si on veut limiter à 0,1 ou 2 par exemple
                      h1 = key - ‘0’;
                      indicateur++; // modif OK on passe à celui d’après 
                  }
                  break;
     
              case 2:
            ...
          }
        }
      }
      ...
    }
    Assurez vous juste d’avoir des bonnes apostrophes

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    JayM,
    je suis reparti de ton premier code en mettant les bons guillemets et ça fonctionne.
    Comme je te l'ai dit dans mon post précédant, la problématique est d'avoir un m1 et un s1 inférieur à 6.

    case 3; "tant que key >=6" rien ne se passe else " m1=key-'0';..." (idem pour case 5)

    dans TON dernier poste, si la condition est remplie, ça prend la valeur de la touche, sinon, valeur=0

  8. #8
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 725
    Points : 5 415
    Points
    5 415
    Par défaut
    Il faut décider quoi faire si la valeur n’est pas acceptable
    Dans mon dernier code j’ignore la touche (pour le premier digit des heure) si ce n’est pas 0 1 ou 2
    C’est un exemple, suffit de faire la même chose pour les autres et bien sûr ne pas faire avancer l’indice - il faut qu’il soit dans le if

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    pompier
    Inscrit en
    Janvier 2020
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : Janvier 2020
    Messages : 76
    Points : 36
    Points
    36
    Par défaut
    et oui j'ai réfléchi et j'en était arrivé à la même conclusion que toi.
    merci beaucoup pour ton aide.

    voilà le code complet. maintenant, je n'ai plus qu'à transformer ses valeurs en temps et insérer mon code de compte à rebours.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    //declaration des variables pour le compteur
    int h1=0;
    int h2=0;
    int m1=0;
    int m2=0;
    int s1=0;
    int s2=0;
    int i=1;
    int ii=0;
    byte indicateur = 1;  // on attend h1
     
    #include <Keypad.h>
    const byte ROWS = 4; //4 lignes
    const byte COLS = 4; //4 colonnes
    char keys[ROWS][COLS] = {
      {'1','2','3','A'},
      {'4','5','6','B'},
      {'7','8','9','C'},
      {'*','0','#','D'}
    };
    //Brancher le clavier sur 9 10 11 12 (colonnes) et 5 6 7 8 (lignes)
    byte rowPins[ROWS] = {5, 6,7, 8}; //Lignes
    byte colPins[COLS] = {9,10, 11, 12}; //Colonnes
     
     
    // Initialiser une instance de la classe keypad
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Entrer temps HHmmss");
     
      // Pour activer l'état HOLD
      unsigned int time_hold = 4;
      keypad.setHoldTime(time_hold);
     
      //Anti rebond
      unsigned int time_anti_rebond = 4;  //4 ms
      keypad.setDebounceTime(time_anti_rebond);
     
      pinMode(2, OUTPUT);
       pinMode(3, OUTPUT);
     
    }
     
    void loop()
    {
      digitalWrite(2, HIGH);
       if (indicateur < 7) { // on attend toujours une entrée 
        char key = keypad.getKey();
     
        if ((key != NO_KEY) && (key >= '0') && (key <= '9')) {
          // on a reçu un appui et c’est un chiffre
          switch(indicateur) {
            case 1: h1 = key - '0';Serial.print(h1);Serial.println("_H00min00sec");indicateur++; break;
            case 2: h2 = key - '0';Serial.print(h1);Serial.print(h2);Serial.println("H_0min00sec");indicateur++; break;
            case 3:
            if(key>='6'){
              break;
            }
            if (key <='5'){
              m1 = key - '0';Serial.print(h1);Serial.print(h2);Serial.print("H");Serial.print(m1);Serial.println("_min00sec");indicateur++; break;
            }
            case 4: m2 = key - '0';Serial.print(h1);Serial.print(h2);Serial.print("H");Serial.print(m1);Serial.print(m2);Serial.println("min_0sec");indicateur++; break;
            case 5:
            if(key>='6'){
              break;
            }
            if (key <='5'){
              s1 = key - '0';Serial.print(h1);Serial.print(h2);Serial.print("H");Serial.print(m1);Serial.print(m2);Serial.print("min");Serial.print(s1);Serial.println("_sec");indicateur++; break;
            }
            case 6: s2 = key - '0';Serial.print(h1);Serial.print(h2);Serial.print("H");Serial.print(m1);Serial.print(m2);Serial.print("min");Serial.print(s1);Serial.print(s2);Serial.print("sec");
       indicateur++;break;
            default: break;// ne devrait pas arriver 
          }
     
        }
        }
      }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec boucle for
    Par GLDRX dans le forum LabVIEW
    Réponses: 1
    Dernier message: 14/06/2010, 21h43
  2. Problème avec boucle for
    Par kayenne77 dans le forum Débuter
    Réponses: 1
    Dernier message: 10/03/2009, 08h09
  3. [batch] problème avec boucle for
    Par TanEk dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 22/04/2008, 14h41
  4. Problème avec boucle for() et action POST
    Par Oli_Ifre dans le forum Langage
    Réponses: 4
    Dernier message: 26/04/2007, 09h52
  5. [ActionScript] Problème avec boucle 'FOR'
    Par BnA dans le forum Flash
    Réponses: 7
    Dernier message: 02/11/2006, 09h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo