/* Sistema de controle de Curva de aquecimento com Esp32 para caldeiras.
Ver. 1.1
Autor: Vladmir C. Cavalcanti.
Data: 20/04/2025. */
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int pinoControl = 13;
const int pinoEntrada = 2; // Botão para iniciar/parar
const int botaoAutMan = 3; // Pino digital conectado ao botão
const int botaoV1 = 7;
const int botaoV2 = 8;
const int botaoV3 = 9;
const int NumVal1 = 4;
const int NumVal2 = 5;
const int NumVal3 = 6;
const int V1 = 10; // Saída do relé 1
const int V2 = 11; // Saída do relé 2
const int V3 = 12; // Saída do relé 3
const int potT = A0; // Potenciômetro para ajustar tempo T1
//const int potT2 = A1; // Potenciômetro para ajustar tempo T2
int estadoBotao = 0; // Para armazenar o estado atual do botão
int ultimoEstadoBotao = LOW; // Estado anterior do botão, iniciado como HIGH
bool estModPart = false;
bool ultimoEstModPart = HIGH;
bool estadoVD1 = false; // Para armazenar o estado atual do botão
bool ultimoEstadoVD1 = HIGH; // Estado anterior do botão, iniciado como HIGH
bool estadoVD2 = false; // Para armazenar o estado atual do botão
bool ultimoEstadoVD2 = HIGH; // Estado anterior do botão, iniciado como HIGH
bool estadoVD3 = false; // Para armazenar o estado atual do botão
bool ultimoEstadoVD3 = HIGH; // Estado anterior do botão, iniciado como HIGH
int Mode = 0;
int Quantval = 0;
int Quantival = 1;
int Quant = 0;
int Quanti = 0;
int contador = 1;
int VD1 = 1;
int VD2 = 1;
int VD3 = 1;
int WL0 = 1;
int WL1 = 1;
int WL2 = 1;
int WL3 = 1;
int WL4 = 1;
int WL5 = 1;
int WL6 = 1;
int WL7 = 1;
int MD = 0;
int ValvNum = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
pinMode(pinoEntrada, INPUT_PULLUP); // botão com resistor pull-up interno
pinMode(botaoAutMan, INPUT_PULLUP); // botão com resistor pull-up interno
pinMode(botaoV1, INPUT_PULLUP); // botão com resistor pull-up interno
pinMode(botaoV2, INPUT_PULLUP); // botão com resistor pull-up interno
pinMode(botaoV3, INPUT_PULLUP); // botão com resistor pull-up interno
pinMode(NumVal1, INPUT_PULLUP);
pinMode(NumVal2, INPUT_PULLUP);
pinMode(NumVal3, INPUT_PULLUP);
pinMode(pinoControl, OUTPUT);
pinMode(V1, OUTPUT);
pinMode(V2, OUTPUT);
pinMode(V3, OUTPUT);
digitalWrite(V1, LOW);
digitalWrite(V2, LOW);
digitalWrite(V3, LOW);
lcd.init();
lcd.backlight();
}
void loop() {
bool leitura1 = digitalRead(botaoV1);
bool leitura2 = digitalRead(botaoV2);
bool leitura3 = digitalRead(botaoV3);
bool Mode = digitalRead(pinoEntrada);
if (digitalRead(NumVal1) == LOW && (digitalRead(NumVal2) == HIGH) && (digitalRead(NumVal3) == HIGH)) { // Se o botão estiver pressionado (HIGH)
Quantval = 1;
Quantival = 1;
Quant = 1;
}else if (digitalRead(NumVal1) == LOW && (digitalRead(NumVal2) == LOW) && (digitalRead(NumVal3) == HIGH)) { // Se o botão não estiver pressionado (LOW)
Quantval = 2;
Quantival = 2;
Quant = 2;
} else if (digitalRead(NumVal1) == LOW && (digitalRead(NumVal2) == LOW) && (digitalRead(NumVal3) == LOW)) { // Se o botão não estiver pressionado (LOW)
Quantval = 3;
Quantival = 3;
Quant = 3;
} else if (digitalRead(NumVal1) == HIGH && (digitalRead(NumVal2) == LOW) && (digitalRead(NumVal3) == HIGH)) { // Se o botão estiver pressionado (HIGH)
Quantval = 1;
Quantival = 4;
Quant = 4;
} else if (digitalRead(NumVal1) == HIGH && (digitalRead(NumVal2) == HIGH) && (digitalRead(NumVal3) == LOW)) { // Se o botão estiver pressionado (HIGH)
Quantval = 1;
Quantival = 5;
Quant = 5;
} else if (digitalRead(NumVal1) == HIGH && (digitalRead(NumVal2) == LOW) && (digitalRead(NumVal3) == LOW)) { // Se o botão estiver pressionado (HIGH)
Quantval = 2;
Quantival = 6;
Quant = 6;
} else if (digitalRead(NumVal1) == LOW && (digitalRead(NumVal2) == HIGH) && (digitalRead(NumVal3) == LOW)) { // Se o botão estiver pressionado (HIGH)
Quantval = 2;
Quantival = 7;
Quant = 7;
} else {
Quantval = 0;
Quant = 0;
}
//Quanti = digitalRead(Quant);
estadoBotao = digitalRead(botaoAutMan);
if (estadoBotao == LOW && ultimoEstadoBotao == HIGH) {
contador++; // Incrementa o contador
}
ultimoEstadoBotao = estadoBotao;
if(contador > 2){
contador = 1;
}
if (contador == 1){
Automatico();
} if(contador == 2){
lcd.setCursor(0, 0);
lcd.print("DESCARGA MANUAL");
Manual();
}
}
int Manual(){
//WL = 0;
bool leitura1 = digitalRead(botaoV1);
bool leitura2 = digitalRead(botaoV2);
bool leitura3 = digitalRead(botaoV3);
bool Mod = digitalRead(pinoEntrada);
switch(Quant){
case 0:
while (WL0){
lcd.setCursor(0, 1);
lcd.print(" ");
WL1 = 1;
WL2 = 1;
WL3 = 1;
WL4 = 1;
WL5 = 1;
WL6 = 1;
WL7 = 1;
WL0 = 0;
}
lcd.setCursor(0, 1);
lcd.print("<<SEM VALVULAS>>");
break;
case 1:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL1){
lcd.setCursor(0, 1);
lcd.print(" ");
WL1 = 0;
}
//WL2 = 1;
//WL3 = 1;
if (leitura1 == LOW && ultimoEstadoVD1 == HIGH) {
VD1++; // Incrementa o contador
estadoVD1 = !estadoVD1;
digitalWrite(V1, estadoVD1);
delay(200); // debounce
}
ultimoEstadoVD1 = leitura1;
if(VD1 > 2){
VD1 = 1;
}
if (VD1 == 1){ // VALVULAS ABERTAS
lcd.setCursor(0,1);
lcd.print(" ");
}
if(VD1 == 2){
lcd.setCursor(0, 1);
lcd.print("V1,");
}
break;
case 2:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL2){
lcd.setCursor(0, 1);
lcd.print(" ");
WL2 = 0;
}
//WL1 = 1;
//WL3 = 3;
if (leitura1 == LOW && ultimoEstadoVD1 == HIGH) {
VD1++; // Incrementa o contador
estadoVD1 = !estadoVD1;
digitalWrite(V1, estadoVD1);
delay(200); // debounce
}
ultimoEstadoVD1 = leitura1;
if(VD1 > 2){
VD1 = 1;
}
if (VD1 == 1){ // VALVULAS ABERTAS
lcd.setCursor(0,1);
lcd.print(" ");
}
if(VD1 == 2){
lcd.setCursor(0, 1);
lcd.print("V1,");
}
if (leitura2 == LOW && ultimoEstadoVD2 == HIGH) {
VD2++; // Incrementa o contador
estadoVD2 = !estadoVD2;
digitalWrite(V2, estadoVD2);
delay(200); // debounce
}
ultimoEstadoVD2 = leitura2;
if(VD2 > 2){
VD2 = 1;
lcd.setCursor(4, 1);
lcd.print(" ");
}
if(VD2 == 2){
lcd.setCursor(4, 1);
lcd.print("V2,");
}
break;
case 3:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL3){
lcd.setCursor(0, 1);
lcd.print(" ");
WL3 = 0;
}
//WL2 = 1;
//WL1 = 1;
if (leitura1 == LOW && ultimoEstadoVD1 == HIGH) {
VD1++; // Incrementa o contador
estadoVD1 = !estadoVD1;
digitalWrite(V1, estadoVD1);
delay(200); // debounce
}
ultimoEstadoVD1 = leitura1;
if(VD1 > 2){
VD1 = 1;
}
if (VD1 == 1){ // VALVULAS ABERTAS
lcd.setCursor(0,1);
lcd.print(" ");
}
if(VD1 == 2){
lcd.setCursor(0, 1);
lcd.print("V1,");
}
if (leitura2 == LOW && ultimoEstadoVD2 == HIGH) {
VD2++; // Incrementa o contador
estadoVD2 = !estadoVD2;
digitalWrite(V2, estadoVD2);
delay(200); // debounce
}
ultimoEstadoVD2 = leitura2;
if(VD2 > 2){
VD2 = 1;
lcd.setCursor(4, 1);
lcd.print(" ");
}
if(VD2 == 2){
lcd.setCursor(4, 1);
lcd.print("V2,");
}
if (leitura3 == LOW && ultimoEstadoVD3 == HIGH) {
VD3++; // Incrementa o contador
estadoVD3 = !estadoVD3;
digitalWrite(V3, estadoVD3);
delay(200); // debounce
}
ultimoEstadoVD3 = leitura3;
if(VD3 > 2){
VD3 = 1;
lcd.setCursor(8, 1);
lcd.print(" ");
}
if(VD3 == 2){
lcd.setCursor(8, 1);
lcd.print("V3");
}
break;
case 4:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL4){
lcd.setCursor(0, 1);
lcd.print(" ");
WL4 = 0;
}
if (leitura2 == LOW && ultimoEstadoVD2 == HIGH) {
VD2++; // Incrementa o contador
estadoVD2 = !estadoVD2;
digitalWrite(V2, estadoVD2);
delay(200); // debounce
}
ultimoEstadoVD2 = leitura2;
if(VD2 > 2){
VD2 = 1;
lcd.setCursor(4, 1);
lcd.print(" ");
}
if(VD2 == 2){
lcd.setCursor(4, 1);
lcd.print("V2,");
}
break;
case 5:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL5){
lcd.setCursor(0, 1);
lcd.print(" ");
WL5 = 0;
}
if (leitura3 == LOW && ultimoEstadoVD3 == HIGH) {
VD3++; // Incrementa o contador
estadoVD3 = !estadoVD3;
digitalWrite(V3, estadoVD3);
delay(200); // debounce
}
ultimoEstadoVD3 = leitura3;
if(VD3 > 2){
VD3 = 1;
lcd.setCursor(8, 1);
lcd.print(" ");
}
if(VD3 == 2){
lcd.setCursor(8, 1);
lcd.print("V3,");
}
break;
case 6:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL6){
lcd.setCursor(0, 1);
lcd.print(" ");
WL6 = 0;
}
if (leitura2 == LOW && ultimoEstadoVD2 == HIGH) {
VD2++; // Incrementa o contador
estadoVD2 = !estadoVD2;
digitalWrite(V2, estadoVD2);
delay(200); // debounce
}
ultimoEstadoVD2 = leitura2;
if(VD2 > 2){
VD2 = 1;
}
if (VD2 == 1){
lcd.setCursor(4, 1);
lcd.print(" ");
}
if(VD2 == 2){
lcd.setCursor(4, 1);
lcd.print("V2,");
}
if (leitura3 == LOW && ultimoEstadoVD3 == HIGH) {
VD3++; // Incrementa o contador
estadoVD3 = !estadoVD3;
digitalWrite(V3, estadoVD3);
delay(200); // debounce
}
ultimoEstadoVD3 = leitura3;
if(VD3 > 2){
VD3 = 1;
lcd.setCursor(8, 1);
lcd.print(" ");
}
if(VD3 == 2){
lcd.setCursor(8, 1);
lcd.print("V3,");
}
break;
case 7:
WL0 = 1;
lcd.setCursor(14,1);
lcd.print("ON");
while (WL7){
lcd.setCursor(0, 1);
lcd.print(" ");
WL7 = 0;
}
if (leitura1 == LOW && ultimoEstadoVD1 == HIGH) {
VD1++; // Incrementa o contador
estadoVD1 = !estadoVD1;
digitalWrite(V1, estadoVD1);
delay(200); // debounce
}
ultimoEstadoVD1 = leitura1;
if(VD1 > 2){
VD1 = 1;
}
if (VD1 == 1){ // VALVULAS ABERTAS
lcd.setCursor(0,1);
lcd.print(" ");
}
if(VD1 == 2){
lcd.setCursor(0, 1);
lcd.print("V1,");
}
if (leitura3 == LOW && ultimoEstadoVD3 == HIGH) {
VD3++; // Incrementa o contador
estadoVD3 = !estadoVD3;
digitalWrite(V3, estadoVD3);
delay(200); // debounce
}
ultimoEstadoVD3 = leitura3;
if(VD3 > 2){
VD3 = 1;
lcd.setCursor(8, 1);
lcd.print(" ");
}
if(VD3 == 2){
lcd.setCursor(8, 1);
lcd.print("V3,");
}
break;
}
}
int Automatico(){
WL1 = 1;
WL2 = 1;
WL3 = 1;
WL4 = 1;
WL5 = 1;
WL6 = 1;
WL7 = 1;
//if (Quant > 0){
int T = map(analogRead(potT), 0, 1023, 0, 180) * 60; // 0 a 180 min
//int T2 = map(analogRead(potT2), 0, 1023, 0, 180) * 60;
lcd.setCursor(0, 0);
lcd.print("VALVULA(s): ");
lcd.print(Quantval);
//lcd.print(" min ");
lcd.setCursor(0, 1);
lcd.print("T: ");
lcd.print(T / 60);
lcd.print(" min ");
if (Quant <= 0){
digitalWrite(V1, LOW);
digitalWrite(V2, LOW);
digitalWrite(V3, LOW);
}else if(Quant > 0){
if (digitalRead(pinoEntrada) == LOW) { // botão pressionado
switch (Quantival){
//lcd.clear();
case 1:
if (!aguardarTempo(T, "TEMPO PARA V1 ON")) return;
digitalWrite(V1, HIGH);
delay(5000);
digitalWrite(V1, LOW);
break;
case 2:
if (!aguardarTempo(T, "TEMPO PARA V1 ON")) return;
digitalWrite(V1, HIGH);
delay(5000);
digitalWrite(V1, LOW);
if (!aguardarTempo(T, "TEMPO PARA V2 ON")) return;
digitalWrite(V2, HIGH);
delay(5000);
digitalWrite(V2, LOW);
break;
case 3:
if (!aguardarTempo(T, "TEMPO PARA V1 ON")) return;
digitalWrite(V1, HIGH);
delay(5000);
digitalWrite(V1, LOW);
if (!aguardarTempo(T, "TEMPO PARA V2 ON")) return;
digitalWrite(V2, HIGH);
delay(5000);
digitalWrite(V2, LOW);
if (!aguardarTempo(T, "TEMPO PARA V3 ON")) return;
digitalWrite(V3, HIGH);
delay(5000);
digitalWrite(V3, LOW);
break;
case 4:
if (!aguardarTempo(T, "TEMPO PARA V2 ON")) return;
digitalWrite(V2, HIGH);
delay(5000);
digitalWrite(V2, LOW);
break;
case 5:
if (!aguardarTempo(T, "TEMPO PARA V3 ON")) return;
digitalWrite(V3, HIGH);
delay(5000);
digitalWrite(V3, LOW);
break;
case 6:
if (!aguardarTempo(T, "TEMPO PARA V2 ON")) return;
digitalWrite(V2, HIGH);
delay(5000);
digitalWrite(V2, LOW);
if (!aguardarTempo(T, "TEMPO PARA V3 ON")) return;
digitalWrite(V3, HIGH);
delay(5000);
digitalWrite(V3, LOW);
break;
case 7:
if (!aguardarTempo(T, "TEMPO PARA V1 ON")) return;
digitalWrite(V1, HIGH);
delay(5000);
digitalWrite(V1, LOW);
if (!aguardarTempo(T, "TEMPO PARA V3 ON")) return;
digitalWrite(V3, HIGH);
delay(5000);
digitalWrite(V3, LOW);
break;
}
}
}
}
bool aguardarTempo(int segundos, String mensagem) {
for (int i = segundos; i > 0; i--) {
/*
estModPart = digitalRead(pinoEntrada);
if (estModPart == LOW && ultimoEstadoBotao == HIGH) {
MD++; // Incrementa o contador
}
ultimoEstadoBotao = estModPart;
if(MD > 2){
MD = 1;
}
if (MD == 1){
digitalWrite(pinoControl, HIGH);
} if(MD == 2){
digitalWrite(pinoControl, LOW);
if (Mode == HIGH && ultimoEstModPart == LOW) {
MD++; // Incrementa o contador
estModPart = !estModPart;
//digitalWrite(Mode, pinoControl);
delay(200); // debounce
}
ultimoEstModPart = Mode;
if(Mode > 2){
MD = 1 ;
}
if (Mode = 1){
digitalWrite(pinoControl, HIGH);
}*/
if (digitalRead(pinoEntrada) == HIGH) { // botão solto para cancelar
//lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" MODO DE ");
//delay(600);
lcd.setCursor(0, 1);
lcd.print(" CONFIGURACAO ");
delay(1000);
return false;
}
//lcd.clear();
lcd.setCursor(0, 0);
lcd.print(mensagem);
lcd.setCursor(0, 1);
lcd.print("Tempo: ");
lcd.print(i / 60);
lcd.print("m ");
lcd.print(i % 60);
lcd.print("s ");
delay(1000);
}
return true;
}