Problems with dtostrf and sprintf to print multiple strings to buffer

Hi,

I am working on some code that will take 2 measured temperatures and write them to a buffer. Then each time through the loop the whole buffer will be written to an 16x2 LCD display, in order to prevent any artifacts on the LCD. For now I am just printing to the serial terminal, while I figure it out.

I started with one temp read and all went well. However, when I added the second temp read things went awry.

Hardware used: Arduino UNO

What I think it should be doing:
It should print “23.12C, -10.17C”

What it’s actually doing:
Its printing “17C, -10.17C”

The code

[code]void setup() {
  Serial.begin(9600);
  float temp1 = 23.12F;
  float temp2 = -10.17F;
  Serial.print("Original Values: ");
  Serial.print(temp1);
  Serial.print("\t");
  Serial.println(temp2);

  char float1_str[sizeof(temp1 +1)]; // add 1 for "\0"
  char float2_str[sizeof(temp2 +1)];
  
  char line1[16];
  strcpy(line1, "");

  dtostrf(temp1, 4, 2, float1_str);
  dtostrf(temp2, 4, 2, float2_str);

  sprintf(line1, "% sC, % sC", float1_str, float2_str);

  Serial.println(line1);
}

void loop() {
}

[/code]

What I’ve tried:
I tried using an ftoa function instead and replace the lines

dtostrf(temp1, 4, 2, float1_str);
dtostrf(temp2, 4, 2, float2_str);

with:

 ftoa(float1_str, temp1, 2);
  ftoa(float2_str, temp2, 2);

However the output is the same, so it must be something else causing it.

If I change temp2 to something else, (eg. 23.02) then the output becomes “02, 23.02”.
So clearly it is printing the last 2 characters of temp2, then printing temp2 (completely).

Here is the ftoa function:

char *ftoa(char *buffer, double d, int precision) {

  long wholePart = (long) d;

  // Deposit the whole part of the number.
  itoa(wholePart,buffer,10);

  // Now work on the fraction if we need one.
  if (precision > 0) {

    // We do, so locate the end of the string and insert
    // a decimal point.
    char *endOfString = buffer;
    while (*endOfString != '\0') endOfString++;
    *endOfString++ = '.';

    // Now work on the fraction, be sure to turn any negative
    // values positive.
    if (d < 0) {
      d *= -1;
      wholePart *= -1;
    }
    
    double fraction = d - wholePart;
    while (precision > 0) {

      // Multiple by ten and pull out the digit.
      fraction *= 10;
      wholePart = (long) fraction;
      *endOfString++ = '0' + wholePart;

      // Update the fraction and move on to the
      // next digit.
      fraction -= wholePart;
      precision--;
    }

    // Terminate the string.
    *endOfString = '\0';
  }
   return buffer;
}

It seems when I call either dtostrf or ftoa that it is overwriting the buffer, but I’ve triple checked that those functions when called twice are writing to different char arrays each time.

I feel like I’m missing something simple, but I can’t see it.

Assuming you want what I think you want:

  char float1_str[sizeof(temp1 +1)]; // add 1 for "\0"

should be

  char float1_str[sizeof(temp1) +1]; // add 1 for "\0"

Notwithstanding that error, I think you also have another problem, 'temp1' is a float type. It makes no sense to create char array of that size (except maybe for some special use). It is more likely that you have expectations for this logic that don't make sense in C. I'm not going to try to read your mind, instead you should explain it. 'temp1' has a size of 4 bytes because that is the size of a float variable.

aarg:
Assuming you want what I think you want:

  char float1_str[sizeof(temp1 +1)]; // add 1 for "\0"

should be

  char float1_str[sizeof(temp1) +1]; // add 1 for "\0"

Notwithstanding that error, I think you also have another problem, 'temp1' is a float type. It makes no sense to create char array of that size (except maybe for some special use). It is more likely that you have expectations for this logic that don't make sense in C.

Neither statement makes any sense. temp1 is a float, so sizeof() will always return 4, which has absolutely no relation to how many ASCII characters are needed to store the text representation of the number stored in temp1.

david_2018:
Neither statement makes any sense.

I know. I'm just trying to be gentle. :slight_smile:

It appears I replied while you were still editing your post, the last paragraph was not there when I first read it.

I knew there were some silly errors, but I've staring at it for so long I couldn't see them.

Explanation: So what I am trying to do is convert both temperatures into char arrays and then write them both to a 16 character array, so that I can write a whole line to the LCD display, in order to avoid artifacts that may sometimes otherwise appear.

david_2018:
It appears I replied while you were still editing your post, the last paragraph was not there when I first read it.

Sorry, bad habit of mine. I should stop doing that.

I fixed it, I had to resize the char arrays float1_str and float2_str as they were too small.

I made each one 8 since the LCD is 16.

Thanks for pointing out the error, much appreciated!