Convertire e unire stringhe...

Buonasera a tutti,

Ho un modulo Sim908 GPS e GSM. devo ad intervalli regolari di 1 minuto ricavare le coordinate GPS convertirle da NMEA a Gradi e decimali e poi Inviarle con il modulo GSM ad un numero di cellulare.

il mio problema sta nel fatto che dopo la conversione delle coordinate ho la latitudine e la longitudine in formato DOUBLE ed avrei la necessita di convertirle in char* in modo da poterle inviare tramite sms

la funzione che richiamo per gli l' invio degli sms è questa

char SendSMS(char *number_str, char *message_str);

a queste coordinate dovrei unire un link di google maps in modo che quando ricevo l' sms sullo smartphone facendo un semplice tap mi apre Maps e mi mette un marcatore nelle coordinate ricevute

in poche parole vorrei ricevere un sms cosi :
http://maps.google.com/maps?f=q&q=(LATITUDINE,LONGITUDINE)&z=15

ma non so come convertire un double in char* e nemmeno come poter inserire le 2 variabili all' interno di un altra variabile..
Grazie 1000 a tutti per una risposta!!!

Da float a stringa (vettore char) usi dtostrf(FLOAT,WIDTH, PRECISION,BUFFER);

char buf[10]; 
float n=23.456;
dtostrf(n, 2, 2, buf);
Serial.println(buf);

Per mettere insieme 2 variabili stringa puoi usare strncat()
oppure snprintf()

char buf1[10];
char buf2[10];
char buf3[20];
...
snprintf (buf3,20, "1=%s 2=%s",buf1,buf2);

E' come se stampassi dentro a stringa (vedi printf e i vari tipi di % che puoi usare, escluso %f)

ok grazie sono riuscito in parte a fare quello che volevo ma c'è una cosa che proprio non capisco non su quello che mi hai postato ma sul comportamento di arduino

se io scrivo

Serial.print (convertiLat(lat),10);

dove convertiLat è una funzione fatta da me per la conversione e mi restituisce un double ho una stringa con 10 numeri decimali corretti ad esempio 43.1234567890

ma se io vado ad eseguire questo codice

double Latitudine  = (convertiLat(lat),10);
Serial.print (Latitudine);

mi restituisce 10.00 rendendomi inutilizzabile la giunzione delle stringhe

in parole povere uso questo codice

        double Latitudine  = (convertiLat(lat),10);
        double Longitudine = (convertiLong(lon),10);
  
        lcd1.clear();                           //stampo in un lcd 16x2 le coordinate che risultano giuste
        lcd1.print (convertiLat(lat),10);
        lcd1.setCursor(0,-1);
        lcd1.print (convertiLong(lon),10);
        
        
        char buf3[70];
        char bufLat[13];
        char bufLon[13];

        dtostrf(Latitudine, 2, 10, bufLat);
        dtostrf(Longitudine, 2, 10, bufLon);
        snprintf (buf3,70, "http://maps.google.com/maps?f=q&q=(%s,%s)&z=15",bufLat,bufLon);
        
        Serial.println(buf3);

invece di ricevere una stringa con il link per maps con le coordinate giuste ricevo questo

http://maps.google.com/maps?f=q&q=(10.0000000000,10.0000000000)&z=15

Aspire92:
se io scrivo

Serial.print (convertiLat(lat),10);

dove convertiLat è una funzione fatta da me per la conversione e mi restituisce un double ho una stringa con 10 numeri decimali corretti ad esempio 43.1234567890
ma se io vado ad eseguire questo codice

double Latitudine  = (convertiLat(lat),10);

Serial.print (Latitudine);

