0

I have a loop command reading temperature sensor data from 8 thermistors and are storing them as floats into an array. Instead of printing to Serial on each iteration, I would like to create a comma separated string of these values and send to serial (in one instance, versus 8). What would be the best way to do this? I have tried sprintf commands to no avail.

Thanks in advance!

Edit: I would like to also write this string of comma separated values to a MicroSD card slot so I am under the assumption that creating the string once and printing to Serial AND saving to MicroSD card is more efficient than 8 separate iterations

6
  • 2
    It sounds like you're expecting serial communication to be like a bag of candy. All there in one place at the same time. In reality serial communication is more like this: youtube.com/watch?v=jv9qaPAlK_g
    – Majenko
    Nov 8 '20 at 12:21
  • Unless the thermistor actually delivers floating point results, your code can do less work by storing the fixed-point data and converting that. The array will be smaller, and you would be able to use any of the printf()-family of functions to format your output if that would be helpful, including generating the ASCII data into memory once, and then sending it to both devices (regardless of whether you handle 1 or all 8 results at a time).
    – JRobert
    Nov 8 '20 at 13:25
  • @JRobert - would be able to provide a printf() example? I think for cleanliness this would be ideal. And I do get float values from thermistors
    – NRav
    Nov 8 '20 at 16:21
  • I'd be happy to, except for the fact that the Arduino library printf() functions exclude the floating point conversions. If you don't need any decimal places, then we could do it. Even if you did want a couple of decimal places - but then it starts to get messy because you'll need to extract the whole number of degrees and the fractional remainder rounded to n-places, and convert them separately. It's doable but you lose some of the directness and simplicity of expression that printf() is meant to offer.
    – JRobert
    Nov 8 '20 at 21:18
  • ... In this situation I use dtostrf() to convert the float to ASCII in one buffer, then format any remaining output using printf() - or sprintf() - using the ASCII string versions of the floats, to a serial device or another buffer, respectively. It's workable but the code doesn't look as nice as if the printf() functions would all the work at once.
    – JRobert
    Nov 8 '20 at 21:28
3

Basic Arduinos have no support for floating point in sprintf and related functions.

Instead you have to use dtostrf() to build up a string block by block.

However there is no benefit to building a string then outputting to serial "in one instance" compared to outputting the data a bit at a time. Serial is slow. Very slow. When you "output" data to serial you aren't outputting data. You're merely putting the data into a buffer to be sent when it's possible.

In effect, by using multiple Serial.print() calls, you're building up the string to send in the Arduino's internal serial TX buffer.

By building the string first all you're doing is creating a buffer to copy data into a buffer to send it through serial. It's redundant, wasteful, and utterly pointless.

3
  • Thanks for the response and description @Majenko. I should have also mentioned this too but I was planning to also write the string of comma separated values to a microSD card. I thought it would be better to log the data once versus 8 times each void loop() - hence why creating the string might be optimal
    – NRav
    Nov 8 '20 at 12:26
  • 2
    Same thoughts apply for writing to SD. (file.print only writes to a buffer) You should consider calling flush or close/open less often than after every print, anyway. Nov 8 '20 at 12:34
  • Thanks @DataFiddler. I will try avoiding the building of strings and just submit to Serial/SD writing as data is ingested.
    – NRav
    Nov 8 '20 at 12:45
0

Here's a sample program using sprintf() to convert some float data to ASCII in a buffer, format an output string containing that data into another buffer and print the result on the terminal. It's not quite as neat as

   "sprintf(buffer, "i=%2d, T=%f\n", i, Temp); 

It takes three lines and two buffers but it gets the job done:

#include <Arduino.h>

float getTemp(void);

void setup()
{
   char tempBuf[10+1], outputBuf[50+1];

   // Open console
   Serial.begin(115200);

   // Print 20 successive temperatures to the terminal
   for( uint8_t i = 1;  i <= 20;  ++i){
      float Temp;

      Temp = getTemp();                 // get the next value
      dtostrf(Temp, 6, 2, tempBuf);     // Convert float to ASCII
      sprintf(outputBuf, "i=%2d, T=%s\n", i, tempBuf); // format the value for printing
      Serial.print(outputBuf);          // print the line to the terminal

      delay(1000L);
   }

}


// Function to return temperatures.
// STUB: The data is made-up.
float getTemp(void){
   static uint8_t n = 0;        // count of results returned

   return( (float)n++ * 1.7 );  // index 'n' times an arbitrary multiplier
}



void loop(void)
{
   ;
}

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.