Faça seu rastreador veicular com ESP32, GPS e FreeRTOS 4

Rastreadores são dispositivos que estão se tornando muito comuns no nosso dia-a-dia. Anteriormente presentes de forma majoritária em veículos leves de frotas (táxis, serviços técnicos de telefonia, etc.) e caminhões de empresas logísticas (transporte de cargas diversas), hoje em dia são utilizados até por seguradoras de veículos para traçar perfis de condução de seus clientes e, consequentemente, dar bônus ou “penalidades” aos mesmos dependendo do perfil obtido.’ Gostaria de aprender a fazer seu próprio rastreador veicular com ESP32 e FreeRTOS? Este post vai te ensinar!

Material utilizado

Para fazer o projeto deste post, você precisará somente de um cabo micro-USB e um Módulo WiFi ESP32 com Suporte de Bateria, GPS e LORA 915MHZ. Este módulo já contém o ESP32 e GPS integrados, sendo ideal para o desenvolvimento deste projeto (nenhum circuito adicional será preciso). Além disso, esse módulo ainda conta com suporte para baterias de Li-Ion 18650 e chip para comunicação LoRa, coisas muito úteis em vários projetos ligados à Internet das Coisas.

Se você ainda não conhece este módulo, observe-o na figura 1.

Rastreador com módulo ESP32 LoRa - Imagem 01
Figura 1 – Módulo WiFi ESP32 com Suporte de Bateria, GPS e LORA 915MHZ

Outro fato importante é que este módulo pode ser programado na Arduino IDE da mesma forma que um módulo ESP32 Dev Module comum. Para saber como preparar a sua Arduino IDE para isso, leia o tópico “Desenvolvimento com Arduino IDE” deste artigo aqui do blog.

O que é um rastreador?

Um rastreador é um dispositivo eletrônico capaz de:

  • Obter sua localização geográfica (latitude e longitude) via sinal GPS
  • Enviar periodicamente, de qualquer modo que seja (wi-fi, GPRS, via antena satelital, etc.,) a localização geográfica obtida para um servidor remoto (um sistema em nuvem, por exemplo).
  • Enviar outros dados além da localização, tais como: número de satélites GPS que o rastreador conseguiu captar, dispersão de sinal, velocidade do rastreador, horário obtido via GPS, etc.

Outros pontos importantes sobre rastreadores podem ser citados:

  • A periodicidade do envio de localização para o servidor remoto está atrelada, especialmente, a tarifação por mensagem e/ou plano de dados para o rastreador.
    Por essa razão, de forma geral, é comum que o tempo entre os envios de duas localizações seja de dois minutos ou mais. Em casos extremos (cuja tarifação é muito alta, como no uso de antenas satelitais), esse tempo pode chegar a trinta minutos.
  • Normalmente, os clientes finais não utilizam o rastreador de forma direta, comprando os hardwares dos rastreadores e montando uma infraestrutura para receber os dados por eles enviados. É usual no mercado se contratar uma empresa que forneça um equipamento rastreador e também um acesso a um sistema online, para que você consiga através dele ver os dados de rastreamento desejados. Isso é feito assim pois, desta forma, há maior garantia uma disponibilidade de serviço.

Formas de envio da localização

Conforme dito no tópico anterior, há diversas formas de envio de localização geográfica a um servidor remoto, podendo ser através conectividade móvel / celular (GPRS) e também conectividade local (wi-fi), dependendo do uso do rastreador.

Por exemplo, pode-se utilizar rastreamento com base em conectividade wi-fi em aluguéis de maquinário pesado, tais como: tratores, escavadeiras, betoneiras, guindastes e afins. Para o aluguel desse tipo de maquinário, uma das principais modalidades de cobrança é a por hora de uso. Dessa forma, bastaria saber o momento que a máquina saiu de seu pátio-base e quando retornou, para assim se fazer a diferença de tempo e calcular o preço total do aluguel. Nesse caso, a empresa que aluga os maquinários não precisaria comprar planos de celular para cada rastreador de cada máquina, e sim somente garantir conectividade wi-fi no pátio-base.
Dessa maneira, o rastreador ficaria armazenando continuamente o seu posicionamento (e também horário, obtido via GPS) em memória interna e, chegando ao local com wi-fi, descarregaria estes dados todos de uma só vez via wi-fi no servidor remoto. Isso pode significar uma economia bem relevante, tanto em custo fixo (hardware do rastreador não precisar de modem GPRS e circuitos correlatos) quanto em custo variável (consumo de dados pelo rastreador).

