sprintf et dtostrf Help

Bonjour,

Voici le code qui me pose problème

    char buffer[82]="";
    char ctemp[5]="";
    long baro = (bmp.readPressure()/100)+52;
    float temp = bmp.readTemperature();
    
    dtostrf(temp,5,2,ctemp);

    sprintf(buffer, "$WIMDA,,I,%4u,B,%s,C,,C,,,,C,,T,,M,,N,,M*", baro, ctemp);
    printf("%s", buffer);
    Serial.print(buffer);

Je n'arrive pas à afficher dans ma chaine buffer le ctemp (température xx.xx) que je récupère de mon capteur bmp. Voici le contenu de buffer envoyé au port série :

$WIMDA,,I, 999,B,,C,,C,,,,C,,T,,M,,N,,M*

Pourtant, lorsque je ne transmet que la valeure ctemp, là j'ai bien une température au format chaine qui est transmise. Au final j'aimerais que buffer contienne ceci :

(si ctemp = 20.50) $WIMDA,,I, 999,B,20.50,C,,C,,,,C,,T,,M,,N,,M*

Bonjour,

Une chaine de caractère ASCIIZ se caractérise par un \0 en fin de chaine. Si tu veut faire un %s il faut que "ctemp" se finisse par ce \0.

Or ici tu demandes à dtostrf() de fabriquer une chaine ASCIIZ avec 5 digits dans "ctemp" qui fait tout juste 5 char ! Pas de place pour le \0 donc d'où ton probléme à mon avis.

Bonsoir et merci pour cette réponse rapide.

Je viens de faire la modification suivante :

char ctemp[7]="";

afin que ctemp puisse contenir aussi le \O mais malheureusement le problème reste identique =(

Je reste toujours avec le résultat $WIMDA,,I, 999,B,,C,,C,,,,C,,T,,M,,N,,M* (sans la valeur de ctemp affichée)

Fait un Serial.println(ctemp); aprés le dtostrf() pour vérifier son bon (ou mauvais) fonctionnement ;)

Bonjour Skywodd,

Merci pour l’info.

Je viens de tester ce code

void setup() {
}
 void loop() {
   
    char buffer[82];
    char ctemp[9];
    const char *nmea = "$WIMDA,,I,";
    long baro = (bmp.readPressure()/100)+58;
    float temp = bmp.readTemperature();
    dtostrf(temp,5,2,ctemp);
    Serial.println(ctemp);
    
    //sprintf(buffer,"%s,%4u,B,%s,C,,C,,,,C,,T,,M,,N,,M*",nmea,baro,ftoa(ctemp,temp,2));
    sprintf(buffer, "%s,%4d,B,%s,C,,C,,,,C,,T,,M,,N,,M*", nmea, baro, ctemp);
    printf("%s", buffer);
    Serial.print(buffer);
    Serial.println(getCheckSum(buffer),HEX);    // pour débuguer et connaitre la valeure renvoyée par la fonction
    delay(2000);                 // Délais d'attente 2 seconde
    }
  
    // Calcul le CRC d'une chaine, retourné sous la forme d'un entier
    int getCheckSum(char *string) {
      int i;
      int XOR;
      int c;
      // Calculate checksum ignoring any 

et voici le resultat obtenu :
19.41
$WIMDA,I,1006,B,C,C,C,T,M,N,M2F
19.46
$WIMDA,I,1005,B,C,C,C,T,M,N,M
2C

ctemp contient bien visiblement ma chaine (19.41 et au second passage 19.46) par contre le sprintf ne me met pas dans buffer le contenu de ctemp ! =(

Merci pour votre aide très précieuses in the string
      for (XOR = 0, i = 0; i < strlen(string); i++) {
        c = (unsigned char)string[i];
        if (c == ‘*’) break;
        if (c != ’


et voici le resultat obtenu :
19.41
$WIMDA,,I,,1006,B,,C,,C,,,,C,,T,,M,,N,,M*2F
19.46
$WIMDA,,I,,1005,B,,C,,C,,,,C,,T,,M,,N,,M*2C

ctemp contient bien visiblement ma chaine (19.41 et au second passage 19.46) par contre le sprintf ne me met pas dans buffer le contenu de ctemp ! =(

Merci pour votre aide très précieuse) XOR ^= c;
      }
      return XOR;
    }

et voici le resultat obtenu :
19.41
$WIMDA,I,1006,B,C,C,C,T,M,N,M2F
19.46
$WIMDA,I,1005,B,C,C,C,T,M,N,M
2C

ctemp contient bien visiblement ma chaine (19.41 et au second passage 19.46) par contre le sprintf ne me met pas dans buffer le contenu de ctemp ! =(

Merci pour votre aide très précieuse

Bon change de technique, évite le sprintf() carrément :

void setup() {
}

void loop() {
  long baro = (bmp.readPressure()/100)+58;
  float temp = bmp.readTemperature();

  Serial.print(F("$WIMDA,,I,"));
  Serial.write(',');
  Serial.print(baro);
  Serial.print(F(",B,"));
  Serial.print(temp, 2);
  Serial.print(F(",C,,C,,,,C,,T,,M,,N,,M*"));
  Serial.println(getCheckSum(buffer), HEX);
  delay(2000);
}

// Calcul le CRC d'une chaine, retourné sous la forme d'un entier
int getCheckSum(char *string) {
  int i;
  int XOR;
  int c;
  // Calculate checksum ignoring any 

s in the string
  for (XOR = 0, i = 0; i < strlen(string); i++) {
    c = (unsigned char)string[i];
    if (c == ‘*’) break;
    if (c != ’


) XOR ^= c;
  }
  return XOR;
}

Bonsoir Skywodd,

Un grand merci pour ton aide qui va me permettre de faire aboutir une partie de mon projet de station météo. Débutant en langage C, je pense que tu l'avais remarqué XD j'apprends petit à petit en fonction des besoins relatif au projet.

Toutefois il me reste encore un point à solutionner. Il me faut impérativement passer en paramètre la chaine complète ($WIMDA,,I,1004,B,21.85,C,,C,,,,C,,T,,M,,N,,M*) dans buffer au niveau de la ligne Serial.println(getCheckSum(buffer), HEX); afin que le calcul du checksum de la chaine contenue dans buffer puisse se faire correctement.

Les différentes lignes Serial.print permettent de 'concaténer' vers le port série mais ne permettent pas de stocker la ligne complète dans buffer ce qui se traduit par un calcul du checksum toujours identique.

[u]exemple[/u] : $WIMDA,,I,1004,B,21.85,C,,C,,,,C,,T,,M,,N,,M*BF (checksum ok) $WIMDA,,I,1004,B,21.84,C,,C,,,,C,,T,,M,,N,,M*BF (checksum erroné) $WIMDA,,I,1004,B,21.81,C,,C,,,,C,,T,,M,,N,,M*BF (checksum erroné) $WIMDA,,I,1004,B,21.82,C,,C,,,,C,,T,,M,,N,,M*BF (checksum erroné) $WIMDA,,I,1004,B,21.80,C,,C,,,,C,,T,,M,,N,,M*BF (checksum erroné)

chaque checksum devrait etre différent du fait que ctemp est à chaque fois différent !

Je pense que la solution n'est pas loin mais mon niveau de programmation n'est pas suffisant pour toucher au but =(

Cordialement

Ok ok ... essaye ça :

void loop() {
  long baro = (bmp.readPressure()/100)+58;
  float temp = bmp.readTemperature();

  char buffer[82];
  char ctemp[9];
  
  dtostrf(temp, 8, 2, ctemp);
  sprintf(buffer, "$WIMDA,,I,,%ld,B,%s,C,,C,,,,C,,T,,M,,N,,M*", baro, ctemp);

  Serial.println(ctemp);
  Serial.print(buffer);
  Serial.println(getCheckSum(buffer), HEX);
  delay(2000);
}

Impec c’est tout bon.

Le projet de station météo va enfin avancer. Un grand merci pour ton aide et ta perspicacité.

Cordialement

pascal74: Impec c'est tout bon. Le projet de station météo va enfin avancer. Un grand merci pour ton aide et ta perspicacité.

N'oublie pas d'éditer ton 1er message et d'ajouter [Résolu] ;)