Char verketten?

Hallo,

ich bastel gerade an einem 433Mhz-Sender (Arduino Uno) der ein paar Sensorwerte an einen 433 Empfänger (Arduino Ethernet) schickt. Ich nutze da die VirtualWire-Bibliothek, die per Standard einen char-String frisst.

Ich wandle mir einen Float-Temperaturwert wie folgt in einen passenden Char um:

  // String zum Versand anlegen
  char msg[24];

  // Float in Char umwandeln
  // dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf);
  dtostrf(temperature, 2, 2, msg);

Das funktioniert auch. Mein Problem ist nun; ich würde gerne diesen Char-String manipulieren - also am einfachsten einen anderen davor oder danach dranhängen.

Mit Strings funktioniert das wohl; mit Char habe ich da nichts gefunden, und im Test zum Verketten von Char's mit "+" gab's nur Fehlermeldungen.

Momentan hänge ich HINTEN dran ein "N1", was für "Node 1" stehen soll:

// Node-ID anhängen. Format: xx.yy;NX
  // xx.yy = Temperatur, ;=Seperator, N steht für "Node", X für die Node-ID
  msg[5] = ';';
  msg[6] = 'N';
  msg[7] = NODEID;
  msg[8] = '\0'; // Char terminieren

Das ist weder schön, noch gut in der Handhabung. Ich hätte das N1; gerne am ANFANG; dafür müsste ich aber - zumindest ist das die einzige Möglichkeit, die mir da gerade einfällt - alle Werte im Array von der Position 3 nach hinten schreiben, und mein N1; auf die ersten drei Array-Pläte 0-2 schreiben.

Gibts da nicht eine einfache Möglichkeit für?

Memmove: http://www.cplusplus.com/reference/cstring/memmove/

EDIT: Fürs hinten dran hängen kann man das machen:

char msg[24] = "test";
unsigned char mode = 1;
char append[] = { ';', 'N', mode + 48, '\0' };
strcat(msg, append);

So ähnlich kannst du mit memcpy auch einen String an den Anfang kopieren:

char msg[24] = "test";
memmove(msg + 3, msg, strlen(msg));
unsigned char mode = 1;
char copy[] = { 'N', mode + 48, ';'};      //muss nicht unbedingt Null-terminiert werden, da memcpy verwendet wird
memcpy(msg, copy, 3);

Schau dir vielleicht mal string.h an: http://www.c-howto.de/tutorial-strings-zeichenketten-stringfunktionen.html http://www.cplusplus.com/reference/cstring/

Ich poste hier unter Vorbehalt, weil es durchaus sein kann, dass es nicht exakt Dein Problem trifft, aber manchmal helfen auch kleine Hinweise, die nicht 100%ig passen.

Ich hatte für die Ausgabe eines Strings für einen Musikserver den Befehl snprintf benutzt, da man dort innerhalb eines vorgegbenen Strings bestimmte Variablen veränderbar einsetzen kann.

Bei mir sah das dann so aus:

snprintf(SBox, 150, "GET /status?p0=display&p1=RFID-Steuerung%%20wurde%%20erfolgreich%%20nach&p2=%s%%20umgeleitet&p3=10&player=%02x:%02x:%02x:%02x:%02x:%02x HTTP/1.0",namTmp, macAdrTmp[0], macAdrTmp[1], macAdrTmp[2], macAdrTmp[3], macAdrTmp[4], macAdrTmp[5]);

SBox ist der Speicher mit einer Größe von 150 Byte max, in den der in " " stehende Begriff mit Platzhaltern für Variablen steht. Die Variablen selbst stehen anschließend in der Reihenfolge der Platzhalter. (%%20 sind Leerzeichen, %s ein string und in den sechs %02x steht eine Mac-Adresse.

Syntax von snprintf siehe: http://www.cplusplus.com/reference/cstdio/snprintf/ Verwendung der Variablen siehe:http://www.cplusplus.com/reference/cstdio/printf/

Sieht anfangs etwas komliziert aus, aber ist dann, wenn man es brgriffen hat, gut zu benutzen. Google mal snprintf

In meinem Fall wurde eine veränderliche Mitteilung auf einem Mediaplayer dargestellt.

Gruß Eberhard

In ein

``` char msg[30]; ```

kann man überall hin schreiben.

msg[0] = 'N'; // setzt einen Buchstaben an den Anfang
msg[1] = 'T';
msg[2] = ' '; // Leerzeichen müsseen auch gesetzt werden
dtostrf(temperature, 2, 2, msg+3); // schreibt das Ergebnis etwas weiter hinten

Musst nur aufpassen, dass in der Mitte keine 0 (Binär) bleibt, das ist das EndeKennzeichen des Textes.

michael_x:
In ein

** **char msg[30];** **

kann man überall hin schreiben.

msg[0] = 'N'; // setzt einen Buchstaben an den Anfang

msg[1] = ‘T’;
msg[2] = ’ '; // Leerzeichen müsseen auch gesetzt werden
dtostrf(temperature, 2, 2, msg+3); // schreibt das Ergebnis etwas weiter hinten




Musst nur aufpassen, dass in der Mitte keine 0 (Binär) bleibt, das ist das EndeKennzeichen des Textes.

Hallo und vielen Dank für diese Lösung!
Das ich mit +3 das Schreiben “nach hinten setzen” kann, wusste ich nicht - aber das ist eine Lösung, die mir gefällt, weil ich keine zusätzlichen Libs o.ä. brauche.

Funktioniert auch - danke dafür!

Du brauchst auch für andere Varianten keine extra Libs, bzw. du musst sie nicht per Hand einbinden. string.h ist automatisch inkludiert. Genauso wie stdlib.h welche die dstrof()-Funktion enthält

Siehe hier: http://www.nongnu.org/avr-libc/user-manual/modules.html

Wobei das so besser ist :) Deinen ersten Code Abschnitt habe ich irgendwie ignoriert und mich auf deine Frage am Ende beschränkt

Da ich nur ein Anfänger bin, beschäftigt mich die Frage, ob es nicht auch wie folgt geht:

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, "N%d,%s Grad", NODEID, temp) ;

Ausgabebeispiel: "N1,27.35 Grad"

Dabei ist NODEID ein integer-Wert und temp der bereits umgewandelte Temperaturstring.

Was würde dagegen sprechen?

Eberhard

Was würde dagegen sprechen?

nichts. Lies dir die snprintf dok durch, wenn die Werte unterschiedlich lang werden können Führende Nullen erzeugen usw. , geht alles ( ausser %f )

eberduino: Da ich nur ein Anfänger bin, beschäftigt mich die Frage, ob es nicht auch wie folgt geht:

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, "N%d,%s Grad", NODEID, temp) ;

Ausgabebeispiel: "N1,27.35 Grad"

Dabei ist NODEID ein integer-Wert und temp der bereits umgewandelte Temperaturstring.

Was würde dagegen sprechen?

Eberhard

Das hört sich gut an. Warum ich nicht drauf kam? Steck noch nicht so tief in der Materie :) Ich bin es "gewöhnt" - vermutlich von "aktuellen" Sprachen verwöhnt - dass man sich nicht so oft mit dem Umwandeln von Dateitypen beschäftigen muss. Zumindest bei AutoIT, mit dem ich in den letzten Jahren viel gemacht hab, spuckt da keine großen Fehlermeldungen aus.

Aber ich werde das mal prüfen :) Verkürzt den Code - und da ich nur 8 kb habe...