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