Go Down

Topic: String? Pas bien. Char[]? bien! (Read 643 times) previous topic - next topic

savoriano

Je ne comprends pas!
Mon module bt m'envoie ce que les capteurs envoient.
A la fin de la trame les capteurs envoient un 13 et un 10.
Si je lis avec serial.read un 13,avec
sHex = String(Serial2.read(), HEX);
sHex = "d";
pour avoir toujours la même longueur de ma trame j'ajoute un caractere "0" si shex.length = 1
if (sHex.length() == 1) sHex = "0" + sHex;
maintenant mon sHex ="0d"
sTrama += sHex;
ma sTrama = "...................0d"
Le bt envoie un 10
sHex = String(Serial2.read(), HEX);
sHex = "a";
if (sHex.length() == 1) sHex = "0" + sHex;
maintenant mon sHex ="0a"
sTrama += sHex;
ma sTrama = "...................0d0a"
Pour moi "0d0a" sont maintenant des caractères qui sont partie de ma String sTrama.
avec
    if (sTrama.endsWith("0d0a")) //fin de la trame
je comprends que la trame est finie et je commence à l'analyser.
ce bout de code marche presque parfaitement.
Des jours ca ne marche pas. Vu les problèmes qui peuvent survenir à l'utilisation de String je suis en train de refaire cette fonction en utilisant char[] en gardant la même philosophie.
C'est que j'ai imaginé. Peut être que il ne faut pas faire comme çà?
Peut être que la conversion de HEX à String n'est pas nécessaire mais pour moi c'était plus pratique avoir une String quand j'ai  commencé à étudier ces capteurs. Après c'est vrais je n'ai pas cherché plus loin vu que le code marchait. 

Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

lesept

Si tu veux utiliser des chaines de caractères, il faut le faire partout, à commencer par la réception BT. Comme c'est une liaison série, probablement mise en oeuvre avec un SoftwareSerial, tu peux utiliser les tutoriaux de lecture d'un port série (voir celui de J-M-L par exemple).

