Módulo GPS NEO-6M com Raspberry Pi Pico usando MicroPython

Tempo de leitura: 11 minutes

Neste tutorial, aprenderemos sobre um módulo GPS NEO-6M e como fazer a interface com o Raspberry Pi Pico para obter parâmetros de GPS, como latitude, longitude, data de altitude, hora, velocidade, satélites, etc. Aprenderemos como o GPS funciona e a visão geral do módulo GPS NEO-6M com uma introdução, pinagem e especificações. Depois disso, aprenderemos a fazer a interface de um módulo de módulo GPS NEO-6M com o Raspberry Pi Pico.

Para fins de demonstração, exibiremos os parâmetros de localização do GPS, incluindo Latitude, Longitude, Número de Satélites e hora atual no console Thonny shell, bem como em um OLED

Pré-requisitos

Antes de começarmos esta lição, certifique-se de que você esteja familiarizado e tenha a versão mais recente do Python 3 em seu sistema, tenha configurado o MicoPython no Raspberry Pi Pico e tenha um Ambiente de Desenvolvimento Integrado (IDE) em execução no qual faremos a programação. Usaremos o mesmo Thonny IDE que usamos anteriormente quando aprendemos a piscar e perseguir LEDs em micro-python.

 

Introdução ao GPS

O Sistema de Posicionamento Global (GPS) é um sistema de navegação baseado em satélite que consiste em 24 satélites em órbita, cada um dos quais faz dois circuitos ao redor da Terra a cada 24 horas. Esses satélites transmitem três bits de informação – o número do satélite, sua posição no espaço e a hora em que a informação é enviada. Esses sinais são captados pelo receptor GPS, que usa essa informação para calcular a distância entre ele e os satélites GPS. Com sinais de três ou mais satélites, um receptor GPS pode triangular sua localização no solo (ou seja, longitude e latitude) a partir da posição conhecida dos satélites. Com quatro ou mais satélites, um receptor GPS pode determinar uma posição 3D (ou seja, latitude, longitude e elevação).

Além disso, um receptor GPS pode fornecer dados sobre sua velocidade e direção de viagem. Qualquer pessoa com um receptor GPS pode acessar o sistema. Como o GPS fornece posicionamento tridimensional, navegação e cronometragem em tempo real 24 horas por dia, 7 dias por semana, em todo o mundo, ele é usado em várias aplicações, incluindo coleta de dados GIS, levantamento e mapeamento.

Ponto a ser lembrado: Um receptor GPS localiza três ou mais satélites, calcula a distância de cada um e usa essas informações para gerar sua própria localização. Esta operação é baseada em um princípio matemático simples chamado Trilateração.

 

Introdução ao Módulo GPS NEO-6M

O módulo GPS NEO-6M é um receptor GPS que pode localizar todos os locais na Terra, pois é capaz de rastrear aproximadamente 22 satélites. Consiste em um mecanismo de posicionamento u-blox 6 de alto desempenho. Medindo 16 x 12,2 x 2,4 mm, sua arquitetura compacta e seu baixo consumo de energia o tornam uma boa escolha para projetos de IoT. No geral, é um receptor GPS de bom custo-benefício.

 

Visão geral do hardware

Vamos aprender um pouco sobre seu hardware. Para obter leituras de GPS, temos que usar o módulo GPS NEO-6M com uma antena. A antena está firmemente conectada ao módulo através do conector U.FL. Este conector encontra-se no módulo GPS.

Chip GPS NEO-6M

No meio do módulo GPS, você pode encontrar o chip NEO-6M. Este é responsável por rastrear até 22 satélites e qualquer local da Terra em vários canais. Devido à sua natureza de rastreamento altamente sensível, torna o módulo NEO-6M um rastreador GPS popular.

Alguns dos principais recursos do chip NEO-6M incluem:

  • Alta sensibilidade para rastreamento
  • Baixa corrente de alimentação (~45mA)
  • É capaz de rastrear 5 locais por segundo com uma precisão de 2,5m (horizontal).
  • Vem equipado com PSM também conhecido como modo de economia de energia. Este modo causa muito menos consumo de energia ao ligar/desligar o módulo de acordo com a necessidade.
  • Ótimo uso como rastreadores GPS em relógios inteligentes devido ao consumo de energia muito baixo (~ 11mA)

