Hoje
vamos tratar de um assunto bem interessante: o Rastreamento veicular com ESP32
GPS SIM808! E o melhor: sem mensalidade. Vamos controlar o módulo SIM808 via
UART usando ESP32 LoRa. Ainda, iremos obter localização GPS e calcular
distância do dispositivo. Isso, além de enviar SMS de alerta de distanciamento
de dispositivo.
Para
esse vídeo, fiz um teste no meu próprio carro, mas a gravação ficou horrível,
então optei por não utilizá-la. Mas, trago aqui toda a explicação, o esquema e
o código fonte para você começar a entender como funciona a tecnologia de
rastreamento.
Montagem
Fiz
o circuito e coloquei dentro de uma caixa para facilitar o transporte.
Zoom
do display:
Aqui
exibo a distância de um raio:
Detalhes
da montagem:
Inserindo SIM card
Insira
o SIM card no soquete conforme as imagens
ESP32 LoRa Pinout
SIM808 Dev board
Recursos usados
ESP32
LoRa
SIM808
Module GSM GPRS GPS Development Board
Smartphone
SIM
card (Com crédito)
Fonte/Bateria
4V (SIM808)
Fonte/Bateria
5V (ESP32)
Jumpers
Led
Resistor
330ohm
Funcionamento do projeto – Leitura de localização GPS
Fluxo
de dados
O
SIM808 pega os sinais dos satélites e faz um cálculo para saber qual sua
latitude e qual sua longitude. Já integrado nele temos um modem GPRS e um GPS.
Funcionamento do projeto - Envio de SMS
Fluxo
de dados
Biblioteca necessária: TinyGsmClient
Download:
https://github.com/vshymanskyy/TinyGSM
Obs:
A biblioteca SSD1306.h referente ao OLED Display do ESP32 LoRa está anexada
junto ao projeto.
Código
Código
ESP32
Declarações
e variáveis
#include <Arduino.h> #include <HardwareSerial.h> //Comunicação UART com o módulo SIM808 #include "displayESP32LoRa.h" //Funções de display #include "GPRS_Functions.h" //Funções de configuração do GPRS const double LATITUDE_REFERENCE = -22.129688; //Latitude de referência para calcular o distanciamento do dispositivo const double LONGITUDE_REFERENCE = -51.408570; //Longitude de referência para calcular o distanciamento do dispositivo const double MAX_DISTANCE = 1000; //Distância limite usada para disparar SMS de alerta de distanciamento, medida em metros HardwareSerial mySerial(1); //Objeto referente a comunicação UART com o módulo SIM808 const String CELLNUMBER = "+5518999999999"; //Número de celular que recebe mensagens SMS de alerta referentes ao distanciamento do dispositivo //Flag que garante só um envio de sms quando o dispositivo estiver muito longe bool smsSent = false; //Tempo que é aguardado após o envio de um comando AT, usado na função "sendAT" const int TIMEOUT_AT = 2000; //Pino serial RX que deve ser conectado no TX do SIM808, usado para configurar a variável "mySerial" const int RX_PIN = 0; //Pino serial TX que deve ser conectado no RX do SIM808, usado para configurar a variável "mySerial" const int TX_PIN = 22; //Pino de sinalização que é ativado no mesmo tempo em que o SMS é enviado para o celular const int pinLed = 17; const int BAUD_RATE = 115200;
Setup
void setup() { pinMode(pinLed, OUTPUT); //Configura Display LoRa if(!loraDisplayConfig()) ESP.restart(); //Seta o baud rate que será usado pelo monitor serial e o que será usado pelo SIM808 serialConfig(); Serial.println("Waiting..."); showDisplay(0, "Waiting...", true); delay(3000); //Informa ao SIM808 o baud rate utilizado, é recomendado rodar este programa pela primeira vez com a velocidade de 9600 if(!baudConfig()) ESP.restart(); //Seta sms como modo texto if(!smsConfig()) { showDisplay(0, "SMS config failed!", true); Serial.println("SMS config failed!"); delay(3000); ESP.restart(); } showDisplay(0, "SMS config ok", true); Serial.println("SMS config ok");
Setup – continuação
//Ativa o recurso de GPS do módulo if(!gpsConfig()) { showDisplay(1, "GPS config failed!", false); Serial.println("GPS config failed!"); delay(3000); ESP.restart(); } showDisplay(1, "GPS config ok", false); showDisplay(2, "Setting modem...", false); Serial.println("GPS config ok, setting modem..."); //Configura e inicializa o GPRS if(!modemConfig(mySerial)) { //Exibe no console e no display Serial.println("Modem init fail"); showDisplay(3, "Modem init fail", false); delay(5000); ESP.restart(); } //Exibe no console e no display showDisplay(3, "Modem ok", false); Serial.println("Modem ok"); }
Setup – serialConfig, baudConfig e smsConfig
void serialConfig() { //Set console baud rate Serial.begin(BAUD_RATE); //Configura baud rate do ESP32 UART mySerial.begin(BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN); //Esp32 lora 0 = RX, 22 = TX } //Configuração de mensagens SMS bool smsConfig() { //Define modo SMS para texto (0 = PDU mode, 1 = Text mode) if(sendAT("AT+CMGF=1").indexOf("OK") < 0) return false; //Se obteve sucesso retorna true return true; } //Configuração referente ao gps bool gpsConfig() { if(sendAT("AT+CGNSPWR=1").indexOf("OK") >= 0) //Liga fonte de energia do GNSS (1 = ligar, 0 = desligar) if(sendAT("AT+CGPSINF=0").indexOf("OK") >= 0) //Tenta obter pela primeira vez a localização GPS return true; return false; } //Informa ao SIM808 o baud rate utilizado, é recomendado rodar este programa pela primeira vez com a velocidade de 9600 bool baudConfig() { //Se obteve sucesso retorna true if(sendAT("AT+IPR="+String(BAUD_RATE)).indexOf("OK") >= 0) return true; return false; }
Setup – modemConfig e networkConnect
//#define TINY_GSM_MODEM_SIM800 #define TINY_GSM_MODEM_SIM808 // #define TINY_GSM_MODEM_SIM900 // #define TINY_GSM_MODEM_UBLOX // #define TINY_GSM_MODEM_BG96 // #define TINY_GSM_MODEM_A6 // #define TINY_GSM_MODEM_A7 // #define TINY_GSM_MODEM_M590 // #define TINY_GSM_MODEM_ESP8266 // #define TINY_GSM_MODEM_XBEE #include <TinyGsmClient.h> //Biblioteca que configura o modem GSM const char apn[] = "APN"; //YourAPN const char user[] = ""; const char pass[] = ""; HardwareSerial Serial_SIM_Module(1); TinyGsm sim808(Serial_SIM_Module); bool networkConnect() { Serial.print("Waiting for network..."); if (!sim808.waitForNetwork()) { Serial.println(" fail"); return false; } Serial.println(" OK"); Serial.print("Connecting to "); Serial.print(apn); if (!sim808.gprsConnect(apn, user, pass)) { Serial.println(" fail"); return false; } Serial.println(" OK"); return true; } //Configura o modem GPRS bool modemConfig(HardwareSerial mySerial) { Serial_SIM_Module = mySerial; //Inicia modem Serial.println("Setting modem..."); if(!sim808.restart()) return false; //Conecta na rede return networkConnect(); }
Loop
void loop() { String distance, la, lo; float lat, lon; //Tenta obter valores de GPS if(sim808.getGPS(&lat, &lon)) //if(getGSMLocation(mySerial, &la, &lo)) Caso o sinal GPS esteja ruim, teste utilizando a rede GSM substituindo este if { lat = la.toFloat(); lon = lo.toFloat(); Serial.println("GPS signal ok. Values obtained successfully."); //Verifica se o dispositivo ultrapassa a distância limite if(deviceIsTooFar(lat, lon, &distance)) { //Flag que permite o envio de só uma mensagem SMS if(!smsSent) { //Tenta enviar SMS if(sim808.sendSMS(CELLNUMBER, "Device is too far!")) Serial.println("Device is too far - SMS sent"); else Serial.println("Device is too far - fail to send SMS"); showDisplay(0, "Device is too far!", true); digitalWrite(pinLed, HIGH); //acende led sinalizando que o dispositivo está muito longe smsSent = true; delay(5000); } }
Loop
– continuação...
//Se foi possível obter os valores de GPS, exibe no display showDisplay(0, "Latitude: " + String(lat, 6), true); showDisplay(1, "Longitude: " + String(lon, 6), false); showDisplay(2, "Distance: " + distance + "m", false); } else { //Se não foi possível obter os valores, exibe vazio Serial.println("GPS signal is down. Values not obtained."); showDisplay(0, "Latitude: -", true); showDisplay(1, "Longitude: -", false); showDisplay(2, "Distance: -", false); /* showDisplay(0, "Latitude: " + String(LATITUDE_REFERENCE, 6), true); showDisplay(1, "Longitude: " + String(LONGITUDE_REFERENCE, 6), false); showDisplay(2, "Distance: 328m", false); */ } flag = !flag; if(flag) showDisplay(5, "(Refresh)", false); delay(3000); }
Loop – deviceIsTooFar
//Calcula a distância em que o dispositivo está, levando em consideração a curvatura da terra (valor retornado em metros) double getDistance(float lat, float lon) { double dist = 60 * ((acos(sin(LATITUDE_REFERENCE*(PI/180)) * sin(lat*(PI/180)) + cos(LATITUDE_REFERENCE*(PI/180)) * cos(lat*(PI/180)) * cos(abs((lon-LONGITUDE_REFERENCE)) * (PI/180)))) * (180/PI)); return dist*1852; } //Verifica se o dispositivo ultrapassou o limite de distância bool deviceIsTooFar(float lat, float lon, String *distance) { double dist = getDistance(lat, lon); *distance = String(dist); if(dist > MAX_DISTANCE) return true; return false; }
Display
LoRa
#include "SSD1306.h" //Responsável pela comunicação com o display //Define os pinos que serão utilizados pelo display LoRa #define SCK 5 // GPIO5 -- SX127x's SCK #define MISO 19 // GPIO19 -- SX127x's MISO #define MOSI 27 // GPIO27 -- SX127x's MOSI #define SS 18 // GPIO18 -- SX127x's CS #define RST 14 // GPIO14 -- SX127x's RESET #define DI00 26 // GPIO26 -- SX127x's IRQ(Interrupt Request) SSD1306 display(0x3c, 4, 15); //Construtor do objeto do display LoRa
Display
LoRa – loraDisplayConfig
//Configura Display LoRa bool loraDisplayConfig() { //Configura RST do oled como saida pinMode(16,OUTPUT); //Reseta o OLED digitalWrite(16, LOW); //Aguarda 50ms delay(50); //Enquanto o OLED estiver ligado, GPIO16 deve estar HIGH digitalWrite(16, HIGH); //Inicializa display if(!display.init()) return false; //Inverte a tela verticalmente (de ponta cabeça) display.flipScreenVertically(); //Configura a fonte do display display.setFont(ArialMT_Plain_10); //Aguarda 200ms delay(200); //Limpa display display.clear(); return true; }
Display
LoRa – showDisplay
//Exibe mensagem recebida como parâmetro void showDisplay(int line, String msg, bool clear) { //Limpa o display if(clear) { display.clear(); //Configura alinhamento de texto à esquerda display.setTextAlignment(TEXT_ALIGN_LEFT); //Configura fonte do texto display.setFont(ArialMT_Plain_10); } //Escreve na pos 0,25 a mensagem display.drawString(0 , line*10 , msg); //Exibe no display display.display(); }
Links
Biblioteca
TinyGSM:
Mais
sobre SIM808:
Faça
o download dos arquivos:
7 Comentários
Excelente, valeu...
ResponderExcluirexcelente as seguradoras deveriam adotar
ResponderExcluirObrigado mais uma vez.
o meu sempre retorna falha na configuração do GPS, alguma dica?
ResponderExcluirOlá turorial muito bom! gostaria de saber se o GPS funciona o perde sinal, quando esta dentro de uma casa. No escenario mais pesimista dentro de uma casa com teto de concreto e janelas fechadas. É para fazer um sistema de traking anti-robos.
ResponderExcluirObrigado!
O meu também está apresentando a mesma mensagem.
ResponderExcluirCaros Srs.,
ResponderExcluirEstou desenvolvendo um sistema que necessita de localização GPS, então adquiri todas os componentes listados acima e carreguei o código do site, porém não funcionou. Onde posso conseguir ajuda para fazê-lo funcionar?
muito bom! parabéns
ResponderExcluir