Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

PIC 18 e GPS!

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] PIC 18 e GPS!

Messaggioda Foto Utentericello9 » 21 mag 2012, 15:24

Ciao a tutti, oggi sono alle prese con un modulo gps.
Il mio intento è quello di collegare, tramite usart, un modulo gps con il mio PIC 18.
Fin qui tutto è filato liscio.
Ho creato un arrary di nome Buffer che mi raccoglie le stringhe inviate dal modulo gps, di seguito vi posto un esempio di stringa di comunicazione:
Codice: Seleziona tutto
GPGSA,A,3,05,29,25,30,16,31,,,,,,,1.51,1.20,0.91*03
$GPRMC,201023.000,A,6548.4901,N,00335.8774,E,0.44,186.45,160512,,,A*61
$GPVTG,186.45,T,,M,0.44,N,0.81,K,A*3A
$PGTOP,11,2*6E
$GPGGA,201024.000,6548.4906,N,00335.8775,E,1,6,1.20,538.0,M,48.0,M,,*5A


I dati che vorreri estrapolare sono la latitudione e longitudine; cioè 6548.4901,N,00335.8774,E.
A questo punto dovrei creare una funzione che mi ritorni come risultato questi due valori.
Non conosco molto bene il c e sopratutto con i puntatori mi perdo.
La mia idea è di scorrere il buffer fino a trovare i caratteri "GPRMC", da li contare tre caratteri "," e poi analizzare i dati seguenti che corrispondono alla latitudine e longitudine.
Non so se il mio approccio è corretto ma non conosco alternativa.
Qualcuno sa aiutarmi.
Grazie.
Avatar utente
Foto Utentericello9
195 1 3 7
Stabilizzato
Stabilizzato
 
Messaggi: 360
Iscritto il: 16 mar 2009, 0:13

1
voti

[2] Re: PIC 18 e GPS!

Messaggioda Foto UtenteAjKDAP » 21 mag 2012, 19:35

Anch'io ho in previsione di utilizzare un modulo GPS seriale visto che è lì fermo nella scrivania...

Devo ancora documentarmi, ma se mi confermi che la sequenza :
Codice: Seleziona tutto
GPRMC,201023.000,A,6548.4901,N,00335.8774,E,0.44,186.45,160512,,,A*61

contiene sempre gli stessi argomenti, allora si puoi adottare la soluzione che hai descritto.

Molti non conoscono o fanno fatica a mandar giù la storia dei puntatori, ma basta studiarseli un po' per capire di averli già usati ogni volta che si è lavorato con un array qualsiasi.

Un esempio per fare un pattern matching può essere questo:

Codice: Seleziona tutto
bufferGPS[128]={};
stringaGPS[5]="GPRMC";
dimensioneBufferGPS=128;
dimensioneStringa=5;

indice=0;
trovato=false;
j=0;

for(i=0; i<(dimensioneBufferGPS-dimensioneStringa) && !trovato; i++)
{
   if(bufferGPS[i]==stringaGPS[j])
   {
      j++;
      if(j==dimensioneStringa)
      {
         trovato=true;
         indice=i;
      }
   }else{
      if(j>0)
      {
         i=i-j;
         j=0;
      }      
   }
   
}


l'ho scritto ora velocemente, quindi spero che non ci siano errori, ma prova a debuggartelo :mrgreen: a mente o meglio con carta e penna e prova a capire le operazioni che esegue.
Alla fine del ciclo, la variabile INDICE deve contenere l'indice del bufferGPS che contiene l'ultima lettera della stringa da cercare, in questo caso la lettera C di "GPRMC".
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.255 2 6 9
Expert EY
Expert EY
 
Messaggi: 796
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

0
voti

[3] Re: PIC 18 e GPS!

Messaggioda Foto Utentericello9 » 21 mag 2012, 23:01

L'ho analizzata e dovrebbe funzionare, domani lo testo sul mio PIC.
L'unico problema è che per ogni ricerca che devo fare devo riscrivere tutto il codice creando più disordine e utilizzando più memoria programma.
L'ideale sarebbe avere una funzione che mis volga questo compito.
Sai darmi una mano?
Grazie.
Marcello.
Avatar utente
Foto Utentericello9
195 1 3 7
Stabilizzato
Stabilizzato
 
Messaggi: 360
Iscritto il: 16 mar 2009, 0:13

1
voti

[4] Re: PIC 18 e GPS!

Messaggioda Foto UtenteAjKDAP » 21 mag 2012, 23:29

certo, puoi inserire il codice in una funzione da richiamare quante volte vuoi, bisogna prima decidere cosa deve fare la funzione, tipo:

-che tipo ha il buffer gps in ricezione? quanti elementi ha?

-vuoi che la funzioni ricavi le due coordinate, in che modo deve restituirle? due stringhe di char separate?

-ora le coordinate sono sempre NORD-EST, ma vuoi gestire anche gli altri quadranti del globo? :)

intanto fissiamo questi punti :) poi andiamo oltre :mrgreen:
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.255 2 6 9
Expert EY
Expert EY
 
Messaggi: 796
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

1
voti

[5] Re: PIC 18 e GPS!

Messaggioda Foto Utentenextime » 21 mag 2012, 23:58

la butto li, l'ho scritta di getto e non l'ho testata, quindi e' da provare, ma magari una funzioncina come questa
potrebbe fare al tuo caso:

Codice: Seleziona tutto
char * strnmatch(const char *searchString, size_t count, char *smatch, size_t matchcount);

char * strnmatch(const char *searchString, size_t count, char *smatch, size_t matchcount)
{
   char c;
   char pos=0;

   while(count--)
   {
      if(matchcount-pos)
      {
           c  = *searchString++;
           if(!c)
              return NULL;
           else if(c==*(smatch))
           {
              smatch++;
              pos++;
           } 
           else if(c==*(smatch-pos))
           {
              smatch=smatch-pos+1;
              pos=1;

           }
           else
           {
              smatch-=pos;
              pos=0;
           }
        }
        else
        {
           return (char*)searchString-pos;
        }
   }
   return NULL;
}     


A questa puoi passare come argomenti il tuo buffer, la dimensione del buffer, la stringa da cercare in quel buffer, la dimensione della stringa da cercare, e lui ti risponde dandoti NULL se non la trova oppure un puntatore all'inizio della stringa che hai cercato.
Franco (nextime) Lanza
Direttore ricerca & sviluppo, main developer e Geek
presso Unixmedia S.r.l. - Sistemi domotici innovativi su rete Ethernet
Sito aziendale: http://www.unixmedia.it
Prodotti, shop, area-tecnca: http://domotika.unixmedia.net
Avatar utente
Foto Utentenextime
463 2 7
Expert
Expert
 
Messaggi: 115
Iscritto il: 27 apr 2012, 22:17
Località: Lonate Pozzolo

0
voti

[6] Re: PIC 18 e GPS!

Messaggioda Foto Utentericello9 » 22 mag 2012, 7:35

AJKDAP ha scritto:-che tipo ha il buffer gps in ricezione? quanti elementi ha?

-vuoi che la funzioni ricavi le due coordinate, in che modo deve restituirle? due stringhe di char separate?

-ora le coordinate sono sempre NORD-EST, ma vuoi gestire anche gli altri quadranti del globo? :)



La dimensione del buffer deve riuscire a contenere la stringa che mi serve per poi analizzarla, gli altri dati sono superflui;
Codice: Seleziona tutto
$GPRMC,201023.000,A,6548.4901,N,00335.8774,E,0.44,186.45,160512,,,A*61


La funzione dovrebbe ritornare come valori le due coordinate,possibilmente con due stringhe separata così da poterle gestire meglio.
In questo caso le coordinate sono nord-est ma potrebbero cambiare.
Grazie per l'aiuto.
Avatar utente
Foto Utentericello9
195 1 3 7
Stabilizzato
Stabilizzato
 
Messaggi: 360
Iscritto il: 16 mar 2009, 0:13

1
voti

[7] Re: PIC 18 e GPS!

Messaggioda Foto UtenteAjKDAP » 22 mag 2012, 9:36

Okey per le coordinate separate in due stringhe diverse, magari della forma: "6548.4901N" e "00335.8774E"

Però per quanto riguarda il buffer in ingresso la mia domanda era un'altra più specifica, come acquisisci la stringa NMEA? La ricezione UART del tuo PIC dove salva la stringa? Salva semplicemente un tot di bytes? oppure è più intelligente e salva ogni stringa NMEA intera?
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.255 2 6 9
Expert EY
Expert EY
 
Messaggi: 796
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

0
voti

[8] Re: PIC 18 e GPS!

Messaggioda Foto Utentericello9 » 22 mag 2012, 13:45

