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.
Conheça a Metodologia Eletrogate e Lecione um Curso de Robótica nas Escolas da sua Região!