IoT

Monitoramento do Nível de Reservatórios de Água

Eletrogate 27 de março de 2025

Introdução

Este projeto tem como objetivo implementar o Monitoramento do Nível de Reservatórios de Água (Caixa D’Água ou Cisterna), em dois cenários diferentes, através do uso do microcontroladores Heltec ESP32 Lora V3 e o ESP32/NANO usando o sensor ultrassônico AJ-SR04M/JSN-SR04T para determinar o nível da água. O Monitoramento será constituído de estações de coleta (N) e uma estação central para visualização dos dados coletados pelas estações coletoras, comunicando através de uma Rede Lora.


Motivação

No post Rede LoRa Integrada com Web Server apresentamos uma alternativa para estações de coleta de temperatura, umidade, pressão atmosférica e altitude utilizando a Rede Lora. Recentemente, conversando com um colega de universidade, ele me perguntou sobre a possibilidade de estender a funcionalidade da Rede Lora para um problema que ele estava tendo no controle de nível de diversos reservatórios de água existentes na chácara dele, dado que a chácara possui dimensões significativas e sem cobertura de sinal WiFi, principalmente na região dos reservatórios. Estudando melhor o assunto e pesquisando na Internet, percebi que o tema é bastante explorado com diversas alternativas, inclusive com a existência de produtos. Grande parte das soluções apresentadas na Internet se baseiam no uso de fios submersos usando a eletrólise para fechar o contato e acender os LED’s indicadores de nível.

Discutindo esta alternativa como o meu colega, ele imediatamente questionou a solução argumentando que a eletrólise pode liberar metais na água a longo prazo e potencialmente contaminá-la. Quando uma corrente elétrica passa através da água, especialmente se houver íons metálicos presentes, pode ocorrer a oxidação e redução desses íons nos eletrodos, resultando na liberação de metais na água. Isso pode ser um problema em sistemas de medição de nível de água que utilizam fios ou eletrodos submersos, pois a eletrólise contínua pode levar à contaminação da água com metais dissolvidos.

Fazendo uma pesquisa mais profunda sobre o assunto, identificamos que existem materiais que podem minimizar o efeito da eletrólise mantendo o contato direto com a água. Alguns desses materiais incluem:

  1. Aço Inoxidável: É resistente à corrosão e à eletrólise, tornando-se uma boa opção para sensores de nível de água.
  2. Titânio: É altamente resistente à corrosão e à eletrólise, mas pode ser mais caro.
  3. Plásticos Condutores: Alguns plásticos condutores podem ser usados para minimizar a eletrólise, embora possam não ser tão eficazes quanto os metais mencionados acima.
  4. Revestimentos Protetores: Aplicar revestimentos protetores, como revestimentos cerâmicos ou poliméricos, nos eletrodos pode ajudar a reduzir a eletrólise e a liberação de metais na água.

Diante da possibilidade de contaminação, resolvemos abandonar o caminho por eletrólise e partir para uma solução não invasiva utilizando sensores ultrassônicos mais adaptados para o ambiente de muita umidade.

Em síntese, esta foi a motivação para o desenvolvimento deste projeto.


Sobre os Sensores AJ-SR04M, JSN-SR04T e HC-SR04

Os sensores ultrassônicos são amplamente utilizados para medições de distância em aplicações de automação e robótica. Entre os modelos mais comuns estão o HC-SR04, o AJ-SR04M e o JSN-SR04T, cada um com características distintas que influenciam sua aplicação em diferentes ambientes.

HC-SR04: Popular, porém sensível a umidade

O HC-SR04 é o sensor ultrassônico mais conhecido e utilizado devido ao seu custo acessível e facilidade de integração com microcontroladores como o ESP8266 e ESP32. Ele funciona emitindo pulsos ultrassônicos e medindo o tempo de retorno do eco para calcular a distância.

No entanto, o HC-SR04 possui algumas limitações:

  • Sensível à umidade e poeira: Como seus componentes eletrônicos e transdutores ficam expostos, ele não é adequado para ambientes externos, úmidos ou sujeitos a sujeira.
  • Alcance limitado e menor estabilidade: Seu alcance típico é de 2 cm a 4 metros, mas medições podem ser instáveis em superfícies inclinadas ou irregulares.

AJ-SR04M e JSN-SR04T: Alternativas robustas para ambientes externos

Para aplicações externas ou em ambientes úmidos, os sensores AJ-SR04M e JSN-SR04T são alternativas superiores ao HC-SR04, pois possuem proteção contra umidade e componentes encapsulados.

AJ-SR04M: Sensor compactado e resistente

O AJ-SR04M é uma versão aprimorada do HC-SR04, mas com design selado e encapsulamento metálico, tornando-o mais resistente a poeira e umidade. Suas principais características incluem:

  • Alcance de 3 a 5 metros com precisão superior ao HC-SR04.
  • Operação confiável em ambientes externos sem risco de oxidação dos contatos.
  • Baixo consumo de energia, ideal para sistemas alimentados por bateria.
  • Compatível com 3,3V e 5V, facilitando a integração com ESP8266 e ESP32.

JSN-SR04T: Sensor ultrassônico à prova d’água

O JSN-SR04T é um sensor totalmente à prova d’água, projetado especificamente para aplicações em ambientes externos, como medições em reservatórios de água, sistemas de irrigação e aplicações industriais. Diferente do HC-SR04 e do AJ-SR04M, ele possui um transdutor ultrassônico separado da placa controladora, conectado por um cabo.

Principais vantagens do JSN-SR04T:

  • Totalmente impermeável (IP67), podendo ser submerso parcialmente sem danos.
  • Alcance estendido de até 6 metros, superior ao HC-SR04 e ao AJ-SR04M.
  • Menor interferência de ruídos externos, proporcionando medições mais estáveis.
  • Ideal para medições de nível em tanques de água, rios e ambientes expostos à chuva.

Comparação entre os sensores

Característica HC-SR04 AJ-SR04M JSN-SR04T
Alcance 2 – 4m 3 – 5m 3 – 6m
Resistência à água ❌ Não ✅ Parcial ✅ Totalmente impermeável
Proteção contra poeira ❌ Não ✅ Sim ✅ Sim
Tensão de operação 5V 3.3V / 5V 5V
Aplicação recomendada Ambientes internos Ambientes externos moderados Ambientes úmidos e externos severos

Conclusão

Enquanto o HC-SR04 é uma opção barata e funcional para aplicações internas e secas, os modelos AJ-SR04M e JSN-SR04T são mais adequados para ambientes adversos. O AJ-SR04M oferece proteção contra poeira e umidade sem perder a simplicidade do HC-SR04, enquanto o JSN-SR04T é a escolha definitiva para aplicações ao ar livre, sendo totalmente selado contra água e agentes externos.

Se a sua aplicação envolve automação residencial, agrícola ou industrial, escolher o sensor adequado garante maior confiabilidade e durabilidade, evitando falhas prematuras e manutenções constantes.

Figura 1 – Posicionamento do Sensor no Reservatório na tampa da caixa d’água distanciado no mínimo 20cm até o nível cheio do reservatório.


Cenário 1 - Uso do Heltec Lora V3

No post Monitoramento de Temperatura com Heltec ESP32 LoRa você encontrará mais informações sobre o Heltec Lora V3. O interessante que não conseguimos usar as API’s da forma que o post explicou provavelmente porque a biblioteca da Heltec Automation deve ter sofrido alterações já que o artigo é de 2021. Tivemos que usar as API’s de acordo com os exemplos que vieram na versão instalada da biblioteca (figura a seguir). Na Referência 1 você encontra o passo a passo para instalação da biblioteca oficial.

Figura 2 – Versão da Biblioteca Oficial da Heltec Automation e a Placa a selecionar

Materiais Necessários para a Estação Coletora

  1. Placa LoRa Wifi 433MHz SX1276 – ESP32 Display OLED 0.96
  2. Sensor de Distância Ultrassônico JSN-SR04T a Resistente a Água
  3. Módulo Relé 2 Canais 5V com Optoacoplador
  4. Led RGB Difuso 5mm – Catodo Comum
  5. Buzzer Ativo 3v
  6. Protoboard 830 Pontos
  7. WorkPlate 830 Pontos
  8. Kit com 140 Jumpers Rígidos em U para Protoboard

Bibliotecas

#include "LoRaWan_APP.h"                     // Biblioteca para a comunicação via LORA   
#include "HT_SSD1306Wire.h"                  // Biblioteca para tratar o Display
#include <Arduino.h>                         // Biblioteca padão do Arduino
#include <Wire.h>                            // Biblioteca para tratar dispositivos I2C    
#include <ctime>                             // Biblioteca para manipulação de tempo
#include <cmath>                             // Biblioteca para usar ceil()
#include <time.h>                            // Biblioteca para manipulaçãao de tempo
#include <WiFi.h>                            // Biblioteca para a rede wifi
#include <ESPAsyncWebServer.h>               // Biblioteca para Servidor Web Assíncrono
#include <AsyncTCP.h>                        // Biblioteca usada pelo Servidor Assíncrono
#include <ESPmDNS.h>                         // Biblioteca para adicionar aliases no DNS da Rede Local
#include <ArduinoJson.h>                     // Biblioteca para manipulação de estrutiras JSON
#include <SPIFFS.h>                          // Biblioteca que implementa o filesystem  
#include <FS.h>                              // Biblioteca para manipular arquivos no filesystem
#include <HCSR04.h>                          // Biblioteca para tratar o Sensor Aj-SR004M
#include <Ticker.h>                          // Biblioteca para programaçao de eventos
#include <ElegantOTA.h>                      // Biblioteca para atualização via Web
#include <LedRGB.h>                          // Biblioteca para tratar Led RGB
#include <vector>                            // Biblioteca para manipulação de vetores 

Características da Aplicação Coletora

  • A aplicação é do tipo AsyncWebServer rodando no modo AP na porta 80 (sem fio não conectado ao roteador). O acesso ao modo AP e à aplicação são feitos com autenticação (usuário/senha).
  • A parametrização da aplicação é feita através de uma página HTML.
  • A aplicação fará a inclusão de Alias no DNS da Rede Local (mDNS).
  • A aplicação permite uma autoatualização através da biblioteca ElegantOTA que permite fazer a atualização da versão do programa através de uma interface HTML. Isso evita ter que remover a estação do local de coleta para o UPLOAD da nova versão. Normalmente este tipo de equipamento fica em locais de difícil acesso e com isso economiza-se tempo e diminui-se o risco de danos ao equipamento na remoção para atualização na forma tradicional.
  • A estação coletora transmite os dados para uma estação Central responsável por prover a interface HTML numa rede local para a visualização dos dados das diversas estações coletoras. A comunicação é feita usando o módulo LORA nativo do Heltec que opera na frequência de 915 MHz. Observação: Neste post utilizamos a versão 915 MHz do Heltec Lora V3.
  • Os seguintes parâmetros deverão ser informados para a operação:
    • USER => nome do usuário para utilização da aplicação (ex: admin)
    • PASS => senha do usuário
    • PASS AP => para conexão no equipamento como se fosse um roteador.
    • ID => Identificação da Estação Coletora
    • D0 => distância entre em cm entre o sensor e o nível cheio (20 <=D0 <= 800)
    • DF => distância entre em cm entre o sensor e o nível vazio (DF <= 800)
    • VARREDURA => intervalo de tempo entre as transmissões
    • PERCENTUAL=> percentual crítico que, quando abaixo dele, um sinal sonoro será emitido.
    • INTERVALO => intervalo em mseg para o sinal sonoro
    • HABILIAR ALARME => informa se o Alarme deve estar ativado ou desativado
    • REINICIAR APÓS OTA => se deve ocorrer auto inicialização após a atualização de versão, caso contrário o reboot terá que ser manual pressionando-se o botão de reboot do HELTEC.

Os parâmetros são persistidos no FILESYSTEM no formato JSON conforme layout a seguir e o nome do arquivo é definido pela constante:

#define JSON_CONFIG_FILE    “/config.json”   // Arquivo JSON de configuração

{
   "user": "admin",
   "pass": "caixa@2024",
   "passAP": "12345678",
   "id": "Reservatorio#1",
   "d0": 20,
   "df": 32,
   "intervalo": 1000,
   "percentual_alarme": 15,
   "habilita_alarme": false,
   "varredura": 5000,
   "autoRebootOTA": false
}
  • O pacote transmitido é no formado JSON onde ID representa a Identificação da estação transmissora, Percentual representa a taxa de ocupação do reservatório e a temperatura do processador.
{“id”:”Reservatorio#1″,”percentual”:0,”temperatura”:55.9}
  • Um LED RBG é utilizado para mostrar em forma de COR os status do Nível da Água, conforme as condições a seguir::
    • De 0 <= DI < 25% => Vermelho
    • De 25% <= DI < 50% => Laranja
    • De 50% <= DI < 75% => Azul
    • De 75% <= DI <= 100% => Verde
  • Um Buzzer é utilizado para alarmar a cada INTERVALO quando o nível estiver abaixo do PERCENTUAL informado na parametrização mencionada anteriormente e/ou quando a TEMPERATURA do processador estiver elevada (acima de 70 graus).
  • Um DISPLAY OLED é utilizado para mostrar: ID, PERCENTUAL e o ELAPSETIME no formato dd/mm/yyyy hh:mm:ss desde a inicialização. Como a aplicação trabalha no modo AP, ou seja, não conectado à Internet, o relógio interno é sincronizado via BROADCAST com a estação central, que por sua vez trabalha com conexão à Internet e sincroniza com o servidor NTP do Brasil.
  • A atualização de versão também exige autenticação para melhor segurança.
  • Um Relé de 2 canais será utilizado para permitir o acionamento de duas cargas. Através de uma FORM html, a programação do acionamento dos relés pode ser configurada por três formas: eventos temporários, eventos por nível coletado e o controle manual dos relés.
  • Para acessar a aplicação é necessário entrar no ambiente de Conexão WiFi do celular, tablet ou desktop. Em seguida deve-se procurar pelo SSID definido na parametrização como ID. Após encontrar o ID na lista de Redes Disponíveis deve-se clicar no ID para fazer a conexão. O modp AP é autenticado e a senha PASS AP, também fornecida na parametrização, deve ser fornecida para a conexão no modo AP. A senha inicial do modo AP é definida pela constante a seguir em tempo de compilação do aplicativo:

#define DEFAULT_PASS_AP     “12345678”       // Senha default do AP Mode

Depois de conectado, a aplicação é acionada através da URL:

http://192.168.4.1                                => link da aplicação

Um tela de autenticação será mostrada para entrar com o USER/PASS definidos na parametrização.

Figura 3 – Tela com as Redes disponíveis

Figura 4 – Tela com SSID do Modo AP a selecionar

Uma vez conectado no Modo AP identificado com o nome do Reservatório, a tela principal da aplicação pode ser acessada com a http://192.168.4.1

Figura 5 – Tela Principal da Aplicação

Figura 6 – Tela de Configuração – Parte 1

Figura 7 – Tela de Configuração – Parte 2

Incorporamos na aplicação o agendamento de eventos para acionar o relé conforme publicado no post Controle Automático de Relés.

Figura 8 – Tela de Programação Temporal de Relés

Adicionamos o agendamento de eventos  baseados no nível computado a cada varredura.

Figura 9 – Tela de Programação Por Nível de Relés

Separamos o Controle Manual dos Relés numa tela separada.

Figura 10 – Tela de Controle Manual de Relés

A seguir, apresentamos as telas para a atualização de versão do programa utilizando a biblioteca ElegantOTA que permite a atualização pela interface Web sem a necessidade de recolher a estação e levar até um notebook/desktop.

Figura 11 – Tela de Autenticação para Atualização

Figura 12 – Tela para Atualização de Versão

A atualização de versão depende da IMAGEM gerada pelo ambiente de desenvolvimento. O Arduino IDE V2 foi usado para a compilação e geração da imagem:

Figura 13 – Geração de Imagem para Atualização

Após a Compilação/Exportação, uma pasta chamada build é criada no diretório da aplicação:

Figura 14 – Local da Geração da Imagem

Abaixo da estrutura da pasta BUILD, os seguintes arquivos serão encontrados, mas apenas o arquivo enfatizado deve ser fornecido na tela da seleção de arquivo na atualização OTA:

Figura 15 – Arquivos Gerados Pelo Arduino IDE V2

Eventos Temporais

A programação de eventos temporais parte da definição de uma Data Base e Operadores de comparação com a Data do Processamento na varredura da lista. Com isso, é possível definir eventos futuros usando as condições (=, > ou >=). As condições (> e >=) significariam fazer o agendamento a partir da Data Base em diante. O operador = significaria programar somente naquele dia. O operador != significaria fazer o agendamento em qualquer dia diferente da Data Base. Já os operadores (< e <=) serviram para definir agendamentos até a Data Base.

Uma vez satisfeitos os critérios de Data Base, Condição versus Data de Processamento, os outros demais critérios serão considerados: a Hora Inicial e Hora Final no formato hh:mm, qual relé deverá ser acionado pelo agendamento, quais dias da semana deverão ser considerados.

O fator de Repetição pode ser usado para forçar a repetição a cada intervalo de tempo em minutos. Por exemplo: se a Hora Inicial=07:00, a Hora Final=7:10 e Repetir a cada=60 minutos, os agendamentos serão: de 07:00 às 7:10, de 08:00 às 08:10, de 09:00 às 09:10 e assim sucessivamente até completar o dia. Desta forma, evita-se definir múltiplos eventos para cada faixa horária economizando espaço de armazenamento na memória, no FileSystem e o tempo de processamento numa lista muito extensa.

Uma descrição de até 50 caracteres deve ser definida para nomear o Agendamento, por exemplo: “Irrigação Fundo da Casa”, “Ligar Bomba da Piscina”, etc.

Importante: Um ponto de atenção com relação a agendamentos futuros é  a marcação dos Dias da Semana. Se nenhum dia da semana estiver marcado o evento futuro não ocorrerá.

A estrutura de dados para representar cada registro de Agendamento Temporal é feita como a seguir:

//---------------------------------------
// Estrutura para agendamentos temporais
//----------------------------------------

struct Agendamento
{
   String idEvento;                         // Identificador do Evento
   String horaInicial;                      // Hora para começar o evento
   String horaFinal;                        // Hora par aterminar o evento
   int repetirCadaMinutos;                  // Fator de repetição do agendamento
   String descricao;                        // Nome do evento
   int releSelecionado;                     // Qual rele a ser acionado
   std::vector<int> diaSemana;              // Dias da Semana para o eventos
   String dataBase;                         // Data Base do evento para comparação com data processamento
   String condicao;                         // Qual a condição de comparação
   bool habilitado;                         // Se o Evento está habilitado ou não
};

A lista de agendamentos é armazenada em memória através de um <vector> como a seguir:

std::vector<Agendamento> dbAgendaTemporal;   // Vetor para a agenda temporal

A comunicação entre o Heltec e o Navegador (exceto o Internet Explorer) é feita através de WebSocket conforme o fluxo de troca de mensagens a seguir, tanto para agendamentos temporais ou por nível:

Figura 16 – Fluxo de Mensagens via WebSocket

Eventos Por Nível

Os Eventos Por Nível baseiam-se na leitura feita do nível a cada varredura. Se Percentual for menor ou igual ao PercentualMin especificado na parametrização o relé selecionado será ligado. Se o Percentual for maior ou igual ao PercentualMax, também definido na parametrização, o relé selecionado será desligado.

A estrutura de dados para representar cada registro de Agendamento Por Nível é feita como a seguir:

//---------------------------------------
// Estrutura para agendamentos por nível
//---------------------------------------struct AgendamentoNivel

{
   String idEvento;                         // Identificador do Evento
   int percentualMin;                       // Percentual mínimo para ligar o relé
   int percentualMax;                       // Percentual máximo para desligar o relé
   String descricao;                        // Nome do evento
   int releSelecionado;                     // Qual rele a ser acionado
   bool habilitado;                         // Se o Evento está habilitado ou não
};

A lista de agendamentos por nível é armazenada em memória através de um <vector> como a seguir:

std::vector<AgendamentoNivel> dbAgendaNivel; // Vetor para a agenda por nível

No FileSystem, as listas são armazenadas no mesmo arquivo físico FileSystem SPIFFS no formato JSON. No nome do arquivo é definido pela constante a seguir:

#define JSON_AGENDA_FILE    “/agenda.json”   // Aqruivo JSON de Agendamentos

{
   "temporais": [
   {
     "idEvento": "1736455043215",
     "horaInicial": "17:00",
     "horaFinal": "17:15",
     "repetirCadaMinutos": 60,
     "descricao": "Teste1",
     "habilitado": false,
     "releSelecionado": 0,
     "dataBase": "2025-01-09",
     "condicao": ">",
     "diaSemana": [
       1,
       3,
       5
     ]
  },
  {
     "idEvento": "1736455106691",
     "horaInicial": "18:41",
     "horaFinal": "18:42",
     "repetirCadaMinutos": 5,
     "descricao": "Teste2",
     "habilitado": false,
     "releSelecionado": 1,
     "dataBase": "2025-01-14",
     "condicao": ">=",
     "diaSemana": [
       2,
       4,
       6
     ]
  }
  ],
    "niveis": [
    {
      "idEvento": "125478",
      "percentualMin": 15,
      "percentualMax": 99,
      "descricao": "Abastecer Caixa",
      "releSelecionado": 0,
      "habilitado": false
    }
  ]
}

 

Diagrama do circuito

Figura 17 – Diagrama Esquemático do Circuito

Circuito em Bancada

Figura 18 – Protótipo do Circuito em Bancada

Materiais Necessários para a Estação Receptora

  1. Placa LoRa Wifi 433MHz SX1276 – ESP32 Display OLED 0.96
  2. Protoboard 400 Pontos
  3. Base Acrílica para Fixar Protoboard

Bibliotecas

#include <Arduino.h>                         // Biblioteca padão do Arduino
#include "LoRaWan_APP.h"                     // Biblioteca para a comunicação via LORA 
#include "HT_SSD1306Wire.h"                  // Biblioteca para tratar o Display
#include <WiFiManager.h>                     // Biblioteca WiFi Manager 
#include <WiFi.h>                            // Biblioteca para a rede wifi 
#include <AsyncTCP.h>                        // Biblioteca usada pelo Servidor Assíncrono
#include <ESP32Ping.h>                       // Biblioteca Ping
#include <FS.h>                              // Biblioteca para manipular arquivos no filesystem
#include <SPIFFS.h>                          // Biblioteca que implementa o filesystem  .  
#include <ESPAsyncWebServer.h>               // Biblioteca para Servidor Web Assíncrono
#include <ESPmDNS.h>                         // Biblioteca para adionaar aliases no DNS da Rede Local
#include <ArduinoJson.h>                     // Biblioteca para manipulação de estrutiras JSON
#include <Ticker.h>                          // Biblioteca para programaçao de eventos
#include <ElegantOTA.h>                      // Biblioteca para atualização via Web

Características da Aplicação Receptora

  • A aplicação é do tipo AsyncWebServer rodando no modo WiFi na porta 80 disponibilizando uma interface HTML para a visualização dos dados enviados pelas estações coletaras. O HTML conterá um painel para cada estação coletora, de modo que, é possível ter uma visão geral em uma única página Web.
  • A parametrização da aplicação é feita através do WiFiManager também em uma interface Web.
  • A aplicação fará a inclusão de Alias no DNS da Rede Local (mDNS).
  • Assim como na Estação Coletora, a aplicação também permite uma autoatualização através da biblioteca ElegantOTA.
  • A estação receptora receberá os dados das estações coletoras utilizando o módulo LORA nativo do Heltec que opera na frequência de 915 MHz. Importante:  a biblioteca da Heltec nos permitiu extrair o RSSI (força do sinal Lora) ao receber os dados da estação Coletora. O RSSI é um indicador fundamental para sabermos se o alcance está adequado.
  • A aplicação mostra num Display OLED o número de usuários conectados e o timestamp no formato dd/mm/yyyy hh:mm:ss.
  • A aplicação também sincroniza o relógio interno com o horário do servidor NTP oficial do Brasil. Adicionalmente, o horário oficial será enviado quando as estações coletoras enviarem o BROADCAST de solicitação.
  • Os seguintes parâmetros deverão ser informados para a operação:
    • DNSNAME => nome/aliás para inclusão no DNS da rede local
    • NTPSERVER => url do NTP Server do Brasil para sincronismo do relógio interno
    • IntervaloNTP => intervalo de tempo para reatualizar o sincronismo do relógio interno
    • USER => Usuário para a atualização de versão
    • PASS => Senha para a atualização de versão
    • DF => distância entre em cm entre o sensor e o nível vazio (DF <= 800)
    • VARREDURA => intervalo de tempo entre as transmissões
    • AutoRebootOTA => se deve fazer reboot automático após a atualização de versão.

Os parâmetros são persistidos no FILESYSTEM no formato JSON conforme layout a seguir e  o nome do arquivo é definido pela constante:

#define JSON_CONFIG_FILE    “/config.json”   // Arquivo JSON de configuração

{
   "DnsName": "reservatorios",
   "NTPServer": "a.st1.ntp.br",
   "Timezone": "<-03>3",
   "intervaloNTP": "720",
   "usuarioOTA": "admin",
   "senhaOTA": "heltec@reservatorio",
   "autorebootOTA": true,
}

 

Uso do WifiManager

A biblioteca WifiManager foi utilizada pela permitir a definição da rede Wifi a ser utilizada pelo próprio usuário evitando assim que o SSID/Senha fiquem internos no código implicando em recompilação do aplicativo toda vez que a rede fosse mudada ou a senha alterada. Além disso, o WifiManager permite que o usuário defina certos parâmetros da aplicação dando maior flexibilidade e liberdade.

Passo a passo de como utilizar:

  • Na primeira execução do programa, o WifiManager não estará configurado e entrará no AP MODE, onde poderá ser visto na lista de AP’s da Rede WiFi (Erro! Fonte de referência não encontrada.). Opcionalmente, pressionando-se o botão BOOT do ESP32 no Modo Normal, o modo de configuração também será ativado.
  • Deve-se selecionar o ESP32_XXXX (onde XXXX é o serial do ESP32). Veja a Erro! Fonte de referência não encontrada..
  • Uma vez conectado no ESP32, deve-se acessar a URL http://192.168.4.1:8080 para a tela de entrada do WiFiManager (Erro! Fonte de referência não encontrada.).
  • Uma tela aparecerá com os parâmetros a serem definidos antes de pressionar SAVE. Quando os parâmetros estiverem todos definidos e conferidos (inclusive o SSID da Rede WiFi e a senha), deve-se pressionar o botão SAVE mas abaixo na tela. O WiFiManager salvará os parâmetros no SPIFFS e o ESP32 entrará com a aplicação ativa, conectado na Rede WiFi selecionada e poderá ser acessado via a URL http://reservatorios.local , supondo que o DNSNAME definido seja reservatorios (sem acentuação).

 

Utilização da ElegantOTA

A biblioteca ElegantOTA foi utilizada para permitir a atualização do aplicativo pela interface Web sem a necessidade de levar o circuito do ESP32 até a estação de compilação. Isso permite, por exemplo, que o desenvolvedor libere uma nova versão em qualquer lugar do mundo e o próprio usuário instale a nova versão dando maior independência. As telas são similares às apresentadas para a estação Coletora. A seguir está a URL a ser usado para acessar a tela de atualização:

http://reservatorios.local/update

A Aplicação Receptora pode ser acessada através do link abaixo:

http://reservatorios.local

A aplicação mostrará uma página HTML constituída de painéis, um para cada estação coletora. Os painéis serão ajustados na vertical caso haja mais de uma estação coletora.  Na tela apresentada a seguir, está representada apenas uma estação coletora pois no desenvolvimento apenas uma estação foi prevista. As informações apresentadas são:

  • Nome da estação que enviou os dados
  • Percentual de ocupação do Reservatório
  • Temperatura do processador da estação coletora
  • RSSI ou a força do sinal da rede Lora na comunicação com a estação coletora
  • TIMESTAMP da recepção dos dados

Figura 19 – Tela da Estação Receptora

No diagrama do circuito há apenas o microcontrolador Heltec ESP32 Lora V3 sem nenhum outro componente.

Figura 20 – – Diagrama do Circuito

 


Cenário 2 - Uso do ESP32 e NANO

No Cenário 2 utilizaremos o microcontrolador ESP32 como nó central da Rede Lora e também como nó Coletor. Teremos uma segunda estação coletora utilizando o Arduino NANO no modo Deep Sleep com timer. A comunicação Lora utilizará o módulo E32-433T20D conforme explicado no post Rede LoRa Integrada com Web Server – Blog Eletrogate.

Sugerimos a leitura do post mencionado que detalhada a utilização do módulo E32-433T20d.

Materiais Necessários para a Estação Coletora 1

  1. Módulo WiFi ESP32 Bluetooth 30 pinos
  2. Módulo RF Wireless LoRa 433MHz – Longo Alcance
  3. Protoboard 400 Pontos
  4. Sensor de Distância Ultrassônico JSN-SR04T a Resistente a Água
  5. Módulo Relé 1 Canal 3V 10A com Borne KRE para ESP32
  6. Placa de Expansão para ESP32 30 Pinos – com Terminais de Alimentação
  7. Led RGB Difuso 5mm – Catodo Comum
  8. Buzzer Ativo 3v

Bibliotecas

#include <Arduino.h>                         // Biblioteca padão do Arduino
#include <Wire.h>                            // Biblioteca para tratar dispositivos I2C    
#include <ctime>                             // Biblioteca para manipulação de tempo
#include <cmath>                             // Biblioteca para usar ceil()
#include <time.h>                            // Biblioteca para manipulaçãao de tempo
#include <WiFi.h>                            // Biblioteca para a rede wifi
#include <ESPAsyncWebServer.h>               // Biblioteca para Servidor Web Assíncrono
#include <AsyncTCP.h>                        // Biblioteca usada pelo Servidor Assíncrono
#include <ESPmDNS.h>                         // Biblioteca para adicionar aliases no DNS da Rede Local
#include <ArduinoJson.h>                     // Biblioteca para manipulação de estrutiras JSON
#include <SPIFFS.h>                          // Biblioteca que implementa o filesystem  
#include <FS.h>                              // Biblioteca para manipular arquivos no filesystem
#include <HCSR04.h>                          // Biblioteca para tratar o Sensor Aj-SR004M
#include <Ticker.h>                          // Biblioteca para programaçao de eventos
#include <ElegantOTA.h>                      // Biblioteca para atualização via Web
#include <LedRGB.h>                          // Biblioteca para tratar Led RGB
#include <vector>                            // Biblioteca para manipulação de vetores 
#include <HardwareSerial.h>                  // Biblioteca para tratar a Serial

A especificação funcional é a mesma do Heltec Lora V3 explicado anterioremente.

Figura 21 – Estação Coletora com ESP32 + E32-433T20D

 

Figura 22 – Diagrama do Circuito

Implementação com Arduino NANO no Nó Coletor 2 com o Módulo Lora E32-4333t20D

Nesta implementação teremos uma estação coletora mais simples trabalhando no modo DEEP SLEEP MODE para economia de energia. O Módulo acordará a cada 8s usando o TIMER do WatchDog para enviar os dados do reservatório. A tensão de alimentação do E32-433T20D é de 5V (de 2,3V a 5,2V, nunca permanecendo no limite superior por muito tempo pois pode danificar o módulo), mas o nível de comunicação é em 3,3V (de 2,5V a 3,6V). Por isso, usamos um divisor de tensão entre o TX do Arduino NANO com o RXD do módulo usando dois resistores (R330 + R470). No ESP32 não teremos tal preocupação pois a tensão de operação já é 3,3V.

Materiais Necessários para a Estação Coletora 2

  1. Nano V3.0 + Cabo Usb para Arduino
  2. Módulo RF Wireless LoRa 433MHz – Longo Alcance
  3. Protoboard 400 Pontos
  4. Sensor de Distância Ultrassônico JSN-SR04T a Resistente a Água
  5. Led RGB Difuso 5mm – Catodo Comum
  6. Buzzer Ativo 5V

Bibliotecas

#include <avr/sleep.h>             // Biblioteca para o Deep Sleep Mode
#include <avr/wdt.h>               // Biblioteca para WatchDog
#include <SoftwareSerial.h>        // Biblioteca para tratar a Serial
#include <HCSR04.h>                // Biblioteca para tratar o Sensor Aj-SR004M
#include <ArduinoJson.h>           // Biblioteca para manipulação de estrutiras JSON
#include <LedRGB.h>                // Biblioteca para tratar Led RGB

 

Figura 23 – Estação Coletora com Arduino NANO + E32-433T20D

Figura 24 – Diagrama do Circuito

Implementação com ESP32 no Nó Central com o Módulo Lora E32-4333t20D

Materiais Necessários para a Estação Receptora

  1. Módulo WiFi ESP32 Bluetooth 30 pinos
  2. Módulo RF Wireless LoRa 433MHz – Longo Alcance
  3. Protoboard 400 Pontos

Bibliotecas

#include <Arduino.h>                         // Biblioteca padão do Arduino
#include <WiFiManager.h>                     // Biblioteca WiFi Manager 
#include <WiFi.h>                            // Biblioteca para a rede wifi 
#include <AsyncTCP.h>                        // Biblioteca usada pelo Servidor Assíncrono
#include <ESP32Ping.h>                       // Biblioteca Ping
#include <FS.h>                              // Biblioteca para manipular arquivos no filesystem
#include <SPIFFS.h>                          // Biblioteca que implementa o filesystem    
#include <ESPAsyncWebServer.h>               // Biblioteca para Servidor Web Assíncrono
#include <ESPmDNS.h>                         // Biblioteca para adicionar aliases no DNS da Rede Local
#include <ArduinoJson.h>                     // Biblioteca para manipulação de estrutiras JSON
#include <Ticker.h>                          // Biblioteca para programaçao de eventos
#include <ElegantOTA.h>                      // Biblioteca para atualização via Web
#include <HardwareSerial.h>                  // Biblioteca paara a comunicação serial

 

Figura 25 – Estação Receptora com ESP32 + E32-433T20D

Figura 26 – Diagrama do Circuito

Figura 27 – Tela da Estação Receptora ESP32

Importante:

  • Neste cenário não conseguimos determinar o valor do RSSI (força do sinal Lora) ao receber os dados da estação Coletora. Isso se deve ao fato de usarmos o Modo Transparente do módulo E32-433T20D que não disponibiliza o RSSI nesta modalidade.  Por questão de padronização da interface, estamos mostrando o RSSI da Rede WiFi do Receptor e não da Rede Lora. Isso é um ponto negativo pois o valor do RSSI da Rede Lora é importante para sabermos o alcance das estações Coletoras.
  • A informação de Temperatura do Processador no ESP32 mostrou-se pouco confiável, provavelmente a biblioteca suporta a chamada da determinação da temperatura, mas o hardware não deve possuir o sensor adequado.
  • Para o Arduino NANO, o microcontrolador não possuiu o sensor de temperatura do processador.

 


Comparação dos Cenários do Ponto de Vista de Alcance

Um dos fatores mais importantes na escolha do hardware para comunicação LoRa é o alcance efetivo da transmissão, que pode ser influenciado por fatores como potência do transmissor, sensibilidade do receptor, frequência utilizada e obstáculos no ambiente. Para avaliar o desempenho dos dois cenários implementados, realizamos testes práticos de transmissão e recepção em campo aberto, considerando diferentes distâncias e condições de visibilidade.

Cenário 1 – Heltec LoRa V3 como Coletor e Receptor

No primeiro cenário, utilizamos o Heltec LoRa V3 tanto para a coleta quanto para a recepção dos dados. O Heltec V3 integra um módulo LoRa SX1262, que oferece boa sensibilidade e alcance, mas possui algumas limitações devido à potência de transmissão relativamente menor em comparação com soluções externas.

Cenário 2 – ESP32 com Módulo LoRa E32-433T20D

No segundo cenário, adotamos um ESP32 acoplado ao módulo E32-433T20D como coletor e receptor. Esse módulo opera na faixa de 433 MHz e possui uma potência de transmissão significativamente maior, permitindo alcançar distâncias superiores ao Heltec V3 em condições semelhantes.

Resultados dos Testes de Alcance

Realizamos três medições em diferentes condições de visibilidade e obstáculos para comparar o desempenho de ambos os cenários:

  1. Distância de 500m – Obstáculo de Mata
    • O Heltec LoRa V3 não conseguiu estabelecer a comunicação, possivelmente devido à atenuação do sinal causada pela vegetação densa.
    • O E32-433T20D conseguiu transmitir e receber os dados, demonstrando maior capacidade de atravessar obstáculos.
  2. Distância de 707m – Visada Direta sem Obstáculos Significativos
    • Ambos os dispositivos (Heltec LoRa V3 e E32-433T20D) funcionaram corretamente, mantendo a comunicação estável.
    • Isso indica que, dentro desse alcance e sem barreiras físicas, ambos os módulos são viáveis para transmissão.
  3. Distância de 2192m – Visada Direta sem Obstáculos Significativos
    • O Heltec LoRa V3 não conseguiu transmitir com sucesso nessa distância.
    • O E32-433T20D conseguiu estabelecer a comunicação, evidenciando sua superioridade em longas distâncias.

Análise Comparativa

Com base nos testes, podemos observar que:

  • O Heltec LoRa V3 é adequado para cenários onde as distâncias não ultrapassam 700m em campo aberto, mas sua capacidade de atravessar obstáculos é limitada.
  • O E32-433T20D, por operar com maior potência de transmissão e sensibilidade, demonstrou um alcance superior, conseguindo transmitir dados em distâncias superiores a 2 km em visada direta e atravessando obstáculos que impediram a comunicação do Heltec.

Conclusão sobre o Alcance

Se o projeto exigir comunicação em ambientes urbanos, com barreiras como vegetação e construções, o E32-433T20D é claramente a melhor opção. No entanto, em aplicações onde o alcance máximo não é um fator crítico e há visada direta, o Heltec LoRa V3 ainda pode ser uma alternativa viável devido à sua integração simplificada e menor consumo de energia.

Esse comparativo destaca a importância de escolher a solução LoRa mais adequada para cada cenário de aplicação, equilibrando fatores como alcance, consumo energético e facilidade de implementação.

Figura 28 – Medição 1: Heltec não funcionou, mas E32433T20D sim (mata como obstáculo)

Figura 29 – Medição 2:  Ambos funcionaram

Figura 30 – Medição 3: Heltec não funcionou, mas o E32-433T20D sim


Códigos Fonte

Os códigos fonte foram colocados numa pasta ZIP cujo o link para download é:

Monitoramento do Nível de Reservatórios

Figura 31 – Estrutura do ZIP com os Fontes


Conclusão

Neste projeto, desenvolvemos um sistema de monitoramento de nível de reservatórios e controle de relés utilizando diferentes cenários de hardware e comunicação sem fio. Implementamos duas abordagens distintas para atender a diferentes necessidades de coleta e transmissão de dados, para permitir maior flexibilidade.

No Cenário 1, utilizamos a Heltec LoRa V3 tanto como coletor quanto receptor, explorando sua capacidade de comunicação LoRa para transmissão dos dados do sensor de nível de água. Esta abordagem simplificou a arquitetura do sistema ao unificar os papéis de coleta e recepção em um único dispositivo, reduzindo a complexidade da rede. Além disso, a integração com um servidor AsyncWebServer permitiu a visualização dos dados em tempo real via interface web, tornando a solução prática e acessível para monitoramento remoto.

Já no Cenário 2, ampliamos a escalabilidade do projeto ao introduzir um ESP32 como receptor e múltiplos dispositivos de coleta, incluindo um ESP32 e um Arduino Nano operando em Deep Sleep Mode. Essa abordagem foi projetada para cenários onde a eficiência energética é uma prioridade, especialmente para sensores alimentados por baterias. O uso do Arduino Nano em modo de baixo consumo permitiu ter maior autonomia, enquanto o ESP32 coletor permitiu uma comunicação eficiente dos dados capturados. Os dados recebidos pelo ESP32 receptor foram disponibilizados através da interface web viabilizando o acesso remoto das medições.

Além da transmissão, implementamos um mecanismo de alarme baseado no acionamento de um buzzer para alertar o usuário sobre níveis críticos de água.

Ambos os cenários mostraram-se funcionais e adaptáveis a diferentes necessidades. O Cenário 1 é ideal para implementações mais simples e integradas, enquanto o Cenário 2 oferece maior flexibilidade  para aplicações distribuídas.

Com este projeto, buscamos  demonstrar a viabilidade de um sistema de monitoramento de nível de água eficiente, capaz de operar tanto em ambientes com cobertura Wi-Fi quanto em locais remotos utilizando comunicação LoRa. O sistema pode ser facilmente expandido para incluir mais sensores, diferentes protocolos de comunicação e até integração com automação residencial.


Sobre o Autor


Alberto de Almeida Menezes
tinho.menezes@gmail.com

Bacharel em Engenharia de Áudio e Produção Musical pela Berklee College of Music.


Dailton de Oliveira Menezes
dailton.menezes@gmail.com

Bacharel em Ciência da Computação pela Universidade Federal de Minas Gerais.


Eletrogate

27 de março de 2025

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!