Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


Rastreamento veicular com ESP32 GPS SIM808 – Sem mensalidade




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

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:



Postar um comentário

7 Comentários

  1. excelente as seguradoras deveriam adotar

    Obrigado mais uma vez.

    ResponderExcluir
  2. o meu sempre retorna falha na configuração do GPS, alguma dica?

    ResponderExcluir
  3. Olá 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.

    Obrigado!

    ResponderExcluir
  4. O meu também está apresentando a mesma mensagem.

    ResponderExcluir
  5. Caros Srs.,

    Estou 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?

    ResponderExcluir