Shields

Tutorial Completo: Shield GPS + MicroSD

Eletrogate 12 de agosto de 2020

Introdução

Os chips de GPS da fabricante UBLOX da série de NEO-6 são bastantes conhecidos, e tem muitas variações de modelos e de produtos finais utilizados. O mais famoso, com certeza, são os módulos GPS NEO-6M com e sem antena, que são muito usados em projetos de drones, projetos de monitoração de objetos, etc.

A principal vantagem de uso desses módulos GPS é a simplicidade e a disposição de bibliotecas para coletar os dados já tratados. Se você é novo no nosso blog, e quer saber mais sobre GPS, detalhes de funcionamento e também sobre o módulo NEO6M, clique aqui e acesse nosso post sobre o assunto.

O produto que abordaremos hoje é uma shield GPS que tem tanto a função do módulo, e tem um adicional: Ela possui um slot para cartão SD.

Vantagens de utilizar a Shield GPS em relação ao módulo:

  • Não há necessidade de utilização de protoboard
  • Se encaixa perfeitamente ao Arduino
  • Possui uma bateria para que a localização seja achada mais rapidamente se caso haja uma perda de energia
  • Essa shield acompanha uma antena de cabo bem longo
  • Possui um slot para salvar as localizações no cartão SD
  • Bateria para recuperação rápida da localização, em caso de perda de energia

Diagrama

Um diagrama de uma versão da Shield é esse, onde pode se notar a conexão que os pinos controlados pelos Mini Jumpers são ligados aos pinos físicos do Arduino D1 ao D7.  Os dois pinos que forem selecionados serão responsáveis pela comunicação serial, logo, não deve ser utilizado para outros fins. Vale sempre lembrar, que se deve ligar o pino TX selecionado da shield ao RX do Arduino, atente isso na hora de programar.

Como pode ser visto, o pino 8 é usado também pela shield, pois este pino é o que faz o serviço de selecionar o cartão MicroSD no protocolo SPI.


Montagem

Coloque os mini jumpers (peças amarelas) nessas posições, para utilizar com o projeto. Com essa montagem, os pinos 3, 4,  8, 11, 12 e 13 estão reservados para a utilização da shield.

Colocando a Shield por cima do seu Arduino, verifique se todos os pinos estão se encaixando corretamente e então pressione para fazer a conexão e está pronto.

Coloque um cartão MicroSD no slot e o aperte até travar. Para retirar o cartão MicroSD, pressione novamente que ele irá sair. Dê preferência a cartões MicroSD de qualidade e Classe 10. Na minha experiência, cartões de baixa qualidade começa a falhar depois de um tempo.

Conecte a antena no adaptador IPX, e conecte o conector a shield.


Obtendo Data, Hora e Localização

Com o código abaxo carregado, ele fará a função de mostrar no Monitor Serial a posição de latitude e longitude da sua localização, e mostrará também o horário e data que  o satélite fornece. Graças a essas informações de data e hora, você pode utilizar essa shield também como uma espécie de RTC.

É comum o sinal de localização demorar alguns minutos para ser captado, se caso demorar muito coloque a antena na parte mais externa da casa. Quando o sinal for captado, o led onboard começará a piscar.

Este código possui um adicional bem legal, que é registrar as informações também no cartão SD! Dessa forma você tem um sistema de monitoramento de posição de forma muito simples.

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <SPI.h>
#include <SD.h>

#define FusoHorario -3 // Define o fuso-horario GMT -3, o padrão é brasília -3

#define GPS_RX 4 // Pino que foi definido pela posição do MicroJumper
#define GPS_TX 3 // Pino que foi definido pela posição do MicroJumper

SoftwareSerial GPS_Serial(GPS_RX, GPS_TX); // Definindo os pinos GPS_RX e GPS_TX como comunicação serial entre o Arduino e GPS
TinyGPS GPS; //Criando o objeto GPS

uint8_t chipSelect = 8; // O pino CS da shield GPS

void setup() {
  GPS_Serial.begin(9600); // // Inicializando as comunicações seriais com os Bauds definidos
  Serial.begin(9600);
  Serial.println("Inicializando o cartao MicroSD...");
  if (!SD.begin(chipSelect)) { // Se o cartão não estiver presente ou falhar....
    Serial.println("O MicroSD falhou ou nao esta presente");
    delay(1000);
  }
  Serial.println("O cartao foi inicializado corretamente.");
}

