Convert string to double retaining 7 decimals

Hi, I am a new programmer. I have a String called tempMessage which contains longitude and latitude, which are constantly changing.
in my code, I do
longitude = tempMessage.toDouble();

Say that tempMessage is 34.134408, longitude is only 34.13,
if its -117.707238, it becomes 117.71, loosing the sign.

How do I convert to preserve as many decimals as possible from the string to the double?

If it is a char array using atof, then how do I record bytes one at a time, add to the char array, and then convert the char array?

my full processing code is:

void parseMessage(char rxPacket[], int16_t rxSize, int16_t rssi){
  Serial.printf("\r\nreceived packet \"%s\" with rssi %d , length %d\r\n",rxPacket,rssi,rxSize);
  int numCommas = 0;
  String tempMessage;
  String val;
  for(int i = 0; i <= rxSize; i++){
    val = String(rxPacket[i]);
    
    if(val == ","){
      switch(numCommas){
        case 0: 
          //int hour
          rGpsData.gps_hour = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C  tM: "); Serial.println(tempMessage);
          break;
        case 1:
          //int minute
          rGpsData.gps_minute = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 2:
          //int second
          rGpsData.gps_second = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 3: 
         //int sats
          rGpsData.satellitesConnected = tempMessage.toInt();
          Serial.print("rGpsData.satellitesConnected"); Serial.println(rGpsData.satellitesConnected);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 4:
          //float lat
          rGpsData.latitude = tempMessage.toDouble();
          //rGpsData.latitude = tempMessage.toFloat(); // atof(tempMessage)
          Serial.print("rGpsData.latitude"); Serial.println(rGpsData.latitude);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 5:
          //float long
          rGpsData.longitude = tempMessage.toDouble();
          //rGpsData.longitude = tempMessage.toFloat();
          Serial.print("rGpsData.longitude"); Serial.println(rGpsData.longitude);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 6:
          //double altitudeM
          rGpsData.altitudeM = tempMessage.toDouble();
          //rGpsData.altitudeM = tempMessage.toFloat();
          Serial.print("rGpsData.altitude"); Serial.println(rGpsData.altitudeM);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print(" tM: "); Serial.println(tempMessage);
          break;
        case 7:
          //bool valid
          if(tempMessage == "1"){
            rGpsData.valid = true;
          }
          else if (tempMessage == "0"){
            rGpsData.valid = false;
          }
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;  
        case 8:
          Serial.println("8 commas");
              
          Serial.print("8 nC: "); Serial.print(numCommas);
          Serial.print("8 tM: "); Serial.println(tempMessage);
          break;  
      }
      
      //Serial.print(" == nC: "); Serial.print(numCommas);
      //Serial.print(" == tM: "); Serial.println(tempMessage);
      tempMessage = "";
      numCommas++;
    }
    else if(val == "|"){
      if(rxPacket[i-1] == '1'){
        rGpsData.valid = true;
      }
      else if (rxPacket[i-1] == '0'){
        rGpsData.valid = false;
      }
      Serial.print("Valid: "); Serial.println(rGpsData.valid);
      break;
    }
    else{
      tempMessage += val;
    } 
  }   
}

example output:

received packet "19,11,28,9,34.134408,-117.707238,196.40,1|" with rssi -29 , length 42
rGpsData.satellitesConnected9
C tM: 9
rGpsData.latitude34.13
C tM: 34.134408
rGpsData.longitude-117.71
C tM: -117.707238
rGpsData.altitude196.40
tM: 196.40
Valid: 1

Tm is the temprory message, while the value show is what I'm writing it to.

(I just used C to show that it was an output from inside the case statement)

rGpsData is a struct with all the data inside, I want to write to update that data so that I can use it later, but constantly be updating it so that it is accurate.

My actual full code is here, just in case you want to look through for how I'm getting the message and using it and suggest a better way