Atualmente, em alguns casos, é possível utilizar rastreador com conectividade wi-fi para rastreamento “em tempo real” (respeitando o tempo entre envio de localizações, conforme descrito no tópico anterior). Isso é possível devido a boa parte dos smartphones vendidos terem função Hotspot ou até mesmo em veículos (carros e ônibus) que possuem roteadores wi-fi.

Outra forma comum de se fazer o envio de dados dos rastreadores é via GPRS (conectividade à Internet via celular). Nesta forma, basta haver cobertura de sinal de uma (ou mais) operadoras para que o rastreador consiga fazer o envio dos dados ao servidor remoto / nuvem. Em virtude da tendência de cada vez mais se ter zonas de coberturas de conectividade à Internet via celular, esta ainda é uma forma muito utilizada para envio dos dados do rastreador. O maior problema desta modalidade de envio reside no preço, afinal planos de dados ainda não custam barato.

Outra vertente que está começando a ganhar força nos meios de rastreamento são as LPWANs (Low-Power Wide Area Network), tais como LoRaWAN e Sigfox. Dessa forma, a cobertura em zona urbana e rural poderia ser garantida e, ainda, com um gasto em energia elétrica muito menor que via GPRS ou wi-fi. Isso viabilizaria rastreadores portáteis alimentados com baterias de baixa carga.
Por enquanto poucas empresas exploram esta maneira de envio de dados de rastreamento, porém acredito ser uma forte tendência num futuro próximo.

Overview do projeto do rastreador veicular com ESP32 e FreeRTOS

O projeto de um rastreador veicular com ESP32 e FreeRTOS feito aqui nesse post utiliza conectividade wi-fi para envio das localizações geográficas e o horário (obtido via GPS) para a nuvem. As localizações são enviadas via MQTT para um broker público, onde podem ser lidas por qualquer cliente MQTT no mundo.

Para garantir um bom funcionamento do rastreador, o software desenvolvido para esse projeto faz uso do FreeRTOS. Há, ao todo, duas tarefas executadas pelo FreeRTOS neste projeto:

  1. task_leitura_gps: tarefa responsável por obter de forma periódica (nesse caso, de dois em dois minutos) do módulo GPS as localizações geográficas e horários (via GPS). As localizações geográficas e horários são armazenados numa fila, com posições (espaços) suficientes para suportar até 8 horas de rastreamento (o suficiente para cobrir um dia inteiro de operação).
    O uso de uma fila para armazenar as posições garante que estas fiquem armazenadas de forma segura e que sejam lidas na exata forma que foram inseridas na fila. A ordem de leitura é algo muito importante se você desejar traçar a rota que o rastreador percorreu, funcionalidade bastante comum em sistemas que utilizam localização GPS.
  2. task_wifi_mqtt: tarefa responsável por se conectar ao wi-fi, se conectar ao broker MQTT, garantir que ambas conexões estejam estabelecidas e por enviar as localizações geográficas salvas na fila (quando há conectividade wi-fi e MQTT presentes).

Dessa forma, a funcionalidades de obtenção de localização geográfica e garantia de conectividade operam em paralelo, o que maximiza a performance do rastreador.

Se você não estiver familiarizado com o FreeRTOS e seu uso com Arduino, recomendo a leitura deste e deste posts aqui do blog para entender mais sobre o assunto.

Bibliotecas necessárias para o rastreador veicular com ESP32 e FreeRTOS

