Error de compilación de Arduino Sketch: tratando de concatenar el flotador con una cadena

No estoy seguro de si debería publicar esto aquí o en Stackoverflow, pero dado que esta audiencia probablemente tenga más experiencia con Arduino, pensé que este sería el mejor lugar.

Acabo de comprar un escudo Ethernet y, como primer proyecto con él, estoy tratando de publicar una lectura de temperatura TMP36 en Pachube. Si bien Pachube acepta múltiples formatos para sus datos, estoy tratando de publicar esto en JSON, porque me gusta JSON. Sin embargo, tengo problemas para obtener mi valor de temperatura, que es un valor flotante, en la cadena JSON. Soy un desarrollador de Python/PHP y relativamente nuevo en C, así que busqué mucho en Google pero aún no he descubierto la forma correcta de hacerlo. Aquí está mi código:

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

Sigo recibiendo el siguiente error del IDE de Arduino (versión 1.0): "No se puede convertir 'String' a 'const char' para el argumento '2' a 'int sprintf(char, const char*, ...)'"

Descubrí que estoy llamando a sprintf() con la cantidad incorrecta de argumentos/argumentos en el orden incorrecto, ya que no devuelve la cadena formateada. Sin embargo, ni siquiera estoy seguro de que sprintf() sea la mejor función para lograr el objetivo de convertir el valor de punto flotante del sensor en una cadena. Hay una mejor manera de hacer esto

¿Por qué la votación cerrada? las preguntas de firmware se especifican explícitamente como sobre el tema de acuerdo con las preguntas frecuentes
@tcrosley, la otra parte de las preguntas frecuentes es "para aplicaciones bare-metal o RTOS". En general, las preguntas de programación pura encajan mejor en StackOverflow a menos que interactúen de alguna manera con el bare-metal, como E/S o interrupciones o cualquier otro código específico relacionado con bare-metal. Pero dicho esto, soy algo indiferente sobre el tema.
@Kellenjb, creo que la frase "firmware para aplicaciones completas" encaja perfectamente con esta pregunta. No veo dónde eso necesariamente limita las preguntas solo al registro o áreas relacionadas con el hardware, pero puede incluir preguntas como esta, donde el problema es una versión reducida de una biblioteca C estándar dictada por los recursos disponibles en un pequeño microcontrolador.
@Kellenjb: aunque inicialmente parece una pregunta básica de C ++, la respuesta a continuación parece indicar que una parte clave del problema es única debido a la implementación incompleta de la biblioteca en este entorno integrado. En resumen, un buen argumento para tomarse un tiempo para ver qué sucede antes de iniciar el proceso de cierre.
Sí, aunque a primera vista esto es C++ puro y, por lo tanto, digno de desbordamiento, en realidad no es así. Esto es específico para Arduino, que, aunque no "programa los huesos básicos", es tan bueno como, ya que no es una programación C ++ "normal". Publicar esto en SO probablemente resultaría en cómo usar sprintf() para hacer el trabajo, pero eso no funcionaría. Este es el mejor lugar para el tipo de conocimiento que obtiene la respuesta correcta a la pregunta rápidamente, por lo que obviamente debería ser sobre el tema.

Respuestas (1)

No puede usar sprintf()para formatear un flotador en una cadena en el Arduino.

No solo el formato del comando es incorrecto, sino que sprintf en Arduino no admite flotadores.

Hay una función dtostrf()que convierte un flotante en una matriz de caracteres. Puedes usarlo como:

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

El formato de la dtostrffunción es:

dtostrf(value, width, precision, output);

donde valueestá el valor flotante que desea convertir, widthes el número mínimo de caracteres para mostrar antes del punto decimal (rellenando con espacios según sea necesario), precisiones el número de lugares decimales y outputes la matriz de caracteres para colocar los resultados.

¡Gracias! Compiló muy bien con ese código. No puedo probarlo con Pachube en este momento, pero actualizaré este hilo cuando lo haga, si está interesado en el resultado.
Al hacer uso de esto, tenga en cuenta la distinción entre las cadenas de caracteres de estilo C y los objetos de cadena de estilo C++, y que se realiza una conversión explícita de uno a otro en la mitad.
@ChrisStratton Gracias. Eso habría sido fácil de pasar por alto. ¿ Te refieres a la línea con tempAsString = String(temp);la derecha?
Esa es la línea, sí.