Forum: Mikrocontroller und Digitale Elektronik converting char arrays in int, float, string


von Max M. (Firma: Herr) (maxtox)


Lesenswert?

Hi,

und wieder eine Herasuvorderung :-)

habe es geschafft, doch ich frage nach einem eleganteren Weg, da ich 
kein Programmierer bin...

Ich habe Payload welches als byte* kommt, to int/float so umgewandelt:
1
//**********
2
int i;
3
for (i = 0; i<length; i++) {
4
message_buff[i] = payload[i];
5
}
6
message_buff[i] = '\0';
7
const char *p_payload = message_buff;
8
9
//********** converting array to int and float
10
got_double = strtod(p_payload, NULL);
11
got_int = atoi(p_payload);
12
got_float = atof(p_payload);
13
if (got_int == 0 || got_int<0) {
14
got_bool = 0;
15
}
16
else { got_bool = 1; }
17
//**********
danach habe ich Payload was so kommt xxx/sdfdfdjh/lksdfkd/sdjsdhf...

 in ein const char * umgewandelt, weil p_p wird als const char* erwartet 
wird
1
PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
2
    return publish(topic,(const uint8_t*)payload,strlen(payload),retained);

hier die umwandlung:
1
//*******convert float value to Char expected by function
2
char temp[5];
3
dtostrf(rrr,4,3,temp); //rrr ist a float value
4
//*******************
5
6
for (i = 0; i<length; i++) {
7
p_buff[i] = p[i];
8
}
9
p_buff[i] = '\0';
10
const char p_p = p_buff; //
11
MQTTclient.publish(p_p, CHAR);
12
//*********

Velleicht kennt Ihr einen einfacheren und ELLEGANTEREN Weg es zu 
konvertieren?

Danke!

Thank you in Advance!

von Klaus W. (mfgkw)


Lesenswert?

Max M. schrieb:
> ELLEGANTEREN

Eleganter wäre es, erstmal lesbaren Quelltext zu schreiben.
Bei dem oben springen ja die Frösche aus dem Teich. Ich lese sowas gar 
nicht im Detail - kann ja nichts taugen, wenn sich jemand sowenig Mühe 
gibt.

Davon abgesehen:

- Wieso konvertierst du in alles mögliche? Zuviel Rechenzeit? Oder 
brauchst du das wirklich?

- Wenn ich von irgendwo eine Zeichenkette bekomme, würde ich mich als 
erstes dafür interessieren, ob überhaupt etwas sinnvolles in einem 
korrekten Format drinsteht, und nicht einfach unreflektiert nach 
irgendwas umwandeln.
Was soll ich mit einer double, wenn der Text "Hilfe" war?

von Max M. (Firma: Herr) (maxtox)


Lesenswert?