Para o projeto de um rastreador veicular com ESP32 e FreeRTOS, você precisará instalar duas bibliotecas:

  1. TinyGPS++ – Biblioteca para comunicação com módulo GPS da placa.
    Obtenha esta biblioteca no repositório Github oficial dela (https://github.com/mikalhart/TinyGPSPlus) e a instale na Arduino IDE via Sketch > Include Library > Add .zip Library…
  2. AXP20X – Biblioteca para comunicação chip de gerenciamento de energia do módulo, de modo a permitir liberar energia para ligar o módulo GPS da placa.
    Obtenha esta biblioteca no repositório Github oficial dela (https://github.com/lewisxhe/AXP202X_Library) e a instale na Arduino IDE via Sketch > Include Library > Add .zip Library…

Código-fonte do rastreador veicular com ESP32 e FreeRTOS

O código-fonte do projeto pode ser visto abaixo.

Observações importantes:

  1. Leia atentamente os comentários contidos no código-fonte para total compreensão do mesmo.
  2. O tamanho da fila de localizações é automaticamente calculado para suportar 8 horas de localizações gravadas. Esse calculo é feito em função do tempo entre o envio de localizações geográficas (define TEMPO_ENTRE_POSICOES_GPS)
  3. Para mudar o tempo entre o envio de localizações geográficas, altere o valor do define TEMPO_ENTRE_POSICOES_GPS no código-fonte, colocando o tempo entre envios desejado (em segundos).
    Lembre-se que quanto menor o tempo, mais posições a fila terá (ela sempre suportará 8 horas de aquisição de localizações). Portanto, tempos entre envios de localização muito curtos podem resultar na geração de uma fila muito grande e, consequentemente, ocupar muita memória RAM do ESP32. Utilize este parâmetro com cuidado.
  4. Como esse projeto roda em um broker público (broker.hivemq.com), é altamente recomendado alterar o tópico MQTT para algo que seja particular a você. Isso evita que projetos de outras pessoas interfiram seus testes e vice-versa. Para alterar o tópico MQTT, altere o valor da constante topico_publish_mqtt no código-fonte.
/* Projeto: rastreador com placa ESP32 TTGO T Beam
 * Autor: Pedro Bertoleti
 * 
 * Bibliotecas utlizadas:
 * - TinyGPS++: https://github.com/mikalhart/TinyGPSPlus
 * - axp20x: https://github.com/lewisxhe/AXP202X_Library
 */
 
#include <TinyGPS++.h>
#include <axp20x.h>
#include <WiFi.h>
#include <PubSubClient.h>

/* Definições gerais */
/* o módulo GPS da placa está ligado na serial 1 do ESP32 */
#define SERIAL_GPS                  1 
#define BAUDRATE_SERIAL_GPS         9600
#define GPIO_RX_SERIAL_GPS          34
#define GPIO_TX_SERIAL_GPS          12
#define TEMPO_ENTRE_POSICOES_GPS    120 //s
#define TEMPO_UM_DIA_DE_TRABALHO    28800 //s (28800s = 8h)
#define TAMANHO_FILA_POSICOES_GPS   (28800/TEMPO_ENTRE_POSICOES_GPS)
#define TEMPO_LEITURA_SERIAL_GPS    1000  //ms

/* definições de temporização das tarefas */
#define TEMPO_PARA_VERIFICAR_WIFI_MQTT     1000  //ms
#define TICKS_ESPERA_POSICAO_GPS           ( TickType_t )1000
#define TICKS_ESPERA_ENVIO_POSICAO_GPS     ( TickType_t )10000

/* Baudrate da serial usada para debug (serial monitor) */
#define BAUDRATE_SERIAL_DEBUG   115200

/* Filas */
/* Fila para armazenar posições GPS */
QueueHandle_t xQueue_GPS;

/* Semáforos */
SemaphoreHandle_t xSerial_semaphore;

/* Estrutura de dados de posição */
typedef struct
{
   float latitude;
   float longitude;
   int horas;
   int minutos;
   int segundos;
}TPosicao_GPS;

/* Variaveis e constantes - wi-fi */
/* Coloque aqui o nome da rede wi-fi ao qual o ESP32 precisa se conectar */
const char* ssid_wifi = " ";

/* Coloque aqui a senha da rede wi-fi ao qual o ESP32 precisa se conectar */
const char* password_wifi = " ";

WiFiClient espClient;

/* Variaveis e constantes - MQTT */
/* URL do broker MQTT */ 
const char* broker_mqtt = "broker.hivemq.com";
const char* topico_publish_mqtt = "filipeflop_localizacao_gps";

/* Porta para se comunicar com broker MQTT */
int broker_port = 1883;

PubSubClient MQTT(espClient);

/* Demais objetos e variáveis globais */
TinyGPSPlus gps;
HardwareSerial GPS(SERIAL_GPS);
AXP20X_Class axp;

/* Protótipos das funções das tarefas */
void task_leitura_gps( void *pvParameters );
void task_wifi_mqtt( void *pvParameters );

/* Protótipos de funções gerais */
void init_wifi(void);
void conecta_wifi(void);
void verifica_conexao_wifi(void);
void init_MQTT(void);
void conecta_broker_MQTT(void);
void verifica_conexao_mqtt(void);

void setup() 
{
    /* Inicializa serial para debug */
    Serial.begin(BAUDRATE_SERIAL_DEBUG);

    /* Inicializa comunicação I²C com chip gerenciador de energia (AXP192) */
    Wire.begin(21, 22);
    if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) 
        Serial.println("Sucesso ao inicializar comunicação com chip de energia (AXP192)");        
    else 
    {
        Serial.println("Falha ao inicializar comunicação com chip de energia (AXP192). O ESP32 será reiniciado...");
        delay(2000);
        ESP.restart();
    }

    /* Energiza módulo GPS */
    axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
    axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
    axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
    axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
    axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
    axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);

    /* Inicializa serial para comunicar com GPS */ 
    GPS.begin(BAUDRATE_SERIAL_GPS, 
              SERIAL_8N1, 
              GPIO_RX_SERIAL_GPS, 
              GPIO_TX_SERIAL_GPS);

    /* Criação das filas */          
    xQueue_GPS = xQueueCreate(TAMANHO_FILA_POSICOES_GPS, sizeof(TPosicao_GPS));

    if (xQueue_GPS == NULL)
    {
        Serial.println("Falha ao inicializar filas. O programa nao pode prosseguir. O ESP32 sera reiniciado...");
        delay(2000);
        ESP.restart();
    }
    
    /* Criação dos semáforos */         
    xSerial_semaphore = xSemaphoreCreateMutex();

    if (xSerial_semaphore == NULL)
    {
        Serial.println("Falha ao inicializar semaforos. O programa nao pode prosseguir. O ESP32 sera reiniciado...");
        delay(2000);
        ESP.restart();
    }
    
    /* Configuração das tarefas */ 
    xTaskCreate(
    task_leitura_gps                    /* Funcao a qual esta implementado o que a tarefa deve fazer */
    , "leitura_gps"                     /* Nome (para fins de debug, se necessário) */
    ,  4096                             /* Tamanho da stack (em words) reservada para essa tarefa */
    ,  NULL                             /* Parametros passados (nesse caso, não há) */
    ,  6                                /* Prioridade */
    ,  NULL );                          /* Handle da tarefa, opcional (nesse caso, não há) */

    xTaskCreate(
    task_wifi_mqtt             
    , "wifi_mqtt"         
    ,  4096    
    ,  NULL                      
    ,  5
    ,  NULL );   

    /* O FreeRTOS está inicializado */
}

