Char* to float with 6 decimal cases

Hello,

I have a char* named var1 with that value=-39.254563

so I use that double var2=strtod(var1,NULL); but the result is -39.25 only with 2 decimal cases. I want that result: -39.254563 with 6 decimal cases,

How can I make it?

Thank you

Roberto

it should have more decimal places (about 4).
I think there is a bug in your code, please post it so we can help you fix it.

Serial.println (var2, 6);

And now?

serial.print for float defaults to two decimal places. There is a optional parameter it takes to specify more than that.

thanks, is a big code.

that line is the source char*: Lparaconverter=latitude; // here the value is -29.252525

and that line is the conversion error: double Lconvertida=strtod(Lparaconverter,NULL);// after conversion the value is -29.25

char aux_str[30];
char aux;
//char aa;
char* Lparaconverter;
char* Longparaconverter;
double latitudeanterior;
double longitudeanterior;
double valoradicao;
double valorsubtracao;
double somalat;
double somalong;

char latitude[15];
char longitude[15];
int t=0;
int k=0;
int l=0;
char inChar;
int index;
char inData[200];
int i;

void setup()
{
l=1;//rastreador foi ligado
latitudeanterior=0.000000;
longitudeanterior=0.000000;
valoradicao=0.000100;
valorsubtracao=-0.000100;
//Init the driver pins for GSM function
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
//Output GSM Timing
digitalWrite(5,HIGH);
delay(1500);
digitalWrite(5,LOW);

Serial.begin(9600);
// Use these commands instead of the hardware switch ‘UART select’ in order to enable each mode
// If you want to use both GMS and GPS. enable the required one in your code and disable the other one for each access.
digitalWrite(3,LOW);//enable GSM TX?RX
digitalWrite(4,HIGH);//disable GPS TX?RX

delay(20000);

// start_GSM();

delay(5000);

start_GPS();

}
void loop()
{

read_GPS();
delay(2000);
double posicaovazia=0.000000;
//////////////////////////////////////
double Lconvertida=strtod(Lparaconverter,NULL);//converte a latitude em double
double Longconvertida=strtod(Longparaconverter,NULL);//converte a latitude em double
//float ftemp = atof(aaa);

//double valor=0.000000;
//String str;
//str=String(valor);
///////////////////////;/////////////////

if (Lconvertida == posicaovazia) //conta as vezes em que está sem sinal de gps
{
t=t++;
}
if (latitudeanterior == Lconvertida)//tempo parado
{
k=k++;
}

if (Lconvertida != posicaovazia)//só envia sms se tiver coordenadas
{

if (latitudeanterior == posicaovazia)// adiciona valor as coordenadas anteriores
{
latitudeanterior=Lconvertida;
longitudeanterior=Longconvertida;
send_GPRS();
delay(30000);
}
else
{

somalat=latitudeanterior - Lconvertida;
// double sublat = latitudeanterior - Lconvertida;
somalong = longitudeanterior - Longconvertida;
// double sublong = longitudeanterior - Longconvertida;

if (somalat < valorsubtracao || somalat > valoradicao)// se diferença da latitude for mair que 10m
{
send_GPRS();
delay(30000);
}
else if (somalong < valorsubtracao || somalong > valoradicao)
{
send_GPRS();
delay(30000);
}
}
}

}

void send_GPRS(){

Serial.println(“AT”); //Send AT command
delay(2000);
Serial.println(“AT”);
delay(2000);
//Send message’
Serial.println(“AT+CMGF=1”);
delay(1000);
Serial.println("AT+CMGS=“7588746080"”);//Change the receiver phone number
delay(1000);
Serial.print(Lparaconverter);
Serial.print(’,’);
Serial.print(longitude);
Serial.print(’,’);
Serial.print(‘2’);//tempo sem sinal gps
Serial.print(’,’);
Serial.print(t);//tempo veiculo parado
Serial.print(’,’);
Serial.print(k);//1 rastreador foi ligado
Serial.print(’,’);
Serial.print(l);//1 rastreador foi ligado

Serial.println("");

// Serial.print(latitude);//the message you want to send
delay(1000);
Serial.write(26);
t=0;
k=0;
l=0;
}

void start_GPS(){
//Configuracion en Inicializacion GPS
Serial.print(“AT”);
delay(1000);
Serial.println(“AT+CGPSIPR=9600”);// (set the baud rate)
delay(1000);
Serial.println(“AT+CGPSPWR=1”); // (turn on GPS power supply)
delay(1000);
Serial.println(“AT+CGPSRST=1”); //(reset GPS in autonomy mode)
delay(10000); //delay para esperar se?al del GPS
}

void read_GPS(){

Serial.println(“AT+CGPSINF=0”);

read_String();

strtok(inData, “,”);
strcpy(longitude,strtok(NULL, “,”)); // Gets longitude
strcpy(latitude,strtok(NULL, “,”)); // Gets latitude

latitude [14] = ‘\0’;
longitude[14] = ‘\0’;

convert2Degrees(latitude);
convert2Degrees(longitude);
Lparaconverter=latitude; //pega valor para converter em double
Longparaconverter=longitude;

// Lanterior=latitude;
}