/*
  parse data coming in and assign it to rdata stuffs on every recieve cycle.
*/

#include "Arduino.h"
#include <Wire.h>

#include "LoRaWan_APP.h"
#include "GPS_Air530.h"
#include "HT_SSD1306Wire.h"

SSD1306Wire  screen(0x3c, 500000, SDA, SCL, GEOMETRY_128_64, GPIO10 ); // addr , freq , i2c group , resolution , rst

Air530Class Gps;

#ifndef LoraWan_RGB
#define LoraWan_RGB 0
#endif

#define RF_FREQUENCY                                915000000 // Hz

#define TX_OUTPUT_POWER                             14        // dBm

#define LORA_BANDWIDTH                              0         // [0: 125 kHz,
                                                              //  1: 250 kHz,
                                                              //  2: 500 kHz,
                                                              //  3: Reserved]
#define LORA_SPREADING_FACTOR                       7         // [SF7..SF12]
#define LORA_CODINGRATE                             1         // [1: 4/5,
                                                              //  2: 4/6,
                                                              //  3: 4/7,
                                                              //  4: 4/8]
#define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT                         0         // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON                  false
#define LORA_IQ_INVERSION_ON                        false


#define RX_TIMEOUT_VALUE                            1000
#define BUFFER_SIZE                                 50 // Define the payload size here

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];

static RadioEvents_t RadioEvents;

int16_t txNumber;

int16_t rssi,rxSize;

struct recieveData{
  double  latitude;
  double  longitude;
  double altitudeM;
  double signalQuality;
  int locationAge;
  double speedKmph;
  double courseDeg; 
  int satellitesConnected;
  int gps_year;
  int gps_day;
  int gps_month; 
  int gps_hour;
  int gps_minute;
  int gps_second;
  int gps_centisecond;
  bool valid;  
  
  //year, day, month, hour, minute, second, centisecond, lat, lng, alt.meters, sats, hdop (quality), age, coursedeg, speedkmph    
};
recieveData rGpsData;

struct selfData{
  double  latitude;
  double  longitude;
  double altitudeM;
  double signalQuality;
  int locationAge;
  double speedKmph;
  double courseDeg; 
  int satellitesConnected;
  int gps_year;
  int gps_day;
  int gps_month; 
  int gps_hour;
  int gps_minute;
  int gps_second;
  int gps_centisecond;
  bool valid;  
};
selfData sGpsData;

uint32_t gpsTimer = 0;
uint32_t displayInformationTimer = 0;

int timer1000 = 1000;

void VextON(void){
  pinMode(Vext,OUTPUT);
  digitalWrite(Vext, LOW);
}

void VextOFF(void) {//Vext default OFF
  pinMode(Vext,OUTPUT);
  digitalWrite(Vext, HIGH);
}


void displayInformation();

void setup() {
    Serial.begin(115200);
    VextON();
    
    Gps.begin(9600);
    Gps.setmode(MODE_GPS);

    rssi=0;
	
	  RadioEvents.RxDone = OnRxDone;
    Radio.Init( &RadioEvents );
    Radio.SetChannel( RF_FREQUENCY );
	
	Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                                   LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                                   LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
                                   0, true, 0, 0, LORA_IQ_INVERSION_ON, true );
   
  screen.init();
  screen.clear();
  screen.display(); 
  screen.setTextAlignment(TEXT_ALIGN_CENTER);
  screen.setFont(ArialMT_Plain_10);
  screen.drawString(screen.width()/2,screen.height()/2,"gps comms 2 RX");
  screen.display(); 
  delay(1000);
  screen.clear();
  Serial.println("into RX mode");

  }

void loop(){
	Radio.Rx( 0 );
  delay(500);
  Radio.IrqProcess( );
  displayInformation();
}

void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ){
    rssi=rssi;
    rxSize=size;
    memcpy(rxpacket, payload, size );
    rxpacket[size]='\0';
    //turnOnRGB(COLOR_RECEIVED,0);
    Radio.Sleep( );
    parseMessage(rxpacket,rxSize, rssi);  
}

void parseMessage(char rxPacket[], int16_t rxSize, int16_t rssi){
  Serial.printf("\r\nreceived packet \"%s\" with rssi %d , length %d\r\n",rxPacket,rssi,rxSize);
  int numCommas = 0;
  String tempMessage;
  String val;
  for(int i = 0; i <= rxSize; i++){
    val = String(rxPacket[i]);
    
    if(val == ","){
      switch(numCommas){
        case 0: 
          //int hour
          rGpsData.gps_hour = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C  tM: "); Serial.println(tempMessage);
          break;
        case 1:
          //int minute
          rGpsData.gps_minute = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 2:
          //int second
          rGpsData.gps_second = tempMessage.toInt();
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 3: 
         //int sats
          rGpsData.satellitesConnected = tempMessage.toInt();
          Serial.print("rGpsData.satellitesConnected"); Serial.println(rGpsData.satellitesConnected);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 4:
          //float lat
          rGpsData.latitude = tempMessage.toDouble();
          //rGpsData.latitude = tempMessage.toFloat(); // atof(tempMessage)
          Serial.print("rGpsData.latitude"); Serial.println(rGpsData.latitude);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 5:
          //float long
          rGpsData.longitude = tempMessage.toDouble();
          //rGpsData.longitude = tempMessage.toFloat();
          Serial.print("rGpsData.longitude"); Serial.println(rGpsData.longitude);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print("C tM: "); Serial.println(tempMessage);
          break;
        case 6:
          //double altitudeM
          rGpsData.altitudeM = tempMessage.toDouble();
          //rGpsData.altitudeM = tempMessage.toFloat();
          Serial.print("rGpsData.altitude"); Serial.println(rGpsData.altitudeM);
          //Serial.print("CnC: "); Serial.print(numCommas);
          Serial.print(" tM: "); Serial.println(tempMessage);
          break;
        case 7:
          //bool valid
          if(tempMessage == "1"){
            rGpsData.valid = true;
          }
          else if (tempMessage == "0"){
            rGpsData.valid = false;
          }
          //Serial.print("CnC: "); Serial.print(numCommas);
          //Serial.print("C tM: "); Serial.println(tempMessage);
          break;  
        case 8:
          Serial.println("8 commas");
              
          Serial.print("8 nC: "); Serial.print(numCommas);
          Serial.print("8 tM: "); Serial.println(tempMessage);
          break;  
      }
      
      //Serial.print(" == nC: "); Serial.print(numCommas);
      //Serial.print(" == tM: "); Serial.println(tempMessage);
      tempMessage = "";
      numCommas++;
    }
    else if(val == "|"){
      if(rxPacket[i-1] == '1'){
        rGpsData.valid = true;
      }
      else if (rxPacket[i-1] == '0'){
        rGpsData.valid = false;
      }
      Serial.print("Valid: "); Serial.println(rGpsData.valid);
      break;
    }
    else{
      tempMessage += val;
    } 
  }   
}