void loop() 
{
    /* todas as funcionalidades são feitas pelas tarefas 
       task_leitura_gps e task_wifi_mqtt */
}

/* 
 *  Funções gerais
 */
 
/* Função: inicializa wi-fi
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void init_wifi(void) 
{
    Serial.println("------WI-FI -----");
    Serial.print("Conectando-se a rede: ");
    Serial.println(ssid_wifi);
    Serial.println("Aguarde...");    
    conecta_wifi();
}

/* Função: conecta-se a rede wi-fi
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void conecta_wifi(void) 
{
    /* Se ja estiver conectado, nada é feito. */
    if (WiFi.status() == WL_CONNECTED)
        return;

    /* refaz a conexão */
    WiFi.begin(ssid_wifi, password_wifi);
    
    while (WiFi.status() != WL_CONNECTED) 
    {        
        vTaskDelay( 100 / portTICK_PERIOD_MS );
        Serial.print(".");
    }
  
    Serial.println();
    Serial.print("Conectado com sucesso a rede wi-fi ");
    Serial.println(ssid_wifi);
    Serial.print("IP: ");
    Serial.println(WiFi.localIP());
}

/* Função: verifica se a conexao wi-fi está ativa 
 *         (e, em caso negativo, refaz a conexao)
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void verifica_conexao_wifi(void)
{
    conecta_wifi(); 
}

/* Função: inicializa MQTT
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void init_MQTT(void)
{
    MQTT.setServer(broker_mqtt, broker_port);  
}

/* Função: conecta-se ao broker MQTT
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void conecta_broker_MQTT(void) 
{
    char mqtt_id_randomico[5] = {0};
    int i;
    
    while (!MQTT.connected()) 
    {
        /* refaz a conexão */
        Serial.print("* Tentando se conectar ao broker MQTT: ");
        Serial.println(broker_mqtt);

        /* gera id mqtt randomico */
        randomSeed(random(9999));
        sprintf(mqtt_id_randomico, "%ld", random(9999));
        
        if (MQTT.connect(mqtt_id_randomico)) 
            Serial.println("Conexao ao broker MQTT feita com sucesso!");
        else 
            Serial.println("Falha ao se conectar ao broker MQTT");
    }
}