Indicador LED de Fixação de Posição

Seguindo em frente, o módulo vem com um indicador LED de correção de posição. Este LED indica através de seu efeito piscante se o módulo está procurando por satélites ou já os encontrou. Se o LED piscar a cada segundo, isso indica que a posição fixa foi encontrada. No entanto, se o LED não piscar, o módulo ainda está procurando os satélites.

Regulador de baixa queda de 3,3 V

O módulo também vem equipado com um regulador LDO de 3,3V (MIC5205). Isso fornece uma regulação de tensão linear eficiente com saída de ruído ultrabaixo e tensão de queda muito baixa. Além disso, o módulo também pode tolerar facilmente 5V.

Especificações

A tabela abaixo mostra algumas especificações do módulo NEO-6M.

TipoGPS
Fornecer2.7 V-3.6 V
Corrente Operacional45mA
Temperatura de operação-40°C ~ 85°C
Precisão da Posição Horizontal2.5m
Protocolo de comunicaçãoNMEA, UBX Binary, RTCM
CaracterísticasRTC Crystal and External Interrupt/Wake up
InterfaceUART, SPI, USB and DDC

Para obter mais informações sobre o módulo NEO-6M, consulte sua folha de dados fornecida aqui.

Pinagem do Módulo NEO 6M

O diagrama abaixo mostra a pinagem do módulo NEO 6M. Consiste em 4 pinos chamados GND, TX, RX e VCC.

GNDEste é o pino terra que será conectado com o terra do microcontrolador.
TXEste é o pino de transmissão usado para comunicação serial.
RXEste é o pino do receptor usado para comunicação serial.
VCCEste é o pino VCC usado para ligar o módulo GPS.

 

Módulo de interface NEO-6M com Raspberry Pi Pico e OLED

Precisaremos dos seguintes componentes para conectar nosso Raspberry Pi Pico ao display OLED e ao módulo GPS NEO-6M.

  • Raspberry PÌ Pico
  • Módulo GPS NEO-6M
  • Tela OLED SSD1306
  • Fios de conexão

 

Raspberry Pi Pico com NEO-6M

O módulo GPS NEO-6M possui 4 terminais que iremos conectar com o Raspberry Pi Pico. Vamos conectar os terminais VCC e GND com pinos 3.3V e GND da placa Raspberry Pi Pico respectivamente. Vamos conectar o terminal TX (transmissor) e o terminal RX (receptor) do módulo GPS com os pinos UART da placa Pi Pico. Vamos primeiro dar uma olhada nos pinos UART do Raspberry Pi Pi.

Pinos UART Raspberry Pi Pico

Raspberry Pi Pico contém dois periféricos UART idênticos com FIFOs 32×8 Tx e 32×12 Rx separados.

A tabela a seguir lista os pinos GPIO para ambos os periféricos UART que são expostos nas pinagens da placa de desenvolvimento Raspberry Pi Pico.

Pinos UARTPinos GPIO
UART0-TXGP0/GP12/GP16
UART0-RXGP1/GP13/GP17
UART1-TXGP4/GP8
UART1-RXGP5/GP9

Para este guia, usaremos os pinos UART1-TX e RX.

Raspberry Pi PicoNEO-6M Module
3.3VVCC
GP5 (UART1 RX)TX
GP4 (UART1 TX)RX
GNDGND

 

Raspberry Pi Pico com NEO-6M e OLED

O display OLED possui 4 terminais que conectaremos com nossos dispositivos. Como o display OLED requer uma tensão de operação na faixa de 3,3-5V, conectaremos o terminal VCC com 3,3V que será em comum com a placa e o módulo GPS. O SCL do display será conectado com o pino SCL do módulo e o SDA do display será conectado com o SDA do módulo. O aterramento de ambos os dispositivos será mantido em comum.

Pinos I2C Raspberry Pi Pico

