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 :

Action effectuée quand même dans un if n'ayant pas ses conditions vraies


Sujet :

Arduino

  1. #1
    Candidat au Club
    Homme Profil pro
    Concepteur de machine spéciale
    Inscrit en
    Décembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Concepteur de machine spéciale
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Action effectuée quand même dans un if n'ayant pas ses conditions vraies
    Bonjour à tous,

    Je suis nouveau sur le forum et j'apprécie déjà beaucoup cet endroit^^

    Je travaille en ingé méca et je viens de me lancer dans le C++ depuis peu pour bricoler le weekend. Je ne connaissais jusqu'à maintenant que les langages d'automatisme indus.
    Je suis en train de remplacer l'électronique de mon sèche linge afin d'avoir un afficheur LCD des capteurs d'humidité, horloge, consommation ect

    J’espère que quelqu'un pourra m'apprendre ce qui cloche dans l'extrait de mon code ci dessous (j'ai enlever tout le reste pour que mon problème soit plus lisible):

    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
    void setup() {
      Serial.begin(9600); 
     
    }
     
    void loop() {
     
    bool Sel;
    unsigned char Nav;
    bool Disptime;
     
      Serial.print ("avant le if :");Serial.print (Sel);Serial.print (Nav);Serial.println (Disptime);
    //le resultat print est=> 000
    if (Sel == true && Nav==5){
      Disptime = true;
        }
    //le résultat print est=> 001 
    //Pourquoi l'état change alors que les conditions du if ne sont pas atteintes???????!!!
      Serial.print ("après le if :");Serial.print (Sel);Serial.print (Nav);Serial.println (Disptime);
    Serial.println();
      delay(2000);
    }
    //le "bug" est contourner si je déplace "bool Disptime;" en variable globale..
    //mais Pourquoi??? je peut aussi init la variable en false à chaque scrutations mais 
    //je ne veut pas faire ça.
    J'arrive facilement à contourner le problème en créant une variable globale mais j'aimerais vraiment comprendre pourquoi Disptime change d'état alors que les conditions du if ne sont pas atteintes.. Si je supprime la ligne dans le if, la variable ne change pas.

    Merci d'avance pour votre aider
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés

  2. #2
    Membre émérite
    Avatar de jpbbricole
    Homme Profil pro
    Retraité des réseaux informatiques
    Inscrit en
    Février 2013
    Messages
    1 012
    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 : 1 012
    Points : 2 341
    Points
    2 341
    Par défaut
    Bonjour Merlin.p

    Je ne suis de loin pas une "pointure" en langage C++ Arduino, mais dans ta déclaration de variable, tu ne mets pas de valeurs dans tes variables:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	bool Sel;
    	unsigned char Nav;
    	bool Disptime;
    Donc tu fais une comparaison == avec ???

    Si tu leur attribue une valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	bool Sel = true;
    	unsigned char Nav = 4;
    	bool Disptime;
    la "mécanique" du if fonctionne.

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

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Tes variables ne sont pas initialisées et donc une valeur que tu ne maitrises pas. Vu ton m'affiche, c'est quand même bizarre que tu rentres dans le if...

    En mettant tes variables en globales, elles ont une valeur par défaut (0, false, nullptr, etc), d'où un changement possible de comportement.

  4. #4
    Candidat au Club
    Homme Profil pro
    Concepteur de machine spéciale
    Inscrit en
    Décembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Concepteur de machine spéciale
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Merci pour vos réponses. Oui le fais d'initialiser mes variables dans la loop est une solution de contournement du problème.
    Effectivement si je déclare ET init la variable dans la loop, elle ne change pas d'état au passage du if.
    En pratique, je ne veux pas le faire dans mon soft vu que le but n'est pas de réinit la variable en false à chaque boucle...
    Le problème est contourné en créant une variable globale (même sans init dans le setup...). C'est ce que j'ai fais directement.
    Mais pour moi le mystère reste entier.

    Pour clarifier ce qui me perturbe:

    Je déclare une variable dans une loop (je ne l'initialise pas) jusque la rien d'étrange..
    Je constate avec un Serial.print que les variables sont toutes à 0 juste après les avoir déclarées (ligne 12)
    Je passe au-dessus d'un if dont les conditions ne sont PAS atteinte (preuve lors du print ligne 12, les valeurs n'atteignent aucune des conditions)
    Ce que contient le if ne devrais rien changer normalement non? Vu que la condition n'est pas atteinte... Pourtant, la variable passe à true! Puis la variable passe à nouveau false a la loop suivante, alors que nul part on la force en false.
    Dans le forme, ça ne me pose pas de problème de déclarer ma variable en globale puis de l'init dans le setup.
    Mais dans le fond, j'aimerais comprendre pourquoi, ce qui est à l'intérieur d'un if faux, modifie l'état d'une variable??
    Peut-être s'agirait t-il d'un bug du compilateur de l'IDE Arduino? Est-ce qu'en faisant exactement la même chose en python par exemple, on reproduit le problème?

    Vous trouverez ci dessous mon programme entier:
    (pour le moment c'est un peu le chantier, il est en cours. Je n'ai pas bien fais l'indentation et il peut être simplifié. Certains truc ne servent plus ou pas encore. Mais il compile et fonctionne comme prévu avec les var globale)
    Si vous avez des remarques pour l'améliorer, bien-sûr je suis preneur^^Je suis un Noob de 2mois...

    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
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    #include <LiquidCrystal_I2C.h>
    #include <cactus_io_DHT22.h>
    #include <Wire.h>
    #define DHT22IN_PIN 5 
    #define DHT22OUT_PIN 6 
    #define DS3231_I2C_ADDRESS 0x68
    #define SEL 7
    #define CLK 2// Connected to CLK of encoder
    #define DT 4 // Connected to DT of encoder
     
    DHT22 dhtIN(DHT22IN_PIN); // Initialize DHT sensor IN
    DHT22 dhtOUT(DHT22OUT_PIN); // Initialize DHT sensor OUT
    LiquidCrystal_I2C lcd(0x20,16,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display
     
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
      return( (val/10*16) + (val%10) );
    }
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
      return( (val/16*10) + (val%16) );
    }
     
    //encoder
    volatile int encoderPosCount = 0; 
    volatile unsigned char CLKLast;  
    volatile unsigned char aVal;
    volatile unsigned char LimitEncoder;
    bool ClearTheLCD;
     
    bool Auto;                //Choice 1
    bool Stat;                //Choice 2         
    bool SetTime;             //Choice 3
    bool DisplaySensor;       //Choice 4
    bool Disptime;            //choice 5
    bool Mainmenu;
     
    void setup()
    {
      Serial.begin(9600); 
      dhtIN.begin();
      dhtOUT.begin();
      lcd.init();                      // initialize the lcd 
      // Print a message to the LCD.
      lcd.backlight();
      Wire.begin();
      // set the initial time here:
      // DS3231 seconds, minutes, hours, day, date, month, year
      //setDS3231time(00,02,0,1,24,12,18);
    pinMode (CLK,INPUT);
    pinMode (DT,INPUT);
    pinMode (SEL, INPUT);
    //CLKLast = digitalRead(CLK); 
     
    bool Auto=false;                //Choice 1
    bool Stat=false;                //Choice 2         
    bool SetTime=false;             //Choice 3
    bool DisplaySensor=false;       //Choice 4
    bool Disptime=false;            //choice 5
    bool Mainmenu=true;
    attachInterrupt(0, encoder, CHANGE);
     
    }  
     
    void loop(){
     
    delay(500);
    bool SensInOK=true;
    bool SensOutOK=true;          
    bool Sel;
    unsigned char Nav;
     
     
    Sel = digitalRead(SEL);
    //Serial.println(Mainmenu);
      LimitEncoder = 8;
      //encoder();
      Nav = encoderPosCount;
     
    if (ClearTheLCD==true){
      lcd.clear();
      ClearTheLCD=false;  
    }
     
     if(!Auto&&!Stat&&!SetTime&&!DisplaySensor&&!Disptime){
      Mainmenu=true;
    }
    if (Mainmenu==true){
      LimitEncoder = 8;
      Nav = encoderPosCount;
     
          switch(Nav){
     
            case 0:
              lcd.setCursor(0,0);
              lcd.print("Automatic");
              break;
            case 2:
              lcd.setCursor(0,0);
              lcd.print("Statistics");
              break;
            case 4:
              lcd.setCursor(0,0);
              lcd.print("Set Time");
              break;  
            case 6:
              lcd.setCursor(0,0);
              lcd.print("Display Sensors");
                if (Sel == true){
                DisplaySensor = true;
                Mainmenu = false;
                lcd.clear();
                }          
              break;
            case 8:
              lcd.setCursor(0,0);
              lcd.print("Display time");
                if (Sel == true){
                Disptime = true;
                Mainmenu = false;
                lcd.clear();
                }
              break;    
              }
    }
     
     
     
     
        // Check if any reads failed IN and exit early (to try again).
      if (isnan(dhtIN.humidity) || isnan(dhtIN.temperature_C)) {
          SensInOK = false;
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Sensor Hum&temp IN");
          lcd.setCursor(0,1);
          lcd.print("IN read failure!");
          Serial.print(SensInOK);
          delay(2000);
      }
      else SensInOK=true;
     
        // Check if any reads failed OUT and exit early (to try again).
      if (isnan(dhtOUT.humidity) || isnan(dhtOUT.temperature_C)) {
          SensOutOK = false;
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("Sensor Hum&temp OUT");
          lcd.setCursor(0,1);
          lcd.print("OUT read failure!");
          delay(2000);
      }
      else SensOutOK=true;
     
    if (SetTime==true){
     
    }
     
    if (Auto==true&&SensInOK==true&&SensOutOK){
     
    }
    if (Stat==true){
     
    }
    if (DisplaySensor == true){
     
      dhtIN.readHumidity();
      dhtIN.readTemperature();
      dhtOUT.readHumidity();
      dhtOUT.readTemperature();
      if (SensInOK == true&&SensOutOK==true ){
     
      lcd.setCursor(0,0);
      lcd.print("IN ");
      lcd.setCursor(3,0);
      lcd.print(dhtIN.humidity);
      lcd.setCursor(8,0);
      lcd.print("% t");
      lcd.setCursor(11,0);
      lcd.print(dhtIN.temperature_C);        
     
     
      lcd.setCursor(0,1);
      lcd.print("OUT");
      lcd.setCursor(3,1);
      lcd.print(dhtOUT.humidity);
      lcd.setCursor(8,1);
      lcd.print("% t");
      lcd.setCursor(11,1);
      lcd.print(dhtOUT.temperature_C);
      }
     
     delay(2000);
        if (Nav!=6){
        lcd.clear();
        DisplaySensor = false;
        encoderPosCount = 0;
      }  
    }
    if (Disptime==true){
      displayTime(); // display the real-time clock data on the LCD
        if (Nav!=8){
        lcd.clear();
        Disptime = false;
        encoderPosCount = 0;
      }  
    }
     
    }//end of loop
     
     
    void encoder (){  //encoder ISR
    aVal = digitalRead(CLK);
              if (aVal != CLKLast){ // if the knob is rotating, we need to determine direction
              // We do that by reading pin B.
                  //lcd.clear();
                  if (digitalRead(DT) != aVal && encoderPosCount <= (LimitEncoder-1)) {  
                    // Means pin A Changed first-We're Rotating Clockwise
                  encoderPosCount ++;
                  } 
                  else if (encoderPosCount >=1){// Otherwise B changed first and we're moving CCW
                  encoderPosCount--;
                  }
                    Serial.print("Encoder Position: ");
                    Serial.println(encoderPosCount);    
                    }
              CLKLast = aVal;
              ClearTheLCD =true;  
    } //Fin encoder    
     
    void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
    {
      // sets time and date data to DS3231
      Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0); // set next input to start at the seconds register
      Wire.write(decToBcd(second)); // set seconds
      Wire.write(decToBcd(minute)); // set minutes
      Wire.write(decToBcd(hour)); // set hours
      Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
      Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
      Wire.write(decToBcd(month)); // set month
      Wire.write(decToBcd(year)); // set year (0 to 99)
      Wire.endTransmission();
    }
    void readDS3231time(byte *second,byte *minute,byte *hour,byte *dayOfWeek,byte *dayOfMonth,byte *month,byte *year)
    {
      Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0); // set DS3231 register pointer to 00h
      Wire.endTransmission();
      Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
      // request seven bytes of data from DS3231 starting from register 00h
      *second = bcdToDec(Wire.read() & 0x7f);
      *minute = bcdToDec(Wire.read());
      *hour = bcdToDec(Wire.read() & 0x3f);
      *dayOfWeek = bcdToDec(Wire.read());
      *dayOfMonth = bcdToDec(Wire.read());
      *month = bcdToDec(Wire.read());
      *year = bcdToDec(Wire.read());
    }
    void displayTime()
    {
      byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
      // retrieve data from DS3231
      readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
      &year);
      // send it to the serial monitor
      lcd.setCursor(0,0);
      lcd.print(hour, DEC);
      // convert the byte variable to a decimal number when displayed
      lcd.setCursor(2,0);  
      lcd.print("h");
      if (minute<10)
      { 
        lcd.setCursor(3,0);
        lcd.print("0");
      }
      lcd.setCursor(3,0);
      lcd.print(minute, DEC);
      lcd.setCursor(5,0);
      lcd.print(":");
      if (second<10)
      {
        lcd.setCursor(7,0);
        lcd.print(" ");
      }
      lcd.setCursor(6,0);
      lcd.print(second, DEC);
     
      lcd.setCursor(8,0);
      lcd.print(" ");
      lcd.setCursor(0,1);
      lcd.print(dayOfMonth, DEC);
      lcd.setCursor(2,1);
      lcd.print("/");
      lcd.setCursor(3,1);
      lcd.print(month, DEC);
      lcd.setCursor(5,1);
      lcd.print("/");
      lcd.setCursor(6,1);
      lcd.print(year, DEC);
     
      switch(dayOfWeek){
      case 1:
        lcd.setCursor(9,1);
        lcd.print("Sunday   ");
        break;
      case 2:
        lcd.setCursor(9,1);
        lcd.print("Monday   ");
        break;
      case 3:
        lcd.setCursor(9,1);
        lcd.print("Tuesday  ");
        break;
      case 4:
        lcd.setCursor(9,1);
        lcd.print("Wednesday");
        break;
      case 5:
        lcd.setCursor(9,1);
        lcd.print("Thursday");
        break;
      case 6:
        lcd.setCursor(9,1);
        lcd.print("Friday");
        break;
      case 7:
        lcd.setCursor(9,1);
        lcd.print("Saturday");
        break;
      }
     
    }

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Merlin.p Voir le message
    Je déclare une variable dans une loop (je ne l'initialise pas) jusque la rien d'étrange..
    Si, c'est anormal !!! Si je compile ton code sur mon PC pour créer une programme Windows, gcc me sort des warnings. Exemple :
    warning: 'Sel' is used uninitialized in this function [-Wuninitialized]
    Citation Envoyé par Merlin.p Voir le message
    Peut-être s'agirait t-il d'un bug du compilateur de l'IDE Arduino?
    C'est un undefined behavior : https://stackoverflow.com/questions/...fined-behavior
    Le compilateur peut faire ce qu'il veut et donc tu ne peux rien déduire de son comportement. En tout cas, c'est la théorie avec les undefined behaviors.
    Dans la réalité, tu printes les valeurs avant le if, je m'attendrais à ce qu'il ne rentre pas dedans. Pour lever tout doute, rajoute un Serial.println("on est dans le if"); au bon endroit.

    Citation Envoyé par Merlin.p Voir le message
    Est-ce qu'en faisant exactement la même chose en python par exemple, on reproduit le problème?
    Non, parce qu'en Python toutes tes variables ont des initialisations par défaut. C'est le cas en C pour les variables globales, mais pas pour les variables locales à une fonction.

  6. #6
    Candidat au Club
    Homme Profil pro
    Concepteur de machine spéciale
    Inscrit en
    Décembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Concepteur de machine spéciale
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Aaaa super, je comprend mieux. Merci!
    Je n'avais pas encore la notion de undefined behavior. L'IDE Arduino ne préviens pas de ça. C'est bon à savoir!
    J'avais déja testé le print dans le if. Effectivement, l'action ne sort pas, seul la variable est impactée.
    J'avais constaté pleins de choses reproductibles mais illogiques, comme par exemple si j'ajoute un autre if sans condition atteinte en amont:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (Sel == true && Nav==5){
      Disptime = false;
        }  
     
    if (Sel == true && Nav==8){
      Disptime = true;
        }
    je ne rentre dans aucun d'eux, mais en pratique la variable reste à zéro..

    Les comportements sont tout à fais reproductible d'un cas à l'autre mais complètement erratique!

    Ton explication me rassure beaucoup

    Pour résumer ce que je retient de l’expérience:

    Dans mon cas, utiliser une variable globale me convient. Ça résous mon bug, vu qu'une var globale est init forcément à zéro (si aucune instruction d'init contraire)
    Les variables locale sont souvent très utile. Il arrive que l'on ne puisse pas les init à chaque loop..

    par exemple:
    Si je crée un ISR, j'ai pas forcément envi de passer par des var globale qui vont charger ma RAM inutilement car je devrais les mettre en volatile.
    Si dans cet ISR j'ai envi de mettre une petite char pour compter un truc, je ne veut pas init ma variable à chaque fois!

    Le problème de undefined behavior est lié au fais de laisser une variable locale en errance, sans instructions. Il ne viens pas du fais de ne pas l'initialiser.
    Si dans mon cas, j'avais eu besoin d'une var locale sans l'init à chaque loop, est ce que l'écriture suivante règle le problème "proprement" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (Sel == true && Nav==5){
      Disptime = true;
        }
        else Disptime = false;
    tout simplement Non?... Le message à comprendre pour ceux qui rencontrerons le même soucis, n'est pas d'init forcément les variables ou les mettre en globale. Il faut juste savoir que les variables locales non initialisées sont instables tant qu'elle ne rencontre pas d'instruction claire. Cette subtilité entre globale et locale est primordiale. Est ce que c'est ça?

  7. #7
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Bonjour,

    juste une petite remarque :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (Sel == true && Nav==5)
        Disptime = true;
    else 
        Disptime = false;

    Tu peux simplifier ce genre d'instructions en écrivant
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    Disptime = (Sel == true && Nav==5);

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Globalement c'est ça.

    Pour savoir si tu as besoin d'une variable locale ou globale, il faut répondre à la question : où ai-je besoin de ma variable ? Si tu as besoin d'une variable dans une fonction uniquement, par exemple pour faire un calcul et que cette variable ne sert plus quand on sort de la fonction, alors tu as besoin d'une variable locale. Si tu as besoin d'une variable dans plusieurs fonctions différentes, alors une variable globale est peut-être la solution. J'insiste sur le "peut-être" car une variable globale est rarement une bonne solution. En effet, tu peux passer des paramètres à une fonction et donc cette variable dont tu as besoin dans plusieurs fonctions peut être passées en paramètres. Il y a des tonnes d'articles sur internet expliquant pourquoi les variables globales, c'est (en général) mal. Il y a une contre-indication et c'est justement les interruptions : une fonction d'interruption ne prend pas de paramètre et ne renvoie rien. Si par exemple ta fonction loop() regarde la valeur d'un flag (TRUE ou FALSE) pour effectuer ou pas un traitement, et que tu souhaites qu'une interruption générée par un bouton poussoir change l'état de ce flag, tu es obligé de passer par une variable globale.

    De manière générale, une variable doit être initialisée avant d'être utilisée (*). Je ne sais ce que tu entends par "instruction claire". Certains compilateurs utilisent un message comme "variable xxx is read before it is initialized" pour le même type de warning. La solution ? Moi j'utilise toujours une initialisation avec une valeur qui me va bien. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool flag = false;
    if(condition) flag = true;
    Inutile de mettre un else pour un booléen : la valeur initiale est là pour ça. La solution d'Auteur est également bien pratique, je m'en sers également, ça fait la même chose mais peut être plus lisible dans les cas simples.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if (Sel == true && Nav==5){
      Disptime = true;
        }
        else Disptime = false;
    Ca ne règle rien si Sel et/ou Nav ne sont pas initialisées !

    Je n'avais pas encore la notion de undefined behavior. L'IDE Arduino ne préviens pas de ça. C'est bon à savoir!
    Personne ne t'avertira des undefined behaviors. C'est le pire truc du C (et du C++ par la même occasion). Pour moi, c'est loin devant les pointeurs, la différence entre pointeur et tableau, ou encore les chaines de caractères char*. Sans devenir paranoaique (surtout en tant que débutant pour du code d'amusement), il faut avoir conscience du problème.

    Un peu de lecture :
    https://en.cppreference.com/w/cpp/language/ub (pour toi, voir notamment la section Uninitialized scalar)
    https://markshroyer.com/2012/06/c-both-true-and-false/ (on dirait ton cas)
    http://blog.llvm.org/2011/05/what-ev...ould-know.html

  9. #9
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Citation Envoyé par Bktero
    Il y a une contre-indication et c'est justement les interruptions : une fonction d'interruption ne prend pas de paramètre et ne renvoie rien. Si par exemple ta fonction loop() regarde la valeur d'un flag (TRUE ou FALSE) pour effectuer ou pas un traitement, et que tu souhaites qu'une interruption générée par un bouton poussoir change l'état de ce flag, tu es obligé de passer par une variable globale.
    j'ajouterai un point important : dans le cas des interruptions, les variables globales doivent être déclarées volatile également. Par exemple :
    https://www.arduino.cc/reference/en/...tachinterrupt/

  10. #10
    Candidat au Club
    Homme Profil pro
    Concepteur de machine spéciale
    Inscrit en
    Décembre 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Concepteur de machine spéciale
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2018
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    Merci pour vos réponses

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 19/11/2008, 09h06
  2. Réponses: 9
    Dernier message: 23/06/2008, 15h54
  3. Réponses: 7
    Dernier message: 05/09/2007, 10h39
  4. [Dates] Action à effectuer quand date1 est > a Date2
    Par bilou95 dans le forum Langage
    Réponses: 2
    Dernier message: 14/12/2006, 09h31
  5. boucle simple dans une dataGrid avec quand même une erreur !
    Par fkr dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 07/11/2005, 15h04

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