/* Função: verifica se a conexao ao broker MQTT está ativa 
 *         (e, em caso negativo, refaz a conexao)
 * Parametros: nenhum
 * Retorno: nenhum 
 */
void verifica_conexao_mqtt(void)
{
    conecta_broker_MQTT(); 
}

/* 
 *  Tarefas
 */

/* Esta task é responsável por: 
 * - Obter a localização (latitude e longitude) do módulo GPS 
 * - Enviar a localização obtida para outras tasks (usando uma fila) 
 */
void task_leitura_gps( void *pvParameters )
{
    TPosicao_GPS posicao_gps;
    unsigned long timestamp_start = 0;
    char str_horario[20] = {0};
     
    while(1)
    {
        /* Espera pelo tempo (definido em TEMPO_ENTRE_POSICOES_GPS) entre posições GPS */
        vTaskDelay( (TEMPO_ENTRE_POSICOES_GPS*1000) / portTICK_PERIOD_MS );

        /* Faz a leitura de todos os dados do GPS (por alguns milissegundos) */
        timestamp_start = millis();
        do
        {
            while (GPS.available())
            gps.encode(GPS.read());
        } while ( (millis() - timestamp_start) < TEMPO_LEITURA_SERIAL_GPS);

        /* Obtem e envia posição / localização para outras tasks usando uma fila*/
        posicao_gps.latitude = gps.location.lat();
        posicao_gps.longitude = gps.location.lng();
        posicao_gps.horas = gps.time.hour();
        posicao_gps.minutos = gps.time.minute();
        posicao_gps.segundos = gps.time.second();
        xQueueSend(xQueue_GPS, ( void * ) &posicao_gps, TICKS_ESPERA_ENVIO_POSICAO_GPS);
        
        xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
        Serial.println("Localizacao GPS obtida:");
        Serial.print("* Latitude: ");
        Serial.println(posicao_gps.latitude);
        Serial.print("* Longitude: ");
        Serial.println(posicao_gps.longitude);
        sprintf(str_horario,"%02d:%02d:%02d", posicao_gps.horas,
                                              posicao_gps.minutos,
                                              posicao_gps.segundos); 
        Serial.print("Horario (GMT 0): ");
        Serial.println(str_horario);
        
        xSemaphoreGive(xSerial_semaphore);
    }
}
 
/* Esta task é responsável por: 
 * - Conectar e reconectar (em caso de perda de conexao) no wi-fi
 * - Conectar e reconectar (em caso de perda de conexao) no broker MQTT
 * - Enviar, quando houver, as posições GPS da fila para a nuvem
 */
void task_wifi_mqtt( void *pvParameters )
{
    TPosicao_GPS posicao_gps_recebida;
    char msg_mqtt[200] = {0};
    
    /* Inicializa wi-fi e faz a conexao */
    xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
    init_wifi();
    xSemaphoreGive(xSerial_semaphore);
   
    /* Inciializa mqtt e faz conexao ao broker */  
    xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
    init_MQTT();
    xSemaphoreGive(xSerial_semaphore);

    while(1)
    {
        /* Verifica tudo novamente após tempo definido em TEMPO_PARA_VERIFICAR_WIFI_MQTT */
        vTaskDelay( TEMPO_PARA_VERIFICAR_WIFI_MQTT / portTICK_PERIOD_MS );
      
        /* verifica se a conexao wi-fi e ao broker MQTT estão ativas 
           (e, em caso negativo, refaz a conexao)
        */
        xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
        verifica_conexao_wifi();
        verifica_conexao_mqtt();
        xSemaphoreGive(xSerial_semaphore);

        /* Se há posições GPS na fila para serem enviadas por MQTT, faz o envio aqui */          
        if( xQueueReceive( xQueue_GPS, &( posicao_gps_recebida ), TICKS_ESPERA_POSICAO_GPS) )
        {     
            sprintf(msg_mqtt,"Latitude: %f  Longitude: %f Horario: %02d:%02d:%02d", posicao_gps_recebida.latitude, 
                                                                                    posicao_gps_recebida.longitude,
                                                                                    posicao_gps_recebida.horas,
                                                                                    posicao_gps_recebida.minutos,
                                                                                    posicao_gps_recebida.segundos);
            MQTT.publish(topico_publish_mqtt, msg_mqtt);
            
            xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
            Serial.println("Localizacao GPS enviada para nuvem");
            xSemaphoreGive(xSerial_semaphore);
        }

        /* keep-alive da comunicação com broker MQTT */
        MQTT.loop();
    }
}

Testando o rastreador veicular com ESP32 e FreeRTOS

Para testar o projeto, siga o procedimento abaixo:

  1. Coloque suas credenciais wi-fi (nome da rede e senha) no código-fonte, nas constantes ssid_wifipassword_wifi.
  2. Compile o projeto e o grave na placa (utilizando como board o ESP32 Dev Module).
  3. Com um cliente MQTT qualquer no seu smartphone ou computador, conecte-se ao broker público broker.hivemq.com na porta 1883 e se subscreva ao tópico MQTT do seu código-fonte (definido na constante topico_publish_mqtt).Segue abaixo algumas sugestões de clientes MQTT:
    – Computador: MQTT Lens
    – Smartphone Android: MyMQTT
  4. Observe no cliente MQTT as mensagens com a localização (latitude e longitude) e horário obtidos via GPS (considerando GMT 0, ou seja, fuso-horário de Greenwich) chegando na temporização configurada no seu código-fonte (no define TEMPO_ENTRE_POSICOES_GPS).

Observações importantes sobre o uso de GPS em projetos:

  • O sinal de GPS tende a ser muito fraco ou “inexistente” (impossível de ser recebido pelo módulo) em locais onde o módulo não tenha visada direta para o céu, tais como: interior de construções (casas, apartamentos, estabelecimentos comerciais, etc.), túneis, embaixo de pontes, metrô, etc. Logo, quando for testar, faça isso em um ambiente externo a sua casa/apartamento com visada direto para o céu ou, de forma alternativa, coloque o placa numa janela de sua casa / apartamento.
  • O módulo GPS não recebe instantaneamente o sinal dos satélites GPS. É preciso de alguns segundos (algumas vezes minutos, dependendo de onde você está) para o módulo GPS conseguir receber os dados dos satélites GPS e disponibilizar a localização via serial para o ESP32. Este tempo é chamado em documentos técnicos de Cold Start.
  • Sempre que possível, mantenha a antena GPS do módulo (antena cerâmica) virada para cima (em direção ao céu). Isso facilita a recepção dos dados dos satélites GPS.
  • Se você for utilizar em seu projeto o horário obtido via GPS, não se esqueça todo horário obtido por GPS é referenciado ao fuso horário GMT 0 (fuso-horário de Greenwich). Cabe a você, projetista / desenvolvedor, saber em que fuso-horário está e somar ou subtrair horas do horário obtido para correção do horário.

Gostou deste post sobre fazer rastreador veicular com ESP32 e FreeRTOS? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

4 Comentários

  1. Olá Pedro, gostaria de dizer que o campo “tempo um dia de trabalho” em define está com valor em segundos incorreto, sendo o certo 2880s. Muito obrigado por disbonibilizar esse tutorial e seu conhecimento!

  2. Parabéns, ótimo projeto

  3. Olá ,Pedro Bertoleti !

    Uma honra poder te escrever. Em promeiro lugar quero te parabenizar pelo domínio das tecnologias IoT. Poucas pessoas tem tanto conhecimento acumulado e disseminam isso internet afora.
    Sobre o projeto de reatreamento veicular, cheguei a comprar o módulo esp32 wifi lora 915Mhz mas veio uma dúvida:
    É um rastreador veicular que depende de wifi ? O veículo precisa estar próximo da rede para poder se comunicar e assim eu ter as informações ? Desculpe se pareço leigo, mas penso que para esse projeto ser completo, o módulo deveria ser capaz de se comunicar com o broker sem depender de rede wifi…tipo através de uma rede 4g estou certo ?
    Imagino que exista sim aplicações para esse projeto especificamente, mas não de modo geral certo ?
    Espero ter sido claro nas minhas dúvidas…e agradeço desde já pela atenção !
    Espero também que não pare de publicar artigos e projetos novos na internet !
    Grade abraço !

    Ricardo Simões Silva
  4. Tens algum projeto de Indoor Location com Mobile, Beacon e Raspberry Pi?