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 :

Un IF récalcitrant


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Coach
    Inscrit en
    Novembre 2019
    Messages
    228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Coach

    Informations forums :
    Inscription : Novembre 2019
    Messages : 228
    Par défaut Un IF récalcitrant
    Bonjour,

    Comme toujours après avoir passé des heures sur un programme, on finit par ne plus voir ce qui est sans doute évident....

    J'ai une fonction appelée f3 qui ne doit pouvoir faire quelque chose QUE si une variable nommée "active_input" prend un certaine valeur, en l'occurrence la valeur "REW_CUEING_1/3rd".

    Le code de f3 commence donc par un test (voir si active_input a une valeur autorisant f3 à continuer), qui, s'il n'est pas satisfait, interdit à fd'exécuter les actions qu'elle est sensée faire;

    Le code et la sortie du Moniteur série se trouvent ci-dessous, mais je ne comprends pas pourquoi rien ne se passe alors que le test devrait être satisfait puisque "active_input" a bien la valeur souhaitée ???

    Voici la sortie du Moniteur Série:
    Nom : if de F3_M.JPG
Affichages : 272
Taille : 66,3 Ko

    et le code:
    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
     
    void f3()
    	{	//les 5 lignes ci-dessous permettent de connaitre les valeurs des booléens permettant ou pas,
    		// d'enclancher les actions de f3
    		Serial.print(F("Entrée dans void f3: valeur de status_rew_engaged= "));
    		Serial.println(status_rew_engaged);
    		Serial.println(F("et"));
    		Serial.print(F("Entrée dans void f3: valeur de status_function_pause= "));
    		Serial.println(status_function_pause);
    		Serial.print(F("Entrée dans void f3: valeur de status_f3_engaged= "));
    		Serial.println(status_f3_engaged);
     
    		//les deux vaeurs ci-dessous définissent si on rentre dans F3 ou pas
    		Serial.print(F("TEST PRINCIPAL void f3: valeur de active_input= "));
    		Serial.println(active_input);
     
    		if((active_input == "REW_CUEING_1/3rd")||(active_input == "REW_CUEING_1/6th"))
    		// ce test est le test principal autorisant ou non, l'activation de F3:
     
    		{
    				if(status_f3_engaged == false)   // c'est-àdire si F3 n'est pas déjà engagée
     
    				{
    					Serial.println(F("void f3 partie false: Réception du code du Bouton F3:"));
    					Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
     
    					Serial.print(F("void f3 partie false: valeur de status_f3_engaged= "));
    					Serial.println(status_f3_engaged); 		
     
    					digitalWrite(relai_REW,HIGH);	
    					Serial.println(F("void f3 partie false: relai_REW passé à HIGH et on le laisse à HIGH"));
    					Serial.println(F("et donc l'appareil baisse sa vitesse à 1/6ème"));
     
     
    					Serial.println(F("void f3 partie false: relai_REW toujours à HIGH"));
     
    					status_f3_engaged = !status_f3_engaged; // inverse le status de la fonction F3 à true puisqu'on vient de l'appeler
     
    					Serial.print(F("void f3 partie false: le status_f3_engaged a été passé à "));
    					Serial.println(status_f3_engaged);
    					Serial.println();
     
    					strcpy(active_input, "REW_CUEING_1/6th");	
     
    					lcd.clear(); // clear display
    					lcd.setCursor(0,1); // left second line (1 from 1-16, Ligne 1 from 0-1)
    					lcd.print(" < CUEING 1/6th"); 
    				}
    				else	
    				{
    					Serial.println(F("void f3 partie true: Réception du code du Bouton F3:"));
    					Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX);
     
    					Serial.print(F(" partie true: valeur de status_f3_engaged= "));
    					Serial.println(status_f3_engaged); // affiche true ou false selon la valeur de ce booléen
    					Serial.println(F("void f3 partie true: devrait etre vrai, donc Relai_REW devrait etre actif"));
     
    					status_f3_engaged = !status_f3_engaged; // inverse le status de la fonction F3 à true puisqu'on vient de l'appeler
     
    					digitalWrite(relai_REW,LOW);	
    					Serial.println(F("void f3 partie true: relai_REW passé à LOW"));
    					Serial.println(F("void f3 partie true: et donc l'appareil devrait re-accélerer à 1/3rd tout en restant en CUEING ARRIERE"));
     
    					strcpy(active_input, "REW_CUEING_1/3rd"); 
     
    					lcd.clear(); // clear display
    					lcd.setCursor(0,1); // left second line (1 from 1-16, Ligne 1 from 0-1)
    					lcd.print(" < CUEING 1/3rd"); // affiche que l'on est en CUEING ARRIERE 1/3rd
    				}
    		}
    	}
    // ---------------------------------------------------------------------------------------------------------------
    // FIN DE LA DELARATION DE LA FONCTION FACTORISEE F3
    Comme d'habitude ce doit être ultra-simple, mais après des jours sur du code, on n'y voit plus rien...
    Merci

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 196
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 196
    Billets dans le blog
    47
    Par défaut
    Bonsoir grizzly06,

    Citation Envoyé par grizzli06 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    		if((active_input == "REW_CUEING_1/3rd")||(active_input == "REW_CUEING_1/6th"))
    		// ce test est le test principal autorisant ou non, l'activation de F3:
     
    ...
     
    					strcpy(active_input, "REW_CUEING_1/6th");
    Je dirais qu'active_input est un tableau de char, et non un String.
    On peut comparer des String avec l'opérateur ==, mais pour les tableaux de char il faut passer par strcmp().

  3. #3
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    il y a des chances en effet

    faut espérer qu'il y a la place nécessaire dans le buffer.

    ce serait sans doute plus simple de conserver dans active_input un entier qui pourrait être l'index la chaîne de caractère si on en a besoin pour l'affichage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const char * lesInput[]*= {"INCONNUE", "REW CUEING 1/3rd", "REW CUEING 1/6th", "AUTRE CHOSE", "ET ENCORE"}; 
    byte active_input = 0;
    et on mettrait active_input à 1 par exemple pour choisir "REW CUEING 1/3rd" et les tests se feraient alors en comparant des entier, vous pourriez faire des switch etc...

    et un petit enum serait encore mieux pour la lisibilité du code

  4. #4
    Membre confirmé
    Homme Profil pro
    Coach
    Inscrit en
    Novembre 2019
    Messages
    228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Coach

    Informations forums :
    Inscription : Novembre 2019
    Messages : 228
    Par défaut
    On peut comparer des String avec l'opérateur ==, mais pour les tableaux de char il faut passer par strcmp()
    Quel âne je suis !
    mille mercis

    faut espérer qu'il y a la place nécessaire dans le buffer.
    je ne comprends pas bien ce problème de buffer, mais y a-t-il un moyen de s'assurer "qu'il y a la place nécessaire dans le buffer" ?? (à part compiler et voir si ça marche)
    ça m'inquiète cette question du buffer que je ne comprends pas: si ça passe à la compil , ce devrait être bon ?

    ce serait sans doute plus simple de conserver dans active_input un entier qui pourrait être l'index la chaîne de caractère si on en a besoin pour l'affichage.
    ça me paraît un peu compliqué car "active_input" peut prendre plusieurs valeurs (14 en fait, toutes faisant 16 caractères de long, donc un char de 17), et si l'utilisation de strcmp() fonctionne, ce serait plus facile pour moi à coder....

    Je vais tester strcmp() cet après-midi et je reviens vers vous
    Mille mercis !

  5. #5
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    ça me paraît un peu compliqué car "active_input" peut prendre plusieurs valeurs (14 en fait, toutes faisant 16 caractères de long, donc un char de 17), et si l'utilisation de strcmp() fonctionne, ce serait plus facile pour moi à coder....
    strcmp() fonctionnera bien sûr mais c'est plus consommateur de resources qu'un simple entier qui serait l'index dans un tableau de chaînes si vous avez besoin d'afficher cette chaîne. Si vous n'avez pas besoin de l'afficher, alors un enum est le meilleur choix.

    pour le buffer, si vos chaînes occupent toutes 17 octets, il faut qu'il ait 17 octets comme cela le strcpy() ne débordera pas. Si vous voulez être tranquille en cas de changement des chaînes et d'oubli, utilisez strlcpy() en passant la taille du buffer à la fonction, vous serez sûr ainsi de ne jamais déborder.



    voici un exemple de code avec un enum et un tableau de chaînes
    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
    enum : byte {TEXT0, TEXT1, TEXT2, TEXT3, TEXT4, TEXT5, TEXT_TOTAL} active_input = TEXT0;
    const char * lesTextes[] = {"texte 0", "texte 1", "texte 2", "texte 3", "texte 4", "texte 5"};
     
    void setup() {
      Serial.begin(115200); Serial.println();
     
      Serial.print("Il y a "); Serial.print(TEXT_TOTAL); Serial.println(" valeurs connues pour les textes.");
     
      Serial.print("Le texte choisi est : "); Serial.println(lesTextes[active_input]);
     
      // on change
      active_input = TEXT3;
      Serial.print("maintenant c'est : "); Serial.println(lesTextes[active_input]);
     
      // ou on les imprime tous
      for (byte i = 0; i < TEXT_TOTAL; i++) {
        Serial.print("Texte # "); Serial.print(i); Serial.print(" : \t");
        Serial.println(lesTextes[i]);
      }
    }
     
    void loop() {}
    si vous faites tourner ce code, vous verrez dans le moniteur série (à 115200 bauds)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    il y a 6 valeurs connues pour les textes.
    Le texte choisi est : texte 0
    maintenant c'est : texte 3
    Texte # 0 : 	texte 0
    Texte # 1 : 	texte 1
    Texte # 2 : 	texte 2
    Texte # 3 : 	texte 3
    Texte # 4 : 	texte 4
    Texte # 5 : 	texte 5


    et si vous voulez comparer il suffit de faire un ==

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (active_input == TEXT3) {
      ...
    }
    ou si vous voulez faire des opérations différentes suivant la valeur choisie, un switch va fonctionner alors que ce n'est pas possible avec des chaînes.

    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
      switch (active_input) {
        case TEXT0:
          // ...
          break;
     
        case TEXT1:
          // ...
          break;
     
        case TEXT2:
          // ...
          break;
     
        case TEXT3:
          // ...
          break;
     
        case TEXT4:
          // ...
          break;
     
        case TEXT5:
          // ...
          break;
     
        default: break;
      }
    et cerise sur le gâteau vous n'avez aucune manipulation de chaîne donc aucun risque de dépassement mémoire.

  6. #6
    Membre confirmé
    Homme Profil pro
    Coach
    Inscrit en
    Novembre 2019
    Messages
    228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Coach

    Informations forums :
    Inscription : Novembre 2019
    Messages : 228
    Par défaut
    J'ai testé et le strcmp() fonctionne divinement, évidemment ! donc mon problème, qui était un des derniers avec ce programme, est résolu: merci à tous !!

    @JayM:
    Comme toujours il y a les "super forts" (comme toi), et les autres.... comme moi !

    Tes exemples sont supers, mais je n'en ai pas vraiment besoin pour l''instant, c'est trop éloigné de mon utilisation actuelle et de l'organisation de mon code actuel.

    Par contre ce que vous dites ici:
    pour le buffer, si vos chaînes occupent toutes 17 octets, il faut qu'il ait 17 octets comme cela le strcpy() ne débordera pas. Si vous voulez être tranquille en cas de changement des chaînes et d'oubli, utilisez strlcpy() en passant la taille du buffer à la fonction, vous serez sûr ainsi de ne jamais déborder.
    m'intéresse, car l'absence de débordement est quelque chose qui m'intéresse (fiabilité)...

    Vous pouvez préciser à quoi vous pensez avec strlcpy() pour éviter les dépassements de buffer ?? (car au-dessus nous parlions de strcmp()).


    N.B.: je ne cherche pas la performance, le programme est certes volumineux, mais il ne fait pas de calculs compliqués (principalement des IF, lesquels déclenchent quelques actions derrières), une Nano même pas Every s'en sort bien a priori.

  7. #7
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Citation Envoyé par grizzli06 Voir le message
    m'intéresse, car l'absence de débordement est quelque chose qui m'intéresse (fiabilité)...
    Vous pouvez préciser à quoi vous pensez avec strlcpy() pour éviter les dépassements de buffer ?? (car au-dessus nous parlions de strcmp())
    c'est pour remplacer l'appel qui vous sert à remplir le contenu du buffer active_input
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     strcpy(active_input, "REW_CUEING_1/6th");
    j'imagine que active_input est défini comme étant
    au lieu de strcpy vous faites

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     strlcpy(active_input, "REW_CUEING_1/6th", sizeof active_input );
    ou simplement en donnant la taille du buffer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     strlcpy(active_input, "REW_CUEING_1/6th", 17 );
    (l'avantage du sizeof c'est que si vous changez la taille du buffer vous n'avez pas à modifier le code)

    -----

    c'est pas optimal de travailler en faisant des comparisons de chaînes connues mais si ça vous convient c'est bien comme ça. Le jour où vous n'aurez plus assez de mémoire, pensez qu'il y a d'autres solutions moins gourmandes.

  8. #8
    Membre confirmé
    Homme Profil pro
    Coach
    Inscrit en
    Novembre 2019
    Messages
    228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Coach

    Informations forums :
    Inscription : Novembre 2019
    Messages : 228
    Par défaut

    comme toujours JayM, tu es une encyclopédie !

    Oui "active_input" est bien définie comme tu le supposes, un char de 17.

    Très intéressant ce strlcpy(), et facile à utiliser.

    Mon programme actuel est assez figé et ne variera que très peu (dans le futur peut-être que je repartirai de ce programme pour le faire évoluer), mais y a-t-il un risque de débordement avec une chaine qui fait toujours 17 de long ?

    En d'autres termes, est-ce que ça vaut le coup que je remplace mes strcpy() par des strlcpy(), vu que mes chaines font toujours 17 de long ?

    Mille mercis Ô Maître

  9. #9
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 899
    Par défaut
    Si vous êtes 100% sûr de ce que vous copiez alors pas besoin de strlcpy. C’est juste par sûreté

    Par principe j’essaye toujours d’avoir un code un peu soigné. Si un jour vous y revenez et que vous avez oublié cette histoire de 17, ça peut vous jouer des tours.

  10. #10
    Membre confirmé
    Homme Profil pro
    Coach
    Inscrit en
    Novembre 2019
    Messages
    228
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Coach

    Informations forums :
    Inscription : Novembre 2019
    Messages : 228
    Par défaut
    OK merci JayM !

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

Discussions similaires

  1. [Delphi 7] [RichEdit] ScrollBar récalcitrant
    Par Droïde Système7 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 23/07/2005, 15h30
  2. [Triggers] Deletes en cascade récalcitrants
    Par Coplan dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/07/2005, 09h19
  3. Répertoire récalcitrant
    Par Pedro dans le forum Windows XP
    Réponses: 15
    Dernier message: 25/03/2005, 14h06
  4. Update récalcitrant !
    Par Jeannotc dans le forum Bases de données
    Réponses: 10
    Dernier message: 16/06/2004, 18h28
  5. Un "0" récalcitrant
    Par bidson dans le forum XMLRAD
    Réponses: 4
    Dernier message: 20/04/2004, 13h56

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