Da muss ich dir recht geben... aber bis jetzt habe ich nur das:
1
void callback(char* topic, byte* payload, unsigned int length) {
2
  //START********************************Convert Calback to int float and bool*************************************** 
3
  Serial.print("Message arrived [");
4
  Serial.print(topic);
5
  Serial.print("] ");
6
  Serial.print("Length:");
7
  Serial.println(length);
8
  Serial.print("Payload:");
9
  Serial.write(payload, length);
10
  Serial.println();
11
12
 //********** Copy the payload to the new buffer 
13
  byte* p = (byte*)malloc(length);
14
  memcpy(p,payload,length);
15
 //********** needs because payload is not deleted 
16
  
17
  
18
  char message_buff[length];
19
  char p_buff[length];
20
  double got_double;
21
  int got_int;
22
  float got_float;
23
  bool got_bool;
24
25
  int i, len;
26
27
  for (i = 0; i<length; i++) 
28
  {
29
    message_buff[i] = payload[i];
30
  }
31
  message_buff[i] = '\0';
32
  const char *p_payload = message_buff;
33
34
  Serial.println("p_payload");
35
  Serial.println(p_payload);
36
37
  got_double = strtod(p_payload, NULL);
38
  got_int = atoi(p_payload);
39
  got_float = atof(p_payload);
40
  if (got_int == 0 || got_int<0) {
41
    got_bool = 0;
42
  }
43
  else { got_bool = 1; }  
44
  Serial.println("BUFF");Serial.println(p_payload);
45
  Serial.println("FLOAT");Serial.println(got_float);
46
  Serial.println("INT");Serial.println(got_int);
47
  Serial.println("BOOL");Serial.println(got_bool);
48
 //**********convert float value to Char expected by function
49
  char temp[5];
50
  dtostrf(rrr,4,3,temp); //rrr ist a float value
51
52
//**********************  
53
  for (i = 0; i<length; i++) {
54
    p_buff[i] = p[i];
55
  }
56
  p_buff[i] = '\0';
57
  const char *p_p = p_buff; //p_p ist topic made from last payload
58
  Serial.println("p_p");
59
  Serial.println(p_p);
60
//  Serial.write(p,length);
61
//  MQTTclient.publish(p_p, temp);
62
//**********************
63
free(p);

Weiss halt noch nicht wie ich am paylaod erkennen kann was das für ein 
tyüe ist... sind ja "nur" bytes (byte array...
Hast du da einen Tipp???


Danke!

von Rolf M. (rmagnus)


Lesenswert?

Max M. schrieb:
> Weiss halt noch nicht wie ich am paylaod erkennen kann was das für ein
> tyüe ist... sind ja "nur" bytes (byte array...
> Hast du da einen Tipp???

Dafür definiert man sich normalerweise ein Protokoll (oder nutzt ein 
existierendes). Das legt genau fest, wann welche Daten übertragen werden 
bzw. schickt die relevanten Infos mit, so dass man nicht beim Empfang 
raten muss, was man da wohl gerade empfangen haben könnte.
Um was mit den Daten anfangen zu können, musst du doch eh die Bedeutung 
kennen, und dann ergibt sich der Typ doch schon meist daraus.
Also was ist es, was du da empfängst?

von Volle22 (Gast)


Lesenswert?

Ein serielles Protokoll mit variablem Inhalt, liefert auch eine 
Information mit die es erlaubt den Inhalt zu identifizieren.

Das kann sich aus der Länge ergeben
oder  z.B durch ein Schlüsselzeichen

von Max M. (Firma: Herr) (maxtox)


Lesenswert?

Hi,

also ich empfange so was:

DOino_01/eins/zwei/drei/vier/fuenf - als topic
100 - als payload


vom server wird folgendes geschickt:

mqtt.0 Send to client [DOino_01] 'DOino_01/eins/zwei/drei/vier/fuenf': 
10

von Max M. (Firma: Herr) (maxtox)


Lesenswert?

es können also nur:

bool
int
float
string

kommen..

deswegen habe ich gedacht ich konvertiere reinkommende daten in alles 
was es sein könnte und dann im code (wenn ich weiß was ich will) gehe 
ich und sage getint oder getfloat...

von Volle22 (Gast)


Lesenswert?

zuerst musst du prüfen ob generell etwas gekommen ist das dem Protokoll 
entspricht. oder ob der Empfang gestört war.

Dann überprüfst du ob du der richtige Empfänger bist
in dem Beispiel: DOino_01  am Anfang bis zum ersten /

Die Nutzdaten sind in dem Beispiel auch einfach zu finden
kommen direkt nach dem Doppelpunkt


Bool   enthalten nur 0 oder 1
Float  einen Punkt

Wie Int "1" sich vom Bool unterscheiden kann ich an dem Beispiel nicht 
sagen


Konvertierungen von Ascii nach Zahlen benötigen sehr viel Rechenzeit
und macht man nur wenn man es muss.

Zeichenvergleich und Suche geht schnell

von Max M. (Firma: Herr) (maxtox)


Lesenswert?

das mit dem punkt (.)

also ich suche im string nach einem punkt? und wenn ja, dann ist es ein 
float?

so meinst du das?

von Volle22 (Gast)


Lesenswert?

Ich kenne das Protokoll nicht und das eine Beispiel zeugt es nicht

aber das westliche Merkmal einer Floatzahl ist der Punkt oder auf 
deutsch die Kommastelle.
 Es gibt natürlich viele Möglichkeiten diese Information zu übertragen.

von Mikro 7. (mikro77)


Lesenswert?

Hallo Max Maxov,

offensichtlich geht es dir um Deserialisierung: 
https://en.wikipedia.org/wiki/Serialization

Also, ein Sender erstellt bspw. aus C-Skalaren (int, float, etc.) ein 
Byte-Array, überträgt dieses Array an den Empfänger, der daraus wieder 
die C-Skalare zurückgewinnt.

Um das Umzusetzen, gibt es sehr viele Möglichkeiten.

Deinem Quelltext nach zu urteilen, serialisierst du deine Daten als 
ASCII String. Das ist absolut ok. Du mußt noch entscheiden wie genau 
dieser ASCII-String aufgebaut sein soll: Wie sieht die Repräsentation 
der einzelnen Skalare in ASCII aus, und, ggf., wie sieht eine Liste von 
Skalaren aus?

Nehmen wir einen ganz einfachen Fall: Es wird lediglich ein Boolean 
übertragen. True als '1' (ASCII 0x31) und False als '0' (0x30). Die 
Nachricht ist somit immer genau ein Byte lang.

Jetzt kommst du. Was möchtest du da übertragen? Welche Kombinationen 
gibt es? Deinen Quelltext nach zu urteilen möchtest du entweder ein 
float, double, int oder boolean übertragen. Häufig benutzt man in diesem 
Fall ein Wertepaar: ein Diskriminator, der anzeigt um welchen Datentyp 
es sich handelt, und dann den Wert selbst.

Die Kodierung des Boolean ist simpel (wie bspw. oben gezeigt). Bei int, 
float und double gibt es allerdings ein paar Fallstricke...

von Max M. (Firma: Herr) (maxtox)


Lesenswert?

S. J. schrieb:
> Die Kodierung des Boolean ist simpel (wie bspw. oben gezeigt). Bei int,
> float und double gibt es allerdings ein paar Fallstricke...

Vielen Dank,

versuche mich da durchzukäpfen!!!!

Danke für den Tipp!

Beitrag #6839101 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.