GPS tracker o altro uso?????

Sto sperimentando l’uso del GPS… ed ho scritto lo sketch di seguito allegato… ancora in fase di studio e sperimentazione:

con riferimento a questa parte dello script:

 void leggiNMEA()
  {
   boolean fine = false;
   int indiceNMEA =0 ;
     do
      {  stringaNMEA[indiceNMEA]=gpsSerial.read();
         if (stringaNMEA[indiceNMEA]=='\n'){fine=true;}
         if (stringaNMEA[indiceNMEA]!=-1){indiceNMEA++;}
      }  while(!fine);
       
    int sum;
    sum = parseHex(stringaNMEA[indiceNMEA-4]) * 16;                   // verifica il checksum
    sum += parseHex(stringaNMEA[indiceNMEA-3]);                       
    for (int k=1; k < (indiceNMEA-5); k++) {sum ^= stringaNMEA[k];}   
    if (sum != 0)                                           
        {Serial.print("\n Checksum Errato ============== "); digitalWrite(led1, LOW);} 
    else                                                      // cheksum OK ... 
        {Serial.print("\n Checksum Esatto -------------- "); digitalWrite(led1, HIGH);

si verifica che se invio dati alla seriale del PC spesso il checksum è errato, se alzo il baud rate della connessione seriale con il PC l’errore non si verifica più…
quindi la prima domanda è questa: E’ possibile che l’invio dei dati alla seriale, così come l’elaborazione di qualche altro calcolo mi determina un ritardo nel prelievo dei dati dal buffer della seriale GPS-Arduino ??? … così che mi trovo una mezza stringa NMEA con con attacata una seconda stringa …chiaramente il checksum è errato…
ripeto… se alzo il baud rate il problema scompare, oppure scompare anche se elimino l’invio dei dati alla seriale …

con riferimento a questa parte dello skect:

      String chkStr;

        chkStr ="";  for(int i=1; i<6; i++){chkStr += stringaNMEA[i];}

        if      (chkStr == "GPGGA")    //GPGGA #1 UTC ora #2 latitudine #3 N/S #4 longitudine #5 E/W #6 Fix #7 n° sat. #9 Quota s.l.m. #10 UM quota
          {      
               }

utilizzo questo sistema per individuare il tipo di stringa NMEA e volevo chiedervi:
esiste un metodo più pratico, veloce ed efficiente per individuare che tipo di stringa si tratta?? … io indiduo il tipo come sopra, poi controllo i primi 6 caratteri e a seconda si tratti di GPGGA, o GPGLL, o GPGSV etc… provvedo ad una scansione della stringa, attarverso l’individuazione della virgola, conto i campi e li metto in variabili stringa gia definite in precedenza … come di seguito:

    if      (chkStr == "GPGGA")    //GPGGA #1 UTC ora #2 latitudine #3 N/S #4 longitudine #5 E/W #6 Fix #7 n° sat. #9 Quota s.l.m. #10 UM quota
          {     //Serial.print ("\n\t1 GPGGA");
                datiNMEA[1]=""; datiNMEA[3]=""; datiNMEA[4]=""; datiNMEA[5]=""; datiNMEA[6]=""; datiNMEA[10]=""; datiNMEA[14]=""; datiNMEA[7]=""; datiNMEA[8]=""; 
                int k =0; int jj=0;
                while(k < dimVettore && stringaNMEA[k]!='\n')
                {if (stringaNMEA[k] == ',' ){jj++; }
                 else {
                       if      (jj == 1) {datiNMEA[1]+= stringaNMEA[k];}    // UTC Ora          
                       else if (jj == 2) {datiNMEA[3]+= stringaNMEA[k];}    // latitudine
                       else if (jj == 3) {datiNMEA[4]+= stringaNMEA[k];}    // N/S
                       else if (jj == 4) {datiNMEA[5]+= stringaNMEA[k];}    // longitudine
                       else if (jj == 5) {datiNMEA[6]+= stringaNMEA[k];}    // E/W
                       else if (jj == 6) {datiNMEA[10]+= stringaNMEA[k];}   // fix
                       else if (jj == 7) {datiNMEA[14]+= stringaNMEA[k];}   // n Sat.
                       else if (jj == 9) {datiNMEA[7]+= stringaNMEA[k];}    // Quota
                       else if (jj == 10){datiNMEA[8]+= stringaNMEA[k];}    // UM
                      };
                k++;}               
               }

          else if (chkStr == "GPGLL")   //GPGLL #1 latitudine #2 N/S #3 longitudine #4 E/W #5 UTC ora #6 Status
         {      //Serial.print ("\n\t2 GPGLL");
                datiNMEA[3] =""; datiNMEA[4] =""; datiNMEA[5] =""; datiNMEA[6] =""; datiNMEA[1] =""; datiNMEA[9] =""; 
                int k =0; int jj=0;
                while(k < dimVettore && stringaNMEA[k]!='\n')
                {if (stringaNMEA[k] == ',' ){jj++;}
                 else {
                       if      (jj == 1) {datiNMEA[3]+= stringaNMEA[k];}    // latitudine             
                       else if (jj == 2) {datiNMEA[4]+= stringaNMEA[k];}    // N/S
                       else if (jj == 3) {datiNMEA[5]+= stringaNMEA[k];}    // longitudine
                       else if (jj == 4) {datiNMEA[6]+= stringaNMEA[k];}    // E/W
                       else if (jj == 5) {datiNMEA[1]+= stringaNMEA[k];}    // UTC Ora          
                       else if (jj == 6) {datiNMEA[9]+= stringaNMEA[k];}    // Status   
                      };
                k++;}
               }

etc…

il sistema funziona, nel senso che riesco a discriminare le stringhe ed ad estrarne la variabile che voglio ed a memorizzarla in

String datiNMEA [16]; // campi contenenti le informazioni di interesse estratte
// #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 #14 #15
// #ora #data #lat. #n/s #long. #e/o #quota #UM #Status #fix #velocita #UM #direzione #n Sat #PDOP
solo che ad un certo punto impazzisce, comincia a trovare stringhe lunghissime, sensza senso e si blocca …
se lo faccio per singoli blocchi funziona bene … se scansiono tutte le stringhe per prelevarne tutte le variabili si blocca …
mi da l’impressione di un problema di RAM e mi chiedevo: la causa puo essere un problema di FULL MEMORY di cui hanno peralto Menniti ed altro in un lunghissimo post di quelche settimana fa??? … cioè devo forse aggiornare l’IDE perchè ci sono troppe variabili e si superano i 64kWord, ovvero 128kB di memoria … spero di non aver fatto troppe domande… ciao

GPS_A_05_05_12_pde.pde (7.95 KB)

se usi l'ide 1.0, allora la seriale è asincrona, oltre al buffer di ricezione ha un buffer di invio. Ora, se riempi il buffer di invio più in fretta di quanto il baud-rate riesca a svuotarlo, il buffer(che credo sia circolare, come quello di ricezione) sovrascrive i dati più vecchi. Ci sono 2 soluzioni: 1- alzi il baud-rate, ma sai che non sarai mai sicuro di non perdere dati; 2- usi una Serial.flush(), che in pratica è una delay() che ti blocca finchè il buffer di invio non è vuoto (la vecchia libreria Serial, non avendo un buffer, è come se chiamasse questa flush() ad ogni write e println(), e la sua flush() serviva per svuortare il buffer di ricezione)

attenzione: il buffer in uscita è di 64byte, NON so come si comporta se invii in un colpo solo una stringa più lunga. probabili comportamenti (in ordine di probabilità decrescente): 1- non se ne frega, e si comporta normalmente quindi mantiene solo gli ultimi 64 byte 2- se ne frega, e rimane bloccata ad inviare dati fichè non raggiunge <= 64 byte (o 0byte) e poi ti lascia continuare quello che stai facendo

grazie lesto.
non ho compreso bene (sono un principiante) ma leggerò qualcosa a proposto.

… In effetti anche se si verifica qualche errore non è un grosso problema, perchè una volta disriminato elimino quei dati… è soltanto che volevo capire …

per le altre questioni che ho scritto hai qualche suggerimento???

dunque, per risolvere il problema, in pratica metti delle serial.flush() subito dopo le print, ma solo se sei sui ide 1.0

per individuare stringhe NMEA, non vedo metodo più semplice e/o veloce.

per la ricezione secondo me hai lo stesso problema dell'invio: al massimo puoi tenere "in attesa" nella libreria Serial 64byte di dati (64 caratteri per capirsi, compresi di spazi, "a capo", virgole, etc...)