Tu reçois tes caractères dans un char (ou un byte, c'est pareil) et tu traites ce char comme il faut pour constituer ta trame au fur et à mesure de l'arrivée des caractères.

Code: [Select]
byte c = MySerial.read();
char temp[2];
sprintf (temp,"%02X",c);
strcat (trama, temp);


(pas essayé, mais l'idée est là)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

hbachetti

#17
Aug 08, 2019, 07:12 pm Last Edit: Aug 08, 2019, 07:13 pm by hbachetti
Quote
sHex = String(Serial2.read(), HEX);//Attention: il ne met pas les 0 non significatifs
Cela vient de ta manière de lire les caractères.

Serial2.read() retourne un caractère c qui vaut '\x0d' ou '\x0a' ou autre.
Ensuite String(c, HEX) transforme  c en représentation hexadécimale : "d" ou "a".
Ensuite tu insère '0' devant.
Pourquoi faire cette transformation inutile ?
Effectivement les caractères dans sHex seront transformés en chaîne :
'a' : "61"
'b' : "62"
'c' : "63"
'\x13" : "0d"
'\x10' : "0a"

Si tu fais comme cela une chaîne "abc\r\n" sera transformée en "6162630d0a".

Sinon, si tu ne convertis pas en hexa :

Code: [Select]

    int c = Serial.read();
    sTrama[LenTrama++] = c;


Ta chaîne "abc\r\n" ou "abc\x0d\x0a" restera telle quelle.

Si tu veux te débarrasser des String il faut éviter de les utiliser jusqu'au bout.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

savoriano

Quote
(pas essayé, mais l'idée est là)
Code: [Select]
sprintf(sHex, "%02x\0", Serial2.read());
c'est pas pareil?

Quote
Si tu fais comme cela une chaîne "abc\r\n" sera transformée en "6162630d0a".
Exacte.C'est comme ça qu'il marchait l'ancienne fonction.

Quote
Si tu veux te débarrasser des String il faut éviter de les utiliser jusqu'au bout.
Dans le code du message #7, j'ai utilisé des String?
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

hbachetti

#19
Aug 08, 2019, 10:51 pm Last Edit: Aug 08, 2019, 10:52 pm by hbachetti
Quote
Dans le code du message #7, j'ai utilisé des String?
Non, mais cette transformation est inutile :

Code: [Select]
    sprintf(sHex, "%02x\0", Serial2.read());
Si tu avais débuté en utilisant de chaînes de caractères "C" au lieu d'utiliser des Srings ce serait moins difficie à expliquer.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

savoriano

Toujours en train de supprimer dans ma fonction cette String j'ai ENCORE une difficulté:
Je veux stocker un adresse MAC (une partie) dans une char[].
Code: [Select]
char caMacCaptAv[5] = {0x51, 0x01, 0x10, 0Xca, '\0'}, caMacCaptAr[5] = {0Xaa, 0X03, 0X40, 0Xca, '\0'};

Mais j'ai un warning:
warning: narrowing conversion of '202' from 'int' to 'char' inside { } [-Wnarrowing]
est-ce grave docteur?
je "dois" garder char car après je dois faire une confrontation entre 2 char
Code: [Select]
       if (strncmp(caTrama, caMacCaptAv, 4) == 0) PosX = 140;//La trame vient elle du capteur avant?
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

supercc

Le compilateur a toujours raison : 202 ne rentre pas dans un char.

savoriano

#22
Aug 10, 2019, 12:02 am Last Edit: Aug 10, 2019, 12:34 am by savoriano
Quote
Le compilateur a toujours raison : 202 ne rentre pas dans un char.
Ok. compris.
donc je ne peux pas faire ca non plus:
Code: [Select]
char caMacCaptAv[9] = {0x5, 0x1, 0x0, 0x1, 0x1, 0x0, 0xC, 0xA, '\0'}, caMacCaptAr[9] = {0Xa, 0xa, 0X0, 0x3, 0X4, 0x0, 0Xc, 0xa, '\0'};

si la réponse est non, je pense que je commence à comprendre ce que hbachetti voulait m'expliquer.

P.S.
Le but de code proposé par hbachetti ne peux pas fonctionner si c>127
Code: [Select]

    int c = Serial.read();
    sTrama[LenTrama++] = c;

a moins que sTrama c'est un array de int.

Quote
A ce rythme d'ici à 30/40 ans je vais devenir aussi fort que vous! :D
Je crois que j'étais un peux optimiste:
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

lesept

#23
Aug 10, 2019, 12:31 am Last Edit: Aug 10, 2019, 12:34 am by lesept
Le compilateur a toujours raison : 202 ne rentre pas dans un char.
tut tut tut
Un char accepte jusqu'à 2^8-1 = 255

202 en hexa s'écrit 0xCA.
Tu as mis un X majuscule, je pense que le problème vient de là.

Edit : désolé, j'ai tout faux. Un char est signé, un byte non. Donc le byte va jusqu'à 255 mais le char à 127.

Tu dois pouvoir utiliser un array de byte
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

supercc

#24
Aug 10, 2019, 09:06 am Last Edit: Aug 10, 2019, 11:25 am by supercc
@lesept, le compilateur a toujours raison (202 ne rentre pas dans un char) mais tu as raison aussi : 202 rentre dans un char.

Paradoxe sympa que je voulais montrer à @savoriano que je vois se battre régulièrement avec des problèmes de transtypage....

J'explique à ma façon :

Un char c'est un entier huit bit en représentation signé (de -128 à + 127). Donc le compilateur à raison 202 ne rentre pas dedans mais il vas quand même copier l'octet, aucune information n'est perdue.

On peut récupérer le 202 en lui demandant de considérer, a posteriori, que finalement ce n'est pas un char mais un unsigned char (byte) par un transtypage explicite.

Code: [Select]

char a=202; // <- le compilateur trouve que c'est louche.
printf("a=%d\n", a); // affiche -54
printf("a=%d\n", (unsigned char)a); // affiche 202


@savoriano, puisque tu développes activement en C je te conseillerai de regarder au moins une fois la référence : le Kernighan et Ritchie. Sans une idée claire des types et des règles de transtypage, programmer en C est pénible ;-)



hbachetti

Si la trame doit contenir des caractères > 127 et < 255, utilise des bytes (unsigned char).
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

savoriano

#26
Aug 10, 2019, 11:19 am Last Edit: Aug 10, 2019, 11:26 am by savoriano
Quote
On peut récupérer le 200 en lui demandant de considérer, a posteriori, que finalement ce n'est pas un char mais un unsigned char (byte) par un transtypage explicite.
Oui, ça je l'ai compris, même pourquoi il y a une différence de 2 (202 et 200)

ce que je ne savais c'est que char était signé!

Quote
@savoriano que je vois se battre régulièrement avec des problèmes de transtypage
S'il y avait que ça!

Comme j'avais expliqué dans ma présentation, je suis complètement autodidacte et c'est la première fois que je participe à un forum comme celui ici.
Le problème d'un autodidacte est que devant à un problème inconsciemment il ne le ressoude pas mais il le contourne.
Maintenant avec tous ces posts du forum (qui sont toujours intéressants) je suis bombardé de informations de tout gendre et je sature un peux.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

supercc

#27
Aug 10, 2019, 11:23 am Last Edit: Aug 10, 2019, 11:25 am by supercc
J'ai mis 200 mais je voulais écrire 202 partout (je viens de corriger dans le post) ;-).

Quote
S'il y avait que ça!
Mon conseil a d'autant plus de valeur ;-). Tu le torches en diagonale en 1 après-midi et ta vie de programmeur en sera changée ;-)

savoriano

#28
Aug 11, 2019, 02:34 am Last Edit: Aug 11, 2019, 02:43 am by savoriano
Quote
regarder au moins une fois la référence : le Kernighan et Ritchie.
Je l'ai commandé car pas en stock!

Ou j'en suis:
Code: [Select]
byte baTrama[50];
byte baMacCaptAv[4] = {81, 1, 16, 202}, baMacCaptAr[4] = {170, 3, 64, 202};//MAC av:51 01 10 ca  MAC ar:aa 03 40 ca
byte LenTrama = 0;

void CapteursPression()
{
  uint32_t  c;
  byte PosX;
  while (Serial2.available() > 0)//il y a quelque chose que le BT veut nous transmettre?
  {
    //lit le BT
    baTrama[LenTrama] = Serial2.read();
    //LenTrama++;
    //sprintf(sHex, "%02x\0", Serial2.read());
    //strcat(sTrama, sHex);
    if ((LenTrama == 7 && baTrama[0] == 'O' && baTrama[1] == 'K' && baTrama[2] == '+') || LenTrama > 38)
    {
        LenTrama = 0;
        return;
    }

    if (baTrama[LenTrama - 1] == 10 && baTrama[LenTrama - 2] == 13) //fin de la trame
    {
      // Analise la trame
      if (LenTrama == 38)//le capteur transmet 2 differentes trames
      { //seulement la plus longue nous interesse
        if (baTrama[0] == baMacCaptAv[0] && baTrama[1] == baMacCaptAv[1] && baTrama[2] == baMacCaptAv[2] && baTrama[3] == baMacCaptAv[3]) PosX = 140;//La trame vient elle du capteur avant?
        else if (baTrama[0] == baMacCaptAr[0] && baTrama[1] == baMacCaptAr[1] && baTrama[2] == baMacCaptAr[2] && baTrama[3] == baMacCaptAr[3]) PosX = 0;//La trame vient elle du capteur ariere?
        else
        {
          LenTrama = 0;
          return;//on sort car la trame ne provient pas de nos capteurs
        }
        c = baTrama[26] * 65536 + baTrama[27] * 256 + baTrama[28];//Calcule la pression

        if (c > 400000UL)//des fois il trouve de pressions incoerrentes!
        {
          LenTrama = 0;
          return;
        }

        if (c < 190000UL && tft.readPixel(PosX + 10 , 259) != RED)//pression insuffisante tft.readPixel(posxa + 6 , posya)
        { // PneuAV sert pour eviter qu'il colorie le pneu à chaque fois
          for (byte a = 41; a < 60; a++) tft.drawCircle(PosX + 60, 259, a, RED);//Colora le gomme in ROSSO
        }
        else if (c > 250001UL && tft.readPixel(PosX + 10 , 259) != BLUE)// Pression elevée
        {
          for (byte a = 41; a < 60; a++) tft.drawCircle(PosX + 60, 259, a, BLUE);//Colora le gomme in BLU
        }
        else if (c < 250000UL && c > 189000UL && tft.readPixel(PosX + 10 , 259) != GREEN) //pression optimale
        {
          for (byte a = 41; a < 60; a++) tft.drawCircle(PosX + 60, 259, a, GREEN);//Colora le gomme in VERDE
        }

        PrintTFT(42 + PosX, 180, String(float(c) / 100000.00), 2);//Ecrit la pression

        c = baTrama[32] * 65536 + baTrama[31] * 256 + baTrama[30];//Calcule la temp.

        PrintTFT(112 + PosX, 300, String(int(c / 100)) + " ", 2);// Ecrit sur le TFT la Temperature
      }
      LenTrama = 0;//efface la trame
    }
    LenTrama++;
  }

Juste compilé.
Pardonnez moi pour mon français, ce n'ai pas ma langue maternelle.

J-M-L

Vous pouvez trouver des vieux PDFs en français meme - à lire directement sur votre ordinateur

Par exemple Introduction_ANSI_C.pdf
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up