Mi fermo al primo pezzo (scusa, ma data l'ora non ho voglia di leggere il resto :smiley: )
La seconda cosa che hai scritto NON ha senso.

La prima chiami una funzione print() della classe Serial che accetta 2 parametri, un numero float e un secondo parametro che indica quanti decimali.
La seconda cosa che scrivi viene interpretata come una sequenza, e in realtà significa solo double Latitudine = 10;
Poi stampi usando print senza secondo parametro, di default il secondo è 2, quindi stampi un float 10 con 2 decimali => 10.00

In pratica togli quel ,10:

double Latitudine  = convertiLat(lat);

ok cosi funziona in effetti non ci avevo pensato!!! :cold_sweat:

pero comunque sia non mi restituisce 10 decimali ma solamente sei e l' ultimo me lo arrotonda!!

mi da 11.9078030000 invece di 11.9078025817

Ma sei su Arduino UNO ???

Ricorda che su Arduino UNO NON esiste il double, esso è uguale al float ovvero solo 32 bit e che ...

"Floats have only 6-7 decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point. Unlike other platforms, where you can get more precision by using a double (e.g. up to 15 digits), on the Arduino, double is the same size as float."

Guglielmo

ora mi è tutto piu chiaro, scusate ma è da poco che mi sono buttato su arduino, posso aggirare questo problema usando un MEGA? ho sia uno rev 3 che mega2560

Per i decimali? No anche su Mega hai solo i float, se usi double sempre un float hai.

Potresti convertire a long prima dei calcoli e poi riportare a float alla fine, lavorando con interi non avresti i problemi degli arrotondamenti nei calcoli intermedi ma solo nell conversione iniziale e finale.

leo72:
Potresti convertire a long prima dei calcoli e poi riportare a float alla fine, lavorando con interi non avresti i problemi degli arrotondamenti nei calcoli intermedi ma solo nell conversione iniziale e finale.

Ma con unsigned long arrivi a +4.294.967.295 (4 miliardi circa) gli basteranno ?
Fa come esempio: 11.9078025817 => 12 cifre :fearful:

Aspire92:
ora mi è tutto piu chiaro, scusate ma è da poco che mi sono buttato su arduino, posso aggirare questo problema usando un MEGA?

Come ti è già stato risposto ... NO, però ...
... se a te servono veramente calcoli con una grande precisione, nulla ti vieta di montare su uno zoccoletto e collegare ad Arduino un chip FPU come QUESTO.

Ci parli in I2C (usa 2 pin ... SCL e SDA), fa calcoli a 64 bit ed è molto veloce ... certo ... non lo regalano ... $19.95 USD, ma se realmente ti serve "precisione" ... questa è la soluzione migliore :wink:

Guglielmo

si teoricamente mi serve precisione perché sto costruendo un localizatore satellitare da mettere in un pallone sonda per poi poterlo ritrovare, quindi più decimali ho più precisione ottengo nelle coordinate, pero ho fatto qualche prova e ho visto che usando 6 decimali anziché 10 ottengo sempre una buona precisione.
prima avevo lo scarto di mezzo metro adesso di 2/5metri che comunque sia sono accettabili!!!
adesso pero sono in un nuovo problema con questa riga

snprintf (buf3,57, "https://www.google.com/maps/preview?q=%s,%s",bufLat,bufLon);

non mi mette la virgola tra le 2 variabili da cosa puo essere dovuto? anche se tra le 2 variabili ci scrivo CIAO non appare ma appare una stringa come questa

https://www.google.com/maps/preview?q=12.12345612.123456
non mi mette la virgola tra 12.123456,12,123456

nid69ita:

leo72:
Potresti convertire a long prima dei calcoli e poi riportare a float alla fine, lavorando con interi non avresti i problemi degli arrotondamenti nei calcoli intermedi ma solo nell conversione iniziale e finale.

Ma con unsigned long arrivi a +4.294.967.295 (4 miliardi circa) gli basteranno ?
Fa come esempio: 11.9078025817 => 12 cifre :fearful:

Sono coordinate, avere sugli 8 decimali significa una precisione più che sufficiente

Aspire92:
adesso pero sono in un nuovo problema con questa riga

snprintf (buf3,57, "https://www.google.com/maps/preview?q=%s,%s",bufLat,bufLon);

non mi mette la virgola tra le 2 variabili da cosa puo essere dovuto? anche se tra le 2 variabili ci scrivo CIAO non appare ma appare una stringa come questa
Google Maps
non mi mette la virgola tra 12.123456,12,123456

Prova a fregarlo cosi, stampando un char di valore 44 (ovvero la virgola):

snprintf (buf3,57, "https://www.google.com/maps/preview?q=%s%c%s",bufLat,44,bufLon);

Oppure così:

snprintf (buf3,57, "https://www.google.com/maps/preview?q=%s\,%s",bufLat,bufLon);

Se vuoi visualizzare il carattere \ devi scrivere \.
La virgola forse viene interpretata come operatore?

Ciao.