Arduino Sketch Kompilierungsfehler: Versuch, Float mit String zu verketten

Ich bin mir nicht sicher, ob ich das hier oder auf Stackoverflow posten sollte, aber da dieses Publikum wahrscheinlich die meiste Erfahrung mit Arduino hat, dachte ich, dass dies der beste Ort wäre.

Ich habe gerade ein Ethernet-Schild gekauft, und als erstes Projekt damit versuche ich, einen TMP36-Temperaturmesswert an Pachube zu veröffentlichen. Während Pachube mehrere Formate für Ihre Daten akzeptiert, versuche ich, dieses Zeug in JSON zu posten, weil ich JSON mag. Ich habe jedoch Probleme, meinen Temperaturwert, der ein Float ist, in den JSON-String zu bekommen. Ich bin ein Python/PHP-Entwickler und relativ neu in C, also habe ich viel gegoogelt, aber noch nicht den richtigen Weg gefunden, dies zu tun. Hier ist mein Code:

float temperature = 85.4; // Or whatever
String jsonData = sprintf("{'version':'1.0.0', 'datastreams':[{'id':'%s', 'current_value':'%f'}]}\n", datastream1, temperature);

Ich bekomme immer wieder die folgende Fehlermeldung von der Arduino IDE (Version 1.0): "Cannot convert 'String' to 'const char' for argument '2' to 'int sprintf(char, const char*, ...)'"

Ich habe herausgefunden, dass ich sprintf() mit der falschen Anzahl von Argumenten/Argumenten in der falschen Reihenfolge aufrufe, da es nicht die formatierte Zeichenfolge zurückgibt. Ich bin mir jedoch nicht einmal sicher, ob sprintf() die beste Funktion ist, um das Ziel zu erreichen, den Gleitkommawert des Sensors in eine Zeichenfolge zu bringen. Gibt es einen besseren Weg, dies zu tun

Warum die knappe Abstimmung? Firmware-Fragen sind laut FAQ explizit als on-topic gekennzeichnet
@tcrosley der andere Teil der FAQ ist "für Bare-Metal- oder RTOS-Anwendungen". Im Allgemeinen passen reine Programmierfragen besser zu StackOverflow, es sei denn, sie interagieren irgendwie mit dem Bare-Metal, wie E / A oder Interrupts oder irgendetwas anderer spezifischer Bare-Metal-bezogener Code. Aber wenn das gesagt ist, bin ich etwas gleichgültig, was das Thema angeht.
@Kellenjb, ich glaube, der Ausdruck "Firmware für Bare-Metal-Anwendungen" passt perfekt zu dieser Frage. Ich sehe nicht, wo das die Fragen notwendigerweise nur auf Register- oder Hardware-bezogene Bereiche beschränkt, aber es kann Fragen wie diese geben, bei denen es um eine abgespeckte Version einer Standard-C-Bibliothek geht, die von den verfügbaren Ressourcen diktiert wird a kleiner Mikrocontroller.
@Kellenjb - Obwohl dies zunächst wie eine einfache C++-Frage aussieht, scheint die folgende Antwort darauf hinzudeuten, dass ein wesentlicher Teil des Problems aufgrund der unvollständigen Bibliotheksimplementierung in dieser eingebetteten Umgebung einzigartig ist. Kurz gesagt, ein gutes Argument dafür, sich Zeit zu nehmen, um zu sehen, was passiert, bevor man den Abschlussprozess einleitet.
Ja, obwohl dies auf den ersten Blick reines C++ und damit überlaufwürdig ist, ist es tatsächlich nicht der Fall. Dies ist spezifisch für Arduino, das, obwohl es nicht "das nackte Knochen programmiert", so gut ist, da es keine "normale" C ++ - Programmierung ist. Das Posten auf SO würde wahrscheinlich dazu führen, wie man sprintf() verwendet, um die Arbeit zu erledigen, aber das würde nicht funktionieren. Dies ist der beste Ort für die Art von Wissen, das schnell die richtige Antwort auf die Frage liefert, also offensichtlich zum Thema gehören sollte.

Antworten (1)

Sie können sprintf()einen Float auf dem Arduino nicht in einen String formatieren.

Nicht nur das Format des Befehls ist falsch, sprintf auf dem Arduino unterstützt auch keine Floats.

Es gibt eine Funktion dtostrf(), die ein Float in ein Zeichenarray umwandelt. Sie können es wie folgt verwenden:

float temperature = 85.4;
char temp[10];
String tempAsString;
String jsonData;

dtostrf(temperature,1,2,temp);
tempAsString = String(temp);

jsonData = "{'version':'1.0.0', 'datastreams':[{'id':'" +
    datastream1 + "', 'current_value':'" + tempAsString + "'}]}\n";

Das Format der dtostrfFunktion ist:

dtostrf(value, width, precision, output);

wobei valueder Gleitkommawert ist, den Sie umwandeln möchten, widthdie Mindestanzahl von Zeichen ist, die vor dem Dezimalkomma angezeigt werden sollen (bei Bedarf mit Leerzeichen auffüllen), precisiondie Anzahl der Dezimalstellen ist und outputdas Zeichenarray ist, in das die Ergebnisse eingefügt werden.

Danke! Es kompiliert gut mit diesem Code. Ich kann es im Moment nicht mit Pachube testen, aber ich werde diesen Thread aktualisieren, wenn ich das tue, wenn Sie an dem Ergebnis interessiert sind.
Beachten Sie bei der Verwendung dessen den Unterschied zwischen Zeichen-Array-Strings im C-Stil und String-Objekten im C++-Stil und dass eine explizite Konvertierung von einem in das andere auf halbem Weg erfolgt.
@ChrisStratton Danke. Das hätte man leicht übersehen können. Du meinst die Zeile mit tempAsString = String(temp);rechts?
Das ist die Linie, ja.