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 :

Faux résultat d'une multiplication


Sujet :

Arduino

  1. #1
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut Faux résultat d'une multiplication
    bonjour à vous,

    je suis en train de réaliser un code afin de réaliser un compte à rebours programmable.

    pour la phase de saisie, aucun souci.
    le temps est au format HHmmss avec des variables de type int h1, h2,m1,m2,s1,s2

    voici ma formule, où je transforme tout en secondes.
    vue le nombre la variable t est de type long (si de type int, même erreur)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    t=((((h1*10)+h2)*(3600))+(((m1*10)+m2)*60)+((s1*10)+s2));
       Serial.println(((h1*10)+h2)*(3600));
        Serial.println(t/3600);
    si je rentre 10H00min00sec,
    le resultat sur le sérial port pour (((h1*1+h2)*(3600)) est -29536 au lieu de 36000
    est pour (t/3600) le résultat est -8

    merci pour votre aide

  2. #2
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    En utilisant des int pour les 6 variables vous forcez le compilateur a faire le gros calcul en int et donc ça dépasse pendant le calcul

    (Êtes vous sûr que vos h1 h2 etc contiennent des chiffres ou est-ce le code ascii du caractère ?)

    Vu que c’est un temps j’utiliserais partout des unsigned long (uint32_t) ou je forcerais les constantes à suivre ce format aussi en ajoutant UL et dans ça cas les calculs intermédiaires seront promus en unsigned long

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    uint32_t t= 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);

  3. #3
    Membre éprouvé
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    février 2013
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Retraité des réseaux informatiques
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : février 2013
    Messages : 423
    Points : 1 065
    Points
    1 065
    Par défaut
    Bonsoir hugobeauce
    Citation Envoyé par hugobeauce Voir le message
    ...vue le nombre la variable t est de type long (si de type int, même erreur)
    Si tu déclares tes variables:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned long t, h1, h2, m1, m2, s1, s2;
    Ton code fonctionne. Sans le unsigned, tu est "victime" du bit de signe
    La prochaine fois, mets ton code en entier, c'est plus facile pour chercher.

    Cordialement
    jpbbricole
    L'expérience est la seule chose qu'il ne faut acheter que d'occasion!

  4. #4
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    merci à vous 2 pour votre aide.
    vos 2 réponses aident un peu, mais ça beug toujours.
    Au delà d'une certaine durée, on va directement sur "Boum"
    je me doutais bien du byte truc.

    Voici le code en entier


    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    //declaration des variables pour le compteur
     
    unsigned long h1=0;      //dizaine heure
    unsigned long h2=0;      //unité heure
    unsigned long m1=0;      //dizaine minute
    unsigned long m2=0;      //unité minute
    unsigned long s1=0;      //dizaine seconde
    unsigned long s2=0;      //unité seconde
     
    byte indicateur = 1;  
    unsigned long t=0;       //temps total en secondes
    uint32_t h=(t/3600);             //nombre d'heure
    uint32_t mn=((t/60)-60*h);       //nombre de minutes de 0 à 59
    uint32_t sec=(t%60);             //nombre de secondes de 0 à 59
     
    #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 );
     
    //initialisation du LCD I2C
    #include <Wire.h> 
    #include <LiquidCrystal_I2C.h>
     
    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
     
     
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Entrer temps HHmmss");
       lcd.init();                      // initialize the lcd 
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(0,0);
      lcd.print("Temps HHmmss?");
      lcd.setCursor(0,1);
      lcd.print("_0H00min00sec");
     
      // 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");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print("_H00min00sec");
            indicateur++; break;
            case 2: h2 = key - '0';Serial.print(h1);Serial.print(h2);Serial.println("H_0min00sec");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.print("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");
              lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
              lcd.setCursor(3,1);lcd.print(m1);lcd.print("_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");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
            lcd.setCursor(3,1);lcd.print(m1);lcd.setCursor(4,1);lcd.print(m2);lcd.setCursor(5,1);lcd.print("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");
              lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
              lcd.setCursor(3,1);lcd.print(m1);lcd.setCursor(4,1);lcd.print(m2);lcd.setCursor(5,1);lcd.print("min");
              lcd.setCursor(8,1);lcd.print(s1);lcd.setCursor(9,1);lcd.print("_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.println("sec");
            lcd.setCursor(0,0);lcd.print(h1);lcd.setCursor(1,0);lcd.print(h2);lcd.setCursor(2,0);lcd.print("H");
            lcd.setCursor(3,0);lcd.print(m1);lcd.setCursor(4,0);lcd.print(m2);lcd.setCursor(5,0);lcd.print("min");
            lcd.setCursor(8,0);lcd.print(s1);lcd.setCursor(9,0);lcd.print(s2);lcd.setCursor(10,0);lcd.print("sec");
       uint32_t t= 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);
           Serial.println("* VALIDER # CORR");
        lcd.setCursor(0,1);lcd.print("* VALIDER # CORR");
        indicateur++;break;
            default: break;// ne devrait pas arriver 
          }
     
        }
        }
        if (indicateur==7){
          char key = keypad.getKey();
     
        if ((key != NO_KEY) && (key == '*') or (key == '#')) {
          // on a reçu un appui et c’est * ou #
          if (key=='*'){
            Serial.println("temps validé");
            lcd.setCursor(0,1);lcd.print("Temps OK          ");
            indicateur=8;
          }
          if (key=='#'){
            Serial.println("entrer tps");
            indicateur=1;
          }
        }
        } 
        if(indicateur==8){
          lcd.clear();
          //Serial.print(t);
          while ( t > 0 ) {     //tant qu'il y a du temps
     uint32_t h=(t/3600);
      mn=((t/60)-60*h);
     sec=(t%60);
    digitalWrite(3, LOW);
          digitalWrite(2, HIGH);
     
     
        if (h>0)          //si le temps est > 1heure
        {
     
     
          Serial.print("0");
          Serial.print(h);
          Serial.print("h");
          lcd.setCursor(0,0);lcd.print("0");lcd.setCursor(1,0);lcd.print(h);lcd.setCursor(2,0);lcd.print("H"); 
          lcd.setCursor(0,1);lcd.print("oui");
     
          }
     
     
       if (h==0)//quand le temps est inférieur à 1heure, on supprime la valeur écrite
          {
            lcd.setCursor(0,0);lcd.print("   ");
            }
     if(((t/60)>=1))      // si le temps est > 1 minute
       {    
        if (mn>=10)       //si il y a pus de 10 minutes
        {
        Serial.print(mn);   //on écrit la caleur de min
        Serial.print("min");
        lcd.setCursor(3,0);lcd.print(mn);lcd.setCursor(5,0);lcd.print("min");
     
        }
        else                //sinon
        {
          Serial.print("0");   //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(mn);
          Serial.print("min");
          lcd.setCursor(3,0);lcd.print("0");lcd.setCursor(4,0);lcd.print(mn);lcd.setCursor(5,0);lcd.print("min");
        }
     
        if (sec>=10)        //s'il y a plus de 10 sec
        {
        Serial.print(sec);    // on affiche sec
        Serial.println("sec");
        lcd.setCursor(8,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        }
        else                //sinon
        {
          Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(sec);
          Serial.println("sec");
          lcd.setCursor(8,0);lcd.print("0");lcd.setCursor(9,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        }
        digitalWrite(2, LOW);
        delay(500);
          digitalWrite(2, HIGH);
        delay(500);
        t--;
    }
       else     //quand temps inférieur à 1 minute
       {
           if (sec>=10)        //s'il y a plus de 10 sec
        {
        Serial.print(sec);    // on affiche sec
        Serial.println("sec");
        lcd.setCursor(0,0);lcd.print("        ");
        lcd.setCursor(8,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        digitalWrite(2, LOW);
        delay(250);
          digitalWrite(2, HIGH);
        delay(250);
        digitalWrite(2, LOW);
        delay(250);
          digitalWrite(2, HIGH);
        delay(250);
        }
        else                //sinon
        {
          Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(sec);
          Serial.println("sec");
           lcd.setCursor(0,0);lcd.print("         ");
        lcd.setCursor(9,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        }
     
        t--;
        }
          }
          digitalWrite(3, HIGH);
          digitalWrite(2, LOW);
         Serial.println("Boum!");
         lcd.clear();
         lcd.print("Boum!");
         indicateur=1;
         Serial.println("Entrer temps HHmmss");
          }
     
    }

  5. #5
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Vos déclarez votre variable t en variable globale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     unsigned long t=0;       //temps total en secondes
    mais vous en ré déclarez une autre en local en ligne 111 qui va cacher l’autre... problème de portée de variables

    Virez le type devant t ligne 111 pour utiliser la variable globale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     uint32_t t= 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);

  6. #6
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut problème de temps dans la boucle
    bon bha cette fois ça fonctionne bien,
    merci pour votre aide.

    autre petit souci, sur le timing.
    Dans 1 premier temps, à la fin de chaque affichage, il y a un delay(1000) de façon à avoir une seconde sur la boucle suivante.

    J'ai fait un clignotement d'une diode sur chaque seconde HIGH/delay(500)/LOW/delay(500); ce qui fait toujours un total de 1000 sur le delay.
    sauf qu'avec un chrono, sur 2 minutes, on a 3 secondes de retard.
    Est-ce normal? comment remédier à cela?

    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    //declaration des variables pour le compteur
     
    unsigned long h1=0;      //dizaine heure
    unsigned long h2=0;      //unité heure
    unsigned long m1=0;      //dizaine minute
    unsigned long m2=0;      //unité minute
    unsigned long s1=0;      //dizaine seconde
    unsigned long s2=0;      //unité seconde
     
    byte indicateur = 1;  
    unsigned long t=0;       //temps total en secondes
    unsigned long h=(t/3600);             //nombre d'heure
    unsigned long mn=((t/60)-60*h);       //nombre de minutes de 0 à 59
    unsigned long sec=(t%60);             //nombre de secondes de 0 à 59
     
    #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 );
     
    //initialisation du LCD I2C
    #include <Wire.h> 
    #include <LiquidCrystal_I2C.h>
     
    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
     
     
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Entrer temps HHmmss");
       lcd.init();                      // initialize the lcd 
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(0,0);
      lcd.print("Temps HHmmss?");
      lcd.setCursor(0,1);
      lcd.print("_0H00min00sec");
     
      // 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");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print("_H00min00sec");
            indicateur++; break;
            case 2: h2 = key - '0';Serial.print(h1);Serial.print(h2);Serial.println("H_0min00sec");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.print("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");
              lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
              lcd.setCursor(3,1);lcd.print(m1);lcd.print("_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");
            lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
            lcd.setCursor(3,1);lcd.print(m1);lcd.setCursor(4,1);lcd.print(m2);lcd.setCursor(5,1);lcd.print("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");
              lcd.setCursor(0,1);lcd.print(h1);lcd.setCursor(1,1);lcd.print(h2);lcd.setCursor(2,1);lcd.print("H");
              lcd.setCursor(3,1);lcd.print(m1);lcd.setCursor(4,1);lcd.print(m2);lcd.setCursor(5,1);lcd.print("min");
              lcd.setCursor(8,1);lcd.print(s1);lcd.setCursor(9,1);lcd.print("_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.println("sec");
            lcd.setCursor(0,0);lcd.print(h1);lcd.setCursor(1,0);lcd.print(h2);lcd.setCursor(2,0);lcd.print("H");
            lcd.setCursor(3,0);lcd.print(m1);lcd.setCursor(4,0);lcd.print(m2);lcd.setCursor(5,0);lcd.print("min");
            lcd.setCursor(8,0);lcd.print(s1);lcd.setCursor(9,0);lcd.print(s2);lcd.setCursor(10,0);lcd.print("sec");
       t= 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);
           Serial.println("* VALIDER # CORR");
        lcd.setCursor(0,1);lcd.print("* VALIDER # CORR");
        indicateur++;break;
            default: break;// ne devrait pas arriver 
          }
     
        }
        }
        if (indicateur==7){
          char key = keypad.getKey();
     
        if ((key != NO_KEY) && (key == '*') or (key == '#')) {
          // on a reçu un appui et c’est * ou #
          if (key=='*'){
            Serial.println("temps validé");
            lcd.setCursor(0,1);lcd.print("Temps OK          ");
            indicateur=8;
          }
          if (key=='#'){
            Serial.println("entrer tps");
            indicateur=1;
          }
        }
        } 
        if(indicateur==8){
          lcd.clear();
          //Serial.print(t);
          while ( t > 0 ) {     //tant qu'il y a du temps
      h=(t/3600);
      mn=((t/60)-60*h);
     sec=(t%60);
    digitalWrite(3, LOW);
          digitalWrite(2, HIGH);
     
     
        if (h>=10)          //si le temps est > 1heure
        {   
           Serial.print(h);
          Serial.print("h");
          lcd.setCursor(0,0);lcd.print(h);lcd.setCursor(2,0);lcd.print("H"); 
          lcd.setCursor(0,1);lcd.print("oui");
     
          }
         if (h<10)          //si le temps est > 1heure
        {
     
     
          Serial.print("0");
          Serial.print(h);
          Serial.print("h");
          lcd.setCursor(0,0);lcd.print("0");lcd.setCursor(1,0);lcd.print(h);lcd.setCursor(2,0);lcd.print("H"); 
          lcd.setCursor(0,1);lcd.print("oui");
     
          }
     
       if (h==0)//quand le temps est inférieur à 1heure, on supprime la valeur écrite
          {
            lcd.setCursor(0,0);lcd.print("   ");
            }
     if(((t/60)>=1))      // si le temps est > 1 minute
       {    
        if (mn>=10)       //si il y a pus de 10 minutes
        {
        Serial.print(mn);   //on écrit la caleur de min
        Serial.print("min");
        lcd.setCursor(3,0);lcd.print(mn);lcd.setCursor(5,0);lcd.print("min");
     
        }
        else                //sinon
        {
          Serial.print("0");   //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(mn);
          Serial.print("min");
          lcd.setCursor(3,0);lcd.print("0");lcd.setCursor(4,0);lcd.print(mn);lcd.setCursor(5,0);lcd.print("min");
        }
     
        if (sec>=10)        //s'il y a plus de 10 sec
        {
        Serial.print(sec);    // on affiche sec
        Serial.println("sec");
        lcd.setCursor(8,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        }
        else                //sinon
        {
          Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(sec);
          Serial.println("sec");
          lcd.setCursor(8,0);lcd.print("0");lcd.setCursor(9,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        }
        digitalWrite(2, LOW);
        delay(500);
          digitalWrite(2, HIGH);
        delay(500);
        t--;
    }
       else     //quand temps inférieur à 1 minute
       {
           if (sec>=10)        //s'il y a plus de 10 sec
        {
        Serial.print(sec);    // on affiche sec
        Serial.println("sec");
        lcd.setCursor(0,0);lcd.print("        ");
        lcd.setCursor(8,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        digitalWrite(2, LOW);
        delay(250);
          digitalWrite(2, HIGH);
        delay(250);
        digitalWrite(2, LOW);
        delay(250);
          digitalWrite(2, HIGH);
        delay(250);
        }
        else                //sinon
        {
          Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
          Serial.print(sec);
          Serial.println("sec");
           lcd.setCursor(0,0);lcd.print("         ");
        lcd.setCursor(9,0);lcd.print(sec);lcd.setCursor(10,0);lcd.print("sec");
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        digitalWrite(2, LOW);
        delay(125);
          digitalWrite(2, HIGH);
        delay(125);
        }
     
        t--;
        }
          }
          digitalWrite(3, HIGH);
          digitalWrite(2, LOW);
         Serial.println("Boum!");
         lcd.clear();
         lcd.print("Boum!");
         indicateur=1;
         Serial.println("Entrer temps HHmmss");
          }
     
    }

  7. #7
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    Citation Envoyé par hugobeauce Voir le message
    bon bha cette fois ça fonctionne bien,
    J'ai fait un clignotement d'une diode sur chaque seconde HIGH/delay(500)/LOW/delay(500); ce qui fait toujours un total de 1000 sur le delay.
    sauf qu'avec un chrono, sur 2 minutes, on a 3 secondes de retard.
    Est-ce normal? comment remédier à cela?
    3 secondes sur 120 c'est 2,5% du temps --> c'est sans doute le temps passé par le code pour faire tout le reste (gérer le lcd, faire des maths etc). Vous travaillez aussi à 9600 bauds, et quand le buffer de 64 caractères est plein, la fonction print devient bloquante, donc ça peut aussi manger du temps là. passez à 115200 bauds

    en parlant du code, appuyez sur ctrl-T dans l'IDE pour indenter tout cela correctement, là c'est vraiment pas lisible... (et dans les case, ne tassez pas tout sur deux ou trois lignes, soit vous mettez chaque instruction sur sa ligne, soit si vous trouvez que c'est trop vous faites des petites fonctions associées à chaque case et virez les lignes vides qui n'ont pas vraiment de fonction de séparation sémantique.

    (au passage j'ai vu aussi que vous aviez deux fois lcd.init(); dans le setup() )

    concernant votre question, si vous voulez rester ajusté sur 1000 millisecondes, il faut gérer l'avancement non pas en faisant un delay() fixe, mais en attendant que millis() ait progressé de 1000

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    unsigned long chronoDepart = millis(); // le moment de départ
    ...
    ...
    ... // ici vous faites des choses
    ...
    ...
    while (millis() - chronoDepart <= 1000) ; // ne rien faire jusqu'à la prochaine seconde

  8. #8
    Rédacteur
    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    mars 2009
    Messages
    515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : mars 2009
    Messages : 515
    Points : 1 835
    Points
    1 835
    Par défaut
    Bonjour .

    J'ajouterai que ce n'est pas une très bonne idée d'utiliser la procédure delay() pour servir de base de temps à une application dont l'objet est, justement, de mesurer le temps. Cette procédure est bloquante, et donc, pendant la durée passée en paramètre, le programme est en stand by : rien ne se passe (ou presque, cf interruptions). Et c'est ce qui fait que le temps d'exécution du programme, qui ne peut tourner qu'une fois le délai passé, s'ajoute à ce délai.

    delay() ne devrait être utilisé, pour des temporisations importantes, comme c'est le cas ici, que pendant le setup(), par exemple pour laisser à une initialisation le temps de se faire, ou dans des programme d'exemple. Ton programme fonctionne bien, mais la dérive dans le temps peut le rendre inutilisable en fonction de la précision dont tu as besoin. Si c'est pour cuire des œufs à la coque, c'est suffisant .

    Pour faire un chrono, je te conseille plutôt la fonction millis(). Les résultats seront incomparables. Tu pourras trouver ici un sketch de démo.

    Il ne faut pas oublier non plus que, ni la fonction delay() ni la fonction millis() ne peuvent être considérées comme des bases de temps extrêmement fiables. Si une bonne précision est requise, il vaut mieux utiliser un shield temps réel.

    Amicalement,
    naute

  9. #9
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    merci JayM et Naute pour vos réponses.

    J'ai regardé en diagonale, et ça répond bien à mes attentes. Après tout le monde a l'aire de se casser la tête sur un problème qui n'en est pas forcément un.

    Si j'ai bien compris

    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
     
    const long interval = 1000;           // tu dis que tu veux un interval de 1000
    const long previousMillis=0;              //initialisation de la variable
     
    void setup() {
      //bla bla bla
    millis();                                // tu lances millis
    }
     
    void loop() {
     
      unsigned long currentMillis = millis();    // à chaque boucle, tu initialise currentMillis (ça s'incrémente 1,2,3,...100,...200,...…..1000?)
     
      if (currentMillis - previousMillis == interval) {     // quand millis-(valeur de millis boucle avant==1000 ; alors action
     
        previousMillis = currentMillis;      //tu attribus previousMillis pour la prochaine boucle.
    }
    }
    alors je suis un bon padaoine? ou pas?

  10. #10
    Membre confirmé
    Homme Profil pro
    savant fou
    Inscrit en
    septembre 2019
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : savant fou

    Informations forums :
    Inscription : septembre 2019
    Messages : 208
    Points : 480
    Points
    480
    Par défaut
    salut
    alors je suis un bon padaoine? ou pas?
    non ce n'est pas tout à fait bon...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const long interval = 1000;           // tu dis que tu veux un interval de 1000
    const long previousMillis=0;              //initialisation de la variable
    --> ce sont des temps, le second surtout lié à millis, donc il faut prendre des unsigned long et comme on va utiliser previousMillis, ça ne peut pas être une constante... donc mettre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const unsigned long interval = 1000UL;           // tu dis que tu veux un interval de 1000, le UL pour bien signifier que l'on comprend que c'est un Unsigned Long 
    unsigned long previousMillis=0;              //initialisation de la variable
    Il n'y a rien à lancer. cet appel ne sert à rien. millis() tourne tout seul pour vous.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    millis();                                // tu lances millis

    sur ce coup là c'est presque juste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      unsigned long currentMillis = millis();    // à chaque boucle, tu initialise currentMillis (ça s'incrémente 1,2,3,...100,...200,...…..1000?)
    à chaque boucle la variable currentMillis prend la valeur de millis() à l'entrée de la boucle, mais comme votre processeur pédale quand même un peu vite (suivant ce que fait la loop) on n'aura pas une incrémentation comme cela, on risque d'avoir 10 fois de suite 1, puis 10 fois de suite 2 etc par exemple si la boucle tourne en un dixième de milliseconde (le processeur exécute 16 millions d'instructions élémentaires par seconde, donc en un dixième de milliseconde (100 micro-secondes) il a quand même le temps de faire 1600 instructions (cycle d'horloge)...

    là encore c'est presque bon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (currentMillis - previousMillis == interval) {     // quand millis-(valeur de millis boucle avant==1000 ; alors action
    il ne faut pas tester si on est égal, mais si on est supérieur ou égal car il se peut que vous ratiez une milliseconde donc faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      if (currentMillis - previousMillis >= interval) {     // quand millis-(valeur de millis boucle avant est plus grand qu'une seconde alors action

    voilà, à part ça (et l'indentation, appuyez sur ctrl-T dans l'IDE) c'est bon

  11. #11
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    Merci Jay M, je vais tester un clignotement de led et après je teste ça dans mon code initiale.

    IDENTATION, c'est ton mot fétiche. LOL, je blague.

  12. #12
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    voilà, j'ai modifié le code, mais sur 5 minutes de décompte, le chrono m'affiche 5minutes 6secondes.

    C'est pas pour faire cuire des œufs à la coque, mais c'est balo.
    Peut-être qu'il y a une coquille dans le code??? qui est indenté (hi hi hi)

    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
     
    //declaration des variables pour le compteur
     
    unsigned long h1 = 0;    //dizaine heure
    unsigned long h2 = 0;    //unité heure
    unsigned long m1 = 0;    //dizaine minute
    unsigned long m2 = 0;    //unité minute
    unsigned long s1 = 0;    //dizaine seconde
    unsigned long s2 = 0;    //unité seconde
     
    byte indicateur = 1;  //dira quelle partie du codetime
    unsigned long t = 0;     //temps total en secondes
    unsigned long h = (t / 3600);         //nombre d'heure
    unsigned long mn = ((t / 60) - 60 * h); //nombre de minutes de 0 à 59
    unsigned long sec = (t % 60);         //nombre de secondes de 0 à 59
     
    //declaration d'un buzzer
    char DIO_Buzzer = 14 ;          //buzzer connecté broche 14
     
    const unsigned long interval = 1000;           // tu dis que tu veux un interval de 1000
    unsigned long previousMillis = 0;            //initialisation de la variable
    const int ledPin = 2;
    int ledState = LOW;
     
    #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 );
     
    //initialisation du LCD I2C
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
     
    LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
     
     
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Entrer temps HHmmss");
      lcd.init();                      // initialize the lcd
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(0, 0);
      lcd.print("Temps HHmmss?");
      lcd.setCursor(0, 1);
      lcd.print("_0H00min00sec");
     
      // 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(ledPin, OUTPUT);
      // pinMode(3, OUTPUT);
      millis();
    }
     
    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'; Serial.print(h1); Serial.println("_H00min00sec");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print("_H00min00sec");
              indicateur++; break;
            case 2: h2 = key - '0'; Serial.print(h1); Serial.print(h2); Serial.println("H_0min00sec");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.print("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");
                lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
                lcd.setCursor(3, 1); lcd.print(m1); lcd.print("_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");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
              lcd.setCursor(3, 1); lcd.print(m1); lcd.setCursor(4, 1); lcd.print(m2); lcd.setCursor(5, 1); lcd.print("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");
                lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
                lcd.setCursor(3, 1); lcd.print(m1); lcd.setCursor(4, 1); lcd.print(m2); lcd.setCursor(5, 1); lcd.print("min");
                lcd.setCursor(8, 1); lcd.print(s1); lcd.setCursor(9, 1); lcd.print("_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.println("sec");
              lcd.setCursor(0, 0); lcd.print(h1); lcd.setCursor(1, 0); lcd.print(h2); lcd.setCursor(2, 0); lcd.print("H");
              lcd.setCursor(3, 0); lcd.print(m1); lcd.setCursor(4, 0); lcd.print(m2); lcd.setCursor(5, 0); lcd.print("min");
              lcd.setCursor(8, 0); lcd.print(s1); lcd.setCursor(9, 0); lcd.print(s2); lcd.setCursor(10, 0); lcd.print("sec");
              t = 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);
              Serial.println("* VALIDER # CORR");
              lcd.setCursor(0, 1); lcd.print("* VALIDER # CORR");
              indicateur++; break;
            default: break;// ne devrait pas arriver
          }
     
        }
      }
      if (indicateur == 7) {
        char key = keypad.getKey();
     
        if ((key != NO_KEY) && (key == '*') or (key == '#')) {
          // on a reçu un appui et c’est * ou #
          if (key == '*') {
            Serial.println("temps validé");
            lcd.setCursor(0, 1); lcd.print("Temps OK          ");
            indicateur = 8;
          }
          if (key == '#') {
            Serial.println("entrer tps");
            indicateur = 1;
          }
        }
      }
      if (indicateur == 8) {
        lcd.clear();
        //Serial.print(t);
        while ( t > 0 ) {     //tant qu'il y a du temps
          h = (t / 3600);
          mn = ((t / 60) - 60 * h);
          sec = (t % 60);
          //digitalWrite(3, LOW);
          //digitalWrite(2, HIGH);
          unsigned long currentMillis = millis();    // à chaque boucle, tu initialise currentMillis
     
          if (h >= 10)        //si le temps est > 1heure
          {
            /* Serial.print(h);
              Serial.print("h");*/
            lcd.setCursor(0, 0); lcd.print(h); lcd.setCursor(2, 0); lcd.print("H");
            lcd.setCursor(0, 1); lcd.print("OUI");
     
          }
          if (h < 10)        //si le temps est > 1heure
          {
     
     
            /* Serial.print("0");
              Serial.print(h);
              Serial.print("h");*/
            lcd.setCursor(0, 0); lcd.print("0"); lcd.setCursor(1, 0); lcd.print(h); lcd.setCursor(2, 0); lcd.print("H");
            lcd.setCursor(0, 1); lcd.print("oui");
     
          }
     
          if (h == 0) //quand le temps est inférieur à 1heure, on supprime la valeur écrite
          {
            lcd.setCursor(0, 0); lcd.print("   ");
          }
          if (((t / 60) >= 1)) // si le temps est > 1 minute
          {
            if (mn >= 10)     //si il y a pus de 10 minutes
            {
              /*Serial.print(mn);   //on écrit la caleur de min
                Serial.print("min");*/
              lcd.setCursor(3, 0); lcd.print(mn); lcd.setCursor(5, 0); lcd.print("min");
     
            }
            else                //sinon
            {
              /*Serial.print("0");   //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(mn);
                Serial.print("min");*/
              lcd.setCursor(3, 0); lcd.print("0"); lcd.setCursor(4, 0); lcd.print(mn); lcd.setCursor(5, 0); lcd.print("min");
            }
     
            if (sec >= 10)      //s'il y a plus de 10 sec
            {
              /*Serial.print(sec);    // on affiche sec
                Serial.println("sec");*/
              lcd.setCursor(8, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
            }
            else                //sinon
            {
              /*Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(sec);
                Serial.println("sec");*/
              lcd.setCursor(8, 0); lcd.print("0"); lcd.setCursor(9, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
            }
            //tone(DIO_Buzzer,500,50);
            /* if (currentMillis - previousMillis <= 500) {     // quand millis-(valeur de millis boucle avant==1000 ; alors action
               digitalWrite(2, LOW);
              }*/
            if (currentMillis - previousMillis >= interval   ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
              previousMillis = currentMillis ;
              /* Serial.println(currentMillis );
                Serial.println(previousMillis );*/
              t--;
              if (ledState == LOW)
                ledState = HIGH;
              else ledState = LOW;
              digitalWrite(ledPin, ledState);
            }
          }
          else     //quand temps inférieur à 1 minute
          {
            if (sec >= 10)      //s'il y a plus de 10 sec
            {
              /*Serial.print(sec);    // on affiche sec
                Serial.println("sec");*/
              lcd.setCursor(0, 0); lcd.print("        ");
              lcd.setCursor(8, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
              //tone(DIO_Buzzer,500,50);
              if (currentMillis - previousMillis >= interval  ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
                previousMillis = currentMillis ;
                /* Serial.println(currentMillis );
                  Serial.println(previousMillis );*/
                t--;
                if (ledState == LOW)
                  ledState = HIGH;
                else ledState = LOW;
                digitalWrite(ledPin, ledState);
              }
            }
            else                //sinon
            {
              /* Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(sec);
                Serial.println("sec");*/
              lcd.setCursor(0, 0); lcd.print("         ");
              lcd.setCursor(9, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
              //tone(DIO_Buzzer,500,50);
              if (currentMillis - previousMillis >= interval   ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
                previousMillis = currentMillis ;
                t--;
                if (ledState == LOW)
                  ledState = HIGH;
                else ledState = LOW;
                digitalWrite(ledPin, ledState);
              }
            }
     
     
          }
        }
     
        Serial.println("Boum!");
        lcd.clear();
        lcd.print("Boum!");
        indicateur = 1;
        Serial.println("Entrer temps HHmmss");
      }
     
    }

  13. #13
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    septembre 2008
    Messages
    883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : septembre 2008
    Messages : 883
    Points : 2 874
    Points
    2 874
    Par défaut
    Bonjour

    Il subsiste une cause de retard dans cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    previousMillis = currentMillis;
    currentMillis peut valoir un peu plus de 1s de que previousMilis alors que dans le concept du programme il devrait valoir exactement 1s de plus. Les quelques ms prises en plus à chaque seconde viennent s'ajouter à la fin.
    A remplacer par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    previousMillis += interval;
    Par contre la précision du quartz est celle qu'il a (et pour faire fonctionner le micro, la précision n'a pas besoin d'être grande). Une tension d'alimentation peu stable réduit également la précision du quartz et en alimentation USB c'est le cas. Et pour finir le retard lors de la dernière comparaison n'est pas compensé.

    Delias

  14. #14
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    Bonjour Delias,

    bon on est presque au top.

    Sur la première seconde, le chrono défile à fond puis se stabilise et le décompte est bien régulier, sans dépassement ou retard.

    Est-ce que ça ne viendrait pas du fait que millis() est dans le setup et qu'il est parti quand tu tape le temps.
    Ne faudrait-il pas le faire partir quand tu appuie sur * pour valider le temps?(je viens d'essayer, c'est pareil )

    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
     
    //declaration des variables pour le compteur
     
    unsigned long h1 = 0;    //dizaine heure
    unsigned long h2 = 0;    //unité heure
    unsigned long m1 = 0;    //dizaine minute
    unsigned long m2 = 0;    //unité minute
    unsigned long s1 = 0;    //dizaine seconde
    unsigned long s2 = 0;    //unité seconde
     
    byte indicateur = 1;  //dira quelle partie du codetime
    unsigned long t = 0;     //temps total en secondes
    unsigned long h = (t / 3600);         //nombre d'heure
    unsigned long mn = ((t / 60) - 60 * h); //nombre de minutes de 0 à 59
    unsigned long sec = (t % 60);         //nombre de secondes de 0 à 59
     
    //declaration d'un buzzer
    char DIO_Buzzer = 14 ;          //buzzer connecté broche 14
     
    const unsigned long interval = 1000;           // tu dis que tu veux un interval de 1000
    unsigned long previousMillis = 0;            //initialisation de la variable
    const int ledPin = 2;
    int ledState = LOW;
     
    #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 );
     
    //initialisation du LCD I2C
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
     
    LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
     
     
    void setup()
    {
      Serial.begin(9600);   //Serial monitor
      Serial.println("Entrer temps HHmmss");
      lcd.init();                      // initialize the lcd
      lcd.init();
      // Print a message to the LCD.
      lcd.backlight();
      lcd.setCursor(0, 0);
      lcd.print("Temps HHmmss?");
      lcd.setCursor(0, 1);
      lcd.print("_0H00min00sec");
     
      // 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(ledPin, OUTPUT);
      // pinMode(3, OUTPUT);
      millis();
    }
     
    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'; Serial.print(h1); Serial.println("_H00min00sec");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print("_H00min00sec");
              indicateur++; break;
            case 2: h2 = key - '0'; Serial.print(h1); Serial.print(h2); Serial.println("H_0min00sec");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.print("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");
                lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
                lcd.setCursor(3, 1); lcd.print(m1); lcd.print("_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");
              lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
              lcd.setCursor(3, 1); lcd.print(m1); lcd.setCursor(4, 1); lcd.print(m2); lcd.setCursor(5, 1); lcd.print("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");
                lcd.setCursor(0, 1); lcd.print(h1); lcd.setCursor(1, 1); lcd.print(h2); lcd.setCursor(2, 1); lcd.print("H");
                lcd.setCursor(3, 1); lcd.print(m1); lcd.setCursor(4, 1); lcd.print(m2); lcd.setCursor(5, 1); lcd.print("min");
                lcd.setCursor(8, 1); lcd.print(s1); lcd.setCursor(9, 1); lcd.print("_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.println("sec");
              lcd.setCursor(0, 0); lcd.print(h1); lcd.setCursor(1, 0); lcd.print(h2); lcd.setCursor(2, 0); lcd.print("H");
              lcd.setCursor(3, 0); lcd.print(m1); lcd.setCursor(4, 0); lcd.print(m2); lcd.setCursor(5, 0); lcd.print("min");
              lcd.setCursor(8, 0); lcd.print(s1); lcd.setCursor(9, 0); lcd.print(s2); lcd.setCursor(10, 0); lcd.print("sec");
              t = 3600UL * (10UL * h1 + h2) + 60UL * (10UL * m1 + m2) +  (10UL * s1 + s2);
              Serial.println("* VALIDER # CORR");
              lcd.setCursor(0, 1); lcd.print("* VALIDER # CORR");
              indicateur++; break;
            default: break;// ne devrait pas arriver
          }
     
        }
      }
      if (indicateur == 7) {
        char key = keypad.getKey();
     
        if ((key != NO_KEY) && (key == '*') or (key == '#')) {
          // on a reçu un appui et c’est * ou #
          if (key == '*') {
            Serial.println("temps validé");
            lcd.setCursor(0, 1); lcd.print("Temps OK          ");
            indicateur = 8;
          }
          if (key == '#') {
            Serial.println("entrer tps");
            indicateur = 1;  //millis(); ça fait la même chose, défilement rapide pendant 1 seconde
          }
        }
      }
      if (indicateur == 8) {
        lcd.clear();
        //Serial.print(t);
        while ( t > 0 ) {     //tant qu'il y a du temps
          h = (t / 3600);
          mn = ((t / 60) - 60 * h);
          sec = (t % 60);
          //digitalWrite(3, LOW);
          //digitalWrite(2, HIGH);
          unsigned long currentMillis = millis();    // à chaque boucle, tu initialise currentMillis
     
          if (h >= 10)        //si le temps est > 1heure
          {
            /* Serial.print(h);
              Serial.print("h");*/
            lcd.setCursor(0, 0); lcd.print(h); lcd.setCursor(2, 0); lcd.print("H");
            lcd.setCursor(0, 1); lcd.print("OUI");
     
          }
          if (h < 10)        //si le temps est > 1heure
          {
     
     
            /* Serial.print("0");
              Serial.print(h);
              Serial.print("h");*/
            lcd.setCursor(0, 0); lcd.print("0"); lcd.setCursor(1, 0); lcd.print(h); lcd.setCursor(2, 0); lcd.print("H");
            lcd.setCursor(0, 1); lcd.print("oui");
     
          }
     
          if (h == 0) //quand le temps est inférieur à 1heure, on supprime la valeur écrite
          {
            lcd.setCursor(0, 0); lcd.print("   ");
          }
          if (((t / 60) >= 1)) // si le temps est > 1 minute
          {
            if (mn >= 10)     //si il y a pus de 10 minutes
            {
              /*Serial.print(mn);   //on écrit la caleur de min
                Serial.print("min");*/
              lcd.setCursor(3, 0); lcd.print(mn); lcd.setCursor(5, 0); lcd.print("min");
     
            }
            else                //sinon
            {
              /*Serial.print("0");   //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(mn);
                Serial.print("min");*/
              lcd.setCursor(3, 0); lcd.print("0"); lcd.setCursor(4, 0); lcd.print(mn); lcd.setCursor(5, 0); lcd.print("min");
            }
     
            if (sec >= 10)      //s'il y a plus de 10 sec
            {
              /*Serial.print(sec);    // on affiche sec
                Serial.println("sec");*/
              lcd.setCursor(8, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
            }
            else                //sinon
            {
              /*Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(sec);
                Serial.println("sec");*/
              lcd.setCursor(8, 0); lcd.print("0"); lcd.setCursor(9, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
            }
            //tone(DIO_Buzzer,500,50);
            /* if (currentMillis - previousMillis <= 500) {     // quand millis-(valeur de millis boucle avant==1000 ; alors action
               digitalWrite(2, LOW);
              }*/
            if (currentMillis - previousMillis >= interval   ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
              previousMillis +=interval;// currentMillis ;
              /* Serial.println(currentMillis );
                Serial.println(previousMillis );*/
              t--;
              if (ledState == LOW)
                ledState = HIGH;
              else ledState = LOW;
              digitalWrite(ledPin, ledState);
            }
          }
          else     //quand temps inférieur à 1 minute
          {
            if (sec >= 10)      //s'il y a plus de 10 sec
            {
              /*Serial.print(sec);    // on affiche sec
                Serial.println("sec");*/
              lcd.setCursor(0, 0); lcd.print("        ");
              lcd.setCursor(8, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
              //tone(DIO_Buzzer,500,50);
              if (currentMillis - previousMillis >= interval  ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
                previousMillis += interval;//currentMillis ;
                /* Serial.println(currentMillis );
                  Serial.println(previousMillis );*/
                t--;
                if (ledState == LOW)
                  ledState = HIGH;
                else ledState = LOW;
                digitalWrite(ledPin, ledState);
              }
            }
            else                //sinon
            {
              /* Serial.print("0");  //on ajoute un 0 pour avoir 2 chiffres
                Serial.print(sec);
                Serial.println("sec");*/
              lcd.setCursor(0, 0); lcd.print("         ");
              lcd.setCursor(9, 0); lcd.print(sec); lcd.setCursor(10, 0); lcd.print("sec");
              //tone(DIO_Buzzer,500,50);
              if (currentMillis - previousMillis >= interval   ) {    // quand millis-(valeur de millis boucle avant==1000 ; alors action
                previousMillis +=interval;// currentMillis ;
                t--;
                if (ledState == LOW)
                  ledState = HIGH;
                else ledState = LOW;
                digitalWrite(ledPin, ledState);
              }
            }
     
     
          }
        }
     
        Serial.println("Boum!");
        lcd.clear();
        lcd.print("Boum!");
        indicateur = 1;
        Serial.println("Entrer temps HHmmss");
      }
     
    }

  15. #15
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    septembre 2008
    Messages
    883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : septembre 2008
    Messages : 883
    Points : 2 874
    Points
    2 874
    Par défaut
    La réponse est ici:
    Citation Envoyé par Jay M Voir le message
    Il n'y a rien à lancer. cet appel ne sert à rien. millis() tourne tout seul pour vous.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    millis();                                // tu lances millis
    Et d'ailleurs le commentaire de cette ligne de code est juste faux.

    millis(); c'est le temps écoulé depuis la mise sous tension de l'Arduino (enfin presque mais c'est surtout avant l'appel à setup();).
    Par contre il manque previousMillis:=millis(); au démarrage du timer. Puisque au lancement du compte à rebours la valeur retournée par millis() ne vaut pas zéro, il faut bien la stocker comme valeur de départ pour le décompte du temps.
    Puisque previousMillis est juste initialisé à 0 dans sa déclaration, ton programme décompte le temps passé dans le setup();


    Delias

  16. #16
    Membre à l'essai
    Homme Profil pro
    pompier
    Inscrit en
    janvier 2020
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Eure et Loir (Centre)

    Informations professionnelles :
    Activité : pompier

    Informations forums :
    Inscription : janvier 2020
    Messages : 35
    Points : 13
    Points
    13
    Par défaut
    B.R.A.V.O.

    ça marche. Merci à tous pour vos précieux commentaires.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 16/09/2013, 21h23
  2. Réponses: 2
    Dernier message: 08/04/2012, 10h12
  3. Réponses: 2
    Dernier message: 31/08/2007, 00h03
  4. Réponses: 5
    Dernier message: 04/07/2006, 12h19

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