Ciao, per ora il buffer lo memorizzo tutto senza distinzione di stringa NMEA:
Ma volevo provare questo codice se può funzionare, in pratica inizio a memorizzare nel buffer solo quando trovo i caratteri GPRMC e fino al carattere $.
Codice: Seleziona tutto
// Controllo che l'interrupt sia stato generato dall'USART 1
if (PIR1bits.RC1IF == 1 )
  {
   buffer[i] = Read1USART();
  If(buffer[i]=='G' && buffer[i+1] =='P' && buffer[i+2]=='GR && buffer[i+3]=='M' && buffer[i+4]=='C' )
     {
     for (i=0; i !'$'; i++)
      buffer[i] = Read1USART();
    }
  }


Come potrai notare la mia conoscenza del c è molto grossolana quindi ogni tuo suggerimento è prezioso.
Grazie.
Marcello.
Avatar utente
Foto Utentericello9
195 1 3 7
Stabilizzato
Stabilizzato
 
Messaggi: 360
Iscritto il: 16 mar 2009, 0:13

1
voti

[9] Re: PIC 18 e GPS!

Messaggioda Foto UtenteAjKDAP » 22 mag 2012, 18:54

ricello9 ha scritto:Come potrai notare la mia conoscenza del c è molto grossolana quindi ogni tuo suggerimento è prezioso


infatti, io ti consiglierei di iniziare leggendo un tot di bytes direttamente dalla seriale e poi in un secondo momento lavorare sul buffer per estrapolare i dati.

Successivamente potrai provare a salvare nel buffer solamente i dati che ti interessano maggiormente, ma ripeto, io tralascerei questa fase per ora...

QUalche suggerimento riguardante il tuo codice:

La funzione Read1USART(); ho letto sull'help di mikroc che legge un singolo byte dalla seriale, quindi NON puoi leggere un singolo byte e poi controllare molti bytes:

Codice: Seleziona tutto
If(buffer[i]=='G' && buffer[i+1] =='P' && buffer[i+2]=='GR && buffer[i+3]=='M' && buffer[i+4]=='C' )


Inoltre questo ciclo for non ha senso:
Codice: Seleziona tutto
for (i=0; i !'$'; i++)
      buffer[i] = Read1USART();


tralasciando il fatto che la negazione dell'uguale si indica con "!=" e non solamente con "!", la cosa più sbagliata è che l'indice i si incrementa da zero fino a 36 visto che il carattere dollaro equivale al numero 36. Quindi leggeresti sempre 36 bytes dalla seriale.
L'idea di leggere fino al carattere $ è corretta, ma il metodo è sbagliato.


Io proverei a leggere di continuo un numero fisso di bytes fino a riempire un buffer, ad esempio semplicemente cosi:
Codice: Seleziona tutto
for (i=0; i<128; i++){
      while(!UART1_Data_Ready() );
      buffer[i] = Read1USART();
}

ed in un secondo momento analizzare il buffer per controllare se è presente la stringa NMEA che ti interessa.

Inoltre non conosco come funziona l'interrupt per l'UART nel tuo PIC18, se l'interruzione viene generata alla ricezione di ogni singolo byte, nella routine di interrupt dovrai solamente salvare un singolo byte nel buffer ed incrementare un indice per la volta successiva.

Altrimenti puoi semplicemente fare a meno dell'interrupt ed aspettare che il byte sia pronto per essere letto, come è specificato nell'help di mikroc:
Codice: Seleziona tutto
if (UART1_Data_Ready() == 1) {
receive = UART1_Read();
}


PS.: dal primo post mi sembrava di aver capito che la ricezione era una cosa assodata, invece ora non so se è tutto ok oppure no, mi confermi che riesci a ricevere i bytes dal GPS e salvarli in un buffer?

Se non è cosi allora concentrati prima su questa fase.

ciao
'˙˙˙·٠•● Alberto ●•٠·˙˙˙'
________________________
http://www.ajk.altervista.org
Avatar utente
Foto UtenteAjKDAP
1.255 2 6 9
Expert EY
Expert EY
 
Messaggi: 796
Iscritto il: 17 mag 2006, 0:13
Località: nella coda dei pronti

0
voti

[10] Re: PIC 18 e GPS!

Messaggioda Foto Utentericello9 » 22 mag 2012, 21:29

Ho fatto un po' di confusione!
il codice originale che ho usato per leggere le stringhe del gps è:
Codice: Seleziona tutto
unsigned char buffer[200];
unsigned char i=0;
// Controllo che l'interrupt sia stato generato dall'USART 1
if (PIR1bits.RC1IF == 1 ) {
   LED_GIALLO = LED_GIALLO^1;
   buffer[i] = Read1USART();
   i++;
   }

Dove gestisco la ricezione di un singolo byte tramite l'interrupt della porta usart1, poi alla pressione di un tasto stampo a video il contenuto dell'array buffer tramite l'usart2.
Come compilatore sto usando mplab della microchip.
Fin qui ci sono.
Adesso come posso procedere?
Grazie per la pazienza.
Avatar utente
Foto Utentericello9
195 1 3 7
Stabilizzato
Stabilizzato
 
Messaggi: 360
Iscritto il: 16 mar 2009, 0:13

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti