Nun hätte ich gerne die beiden Zahlen Zeichenfolgen extrahiert.
1534194143956 ist ein timestamp in Millisekunden nach 1970. Den hätte ich gerne in ein neues char Array "Timestamp" geschrieben.
1.7996292763691 soll in eine float Zahl "Wert" umgewandelt werden.
Nun könnte man die Startstellen auszählen, wann der Wert beginnt. Und die jeweilige Länge.
Der Timestamp fängt an der 11. Stelle an, und ist 13 Stellen lang.
Der Wert fängt an der 31. Stelle an und ist 15 Stellen lang.
Is das eine gute Idee?
Oder kann man irgendwie das "timestamp=" und das "value=" erkennen und danach dann die Stellen bis keine Zahl, bzw. besser bis ein Leerzeichen kommt.
Bis dahin bin ich theoretisch schon.
Nun fehlt mir nur irgendwie der Startimpuls, wie ich das umsetzen kann?!
....bestimmt, aber ich bin doof und versteh das nicht. Das ist das Problem.
Ich habe mir mal dein Beispiel aus dem Link angeschaut.
Ich denke das verstehe ich soweit.
strstr() liefert mir eine Zahl zurück, die der Position im char Array entspricht. (ich hoffe das ist ein Zeiger?! wissen tue ich es nicht)
Ich habe meinen Code soweit angepasst.
Das Problem steckt nun aber an anderer Stelle:
char* PosOfString = (strstr ((char)payload[50], "value="));
will nicht, habs auch schon ohne * probiert.
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload*);*
Merke: Array-Variablen sind äquivalent zu Zeigern auf das erste Element. Der Parameter payload ist daher ein Zeiger. Das ist ganz normal wenn man Arrays/C-Strings übergibt. Das Array zerfällt dann bei der Übergabe in den Zeiger
Immer noch falsch:
Wert = atof(PosOfString + 1);
Ich habe gesagt die Länge des Teil-Strings addieren. Wie lang ist "value="? 6!
strstr() liefert einen Zeiger auf den Anfang des gefundenen Teil-Strings. Wenn du zu der Adresse also die Länge addierst bist du genau bei dem Zeichen danach.
Du kannst hier auch strlen() verwenden wenn du es 100%ig verständlich willst. Aber die Länge ist fix, daher muss man das eigentlich nicht zur Laufzeit berechnen
themanfrommoon:
Das die Zahlen nicht ganz identisch sind, liegt vermutlich an der Genauigkeit der Float Variable im ESP8266 ?!
Korrekt. Genauer geht es mit double. Float und Double ist bei den 8-Bit AVRs identisch und du hast nur 6-7 signifikante Stellen. Aber auf den 32-Bit Prozessoren hat double 64 Bit und daher 15 signifikante Stellen
Ja, sorry, falsch formuliert...
Das Suchen geht natürlich genauso mit strstr()
Was ich meinte war das Zuweisen anstatt mit atof für das double jetzt mit memcpy für das char Array.
Ich habe jetzt folgenden Code der bereits funktioniert.
Und auch aufpassen dass das Array 14 Zeichen lang ist und nicht 13!
Normal nimmt da eher Integer Variablen entsprechender Größe
Variablen fangen in C/C++ übrigens üblicherweise mit Kleinbuchstaben an. Das kompiliert auch so, aber du wist kaum jemanden finden der so Code schreibt
Gegen die Ungenauigkeit würde helfen, wenn Du mit Festkomma-Arithmetik arbeitest.
Sofern Dir 20 Stellen reichen (VOR + HINTER dem Komma) und die Zahl vorne mit <=1844674407 anfängt (genauer ist der Linux-Taschenrechner nicht, bei 64bit unsigned sagt Er halt 1,8...x10^19), kannst Du die übergebenen Zahlen einfachst zusammen rechnen.
UNSIGNED LONG LONG ENDZAHL=0; (oder uint64_t)
Von Vorne beginnend suchst Du ein Zahlzeichen.
Du Multiplizierst ENDZAHL mit 10, addierst dieses Zeichen zu Deiner ENDZAHL und ziehst 0x30 (oder '0') davon wieder ab.
Wenn Du das Komma (Punkt) erkennst, 'merkst' Du Dir, wo Dieses hin muß - dieses Zeichen wird nicht verrechnet.
Mit den folgenden Ziffern machst Du das Gleiche.
Du bekommst eine Zahl mit maximal 20 Stellen in Dezimal, wo Du an der entsprechenden Stelle nur das Komma wieder einsetzen musst.
Also, wenn Du Dir gemerkt hast, daß drei Zeichen vor dem Komma waren, gibst Du die ersten drei Zahlzeichen aus, ein Komma hinterher, die restlichen Zahlzeichen ausgeben.
Im Nachbar-Thread haben wir die Tage viel mit 64-Bit-Zahlen und Deren Anzeige (z.B. per Serial.print) - in diese Richtung gehen meine Gedanken.
Da Du hier bei INT bleibst (bzw. unsigned int), hast Du keine Rundungsfehler - eigentlich hast Du auch keine Komma-Stellen - Die machst Du Dir erst wieder selber rein durch Deine 'Festkomma-Stelle'.