void read_String() {
index=0;

while(Serial.available() > 0) // Don’t read unless
// there you know there is data
{
if(index < 199) // One less than the size of the array
{
inChar = Serial.read(); // Read a character
inData[index] = inChar; // Store it
index++; // Increment where to write next

}
}
inData[199] = ‘\0’; // Null terminate the string
}

int8_t convert2Degrees(char* input){

float deg;
float minutes;
boolean neg = false;

//auxiliar variable
char aux[10];

if (input[0] == ‘-’)
{
neg = true;
strcpy(aux, strtok(input+1, “.”));

}
else
{
strcpy(aux, strtok(input, “.”));
}

// convert string to integer and add it to final float variable
deg = atof(aux);

strcpy(aux, strtok(NULL, ‘\0’));
minutes=atof(aux);
minutes/=1000000;
if (deg < 100)
{
minutes += deg;
deg = 0;
}
else
{
minutes += int(deg) % 100;
deg = int(deg) / 100;
}

// add minutes to degrees
deg=deg+minutes/60;

if (neg == true)
{
deg*=-1.0;
}

neg = false;

if( deg < 0 ){
neg = true;
deg*=-1;
}

float numeroFloat=deg;
int parteEntera[10];
int cifra;
long numero=(long)numeroFloat;
int size=0;

while(1){
size=size+1;
cifra=numero%10;
numero=numero/10;
parteEntera[size-1]=cifra;
if (numero==0){
break;
}
}

int indice=0;
if( neg ){
indice++;
input[0]=’-’;
}
for (int i=size-1; i >= 0; i–)
{
input[indice]=parteEntera*+‘0’;*

  • indice++;*
  • }*
  • input[indice]=’.’;*
  • indice++;*
  • numeroFloat=(numeroFloat-(int)numeroFloat);*
  • for (int i=1; i<=6 ; i++)*
  • {*
    _ numeroFloat=numeroFloat*10;_
  • cifra= (long)numeroFloat; *
  • numeroFloat=numeroFloat-cifra;*
  • input[indice]=char(cifra)+48;*
  • indice++;*
  • }*
  • input[indice]=’\0’;*
    }

please use code tags to prevent code interpreted as forum tags [ i] -> italic

some demo of decimal places shows the number cannot be represented exactly.

void setup() 
{
  Serial.begin(115200);

  float f = -29.252525;
  
  for (int decimals=0; decimals <= 12; decimals++)
  {
    Serial.println(f, decimals);
  }
}

void loop() 
{
}

Hello,

I tried
double Lconvertida=strtod(Lparaconverter,NULL);//converte a latitude em double
Serial.println (Lconv, 6);
but receive only 2 decimal.

the problem is here double Lconvertida=strtod(Lparaconverter,NULL) that conversion bring only 2 decimal I don't know why

note that double is same as float on the Arduino UNO and MEGA (AVR based ones)

float == 32 bit IEEE754 , which has a 24 bit mantisse implying max of 7 significant digits.
Therefor the UNO cannot hold longitude/lattitude to the last digit.

this minimal code shows your problem:

void setup() 
{
  Serial.begin(115200);
  Serial.println("Start ");

  float f = strtod("-39.252525", NULL); 
  Serial.println(f, 6);
}

void loop() {}

output: -39.252521

you might solve it (partly) by using long which has 9 significant digits (multiply by 1000000)
or
by splitting the integer and fractional part in two floats.

if your goal is just to print the value, why not print the string version?

So I need the number with decimals but I don't know how to get it from my code.

So I need the number with decimals but I don't know how to get it from my code.

What number? Get it from where?

double Lconvertida=strtod(Lparaconverter,NULL);//converte a latitude em double
Serial.println (Lconv, 6);

Create a variable and assign it the value returned by strtod(). Then, print something else, and complain that what is printed is not what you want. How useless.

that line convert2Degrees(latitude);, is a result of a char*. I want that value on a variable, float or double, or int, because I want compare wth other value. the value sample is: -12.584745,

Serial.println("AT+CGPSINF=0");

read_String();

strtok(inData, ",");
strcpy(longitude,strtok(NULL, ",")); // Gets longitude
strcpy(latitude,strtok(NULL, ",")); // Gets latitude

latitude [14] = '\0';
longitude[14] = '\0';

convert2Degrees(latitude);

Double is the same as float on an Arduino, and each number can represent at most about 6-7 decimal digits. This number format does not have the accuracy to store latitude and longitude to the precision you want.

that line convert2Degrees(latitude);, is a result of a char*.

What are you talking about? convert2Degrees() might RETURN a char *, but the function is not the result of a char *.

Actually, no it doesn't. It returns a byte. WTF?

On further examination, the function is crap, since it doesn't return anything.