4
\$\begingroup\$

I am not sure if I should be posting this here or on Stackoverflow, but since this audience likely has the most experience with Arduino, I figured this would be the best place.

I just bought an Ethernet shield, and as a first project with it, I'm trying to publish a TMP36 temperature reading to Pachube. While Pachube accepts multiple formats for your data, I'm trying to post this stuff in JSON, because I like JSON. However, I'm running into trouble getting my temperature value, which is a float, into the JSON string. I'm a Python/PHP developer, and relatively new to C, so I've googled a lot but haven't discovered the right way to do this yet. Here is my code:

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

I keep getting the following error from the Arduino IDE (version 1.0): "Cannot convert 'String' to 'const char' for argument '2' to 'int sprintf(char, const char*, ...)'"

I found out I am calling sprintf() with the wrong number of arguments/arguments in the wrong order, since it does not return the formatted string. However, I'm not even sure sprintf() is the best function to use to accomplish the goal of getting the sensor's floating point value into a string. Is there a better way to do this

\$\endgroup\$
  • \$\begingroup\$ why the close vote? firmware questions are explicitly specified as being on-topic according to the faq \$\endgroup\$ – tcrosley Dec 6 '11 at 22:33
  • \$\begingroup\$ @tcrosley the other part of the FAQ is "for bare-metal or RTOS applications" In general, pure programming questions are a better fit on StackOverflow unless they are somehow interacting with the bare-metal, such as I/O or interrupts or any other specific bare-metal related code. But with that said, I am somewhat indifferent on the issue. \$\endgroup\$ – Kellenjb Dec 7 '11 at 0:53
  • \$\begingroup\$ @Kellenjb, I believe the phrase "firmware for bare-metal applications" fits perfectly with this question. I don't see where that necessarily limits the questions to only register or hardware-related areas, but can include questions such as this one, where the issue is a cut-down version of a standard C library dictated by the resources available on a small microcontroller. \$\endgroup\$ – tcrosley Dec 7 '11 at 17:15
  • \$\begingroup\$ @Kellenjb - although this initially looks like a vanilla C++ question, the answer below seems to indicate that a key part of the problem is unique due to the incomplete library implementation in this embedded environment. In short, a good argument for taking time to see what happens before initiating the close process. \$\endgroup\$ – Chris Stratton Dec 7 '11 at 18:02
  • \$\begingroup\$ Yes, while this is at first glance pure C++, and thus overflow-worthy, it is not actually the case. This is specific to Arduino, which, while not "programming the bare bones" is as good as, since it is not "normal" C++ programming. Posting this on SO would probably result in how to use sprintf() to do the job, but that wouldn't work. This is the best place for the kind of knowledge that does get the right answer to the question quickly, so should be obviously on topic. \$\endgroup\$ – Majenko Dec 7 '11 at 20:46
6
\$\begingroup\$

You cannot use sprintf() to format a float into a string on the Arduino.

Not only is the format of the command wrong, but sprintf on the Arduino does not support floats.

There is a function dtostrf() which converts a float into a character array. You can use it like:

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";

The format of the dtostrf function is:

dtostrf(value, width, precision, output);

where value is the float value you wish to convert, width is the minimum number of characters to display before the decimal point (padding with spaces as needed), precision is the number of decimal places, and output is the character array to put the results in.

\$\endgroup\$
  • \$\begingroup\$ Thanks! It compiled just fine with that code. I am not able to test it with Pachube right now, but I will update this thread when I do, if you're interested in the outcome. \$\endgroup\$ – tommytwoeyes Dec 7 '11 at 2:39
  • \$\begingroup\$ While making use of this, please notice the distinction between C-style character array strings and C++ style String objects, and that an explicit conversion from one to the other is made part way through. \$\endgroup\$ – Chris Stratton Dec 7 '11 at 18:06
  • \$\begingroup\$ @ChrisStratton Thanks. That would have been easy to overlook. You mean the line with tempAsString = String(temp); right? \$\endgroup\$ – tommytwoeyes Dec 7 '11 at 23:18
  • \$\begingroup\$ That's the line, yes. \$\endgroup\$ – Majenko Dec 7 '11 at 23:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.