void displayInformation(){
  if(millis() - displayInformationTimer >= timer1000){
    updateSelfInfo();
    Serial.println("========================");
    String lineString;
    screen.clear();
    screen.setFont(ArialMT_Plain_10);
    screen.setTextAlignment(TEXT_ALIGN_LEFT);
  
  //recieved data
    if(rGpsData.valid == true){
      lineString = "R long " + String(long(rGpsData.longitude)) + "  d " + String(rGpsData.gps_day) + "/" + String(rGpsData.gps_month) + "/" + String(rGpsData.gps_year);
      screen.drawString(0, 0,lineString);
      Serial.println(lineString);
  
      lineString = " R lat " + String(long(rGpsData.latitude)) + " alt " + String(rGpsData.altitudeM) + "  t " + String(rGpsData.gps_hour) + ":" + String(rGpsData.gps_minute) + ":" + String(rGpsData.gps_second);
      screen.drawString(0, 16,lineString);
      Serial.println(lineString);
    }
    else if(rGpsData.valid == false){
      screen.setFont(ArialMT_Plain_16);
      screen.setTextAlignment(TEXT_ALIGN_CENTER);
      
      lineString = "Recieved INVALID";
      screen.drawString(0, 0,lineString);
      Serial.println(lineString);
    }
      
  //self data
    if(sGpsData.valid == true){
      lineString = "S long " + String(long(sGpsData.longitude)) + " d " + String(sGpsData.gps_day) + "/" + String(sGpsData.gps_month) + "/" + String(sGpsData.gps_year);
      screen.drawString(0, 32,lineString);
      Serial.println(lineString);
    
      lineString = "lat " + String(long(sGpsData.latitude)) + " alt " + String(sGpsData.altitudeM) + " t " + String(sGpsData.gps_hour) + ":" + String(sGpsData.gps_minute) + ":" + String(sGpsData.gps_second);
      screen.drawString(0, 48,lineString);
      Serial.println(lineString);     
      
    }
    else if(sGpsData.valid == false){
      screen.setFont(ArialMT_Plain_16);
      screen.setTextAlignment(TEXT_ALIGN_CENTER);
      
      lineString = "SELF INVALID";
      screen.drawString(0, 32,lineString);
      Serial.println(lineString);
    }
    screen.display();
    Serial.println("========================");
  }
}

