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 :

Simplification d'un code


Sujet :

Arduino

  1. #1
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut Simplification d'un code
    Bonjour à tous
    j'ai un tableau représentant 10 programmes de 8 maniplulations:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char pg[10][81];              //10 programmes de 10 manips de 8 octets
    Afin d'afficher les 10 manips d'un programme sur un écran LCD de 16 caractères, je procède ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    else if(com[1]=='A'){   //lecture des horaires en RAM
            uint8_t noProg = ci(com[2]);           //conversion char->int
            for(i=0;i<10;i++){
                sprintf(buf0,"Prog %i Manip %i",noProg,i*8);
                sprintf(buf1,"%c%c%c%c%c%c%c%c",pg[noProg][i*8],pg[noProg][i*8+1],pg[noProg][i*8+2],
                pg[noProg][i*8+3],pg[noProg][i*8+4],pg[noProg][i*8+5],pg[noProg][i*8+6],pg[noProg][i*8+7]);
                afficLcd2Lig(buf0,buf1,DURAFF);        //DURAFF durée d'affichage 2s
            }
          }
    N'y aurait-il pas un moyen plus élégant de procéder?

  2. #2
    Membre Expert

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

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

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 582
    Par défaut
    Bonjour,

    A supposer que j'ai bien compris l'objectif, on pourrait écrire en C un truc de ce genre (non testé).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ...
    else if(com[1]=='A') {                           // lecture des horaires en RAM
       uint8_t nPrg = ci(com[2]) ;                   // conversion char->int ???
       char * pC = pg[nPrg];
       buf1[8]   = 0;                                // buf1 de taille supposée > 8, 0 ferme buf1
       for(i = 0; i < 80; i += 8) {
          sprintf(buf0,"Prog %i Manip %i", nPrg, i); // Dommage de tout reconstruire à chaque fois
          strncpy(buf1, pC + i, 8);                  // On copie les 8 lettres suivantes
          afficLcd2Lig(buf0, buf1, DURAFF);          // DURAFF durée d'affichage 2s
       }
    }
    Salutations

  3. #3
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    il faudrait comprendre exactement ce qu'il y a dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char pg[10][81];              //10 programmes de 10 manips de 8 octets
    et si vous avez des caractères nuls.
    l'usage de strncpy() et strncat() pourrait être une option

  4. #4
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Guesset & dit:
    A supposer que j'ai bien compris l'objectif
    Le but est d'afficher sur un LCD à 2 lignes le contenu d'un tableau de 10 commandes, chacune comportant 10 manipulations codées sur 8 caractères, et de le faire manipulation par manipulation, c'est à dire en affichant sur la deuxième ligne les 8 caractères de cette manipulation; la première ligne servant à indiquer le N° de programme et le N° de manip affichés.

    Merci Guesset pour cette solution qui une fois adaptée convient parfaitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
          char buf0[16], buf1[16];    //buffer globaux pour l'affichage LCD
    //.....................
          else if(com[1]=='A'){   //****lecture des horaires en RAM****
            uint8_t noProg = ci(com[2]);      //conversion char -> int
            char *pC = pg[noProg];             //pointeur sur le tableau
            for(i=0;i<10;i++){
              sprintf(buf0,"Prog %i Manip %i",noProg,i);      //ligne 0 de l'afficheur
              strncpy(buf1, pC + i*8,8);                     //ligne 1 de l'afficheur
              buf1[8]='\0';                                //termine l'affichage à 8 caractères
              afficLcd2Lig(buf0,buf1,DURAFF);              //routine d'affichage  DURAFF= durée d'affichage
            }
          }
    Jay a dit:
    l faudrait comprendre exactement ce qu'il y a dans char pg[10][81]
    Il n'y a que des caractères ASCII du code 30 à 39 et 41 à 46 soit de 0 à 9 et A à F
    Je ne pense pas que strncat() puisse convenir .

    Merci pour vos aides

  5. #5
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 754
    Par défaut
    Ceci pourra sans doute le faire (non testé)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    else if(com[1]=='A') {
        uint8_t noProg=ci(com[2]);
        char *pC=pg[noProg];
        buf1[8]=0;
        for(int i=0; i<10; i++, pC+=8) {
            sprintf(buf0, "Prog %i Manip %d", noProg, i);
            memcpy(buf1, pC, 8);
            afficLcd2Lig(buf0, buf1, DURAFF);
        }
    }

  6. #6
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Super edgarjacobs cette solution: je ne savais pas qu'on pouvait indiquer plusieurs incrémentations dans le for.
    Par contre, je dois mettre sinon en mettant 0 ce dernier s'affiche à la suite avec aussi des caractères parasites aux positions 9 à 15 de l'afficheur.
    Merci.

  7. #7
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    Citation Envoyé par mormic Voir le message
    Par contre, je dois mettre sinon en mettant 0 ce dernier s'affiche à la suite avec aussi des caractères parasites aux positions 9 à 15 de l'afficheur.
    il doit y avoir autre chose car
    et
    ça fait exactement la même chose (ça met le 9ème octet de buf1 à zéro)

    si vous voyez des trucs indésirables c'est que le caractère nul de fin de chaîne n'a pas été mis au bon endroit

  8. #8
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    si vous voyez des trucs indésirables c'est que le caractère nul de fin de chaîne n'a pas été mis au bon endroit
    buf0 et buf1 sont définis ainsi dans les variables globales:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char buf0[17], buf1[17];
    Il me servent tout au long du programme à afficher sur un LCD de deux lignes de seize caractères.
    Or, dans le cas présent, je ne veux afficher que 8 caractères sur la deuxième ligne. C'est pourquoi je raccourci momentanément le buffer à 8 caractères avec un NUL (ASCII 00)
    Si je mets un 0 (ASCII 30) en position buffer[8] j'aurais un 0 affiché en 9ème position de la ligne; puis sept caractères aléatoires.

    Ou alors j'ai un gros problème de compréhension?

  9. #9
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 754
    Par défaut
    Si tu écris buf1[8]=0; ça met la valeur zéro (0x00) dans le 9ème octet de buf1

    Si tu écris buf1[8]='0'; ça met la valeur du caractère zéro (0x30) dans le 9ème octet de buf1

  10. #10
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    exactement

    il faut faire attention '\0' ce n'est pas la même chose que '0'. le anti-slash est là, on appelle cela un caractère d'échappement

    cf la liste de ces séquences d'échappement.

    ==> '\0' est la séquence d'échappement octale la plus couramment utilisée, car elle représente le caractère nul de terminaison dans les c-strings

  11. #11
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Si tu écris buf1[8]=0; ça met la valeur zéro (0x00) dans le 9ème octet de buf1
    Bien d'accord sur les différences '\0' , '0', 0 ou 0x00.
    Mais ce que je ne pige pas: buf1[8] est bien un tableau de char alors que 0 ou 0x00 est un numérique !
    Alors qu'est-ce que j'écrit dans la case mémoire si je fais buf1[8]=5; ? 0b0101 ou 0x35 ?

  12. #12
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    Citation Envoyé par mormic Voir le message
    Bien d'accord sur les différences '\0' , '0', 0 ou 0x00
    Pour être sûr qu'on soit bien d'accord :
    si vous avez '\0', 0, 0x00, 0b0 c'est la valeur numérique de type entier 0 (le zéro mathématique)
    et si vous avez '0', c'est la valeur numérique du code ASCII du symbole '0', c'est à dire 48


    Citation Envoyé par mormic Voir le message
    Mais ce que je ne pige pas: buf1[8] est bien un tableau de char
    Non buf1[8] n'est pas un tableau de char, c'est la 9ème case du tableau buf1, c'est juste un octet de type char, donc représenté par un octet en mémoire.
    Sur Arduino, le type char est signé, ce qui signifie qu'il peut prendre des valeurs de -128 à 127 (cela peut dépendre de l'architecture de la plateforme et du compilateur) si on veut s'en servir pour faire des maths (mais ce serait mieux d'utiliser int8_t comme type dans ce cas, c'est plus parlant).

    ==> le fait que ce soit un char ne change rien au fait que vous mettez ce que vous voulez dans cet octet.

    Citation Envoyé par mormic Voir le message
    que 0 ou 0x00 est un numérique !
    Alors qu'est-ce que j'écris dans la case mémoire si je fais buf1[8]=5; ? 0b0101 ou 0x35 ?
    si vous faites buf1[8]=5; vous écrivez la valeur 5 dans ce 9ème octet du tableau.

    Ce que change le type, c'est la façon dont c'est interprété quand vous faites un print() par exemple. si le type de l'octet est byte, la fonction print appelée transforme en ASCII la valeur numérique de l'octet.

    si j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    byte b = 65; 
    Serial.println(b);
    ou même (c'est identique)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    byte b = 'A'; 
    Serial.println(b);
    je vois dans la console la valeur numérique de l'octet, de la lettre A, soit 65

    mais si j'écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char c = 'A'; 
    Serial.println(c);
    ou même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char c = 65; 
    Serial.println(c);
    je vois dans la console le symbole du code ASCII pour la valeur 65, soit la lettre A.

    voici un code pour tester vous même
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    byte b = 'A';
    char c = 65;
     
    void setup() {
      Serial.begin(115200);
      Serial.print("b="); Serial.println(b);
      Serial.print("c="); Serial.println(c);
    }
     
    void loop() {}
    il faut bien comprendre qu'un octet c'est un octet et que ce que l'on met dedans c'est juste 8 bits. La façon dont ces bits sont interprétés c'est la responsabilité de la fonction qui travaille sur ces bits et généralement les fonctions utilisent l'information du type pour "deviner" ce que l'on veut faire.

  13. #13
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    Merci bien pour ces éclaicissements mais:
    si vous faites buf1[8]=5; vous écrivez la valeur 5 dans ce 9ème octet du tableau
    Cet octet contient-il 0011 0011 (53) ou 0000 0101 (5) ?

  14. #14
    Expert confirmé

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

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 884
    Par défaut
    Si vous faites alors il contient le nombre 5, pas le code ASCII de 5 ➜ donc 0b101 en binaire.

    Si vous faites alors il contient le code ASCII du symbole 5, c'est à dire 53 ➜ donc 0b110101 en binaire.

    ---

    c'est assez simple à vérifier, testez ce programme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    char b = 5;
    char c = '5';
     
    void setup() {
      Serial.begin(115200);
      Serial.print("b = 0b"); Serial.println(b, BIN);
      Serial.print("c = 0b"); Serial.println(c, BIN);
    }
     
    void loop() {}

  15. #15
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 754
    Par défaut
    Mais ce que je ne pige pas: buf1[8] est bien un tableau de char
    Non, buf1[8] est un caractère, c'est buf1 qui est un tableau de char. Mais ce qu'il faut retenir, c'est qu'un char n'est jamais qu'un entier codé sur 8 bits.

  16. #16
    Membre éclairé
    Homme Profil pro
    bricoleur
    Inscrit en
    Octobre 2014
    Messages
    406
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : bricoleur
    Secteur : Alimentation

    Informations forums :
    Inscription : Octobre 2014
    Messages : 406
    Par défaut
    buf1[8] est un caractère, c'est buf1 qui est un tableau de char.
    Oui j'ai bien assimilé que char buf1[8] est la déclaration d'un tableau de 8 caractères et que buf1[0] à buf1[7] sont des cases de ce tableau. Je m'étais mal exprimé.

    Quoiqu'il en soit, je vous remercie tous pour ces éclaircissements qui vont me permettre d'avancer plus sereinement.

    Bien cordialement

  17. #17
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 754
    Par défaut
    Il est important de savoir avec quoi on travaille. Car sans code, si tu dis que que buf1[8] est un tableau de caractères, alors c'est que tu as déclaré char buf1[....][....];

  18. #18
    Membre Expert

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

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

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 582
    Par défaut
    Bonjour,

    Le code actuel n'a pas les mêmes résultats que celui d'origine sprintf(buf0, "Prog %i Manip %i", noProg, i*8) qui est devenu sprintf(buf0, "Prog %i Manip %i", noProg, i). Ce dernier correspond sans doute mieux au besoin mais j'avais proposé un code à fonctionnalité égale d'où l'incrément i de 8 en 8.

    Par ailleurs, j'ai été surpris d'un dimensionnement de tableau à 81 pour 10 actions de 8 octets (initialement j'ai pensé à un éventuel 0 terminal mais cela ne semble pas être le cas).

    De même, on veut afficher jusqu'à 16 caractères par ligne mais les buffers n'ont que 16 caractères ce qui limite à 15 caractères utiles + le 0 final.

    Si on recherche une efficacité accrue du code (vraisemblablement sans objet ici), on pourrait écrire quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // ...
    else if(com[1] == 'A') {                         // lecture des horaires en RAM
       uint8_t noProg = ci(com[2]);                  // conversion char -> int
       char    *pC    = pg[noProg];                  // pointeur sur le tableau
       sprintf(buf0, "Prog %i Manip 0", noProg);     // ligne 0 de l'afficheur
       buf1[8]  = 0;                                 // termine l'affichage de 8 caractères
       for(char *pC0 = buf0 + strlen(buf0) - 1; *pc0 <= '9'; (*pc0)++, pC += 8) {
          strncpy(buf1, pC, 8);                      // ligne 1 de l'afficheur
          afficLcd2Lig(buf0, buf1, DURAFF);          // routine d'affichage  DURAFF= durée d'affichage
       }
    }
    Cela illustre tous les sujets illustrés par des portions de codes tellement petites (voire quelquefois absentes) qu'il est difficile de leur faire une réponse de fond.

    Salutations

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

Discussions similaires

  1. [MySQL] Simplification d'un code php
    Par sff dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 05/08/2008, 14h35
  2. simplification d'un code
    Par lolo93 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 29/04/2008, 11h38
  3. Réponses: 2
    Dernier message: 30/05/2007, 15h04
  4. Simplification de mon code?
    Par totoc1001 dans le forum MATLAB
    Réponses: 6
    Dernier message: 31/01/2007, 16h50
  5. [VBA-E] Aide pour simplification de mon code.
    Par pauletta22 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 23/05/2006, 11h34

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