ESP32 (27) – GPS

luca 13/11/2017 4

Nell’articolo di oggi vedremo come interfacciare il chip esp32 ad un ricevitore GPS per conoscere posizione attuale, velocità e molti altri dati…

Ricevitore GPS

Sul mercato esistono moltissimi ricevitori GPS… grazie alla diffusione di navigatori, cellulari e multicotteri è ora possibile acquistarne uno per pochi euro. Per questo tutorial ho utilizzato un ricevitore GPS venduto da Banggood e basato sul chip u-blox NEO-M8:

gps-010 gps-011

Praticamente tutti i ricevitori GPS offrono almeno una interfaccia seriale, possiamo quindi collegarli al chip esp32 sfruttando una delle sue periferiche UART come spiegato in un precedente articolo. A volte non è semplice identificare i vari pin e può essere necessario – come nel mio caso – aprire il case plastico che racchiude il chip per leggere la serigrafia del PCB:

gps-001 gps-002

Dalle fotografie sopra si comprende che il mio ricevitore ha la seguente piedinatura:

  • GND (massa) -> cavo nero
  • VCC (alimentazione) -> cavo rosso
  • TXD (trasmissione) -> cavo verde
  • RXD (ricezione) -> cavo giallo

Ho scelto di utilizzare la periferica UART1 del chip esp32 con i pin 4 (TX) e 16 (RX). Ho quindi effettuato i collegamenti, ricordando che il pin TX del ricevitore GPS va collegato al pin RX del chip esp32 e viceversa:

gps-003

NMEA

I ricevitori GPS inviano dati secondo lo standard NMEA 0183 (normalmente chiamato semplicemente NMEA).

Lo standard prevede l’invio di stringhe (sentences = frasi) formate da un massimo di 80 caratteri e terminate da CRLF. Ogni stringa ha il seguente formato:

$PREFIX,data1,data2 ... dataN-1,datoN*CHECKSUM

Il prefisso (5 caratteri) indica il tipo di dispositivo (per i ricevitori GPS è GP) e il tipo di frase (i successivi 3 caratteri). Ogni frase termina con un checksum (XOR) che consente di verificare la correttezza della frase ricevuta.

Lo standard NMEA definisce molte frasi diverse e i singoli produttori possono aggiungere tipi di frasi proprietarie per comunicare ulteriori dati. Un elenco esaustivo di frasi NMEA è disponibile a questo indirizzo. Vediamo un esempio di frase GGA (Global Positioning System Fix Data):

$GPGGA,183619,3877.038,N,07702.110,W,1,08,0.9,545.4,M,46.9,M,,*47

Il ricevitore sta comunicando la posizione attuale (latitudine 38°77.038′ NORD e longitudine 77°02.110′ OVEST), ottenuta alle 18:36:19 grazie a 8 satelliti. La qualità della posizione è GPS Fix (1).

Per poter ottenere i dati dal ricevitore GPS dobbiamo quindi essere in grado di “comprendere” le frasi NMEA. Ho trovato una comoda libreria, minmea, sviluppata in C e in grado di effettuare il parsing delle frasi NMEA più importanti.

Per integrare la libreria in un progetto esp-idf è sufficiente copiare i due files sorgenti (minmea.c e minmea.h) in una cartella all’interno della cartella components e creare un file component.mk come segue:

gps-001

Il flag evidenziato è necessario perché il framework non contiene la funzione timegm() e quindi, come indicato anche nel README della libreria, va indicato al compilatore di sostituire la funzione con mktime().

Programma

Nel mio repository Github trovate il programma di esempio che ho sviluppato per questo tutorial. Vediamo gli elementi principali:

Per poter utilizzare la libreria minmea, includiamo il relativo file header:

#include "minmea.h"

Leggiamo una riga dalla periferica UART1 e passiamola alla libreria per eseguire il parsing:

char *line = read_line(UART_NUM_1);
switch (minmea_sentence_id(line, false)) {
  case MINMEA_SENTENCE_RMC:
  [...]
  case MINMEA_SENTENCE_GGA:
  [...]
}

Infine verifichiamo se i parametri ricevuti sono diversi da quelli già memorizzati e, in tal caso, visualizziamoli sullo schermo:

float new_latitude = minmea_tocoord(&frame.latitude);
if((new_latitude != NAN) && (abs(new_latitude - latitude) > 0.001)) {
  latitude = new_latitude;
  printf("New latitude: %f\n", latitude);
}

Ho aggiunto un valore di soglia (0.001) per evitare di stampare piccoli spostamenti, dovuti a disturbi o oscillazioni sui dati ricevuti.
Ecco il programma in esecuzione:

gps-010

4 Comments »

  1. Juan Jose Luna 13/11/2017 at 19:14 - Reply

    Hello, good and interesting article.

    I have a question: How many readings gives the GPS per second?

    I ask this because in a smartphone I can’t get more than 1 reading per second, and could be interested in investigating with these uart GPS devices.

    In the Banggood site they say:
    ” Nav. update rate1 Single GNSS: up to 18 HZ
    Concurrent GNSS: up to 10 Hz”

    Is that the true readings per second?
    Thanks

    • luca 14/11/2017 at 09:18 - Reply

      Hi, you can configure the “update rate” (sometimes called “refresh rate”) of the receiver using (for UBlox devices) the u-center config tool. Here’s a video that explains how to do it.

  2. Juan Jose Luna 16/11/2017 at 23:47 - Reply

    Nice, so you just have to send it a hex string. Interesting.
    I’ve seen a module (VK2828U7G5LF) very cheap and I’ve bought one.
    The datasheet tells all the commands (strings) to change the serial baud rate, update rate and so on.

    Thanks!

    • luca 17/11/2017 at 14:12 - Reply

      You’re welcome, let me know if you have success!

Leave A Response »

Questo sito usa i cookie per poterti offrire una migliore esperienza di navigazione maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi