Char-Variable mit Daten füllen; wie macht man's richtig?

Hallo,

ich baue in einem meiner Sketche eine Char-Variable mit Werten zusammen, um diese per 433 zu verschicken.
Momentan sieht das wie folgt aus:

// Temperatur-String zum Versand initialisieren
  char msg[24];

  // Node-ID an erste Stelle schreiben, durch ; separiert von den Nutzdaten
  msg[0] = 'i';
  msg[1] = 'd';
  msg[2] = '=';
  msg[3] = NODEID;
  msg[4] = '&';
  msg[5] = 't';
  msg[6] = 'e';
  msg[7] = 'm';
  msg[8] = 'p';
  msg[9] = '1';
  msg[10] = '=';

  // Float in Char umwandeln
  // dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);
  // +11 um die Daten an die 11. Stelle im Array zu schreiben
  dtostrf(temp1, 2, 2, msg+11);

  msg[16] = '&';
  msg[17] = 'v';
  msg[18] = 'c';
  msg[19] = 'c';
  msg[20] = '=';


  // Long in Char umwandeln
  // +6 um die Daten an die 6. Stelle im Char-Array zu schreiben
  ltoa(readVcc(), msg+21, 10);

Ich vermute mal, dass es eine bessere Möglichkeit gibt, als den einzelnen Array-Elementen die Buchstaben einzeln zuzuweisen.
Wie macht man das den "richtig"? Wie kann ich's optimieren?

Du könntest snprintf() probieren.
Damit kannst du dir beliebige Strings zusammenbasteln.

Wenn das zu sendende Telegramm msg 24 byte lang sein darf und doch vermutlich immer gleich aussehen soll, würde ich das Datentelegramm erzegen mit

snprintf(msg, 24, "ID=%d&temp1=%s&VCC=%s", NODEID, temp,readVCC) ;

Beispiel:
Für NODEID =3, temp1="23,3", und VCC = "5,0"

Ausgabe: "ID=3&temp1=23,3&VCC=5,0"

Wenn Du das '&' durch Leerzeichen ersetzen willst nimm '%%20'.Du hast zwar 24 byte kannst aber nur 23 beschreiben, wegen der Nullterminierung.

Gruß
Eberhard

Hi,

danke für die Hilfe; habe nur ein kleines Problem:
Die Temp1 ist eine Float (22.90)-Var. Und wenn ich zum formatieren %f verwende, kommt nur ein "?" als serieller Output per 433 Mhz an.

Ich habe mich jetzt totgesucht und komme nicht so wirklich weiter.
Ich dachte, ich konvertiere die float in einen string (dtostr) - aber dann wird mein Sketch zu groß und passt nicht mehr auf den ATTiny84.
Meine Zeile sieht aktuell so aus:

snprintf(msg, 24, "id=%d&temp1=%2.2f&vcc=%d", NODEID,temp1,readVcc()) ;

Jemand eine Idee? :confused:

Ja, das ist komisch und bekannt. Float scheint aus irgendeinem Grund bei printf() auf dem AVR nicht implementiert zu sein.

Idee: zuerstmal mit 100 multiplizieren. Dann in eine Ganzkommazahl umwandeln, dass das Komma weg ist. Und als Letztes den ganzzahligen Teil aus der Division temp1/100 und dem gebrochenen Teil aus dem Rest der Division temp1/00 zusammensetzen

float temp1;                                       // z.B. 22,5967
temp1=temp1*100;                                    // 2259,67
int temp1a=(int)temp1;                               // 2259
int tempGanzzahlig = temp1a/100;               // 22
int tempNachkomma = temp1a%100;           // 59

Dann tempGanzzahlig und tempNachkomma in die Funktion snprintf() einseztzen. Weiterrechnen kannst Du mit diesem Konstrukt natürlich nicht mehr.

Das ist nur eine Idee, hab's nicht ausprobiert.
Eberhard

eberduino:
Idee: zuerstmal mit 100 multiplizieren. Dann in eine Ganzkommazahl umwandeln, dass das Komma weg ist. Und als Letztes den ganzzahligen Teil aus der Division temp1/100 und dem gebrochenen Teil aus dem Rest der Division temp1/00 zusammensetzen

float temp1;                                       // z.B. 22,5967

temp1=temp1*100;                                    // 2259,67
int temp1a=(int)temp1;                               // 2259
int tempGanzzahlig = temp1a/100;               // 22
int tempNachkomma = temp1a%100;           // 59




Dann tempGanzzahlig und tempNachkomma in die Funktion snprintf() einseztzen. Weiterrechnen kannst Du mit diesem Konstrukt natürlich nicht mehr.

Das ist nur eine Idee, hab's nicht ausprobiert.
Eberhard

Du bist hart! Funktioniert einwandfrei! Vielen Dank; du hast gerade meinen Code um 30 Zeilen erleichtert und verständlich gemacht :slight_smile: