sprintf acting strangely!

Hi,

So having taken a long time to work out Arduino sprintf doesn't support doubles :frowning: I've come up with this code below to concatenate my GPS data into a string I can send with my LoRa:

uint32_t timer = millis();
char gps_position[100];

...

void loop()
{
    // if millis() or timer wraps around, we'll just reset it
    if (timer > millis()) timer = millis();
     
    // approximately every 1 seconds or so, print out the current stats
    if (millis() - timer > 1000)
    {
        // reset the variable
        gps_position[0] = 0;
        
        if (GPS.fix)
        {
            // print out raw data so we have a comparison
            Serial.print("Location: ");
            Serial.print(GPS.latitude, 4);
            Serial.print(", ");
            Serial.println(GPS.longitude, 4);
            Serial.print("Angle: "); Serial.println(GPS.angle);
            Serial.print("Altitude: "); Serial.println(GPS.altitude);
    
            char temp_lat[9];
            char temp_lon[9];
            char temp_angle[6];
            char temp_altitude[8];
    
            dtostrf(GPS.latitude, 4, 4, temp_lat);
            dtostrf(GPS.longitude, 4, 4, temp_lon);
            dtostrf(GPS.angle, 3, 2, temp_angle);
            dtostrf(GPS.altitude, 5, 2, temp_altitude);
          
            sprintf(gps_position,"%02d:%02d:%02d:%02d,%1i,%s,%s,%s,%s\0",GPS.hour,GPS.minute,GPS.seconds,GPS.milliseconds,GPS.fix,temp_lat,temp_lon,temp_angle,temp_altitude);

            // reset temp variables
            temp_lat[0] = 0;
            temp_lon[0] = 0;
            temp_angle[0] = 0;
            temp_altitude[0] = 0;
        }
    }
}

The problem is the output in serial is doing two really strange things... it's adding the temp_altitude value to the end of the temp_lat as well as at the end and it's just printing out a load of s's instead of the angle. Sometimes it's starts ok but always goes to the s's before too long:

Location: 1234.1234, 12.1234
Angle: 200.47
Altitude: -8.90
21:48:50:00,1,1234.1234-8.90,12.1234,ssssssssssssssssssssssss
⸮,-8.90

If I take out temp_angle across the board then it still appends the temp_altitude to the end of temp_lat and at the end, otherwise the output is fine:

Location: 1234.1234, 12.1234
Angle: 352.21
Altitude: -6.40
21:47:32:00,1,1234.1234-6.40,12.1234,-6.40

(I've changed the GPS values)

Why would this be happening?

littleninja:
Why would this be happening?

Because your temp buffers are too small. You are forgetting the terminating \0 that is automatically appended.
And you don't need to manually append a \0 in the sprintf.

Make sure all buffers are a sufficient size to hold the biggest required character string and the \0 terminator.

Oh, and this:

      // reset temp variables
      temp_lat[0] = 0;
      temp_lon[0] = 0;
      temp_angle[0] = 0;
      temp_altitude[0] = 0;

is unnecessary since these variables go out of scope at the end of the block. If you really need them to have an initialisation, then do it where they are declared.

sprintf doesn't support doubles

With the proper load instructions, sprintf() does support floats.

If you want to do that, the instructions are posted on this forum as well as elsewhere on the web.