Raspberry Pi Pico tem dois controladores I2C. Ambos os controladores I2C são acessíveis através dos pinos GPIO do Raspberry Pi Pico. A tabela a seguir mostra a conexão dos pinos GPIO com os dois controladores I2C. Cada conexão do controlador pode ser configurada através de vários pinos GPIO conforme mostrado na figura. Mas antes de usar um controlador I2C, você deve configurar no software quais pinos GPIO você deseja usar com um controlador I2C específico.

Controlador I2CPinos GPIO
I2C0 – SDAGP0/GP4/GP8/GP12/GP16/GP20
I2C0 – SCLGP1/GP5/GP9/GP13/GP17/GP21
I2C1 – SDAGP2/GP6/GP10/GP14/GP18/GP26
I2C1 – SCLGP3/GP7/GP11/GP15/GP19/GP27

As conexões entre os dois dispositivos que estamos usando podem ser vistas abaixo.

SSD1306 OLED DisplayRaspberry Pi Pico
VCC3.3V
SDAGP0 (I2C0 SDA)
SCLGP1 (I2C0 SCL)
GNDGND

Esquemático Raspberry Pi Pico com OLED e NEO-6M

Siga o diagrama esquemático abaixo e conecte-os de acordo.

Usamos as mesmas conexões especificadas nas tabelas acima. No entanto, você também pode usar outras combinações de pinos SDA/SCL e pinos UART.

Raspberry Pi Pico com diagrama de conexão NEO 6M e OLED
Raspberry Pi Pico com diagrama de conexão NEO 6M e OLED

Entendendo a frase NMEA básica

O módulo GPS NEO-6M envia dados GPS no formato NMEA. É de vários tipos, incluindo $GPRMC, $GPGGA etc. Cada campo de dados NMEA é separado por uma vírgula e começa com um ‘$’

Abaixo você pode ver a sintaxe $GPXXX que denota os diferentes tipos de mensagens NMEA:

$GPGGADados de correção do sistema de posicionamento global. Ele fornece localização 3D e dados de precisão
$GPGSAFornece GPS DOP e satélites ativos
$GPGSVEle fornece as informações detalhadas do satélite GPS
$GPGLLEle fornece a Latitude e Longitude geográfica
$GPRMCEle fornece a posição, velocidade e tempo
$GPVTGEle fornece a velocidade dupla de solo/água

Vamos entender como ler a sentença NMEA básica, ou seja, $GPGGA. Aqui está um exemplo de sentença $GPGGA NMEA:

$GPGGA, 103005, 3807.038, N, 07128.99030, E, 1, 07, 1.43, 134.5, M, 42.9, M, , *78
  • $: Isso indica o início da sentença NMEA
  • GPGGA: Dados de correção do sistema de posicionamento global
  • 103005 : Esta é a hora UTC quando os dados foram acessados em HH:MM:SS. Neste caso, a hora
  • 10:30:05 UTC
  • 3807.038, N : Latitude 38 graus 07.038′ N
  • 07128.99030, E : Longitude 71 graus 28.00030′ E
  • 1: correção de GPS
  • 07 : Número de satélites rastreados
  • 1.43: Diluição horizontal da posição
  • 134.5, M : Mostra a altitude (m) acima do nível do mar
  • 42,9, M: Altura do geóide (nível médio do mar)
  • Campo vazio: tempo em segundos desde a última atualização do DGPS
  • Campo vazio: número de identificação da estação DGPS
  • *78 : os dados da soma de verificação

Biblioteca MicroPython de exibição OLED SSD1306

Já carregamos a biblioteca BME280 MicroPython para o Raspberry Pi Pico. Para um display OLED, também precisaremos carregar uma biblioteca para o Raspberry Pi Pico.

  • Para fazer isso com sucesso, abra seu Thonny IDE com seu Raspberry Pi Pico conectado ao seu sistema. Vá para  Tools > Manage Packages. Isso abrirá o Thonny Package Manager.

  • Pesquise “ssd1306” na barra de pesquisa digitando seu nome e clicando no botão “Pesquisar no PyPI”.

  • A partir dos seguintes resultados de pesquisa, clique no destacado abaixo: micropython-ssd1306

Instale esta biblioteca.

Após alguns momentos, esta biblioteca será instalada com sucesso. Agora estamos prontos para programar nosso Raspberry Pi Pico com display OLED.

 