void loop() {
  bool conexao = false; // Indica se o GPS está conectado e recebendo dados do satelite
  int16_t ano; // Criação das variáveis  que guardará as informações de data
  uint8_t mes, dia, hora, minuto, segundo;

  while (GPS_Serial.available()) { // Ficará em loop até que consiga se conectar.
    char cIn = GPS_Serial.read();
    conexao = GPS.encode(cIn);
  }
  // Se saiu do loop, signifca que conseguiu conectar e está pronto para mostrar os dados
  if (conexao) {
    File dataFile = SD.open("GPSlog.txt", FILE_WRITE); // Associará o objeto dataFile ao arquivo GPSlog.txt. Se caso o arquivo não exista, será criado
    //O objeto dataFile foi setado como escrita, mas dá para utilizar de outras formas.
    
    Serial.println(" \n ----------------------------------------"); 
    dataFile.println(" \n ----------------------------------------"); //Este comando salva a linha no cartão MicroSD
    
    // Se caso não conseguir abrir o arquivo por qualquer razão, irá avisar no MonitorSerial
    if (!dataFile) Serial.println("Erro ao abrir o arquivo GPSlog.txt");  

    //Latitude e Longitude
    long latitude, longitude;
    GPS.get_position(&latitude, &longitude); // obtem a   latitude e longitude

    // se a latitude for algo valido ela será impressa no MicroSD e no MonitorSerial
    if ((latitude != TinyGPS::GPS_INVALID_F_ANGLE)) {
      Serial.print("Latitude: ");
      Serial.println(float(latitude) / 1000000, 6);
      dataFile.print("Latitude: ");
      dataFile.println(float(latitude) / 1000000, 6);

    }
    // se a longitude for algo valido ela será impressa no MicroSD e no MonitorSerial
    if (longitude != TinyGPS::GPS_INVALID_F_ANGLE) {
      Serial.print("Longitude: ");
      Serial.println(float(longitude) / 1000000, 6);
      dataFile.print("Longitude: ");
      dataFile.println(float(longitude) / 1000000, 6);
    }

    // Chamará a função para converter o horário recebido pelo satelite GMT, e converte para o fuso escolhido
    HorarioFuso(&ano, &mes, &dia, &hora, &minuto, &segundo); 
    // imprimindo os dados no monitor serial
    Serial.print("Data (GMT "); Serial.print(FusoHorario); Serial.println(")");
    Serial.print(dia);
    Serial.print("/");
    Serial.print(mes);
    Serial.print("/");
    Serial.println(ano);
    Serial.print("Horario (GMT "); Serial.print(FusoHorario); Serial.println(")");
    Serial.print(hora);
    Serial.print(":");
    Serial.print(minuto);
    Serial.print(":");
    Serial.println(segundo);
    // imprimindo os dados no cartão MicroSD
    dataFile.print("Data (GMT "); dataFile.print(FusoHorario); dataFile.println(")");
    dataFile.print(dia);
    dataFile.print("/");
    dataFile.print(mes);
    dataFile.print("/");
    dataFile.println(ano);
    dataFile.print("Horario (GMT "); dataFile.print(FusoHorario); dataFile.println(")");
    dataFile.print(hora);
    dataFile.print(":");
    dataFile.print(minuto);
    dataFile.print(":");
    dataFile.println(segundo);
    dataFile.close();
  }
}

void HorarioFuso(int16_t *ano_, uint8_t *mes_, uint8_t *dia_, uint8_t *hora_, uint8_t *minuto_, uint8_t *segundo_) {
  uint8_t QntDiasMes[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  int16_t ano;
  int8_t mes, dia, hora, minuto, segundo;
  GPS.crack_datetime(&ano, &mes, &dia, &hora, &minuto, &segundo); //obtendo a data e horário do satelite no padrão GMT
  
  hora += FusoHorario;
  
  if ((ano % 4) == 0) QntDiasMes[1] = 29; // Ano Bissexto
  if (hora < 0) {
    hora += 24;
    dia -= 1;
    if (dia < 1) {
      if (mes == 1) { // Jan 1
        mes = 12;
        ano -= 1;
      } else {
        mes -= 1;
      }
      dia = QntDiasMes[mes - 1];
    }
  }
  if (hora >= 24) {
    hora -= 24;
    dia += 1;
    if (dia > QntDiasMes[mes - 1]) {
      dia = 1;
      mes += 1;
      if (mes > 12) { // Jan 1
        ano += 1;
        mes = 1;
      }
    }
  }
  *ano_ = ano;
  *mes_ = mes;
  *dia_ = dia;
  *hora_ = hora;
  *minuto_ = minuto;
  *segundo_ = segundo;
}

Retirando o SD da Shield e colocando no computador, vemos que os dados foram registrados corretamente:


Conclusão

Aprendemos aqui como utilizar essa shield, e aprendemos mais sobre os recursos interessantes que ela traz. Com ela você pode elevar um pouco mais o nível do seu drone, e pode fazê-lo voar até determinado local e voltar automaticamente para você. Também pode ser feito dispositivos de segurança patrimonial, onde você pode monitorar sempre a localização de determinado item de valor. O limite é a imaginação!

Gostou da shield? Você montou e fez algo legal? Tira uma foto e nos marque no instagram: @eletrogate

Tá sabendo que temos um canal no YouTube? Clique aqui e veja nosso novo vídeo lá!

Se ficou com dúvidas ou queira fazer alguma sugestão, utilize os comentários aqui embaixo.

Não se esqueça de avaliar e muito obrigado por ter lido até aqui.

Um forte abraço e até a próxima!

Conheça a Metodologia Eletrogate e ofereça aulas de robótica em sua escola!


Sobre o Autor


Gustavo Nery

Cursando Engenharia de Controle e Automação pela UFMG. Apaixonado por eletrônica, computação e tecnologias na área de sistemas embarcados. Nos tempos livres me divido entre desenvolver pesquisa na universidade, adquirir novos conhecimentos e estar com a família.


Eletrogate

12 de agosto de 2020

A Eletrogate é uma loja virtual de componentes eletrônicos do Brasil e possui diversos produtos relacionados à Arduino, Automação, Robótica e Eletrônica em geral.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Eletrogate Robô

Cadastre-se e fique por
dentro de novidades!