25 junho 2017

Como usar o módulo GPS GY-NEO6MV2

Neste post vamos mostrar como usar o módulo GPS GY-NEO6MV2 com Arduino Uno, exibindo informações fornecidas pelos satélites do sistema GPS em um display OLED I2C.

Arduino Uno e módulo GPS NEO6MV2

O GY-NEO6MV2 é um módulo de fácil utilização, realizando a comunicação através de comunicação serial. Esse tipo de comunicação faz com que o módulo seja facilmente integrado à projetos que utilizem microcontroladores e também placas como Raspberry Pi, Linkit, Beaglebone, NodeMCU, ESP8266 e outras.

O módulo GPS GY-NEO6MV2


Em termos de pinagem o GY-NEO6MV2 é bem "econômico": são somente 4 pinos, sendo dois de alimentação (Vcc e GND, 2.7 à 5VDC), e dois de comunicação serial (RX e TX).

Pinagem Módulo GPS GY-NEO6MV2


O módulo possui antena embutida e a corrente de operação do conjunto é de apenas 45mA, tornando o módulo GPS GY-NEO6MV2 uma excelente opção para utilização em carrinhos, drones, projetos de navegação aérea ou terrestre e geolocalização.

Conexão do módulo GPS ao Arduino


Nos nossos testes vamos usar o módulo GY-NEO6MV2 com Arduino Uno e um display OLED  I2C, que vai mostrar as informações de data, hora, latitude e longitude fornecidas pelos satélites do sistema GPS.

Circuito Arduino Uno e GPS NEO6MV2


O módulo GPS está conectado aos pinos digitais 3 e 4 do Arduino, e vamos usar a biblioteca SoftwareSerial para efetuar a comunicação com o módulo, liberando a serial por hardware do Arduino para enviar dados ao serial monitor do computador, se necessário. O display OLED utiliza a comunicação I2C e é ligado aos pinos analógicos A4 (SDA) e A5 (SCL).

Fique atento às conexões do Vcc e GND do display OLED, pois em alguns módulos esses pinos vem invertidos.

Programa


O programa utiliza a biblioteca TinyGPS++ (download), e você deve descompactar a pasta da biblioteca e copiá-la para a pasta LIBRARIES da IDE do Arduino.

Vamos também utilizar a biblioteca TimeLib, que servirá para ajustar o fuso horário (TimeZone) depois que os dados de data e hora forem recebidos pelo módulo GPS GY-NEO6MV2.

A TimeLib está junto com a biblioteca Time, que pode ser instalada através da própria IDE, para isso abra a IDE do Arduino, acesse o menu Sketch, selecione Incluir Biblioteca e depois Gerenciar Bibliotecas. Procure pela biblioteca Time, de Michael Margolis, e clique em instalar:

Biblioteca Time Arduino

Realize o mesmo procedimento para instalar a biblioteca U8glib, usada para exibição de gráficos e informações no display OLED.

A TinyGPS++ é uma biblioteca que permite extrair as informações fornecidas pelo módulo GPS de forma simples, fornecendo apenas as informações que desejamos, como no exemplo deste post, as informações de data, hora, latitude e longitude.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
//Programa: Modulo GPS GY-NEO6MV2 com Arduino Uno
//Autor: Arduino e Cia

#include <TimeLib.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <U8glib.h>

//Pinos utilizados para conexao do modulo GY-NEO6MV2
static const int RXPin = 4, TXPin = 3;

//Objeto TinyGPS++
TinyGPSPlus gps;

//Conexao serial do modulo GPS
SoftwareSerial Serial_GPS(RXPin, TXPin);

//Definicoes do display Oled
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_FAST);

void draw()
{
  //Ajuste do horario/timezone
  GPS_Timezone_Adjust();
  //Comandos graficos para o display devem ser colocados aqui
  u8g.setFont(u8g_font_8x13B);
  u8g.drawRFrame(0, 0, 128, 64, 4);
  //Linha Data
  u8g.drawStr(10, 14, "D:        ");
  u8g.setPrintPos(34, 14);
  //Mostra o dia
  if (day() < 10)
  {
    u8g.print("0");
  }
  u8g.print(day());
  u8g.drawStr(51, 14, "/");
  u8g.setPrintPos(60, 14);
  //Mostra o mes
  if (month() < 10)
  {
    u8g.print("0");
  }
  u8g.print(month());
  u8g.drawStr(76, 14, "/");
  u8g.setPrintPos(85, 14);
  //Mostra o ano
  u8g.print(year());

  //Linha Horario
  u8g.drawStr(10, 29, "H:        ");
  u8g.setPrintPos(45, 29);
  //Mostra hora
  if (hour() < 10)
  {
    u8g.print("0");
  }
  u8g.print(hour());
  u8g.drawStr(61, 28, ":");
  u8g.setPrintPos(70, 29);
  //Mostra minutos
  if (minute() < 10)
  {
    u8g.print("0");
  }
  u8g.print(minute());
  u8g.drawStr(86, 28, ":");
  u8g.setPrintPos(95, 29);
  //Mostra segundos
  if (second() < 10)
  {
    u8g.print("0");
  }
  u8g.print(second());

  //Linha latitude
  u8g.drawStr(10, 44, "Lat:         ");
  u8g.setPrintPos(45, 44);
  u8g.print(gps.location.lat(), 5);

  //Linha longitude
  u8g.drawStr(10, 59, "Lon:         ");
  u8g.setPrintPos(45, 59);
  u8g.print(gps.location.lng(), 5);
}

//Ajuste o timezone de acordo com a regiao
const int UTC_offset = -3;

void setup()
{
  //Baud rate Arduino
  Serial.begin(115200);
  //Baud rate Modulo GPS
  Serial_GPS.begin(9600);

  //Mostra informacoes iniciais no serial monitor
  Serial.println(F("Data, Hora, Latitude e Longitude"));
  Serial.println(F("Modulo GPS GY-NEO6MV2"));
  Serial.print(F("Biblioteca TinyGPS++ v. ")); 
  Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println();

  //Definicoes do display Oled
  if ( u8g.getMode() == U8G_MODE_R3G3B2 )
  {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
  }
}

void loop()
{
  //Conexao com modulo GPS
  while (Serial_GPS.available() > 0)
    if (gps.encode(Serial_GPS.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while (true);
  }

  //Chama a rotina de desenho na tela
  u8g.firstPage();
  do
  {
    draw();
  }
  while ( u8g.nextPage() );
  delay(1000);
}

void displayInfo()
{
  //Mostra informacoes no Serial Monitor
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6); //latitude
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6); //longitude
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.day()); //dia
    Serial.print(F("/"));
    Serial.print(gps.date.month()); //mes
    Serial.print(F("/"));
    Serial.print(gps.date.year()); //ano
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour()); //hora
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute()); //minuto
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second()); //segundo
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }
  Serial.println();
}

void GPS_Timezone_Adjust()
{
  while (Serial_GPS.available())
  {
    if (gps.encode(Serial_GPS.read()))
    {
      int Year = gps.date.year();
      byte Month = gps.date.month();
      byte Day = gps.date.day();
      byte Hour = gps.time.hour();
      byte Minute = gps.time.minute();
      byte Second = gps.time.second();

      //Ajusta data e hora a partir dos dados do GPS
      setTime(Hour, Minute, Second, Day, Month, Year);
      //Aplica offset para ajustar data e hora
      //de acordo com a timezone
      adjustTime(UTC_offset * SECS_PER_HOUR);
    }
  }
}

Carregue o programa no Arduino e depois de alguns segundos (ou minutos, dependendo do local), as informações recebidas dos satélites GPS serão mostradas no display OLED e atualizadas à cada 1 segundo. Não se esqueça que o módulo precisa "enxergar" os satélites, ou seja, você terá resultados muito melhores se usar o Arduino com o módulo GPS ao ar livre, ok?

Para verificar se o seu módulo GY-NEO6MV2 está mostrando as informações corretas, abra por exemplo o Google Maps e digite as coordenadas mostradas no display, como na imagem abaixo:

Google Maps Coordenadas GPS

O Google Maps mostrará então no mapa o local exato em que o módulo GPS se encontra(va).

Google Maps Mapa Local

Explore a biblioteca TinyGPS++ para utilizar outros comandos que vão fornecer informações como altitude e velocidade, e também verifique os dados "puros" (raw data), que são enviados pelo módulo através da porta serial. 

Você também pode criar algum tipo de rastreador enviando os dados obtidos pelo GPS através da rede de telefonia celular via SMS ou internet: confira os posts aqui do Arduino e Cia sobre o módulo GSM SIM800L e o GSM GPRS Shield SIM900.

2 comentários:

  1. Não estou conseguindo usar a libre TinyGPS++

    ResponderExcluir
    Respostas
    1. Boa tarde Franklin,

      Esta apresentando alguma mensagem de erro?

      Adilson

      Excluir