Script MicroPython Obtendo Dados GPS do Módulo NEO-6M

from machine import Pin, UART, I2C
from ssd1306 import SSD1306_I2C

import utime, time

i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)

gpsModule = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
print(gpsModule)

buff = bytearray(255)

TIMEOUT = False
FIX_STATUS = False

latitude = ""
longitude = ""
satellites = ""
GPStime = ""

def getGPS(gpsModule):
    global FIX_STATUS, TIMEOUT, latitude, longitude, satellites, GPStime
    
    timeout = time.time() + 8 
    while True:
        gpsModule.readline()
        buff = str(gpsModule.readline())
        parts = buff.split(',')
    
        if (parts[0] == "b'$GPGGA" and len(parts) == 15):
            if(parts[1] and parts[2] and parts[3] and parts[4] and parts[5] and parts[6] and parts[7]):
                print(buff)
                
                latitude = convertToDegree(parts[2])
                if (parts[3] == 'S'):
                    latitude = -latitude
                longitude = convertToDegree(parts[4])
                if (parts[5] == 'W'):
                    longitude = -longitude
                satellites = parts[7]
                GPStime = parts[1][0:2] + ":" + parts[1][2:4] + ":" + parts[1][4:6]
                FIX_STATUS = True
                break
                
        if (time.time() > timeout):
            TIMEOUT = True
            break
        utime.sleep_ms(500)
        
def convertToDegree(RawDegrees):

    RawAsFloat = float(RawDegrees)
    firstdigits = int(RawAsFloat/100) 
    nexttwodigits = RawAsFloat - float(firstdigits*100) 
    
    Converted = float(firstdigits + nexttwodigits/60.0)
    Converted = '{0:.6f}'.format(Converted) 
    return str(Converted)
    
    
while True:
    
    getGPS(gpsModule)

    if(FIX_STATUS == True):
        print("Printing GPS data...")
        print(" ")
        print("Latitude: "+latitude)
        print("Longitude: "+longitude)
        print("Satellites: " +satellites)
        print("Time: "+GPStime)
        print("----------------------")
        
        oled.fill(0)
        oled.text("Lat: "+latitude, 0, 0)
        oled.text("Lng: "+longitude, 0, 10)
        oled.text("Satellites: "+satellites, 0, 20)
        oled.text("Time: "+GPStime, 0, 30)
        oled.show()
        
        FIX_STATUS = False
        
    if(TIMEOUT == True):
        print("No GPS data is found.")
        TIMEOUT = False

 

Como o Código Funciona?

Começaremos importando a classe UART, Pin e I2C do módulo da máquina. Em seguida, também importaremos o módulo utime e time para incorporar atrasos. Também importaremos o ssd1306, que é a biblioteca de exibição OLED que instalamos anteriormente. Isso nos ajudará a acessar todas as funções definidas dentro dele.

from machine import Pin, UART, I2C
from ssd1306 import SSD1306_I2C
import utime, time

Inicializando o OLED

Em seguida, inicializaremos os pinos I2C GPIO para SCL e SDA, respectivamente. Usamos os pinos I2C0 SCL e I2C0 SDA.

Criamos um método I2C() que recebe quatro parâmetros. O primeiro parâmetro é o canal I2C que estamos usando. O segundo parâmetro especifica o pino I2C GPIO da placa que está conectada à linha SDA. O terceiro parâmetro especifica o pino I2C GPIO da placa que está conectada à linha SCL. O último parâmetro é a conexão de frequência do OLED.

Estamos configurando o SCL no pino 1 e o SDA no pino 0.

i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)

Esses dados dos pinos SCL e SDA são salvos no objeto ‘i2c’ que se conectará ao barramento I2C e ajudará na comunicação entre os dois dispositivos

Agora, vamos criar um objeto ‘oled’ de SSD1306_I2C que usa a largura, altura e o objeto i2c como parâmetros.

oled = SSD1306_I2C(128, 64, i2c)

 

Inicializar a comunicação UART

Em seguida, definiremos a conexão NEO-6M UART criando um objeto ‘gpsModule’. Ao usar UART(), especificamos o canal UART como o primeiro parâmetro, a taxa de transmissão como o segundo parâmetro e os pinos TX e RX usados como terceiro e quarto parâmetros. Estamos usando UART1 neste caso com taxa de transmissão de 9600 para a comunicação uart.

Em seguida, imprimiremos esses detalhes de conexão do módulo NEO-6M no console Thonny shell.

gpsModule = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
print(gpsModule)

 

Variáveis de dados

Em seguida, criaremos um objeto array de bytes chamado buff para armazenar as sentenças NMEA.

buff = bytearray(255)

As seguintes variáveis irão armazenar os parâmetros GPS incluindo Latitude, Longitude, Número de satélites e hora UTC.

latitude = ""
longitude = ""
satellites = ""
GPStime = ""

A seguinte função obtém as coordenadas GPS. Estamos executando um loop while para obter os dados GPS da sentença básica NMEA $GPGGA. Latitude, Longitude, Satélites e hora serão adquiridos da sentença NMEA de acordo e salvos em suas respectivas variáveis.

def getGPS(gpsModule):
    global FIX_STATUS, TIMEOUT, latitude, longitude, satellites, GPStime
    
    timeout = time.time() + 8 
    while True:
        gpsModule.readline()
        buff = str(gpsModule.readline())
        parts = buff.split(',')
    
        if (parts[0] == "b'$GPGGA" and len(parts) == 15):
            if(parts[1] and parts[2] and parts[3] and parts[4] and parts[5] and parts[6] and parts[7]):
                print(buff)
                
                latitude = convertToDegree(parts[2])
                if (parts[3] == 'S'):
                    latitude = -latitude
                longitude = convertToDegree(parts[4])
                if (parts[5] == 'W'):
                    longitude = -longitude
                satellites = parts[7]
                GPStime = parts[1][0:2] + ":" + parts[1][2:4] + ":" + parts[1][4:6]
                FIX_STATUS = True
                break
                
        if (time.time() > timeout):
            TIMEOUT = True
            break
        utime.sleep_ms(500)

A função a seguir é responsável por converter os dados brutos de longitude e latitude em valores reais.

def convertToDegree(RawDegrees):

    RawAsFloat = float(RawDegrees)
    firstdigits = int(RawAsFloat/100) 
    nexttwodigits = RawAsFloat - float(firstdigits*100) 
    
    Converted = float(firstdigits + nexttwodigits/60.0)
    Converted = '{0:.6f}'.format(Converted) 
    return str(Converted)

Dentro do loop infinito, chamaremos primeiro a função getGPS(gpsModule). Se os dados do GPS estiverem disponíveis, imprima-os no console Thonny shell e na tela OLED. Se os dados GPS não forem adquiridos dentro do tempo definido no programa, a mensagem “Nenhum dado GPS foi encontrado” será impressa no console do shell.

while True:
    
    getGPS(gpsModule)

    if(FIX_STATUS == True):
        print("Printing GPS data...")
        print(" ")
        print("Latitude: "+latitude)
        print("Longitude: "+longitude)
        print("Satellites: " +satellites)
        print("Time: "+GPStime)
        print("----------------------")
        
        oled.fill(0)
        oled.text("Lat: "+latitude, 0, 0)
        oled.text("Lng: "+longitude, 0, 10)
        oled.text("Satellites: "+satellites, 0, 20)
        oled.text("Time: "+GPStime, 0, 30)
        oled.show()
        
        FIX_STATUS = False
        
    if(TIMEOUT == True):
        print("No GPS data is found.")
        TIMEOUT = False

 

Demonstração

Depois de copiar o código a seguir em um novo arquivo, clique no ícone ‘Salvar’ para salvar o código do programa em seu PC.

Depois de salvar o código, pressione o botão Executar para fazer o upload do código para o seu módulo Raspberry Pi Pico. Antes de fazer o upload do código, certifique-se de que a placa correta esteja selecionada.

No terminal shell do seu IDE, você poderá visualizar os seguintes parâmetros de GPS

Depois que o código for carregado no Raspberry Pi Pico, você também poderá visualizar os dados do GPS no OLED: