Nos últimos 22 anos, após ser proposto o termo “Internet das Coisas”, tendo como referência a interconexão digital de quaisquer objetos físicos com a internet, podendo esses objetos receber ou enviar informações para a rede. Neste projeto será exposto em detalhes como criar um dispositivo para medir o nível de um reservatório de água com graduação de 20% em 20%, de forma a apresentar os resultados por um Web Server, e também tornar automático o processo de enchimento do reservatório d’água sempre que estiver abaixo de 20% da capacidade máxima.
Esta proposta além de possibilitar diversas aplicações para sistemas hidráulicos contando com o monitoramento de tal processo de forma síncrona, se torna de grande viabilidade pelo preço dos materiais necessários para a construção do projeto, se diferenciando de outros processos existentes no mercado.

Módulo WiFi ESP32 Bluetooth 30 pinos

Esta é a placa de desenvolvimento que será usada no projeto, utilizando a programação mais usual para placas de desenvolvimento: a Arduino IDE. Esta placa foi escolhida pelas atribuições que a torna essencial para o projeto, tais como:
Módulo Relé 1 Canal

Tem a função de receber um sinal digital do sistema para atuar como chave, fazendo com que o microcontrolador ligue ou desligue uma carga de maior potência, ou seja, um dispositivo responsável pelo enchimento do reservatório, como uma bomba hidráulica ou uma válvula solenoide de modo a não permitir que o reservatório fique abaixo de 20% (e esvazie) ou acima de 100% (e transborde).
Este módulo pode realizar o chaveamento de duas formas, sendo normalmente aberto (NA), desta forma quando recebe o sinal ele realiza a conexão para que que funcione o atuador desejado. Também há o normalmente fechado (NF), que é o oposto do funcionamento anterior, quando há sinal ele realiza a interrupção do circuito, fazendo com que o atuador se desligue.
Para este projeto é necessário que haja um relé de atuação por 3,3V, pois o sinal enviado pela placa ESP32 é de 3.3V, ou se já tiver um relé de atuação a 5V é necessário um Conversor de Nível Lógico 3.3V-5V Bidirecional – 4 Canais para converter o sinal do ESP32 para 5V, possibilitando a atuação do módulo de relé de 5V.
Conexão do ESP32 com a Arduino IDE
O primeiro passo para o projeto é a configuração da placa ESP32 na plataforma Arduino IDE. Essa ação só é necessária no primeiro uso do módulo no Arduino IDE, se você ainda não tem sua placa configurada na plataforma, clique aqui para aprender a configurar.
Após a conexão entre o ESP32 e o Arduino IDE, basta copiar e colar o código deste post, configurar o usuário e a senha do seu WiFi conforme explicado ao longo dos comentários no programa.
Após incluir os passos anteriores, deve-se carregar no módulo ESP32 o programa, que quando reiniciar e obtiver sucesso na conexão com a rede WiFi, o usuário deve abrir o navegador de internet da sua preferência, tanto no computador ou no celular e digitar o número do endereço IP configurado no Arduino IDE, para que seja exibido o Web Server, que após a montagem do circuito e o posicionamento dos sensores capacitivos de toque, exibirá na tela a porcentagem de líquido existente no reservatório.
Cabeçalhos utilizados para o funcionamento WiFi e do servidor WEB no ESP32:
#include <WiFi.h> #include <WebServer.h>
Parâmetros de rede com a configuração da rede WIFI e número IP:
const char* WIFISSID = "sua_rede"; const char* senha = "sua_senha"; IPAddress local_IP(192, 168, 1, 50); //Defina o IP de acesso IPAddress gateway(192, 168, 1, 1); //Defina o IP do roteador de internet IPAddress subnet(255, 255, 255, 0); //Defina a máscara de sub-rede IPAddress primaryDNS(192, 168, 1, 1);//opcional - DNS primário IPAddress secondaryDNS(8, 8, 8, 8); //opcional - DNS secundário
As variáveis de controle da programação e GPIOs utilizadas:
const int bomba = 15; const int led = 14; int per = 0; String bombastatus = "Desligada";
A configuração de programa (setup) que roda uma única vez ao inicializar o microcontrolador
void setup() {
Serial.begin(115200);
delay(400);
// ip fixo
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}// fim ip fixo
Serial.println("Conectando a rede: ");
Serial.println(WIFISSID);
WiFi.begin(WIFISSID , senha);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Sucesso ao conectar-se a rede WiFi");
Serial.print("endereço de IP para o web server: ");
Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP servidor está funcionando");
pinMode(bomba , OUTPUT);
pinMode(led , OUTPUT);
}
O programa que roda infinitamente (loop) verificando o nível de líquido para determinar o estado do atuador (ligado ou desligado) e chamada das subrotinas do servidor WEB.
void loop() {
server.handleClient();
if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 && touchRead(T7) <= 60 && touchRead(T8) <= 60) {
per = 100;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 && touchRead(T7) <= 60 ) {
per = 80;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 ) {
per = 60;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 ) {
per = 40;
} else if (touchRead(T4) <= 60) {
per = 20;
} else {
per = 0;
}
if (per <= 20) {
// Aciona o relé e o led indicativo
digitalWrite(bomba, HIGH); // Considerando o acionamento do relé com nível alto
digitalWrite(led, HIGH);
bombastatus = "Ligada";
Serial.println("Bomba ligada");
}
else if (per == 100) {
// Desliga o relé e o led indicativo
digitalWrite(bomba, LOW); // Considerando o desacionamento do relé com nível baixo
digitalWrite(led, LOW);
bombastatus = "Desligada";
Serial.println("Bomba desligada");
}
delay(400);
Serial.println(per);
}
E as subrotinas do servidor WEB responsáveis pelas informações que aparecem na página do navegador
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(per));
}
void handle_NotFound() {
server.send(404, "text/plain", "Pagina não existente");
}
String SendHTML(int per) {
String ptr = "<!DOCTYPE html> <html>\n";
ptr += "<head><meta http-equiv=\"refresh\" content=\"0.5\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr += "<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
ptr += "<title>MEDIDOR NÍVEL E AUTOMATIZADOR DO RESERVATÓRIO</title>\n";
ptr += "<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr += "body{margin-top: 50px;}\n";
ptr += "h1 {margin: 50px auto 30px;}\n";
ptr += ".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr += ".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr += ".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr += ".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr += ".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr += ".data{padding: 10px;}\n";
ptr += "</style>\n";
ptr += "</head>\n";
ptr += "<body>\n";
ptr += "<div id=\"webpage\">\n";
ptr += "<h1>MEDIDOR DE NÍVEL E AUTOMATIZADOR DO RESERVATÓRIO</h1>\n";
ptr += "</div>\n";
ptr += "<div class=\"data\">\n";
ptr += "<div class=\"side-by-side humidity-icon\">\n";
ptr += "<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr += "<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr += "c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr += "</svg>\n";
ptr += "</div>\n";
ptr += "<div class=\"side-by-side humidity-text\">Nivel da agua</div>\n";
ptr += "<div class=\"side-by-side humidity\">";
ptr += (int)per;
ptr += "<span class=\"superscript\">%</span></div>\n";
ptr += "</div>\n";
ptr += "</div>\n";
ptr += "</body>\n";
ptr += "</html>\n";
return ptr;
}
Ao digitar em um navegador web o endereço IP do ESP32, o servidor web abrirá com o nível do líquido medido, como aparece na figura abaixo:

Logo abaixo está o código completo:
/* IFMAKER - Itumbiara
Autores: Henrique Xavier
Josemar Junior
APRESENTAÇÃO
Projeto sensor de nível com controlador automático (para bomba elétríca ou solenoide)
Nesta configuação o relé para acionamento de carga liga quando medir 20% do nível e desliga ao atingir 100%.
Pinos utilizados (conexões com o ESP32):
IO14 - led indidicativo de operação do relé
IO15 - RELÉ de acionamento da bomba d'água
IO13 - Sensor de 20%
IO12 - Sensor de 40%
IO14 - Sensor de 60%
IO27 - Sensor de 80%
IO33 - Sensor de 100%
Obs.: Os sensores podem ser qualquer peça metálica que terá contato com a água.
*/
#include <WiFi.h>
#include <WebServer.h>
//++++++++++++++++++++++++++++++++++++
// Definições WIFI
//++++++++++++++++++++++++++++++++++++
const char* WIFISSID = "sua_rede";
const char* senha = "sua_senha";
// Pinos I/O
const int bomba = 15;
const int led = 14;
// Variaveis
int per = 0;
String bombastatus = "Desligada";
//++++++++++++++++++++++++++++++++++++
// Definições de rede
//++++++++++++++++++++++++++++++++++++
IPAddress local_IP(192, 168, 1, 50); //Defina o IP de acesso
IPAddress gateway(192, 168, 1, 1); //Defina o IP do roteador de internet
IPAddress subnet(255, 255, 255, 0); //Defina a máscara de sub-rede
IPAddress primaryDNS(192, 168, 1, 1);//opcional - DNS primário
IPAddress secondaryDNS(8, 8, 8, 8); //opcional - DNS secundário
WebServer server(80);
void setup() {
Serial.begin(115200);
delay(400);
// ip fixo
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}// fim ip fixo
Serial.println("Conectando a rede: ");
Serial.println(WIFISSID);
WiFi.begin(WIFISSID , senha);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("Sucesso ao conectar-se a rede WiFi");
Serial.print("endereço de IP para o web server: ");
Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP servidor está funcionando");
pinMode(bomba , OUTPUT);
pinMode(led , OUTPUT);
}
void loop() {
server.handleClient();
if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 && touchRead(T7) <= 60 && touchRead(T8) <= 60) {
per = 100;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 && touchRead(T7) <= 60 ) {
per = 80;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 && touchRead(T6) <= 60 ) {
per = 60;
} else if (touchRead(T4) <= 60 && touchRead(T5) <= 60 ) {
per = 40;
} else if (touchRead(T4) <= 60) {
per = 20;
} else {
per = 0;
}
if (per <= 20) {
// Aciona o relé e o led indicativo
digitalWrite(bomba, HIGH); // Considerando o acionamento do relé com nível alto
digitalWrite(led, HIGH);
bombastatus = "Ligada";
Serial.println("Bomba ligada");
}
else if (per == 100) {
// Desliga o relé e o led indicativo
digitalWrite(bomba, LOW); // Considerando o desacionamento do relé com nível baixo
digitalWrite(led, LOW);
bombastatus = "Desligada";
Serial.println("Bomba desligada");
}
delay(400);
Serial.println(per);
}
void handle_OnConnect() {
server.send(200, "text/html", SendHTML(per));
}
void handle_NotFound() {
server.send(404, "text/plain", "Pagina não existente");
}
String SendHTML(int per) {
String ptr = "<!DOCTYPE html> <html>\n";
ptr += "<head><meta http-equiv=\"refresh\" content=\"0.5\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr += "<link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
ptr += "<title>MEDIDOR NÍVEL E AUTOMATIZADOR DO RESERVATÓRIO</title>\n";
ptr += "<style>html { font-family: 'Open Sans', sans-serif; display: block; margin: 0px auto; text-align: center;color: #333333;}\n";
ptr += "body{margin-top: 50px;}\n";
ptr += "h1 {margin: 50px auto 30px;}\n";
ptr += ".side-by-side{display: inline-block;vertical-align: middle;position: relative;}\n";
ptr += ".humidity-icon{background-color: #3498db;width: 30px;height: 30px;border-radius: 50%;line-height: 36px;}\n";
ptr += ".humidity-text{font-weight: 600;padding-left: 15px;font-size: 19px;width: 160px;text-align: left;}\n";
ptr += ".humidity{font-weight: 300;font-size: 60px;color: #3498db;}\n";
ptr += ".superscript{font-size: 17px;font-weight: 600;position: absolute;right: -20px;top: 15px;}\n";
ptr += ".data{padding: 10px;}\n";
ptr += "</style>\n";
ptr += "</head>\n";
ptr += "<body>\n";
ptr += "<div id=\"webpage\">\n";
ptr += "<h1>MEDIDOR DE NÍVEL E AUTOMATIZADOR DO RESERVATÓRIO</h1>\n";
ptr += "</div>\n";
ptr += "<div class=\"data\">\n";
ptr += "<div class=\"side-by-side humidity-icon\">\n";
ptr += "<svg version=\"1.1\" id=\"Layer_2\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\"; width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
ptr += "<path fill=\"#FFFFFF\" d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,2.926,2.133,5.05,1.571,7.057\n";
ptr += "c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
ptr += "</svg>\n";
ptr += "</div>\n";
ptr += "<div class=\"side-by-side humidity-text\">Nivel da agua</div>\n";
ptr += "<div class=\"side-by-side humidity\">";
ptr += (int)per;
ptr += "<span class=\"superscript\">%</span></div>\n";
ptr += "</div>\n";
ptr += "</div>\n";
ptr += "</body>\n";
ptr += "</html>\n";
return ptr;
}
O próximo passo é a montagem do circuito. É importante ressaltar que existem diversas versões do ESP32, sendo o módulo utilizado no projeto o ESP32 WROOM32 DevKit.
Para montar o circuito é necessário posicionar 6 jumpers no interior do reservatório de água, sendo 5 para a ligação dos sensores de toque no ESP32 até o reservatório. Os sensores escolhidos para essa tarefa são os presentes nas GPIO 13, 12, 14, 27 e 33, e o jumper restante servirá como GND do reservatório, contudo podem ser modificadas na programação de acordo com as portas disponíveis apresentadas na tabela abaixo.

Fonte: www.randomnerdtutorials.com
Para realizar o contato entre os jumpers e a parte interna do reservatório onde será feito o acionamento (para ilustração deste projeto), foi necessário a perfuração dos locais onde os jumpers serão inseridos e, após a inserção, foi necessária a vedação com massa epóxi bicomponente (Durepoxi), porém há várias outras formas de obter o acionamento de forma interna. A imagem abaixo mostra como ficou o reservatório.

Após esse passo é necessário posicionar o resistor de 220R saindo da GPIO 25 em série com o ânodo do LED difuso para sinalizar a ativação do atuador, feito essa conexão basta ligar o catodo do LED ao GND. O relé de atuação recebe o sinal pela GPIO 26, ativando assim pela ligação normalmente aberta (NA), o atuador que pode ser tanto a eletroválvula, quanto a bomba.
Como apresentado na programação do sistema, o LED ficará no mesmo estado que o atuador, e assim que o sistema apresentar o percentual do nível de líquido no reservatório inferior a 20%, o relé e o LED são simultaneamente ativados até que o reservatório atinja sua capacidade máxima (100%) e desligue.
O sistema completo ficou da seguinte forma:

Para lhe orientar melhor na montagem, abaixo você conta com a lista de GPIOs utilizadas e suas respectivas conexões:
GPIO25 – LED indicativo de operação do relé;
GPIO15 – RELÉ de acionamento da bomba d’água;
GPIO13 – Sensor de 20%;
GPIO12 – Sensor de 40%;
GPIO14 – Sensor de 60%;
GPIO27 – Sensor de 80%;
GPIO33 – Sensor de 100%.
O resultado final do projeto você pode conferir no vídeo abaixo:
Com este projeto é possível obter êxito em diversas aplicações onde é necessário automatizar ou monitorar o nível de líquidos de um reservatório em tempo real à distância, conectado na mesma rede do ESP32, não sendo necessário conexão com a internet. Esse processo de controle é ideal para sistemas que utilizam bombas hidráulicas, pois aguardam um tempo de esvaziamento antes de religar o sistema.
Para mais materiais como esse, continue acompanhando as postagens semanais do blog e não deixe de visitar nossa loja. Lá você encontra todos os componentes necessários para desenvolver esse e muitos outros projetos!
Um forte abraço e até a próxima!
Fernando K.; ESP32 com Touch Button Capacitivo. Publicado em 2 de fevereiro de 2021. Disponível em https://www.fernandok.com/2018/02/esp32-com-touch-button-capacitivo.html (último acesso em 09/11/2021).
José Gustavo Abreu Murta (Blog Eletrogate); Conhecendo o ESP32 – Usando Arduino IDE (2). Publicado em 9 de novembro de 2018. Disponível em https://blog.eletrogate.com/conhecendo-o-esp32-usando-arduino-ide-2/ (último acesso em 09/11/2021).
Last Minute ENGINEERS. Interface DHT11 DHT22 w/ ESP8266 NodeMCU Using Web Server, disponível em: https://lastminuteengineers.com/esp8266-dht11-dht22-web-server-tutorial/ (último acesso em 07/11/2021).
Miguel Sena (Blog Eletrogate); Como criar um WebServer com Esp32 e utilizá-lo junto ao BMP280. Publicado em 14 de setembro de 2021, disponível em: https://blog.eletrogate.com/como-criar-um-webserver-com-esp32-e-utiliza-lo-junto-ao-bmp280/ (último acesso em 08/11/2021).
Henrique Xavier dos Santos (Aluno Engenharia Elétrica / IFG – Itumbiara)
Josemar Alves dos Santos Junior (Professor da área de Indústria / IFG – Itumbiara)
Conheça a Metodologia Eletrogate e ofereça aulas de robótica em sua escola!
|
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!