Probleme beim Datentransfer über SIM800 Modul per MQTT

Hey Andreas.

Das ist mir auch aufgefallen. Warum auch immer. Was ich halt komisch finde ist, dass wenn ich mir die Protokolle auf https://swarm.hiveeyes.org/transmissions anschaue, beim ersten Senden alles richtig geschrieben wird auch so wie es soll (hiveeyes/kasper/Garten/Stand1/data/Temperatur 24.10). Beim 2ten mal schreiben kommt dann ein weiteres “Temperatur” hinzu (hiveeyes/kasper/Garten/Stand1/data/TemperaturTemperatur 26.70)

Kennst du eine Möglichkeit, dieses zu testen? bzw. anders zu schreiben, dass nicht viel Speicher dabei drauf geht?

Aha, einmal klappts also!

Ja, seltsam. Das deutet irgendwie auf ungünstiges Laufzeitverhalten (Speicherkorruption o.ä.) hin. Versuche es doch einmal “so minimal wie möglich”, also ohne Sleepmode und Dinge, die nicht unbedingt notwendig sind und taste Dich in diese Richtung vor.

Wenn alles nichts hilft, musst Du u.U. nochmal einen isolierten Testsketch auflegen, der nur MQTT Kommunikation macht und Dich von dort aus herantasten. Signifikant anders machen wir es in unserer Werkstatt auch nicht, um subtile Bugs in der Firmware aufzuspüren.

Problem

Ich vermute in der Tat, dass diese Zeile zu Speicherkorruption führt. Damit wäre auch das aktuelle Symptom, dass es ein zwei Mal funktioniert, nicht unplausibel.

Konkret ist es vermutlich strcat(top, topic). Mit der Funktionssignatur

char * strcat ( char * destination, const char * source );

sowie der Dokumentation

destination
Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.

http://www.cplusplus.com/reference/cstring/strcat/

kannst Du Dir vermutlich schon selber denken, wo der Hase im Pfeffer liegt: strcat funktioniert nicht ganz so komfortabel wie gedacht. Es alloziert nicht selbständig neuen Speicher um den vergrößerten String darin abzulegen, sondern man muss das vorher selbst tun.

Lösung?

Am besten, Du allozierst Dir auf dem Stack lokal in der Funktion eine neue Variable, die eine ausreichende Größe hat, um sie dann mit dem effektiven Topicstring zu belegen, vielleicht klappt das so in etwa wie im Beispiel für strcat zu sehen:

char effective_topic[255];
strcpy(effective_topic, top);
strcat(effective_topic, topic);
mqtt.publish(effective_topic, temp);

Unter Arduino könnte es aber umso komfortabler auch folgendermaßen klappen:

String effective_topic = top + topic;
mqtt.publish(effective_topic, temp);

Hier liegt es wirklich drann. Warum auch immer. Ich bin jetzt einfach mal her gegangen und habe die Topics oben wieder “lang” geschrieben. Dies dann unten eingetragen und es Funktioniert. Somit lasse ich es erstmal so. Auch mit der Sleep Funktion geht alles.

So jetzt dann “nur” noch alles vom Steckbrett auf ne Platine und dann los^^