void updateSelfInfo(){
  readGps();
   /*//DEBUG PRINTS FOR LOOP
  Serial.print("day: "); Serial.println(data.gps_day);
  Serial.print("month: ");Serial.println(data.gps_month);
  Serial.print("gps_year: "); Serial.println(data.gps_year);
  Serial.print("hour: "); Serial.println(data.gps_hour);
  Serial.print("gps_minute: "); Serial.println(data.gps_minute);
  Serial.print("gps_second: "); Serial.println(data.gps_second); 
  Serial.print("gps_centisecond: "); Serial.println(data.gps_centisecond);
  Serial.print("latitude: "); Serial.println(data.latitude);
  Serial.print("longitude: "); Serial.println(data.longitude);
  Serial.print("altitudeM: "); Serial.println(data.altitudeM);
  Serial.print("satellites: "); Serial.println(data.satellitesConnected;);
  Serial.print("signalQuality: "); Serial.println(data.signalQuality);
  Serial.print("locationAge: "); Serial.println(data.locationAge);
  Serial.print("courseDeg: "); Serial.println(data.courseDeg);
  Serial.print("speedKmph: "); Serial.println(data.speedKmph);
  Serial.println(">>>>>>>>>>>>>>>>>>....................");
  delay(1000);
  */
  
  if (Gps.date.isValid()){
    sGpsData.valid = true;
    sGpsData.gps_day = Gps.date.day();
    sGpsData.gps_month = Gps.date.month();
    sGpsData.gps_year = Gps.date.year();
  }
  else{
    sGpsData.valid = false;
    Serial.print("INVALID++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  }
 
  if (Gps.time.isValid()){ 
    sGpsData.valid = true;
    sGpsData.gps_hour = Gps.time.hour();
    sGpsData.gps_minute = Gps.time.minute();
    sGpsData.gps_second = Gps.time.second(); 
    sGpsData.gps_centisecond = Gps.time.centisecond();
  }
  else{
    sGpsData.valid = false;
    Serial.print(" INVALID++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
  }
  rGpsData.latitude = Gps.location.lat();
  rGpsData.longitude = Gps.location.lng();
  rGpsData.altitudeM = Gps.altitude.meters();
  
  /*//debug prints
  Serial.print("LAT: ");
  Serial.print(Gps.location.lat(),6);
  Serial.print(", LON: ");
  Serial.print(Gps.location.lng(),6);
  Serial.print(", ALT: ");
  Serial.print(Gps.altitude.meters());
  */
  
  rGpsData.satellitesConnected = Gps.satellites.value();
  rGpsData.signalQuality = Gps.hdop.hdop();
  rGpsData.locationAge = Gps.location.age();
  rGpsData.courseDeg = Gps.course.deg();
  rGpsData.speedKmph = Gps.speed.kmph();
  /*// debug prints
  Serial.println(); 
  Serial.print("SATS: ");
  Serial.print(Gps.satellites.value());
  Serial.print(", HDOP: ");
  Serial.print(Gps.hdop.hdop());
  Serial.print(", AGE: ");
  Serial.print(Gps.location.age());
  Serial.print(", COURSE: ");
  Serial.print(Gps.course.deg());
  Serial.print(", SPEED: ");
  Serial.println(Gps.speed.kmph());
  Serial.println();*/
}

void readGps(){
   
  if(millis() - gpsTimer > timer1000){
    while(Gps.available() > 0){

      Gps.encode(Gps.read());
    }
    gpsTimer = millis();
  }  
  
  if (millis() > 5000 && Gps.charsProcessed() < 10)
  {
    
    sGpsData.valid = false;
    Serial.println("No GPS detected: check wiring.");
    while(true);
  }
}

Which Arduino are you using?

The Uno and other 8 bit AVR Arduinos do not support double (it is treated as float), and use of Strings leads to program malfunction or crashes.

See the Serial Input Basics tutorial for parsing serial data using C-strings (zero terminated character arrays).

Say that tempMessage is 34.134408, longitude is only 34.13

Probably because you are printing only two decimal places, the default for serial.print().

That's when you print it.
Try printing with non-defaults

change

into

          Serial.print("rGpsData.latitude"); Serial.println(rGpsData.latitude, 9);// 9 decimal digits printed

same goes for longitude

Note: Due to the limitations of the 'float' data type you can print 9 decimal digits but only about 6.8 significant digits will be accurate. For example, 80% of the time the value 34.134408 will print out as 34.13440XXXX and 20% of the time it will print out as 34.1344XXXXX (where X represents a semi-random digit). Similarly, -117.707238 will come out as -117.7072XXXXX or -117.707XXXXXX.

indeed.

9 was just to show you can ask for more, regardless of the precision of the data

cool, thanks everyone!

One more question - printing to the oled screen has the same issue, it only keeps two decimals even when the actual number has 7.

rGpsData.longitude = -117.706266;
      String testerString = String(rGpsData.longitude);
      Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
      Serial.println(rGpsData.longitude, 8);
      Serial.println(testerString);

the regular longitude prints -117.70633600, but when I do string(longitude) it changes to -117.71

is there some other way to convert a double to a string so that I can print on the oled? Or maybe a char array, and then that to string? I'm very much a novice, sorry.

dtostrf()

1 Like

I tried using dtostrf, but i did something wrong.

   rGpsData.longitude = -117.706266;
      
      String longString;
      char longChar[8];
      Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
      Serial.print("longitude: ");Serial.println(rGpsData.longitude, 8);
      dtostrf(rGpsData.longitude, 6, 8, longChar);
      Serial.print("longChar: "); Serial.println(longChar);
      longString = longChar;
      Serial.print("longString: ");Serial.println(longString);
      lineString = "R long " + longString;// + "  d " + String(rGpsData.gps_day) + "/" + String(rGpsData.gps_month) + "/" + String(rGpsData.gps_year);
      Serial.print("lineString: "); Serial.println(lineString);

but it crashes the serial moniter. What am I doing wrong?

I also tried
Serial.println(testerString.toDouble() );
to see if it was getting the info, but compressing it for somereason,
but got

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-117.70626600 :regular, nothing changed
-117.71 : testerstring
-117.71 : testerstring to double

ps sorry for double posting, I'm moving everything here. I got answers from a different question and figured might as well also ask them since they were there. I'm moving everything here.

When I do

  rGpsData.longitude = -117.706266;
      
      String longString;
      char longChar[8];
      Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
      Serial.print("longitude: ");Serial.println(rGpsData.longitude, 8);
      dtostrf(rGpsData.longitude, 6, 8, longChar);
      Serial.print("longChar: "); Serial.println(longChar);
      longString = String(longChar);
      Serial.print("longString: ");Serial.println(longString);
      lineString = "R long " + longString;// + "  d " + String(rGpsData.gps_day) + "/" + String(rGpsData.gps_month) + "/" + String(rGpsData.gps_year);
      Serial.print("lineString: "); Serial.println(lineString);

Serial prints
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
longitude: -117.70626600
longChar: -117.70626600
long

and cuts off before saying longString

It's related to your use of String functions.

I thought that you can do String(chararray) to convert it.

 Serial.begin(9600);
   Serial.println();
   char buf[10] = "Hello!";

   Serial.print("Char array: ");
   Serial.println(buf);
   String s = String(buf);
   Serial.print("String: ");
   Serial.println(s);

I do pretty much the same thing, i have a char array longChar[8], fill it with dtostrf which is working, then assign it to
longString as longString = String(longChar)

can you point to what am I doing wrong? I'm sorry, I'm very new and don't see it.

What's that for?

so that I can add it onto my variable linestring. I was writing it out step by step.

I use linestring to write everything to the oled, and everything else works except for lat and long. I want to keep their decimal precision even if I have to cut other things from the display, just so i can walk around and make sure the gps works.

lineString = "S long " + String(double(sGpsData.longitude));// + " d " + String(sGpsData.gps_day) + "/" + String(sGpsData.gps_month) + "/" + String(sGpsData.gps_year);
      screen.drawString(0, 32,lineString);
      Serial.println(lineString);
    
      lineString = "lat " + String(double(sGpsData.latitude));// + " alt " + String(sGpsData.altitudeM) + " t " + String(sGpsData.gps_hour) + ":" + String(sGpsData.gps_minute) + ":" + String(sGpsData.gps_second);
      screen.drawString(0, 48,lineString);
      Serial.println(lineString);     

If you have the text representation of the latitude and longitude and only want to display that and not perform any math, then no need to convert those into numbers - just display the string…

they already are numbers, ie -117.706266.
I want to convert the number into a string so that I can display, but when I do its cutting off

rGpsData.longitude = -117.706266; //has a lot of decimals
      
      String longString;
      char longChar[8];
      Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 
      Serial.print("longitude: ");Serial.println(rGpsData.longitude, 8); //prints the raw, its correct
      dtostrf(rGpsData.longitude, 6, 8, longChar); //convert the number to a char array
      Serial.print("longChar: "); Serial.println(longChar);
      longString = String(longChar); //convert the char array to string
      Serial.print("longString: ");Serial.println(longString); //has an error printing and chashes the serial moniter
      lineString = "R long " + longString;// + "  d " + String(rGpsData.gps_day) + "/" + String(rGpsData.gps_month) + "/" + String(rGpsData.gps_year);
      Serial.print("lineString: "); Serial.println(lineString);

Serial prints
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!TESTER!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
longitude: -117.70626600
longChar: -117.70626600
long

We're going in circles.

Ok so if it’s a number just call print on that number and pass a second parameter which is the number of decimal digits you want.

its not about printing to serial, I need to print to an oled display, and ill have other things printing after it, so as the number changes in length the string needs to change to compensate so it looks good on the screen. I'm adding together each of the values I need into the string, so first "lat" then latitude, then "long", longitude, time, etc. When I display it by just adding String(latitude), only two digits appear, but I want to preserve all 6 or 7 on the display.

thank you for helping me through this :slight_smile: