/*
-------------------------------------------------------------------------
Limpeza de placa solar
by: Gabriel luz
empresa: Sun Clear
Vesão: beta 4.0v
*/
//----------------inclusão de biblioteca---------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <EEPROM.h>
//----------------Definições dos pinos-----------------------------------
const int M_ROBO = 13;
const int M_ROBO_REV = 12;
const int M_ESCOV = 14;
const int M_BOMBA = 27;
const int FC_INI = 26;
const int FC_END = 25;
const int BT_UP = 02;
const int BT_DOWN = 05;
const int BT_CONFIR = 04;
const int BT_TROCAR = 16;
const int BRILHO_TELA = 15;
const int BT_EMG = 17;
const int LED_FALHA = 18;
const int LED_FUNCI = 19;
//----------------memória------------------------------------------------
const int S_H_agenda = 50;
const int S_M_agenda = 60;
const int S_intervalo = 64;
const int S_proxima_limpeza = 100;
const int S_proxima_limpeza_M = 90;
const int S_proxima_limpeza_Y = 80;
const int S_tempo_bomba = 120;
const int S_tempo_escova = 110;
const int S_suspencao = 70;
//----------------Inicialização do LCD e RTC-----------------------------
LiquidCrystal_I2C lcd(0x27, 20, 4); // Endereço 0x27 para LCD 16x2
RTC_DS1307 rtc;
//----------------VARIAVEIS GLOBAIS--------------------------------------
//tempo de suspenção da tela
int t_suspencao = 0;
int suspencao = 3000;
//controle do menu
int sel = 0;
int sel_s = 1;
bool menu = false;
int tempo = 0;
bool atualizacao = 0;
bool reset = false;
int status = 0;
bool attmenu = false;
//controle de botões
bool bt_up = false;
bool bt_down = false;
bool bt_confir = false;
bool bt_trocar = false;
int t_bt_up = 0;
int t_bt_down = 0;
int t_bt_confir = 0;
int t_bt_trocar = 0;
//configs
int tempo_bomba = 20;
int tempo_escova = 5;
int H_agenda = 24;
int M_agenda = 0;
int intervalo = 1;
int proxima_limpeza = 1;
int proxima_limpeza_M = 1;
int proxima_limpeza_Y = 2025;
//limite dias
int diasNoMes[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool ehBissexto(int ano) {
return (ano % 4 == 0 && ano % 100 != 0) || (ano % 400 == 0);
}
//-----------------------------------------------------------------------
void setup() {
//declaração de conexões com dispositivos
Serial.begin(115200);
Wire.begin();
lcd.begin(20, 4);
lcd.init();
rtc.begin();
lcd.clear();
lcd.backlight();
EEPROM.begin(256);
//recupera variaveis da memoria
if(EEPROM.readInt(S_H_agenda) >= 0)H_agenda = EEPROM.readInt(S_H_agenda);
if(EEPROM.readInt(S_M_agenda) >= 0)M_agenda = EEPROM.readInt(S_M_agenda);
if(EEPROM.readInt(S_intervalo) > 0)intervalo = EEPROM.readInt(S_intervalo);
if(EEPROM.readInt(S_proxima_limpeza) > 0)proxima_limpeza = EEPROM.readInt(S_proxima_limpeza);
if(EEPROM.readInt(S_proxima_limpeza_M) > 0)proxima_limpeza_M = EEPROM.readInt(S_proxima_limpeza_M);
if(EEPROM.readInt(S_proxima_limpeza_Y) > 0)proxima_limpeza_Y = EEPROM.readInt(S_proxima_limpeza_Y);
if(EEPROM.readInt(S_tempo_bomba) > 0)tempo_bomba = EEPROM.readInt(S_tempo_bomba);
if(EEPROM.readInt(S_tempo_escova) > 0)tempo_escova = EEPROM.readInt(S_tempo_escova);
if(EEPROM.readInt(S_suspencao) > 0)suspencao = EEPROM.readInt(S_suspencao)*100;
Serial.println("--- Valores lidos da EEPROM ---");
Serial.print("H_agenda: "); Serial.println(H_agenda);
Serial.print("M_agenda: "); Serial.println(M_agenda);
Serial.print("intervalo: "); Serial.println(intervalo);
Serial.print("proxima_limpeza (dia): "); Serial.println(proxima_limpeza);
Serial.print("proxima_limpeza (mes): "); Serial.println(proxima_limpeza_M);
Serial.print("proxima_limpeza (ano): "); Serial.println(proxima_limpeza_Y);
Serial.print("tempo_bomba: "); Serial.println(tempo_bomba);
Serial.print("tempo_escova: "); Serial.println(tempo_escova);
Serial.print("suspencao: "); Serial.println(suspencao);
Serial.println("-------------------------------");
//pinos de saida
pinMode(M_ROBO, OUTPUT);
pinMode(M_ROBO_REV, OUTPUT);
pinMode(M_ESCOV, OUTPUT);
pinMode(M_BOMBA, OUTPUT);
pinMode(LED_FALHA, OUTPUT);
pinMode(LED_FUNCI, OUTPUT);
//pinos de entrada
pinMode(FC_INI, INPUT_PULLDOWN);
pinMode(FC_END, INPUT_PULLDOWN);
pinMode(BT_UP, INPUT_PULLDOWN);
pinMode(BT_DOWN, INPUT_PULLDOWN);
pinMode(BT_CONFIR, INPUT_PULLDOWN);
pinMode(BT_TROCAR, INPUT_PULLDOWN);
pinMode(BT_EMG, INPUT_PULLDOWN);
//desliga saidas
digitalWrite(M_ROBO, 1);
digitalWrite(M_ROBO_REV, 1);
digitalWrite(M_ESCOV, 1);
digitalWrite(M_BOMBA, 1);
digitalWrite(LED_FALHA, 0);
digitalWrite(LED_FUNCI, 0);
//escreve logo da empresa
logoEmpresa();
}
//----------------programa principal-------------------------------------
void loop() {
//tela inicial
if(!menu)MenuHome();
//sub rotinas
if(t_suspencao < suspencao && menu){
switch(sel){
case 1: menu_limpeza(); break;//processo de limpeza
case 2: agenda(); break;//tela de configurar agenda
case 3: menu_edit_h(); break;//tela de configurar hora
case 4: config(); break;//tela de configurar tempo de sistema
case 5: menu_reset(); break;//reinicia o esp
case 6: menu_hardreset(); break;//apaga variaveis e reinicia o esp
}
}
//desliga alarme
reset = false;
if(digitalRead(BT_TROCAR))menu = 0;
//suspende tela se não usar
SuspencaoTela();
delay(10);
//led de funcionamento
digitalWrite(LED_FUNCI, 1);
//verifica agenda para iniciar limpeza
if(tempo == 0){
if((H_agenda <= rtc.now().hour()) &&
(M_agenda <= rtc.now().minute()) &&
(proxima_limpeza <= rtc.now().day()) &&
(proxima_limpeza_M <= rtc.now().month()) &&
(proxima_limpeza_Y <= rtc.now().year())){
sel = 0;
menu = 1;
t_suspencao = 0;
SuspencaoTela();
lcd.display();
lcd.backlight();
menu_limpeza();
}
}
}
//apresenta menu inicial
void MenuHome(){
tempo++;
lcd.noBlink();
atualizacao = false;
//escreve as opções de menu bo lcd e no serial
if(sel != sel_s){
sel_s = sel;
Serial.println("--------------------");
if(sel > 0 && sel < 4){
if(sel == 1)EscreveTexto(">Limpeza (ativar)2/3",0,0,1);
if(sel != 1)EscreveTexto(" Limpeza 2/3",0,0,1);
if(sel == 2)EscreveTexto(">Agenda (editar) ",0,1,1);
if(sel != 2)EscreveTexto(" Agenda ",0,1,1);
if(sel == 3)EscreveTexto(">Hora (editar) ",0,2,1);
if(sel != 3)EscreveTexto(" Hora ",0,2,1);
}else if(sel > 3){
if(sel == 4)EscreveTexto(">Config 3/3",0,0,1);
if(sel != 4)EscreveTexto(" Config 3/3",0,0,1);
if(sel == 5)EscreveTexto(">Reiniciar ",0,1,1);
if(sel != 5)EscreveTexto(" Reiniciar ",0,1,1);
if(sel == 6)EscreveTexto(">Reset de Fab. ",0,2,1);
if(sel != 6)EscreveTexto(" Reset de Fab. ",0,2,1);
}else{
EscreveTexto(" ", 0,0,1);
EscreveTexto(" ", 0,1,1);
EscreveTexto(" 1/3", 0,2,1);
}
Serial.println("--------------------");
}
if(sel == 0){
if(status == 0 && !attmenu){
if(H_agenda < 24){
Serial.println("--------------------");
Serial.printf("Próxima limpeza será em: %02d/%02d/%d", proxima_limpeza, proxima_limpeza_M, proxima_limpeza_Y);
Serial.printf(" às: %02d:%02d\n",H_agenda,M_agenda);
EscreveTexto("Proxima limpeza: ", 0,0,0);
EscreveTexto(" / / : ", 0,1,0);
EscreveTexto(" 1/3", 0,2,0);
EscreveNumero2d(proxima_limpeza , 0,1,0);
EscreveNumero2d(proxima_limpeza_M , 3,1,0);
EscreveNumero2d(proxima_limpeza_Y , 6,1,0);
EscreveNumero2d(H_agenda ,12,1,0);
EscreveNumero2d(M_agenda ,15,1,0);
Serial.println("--------------------");
}else{
Serial.println("--------------------");
EscreveTexto("Limpeza nao config. ", 0,0,1);
EscreveTexto(" ", 0,1,0);
EscreveTexto(" 1/3", 0,2,0);
Serial.println("--------------------");
}
attmenu = true;
}
if(status == 10 && attmenu){
Serial.println("--------------------");
Serial.println("limpeza de placa Solar");
Serial.println("SENAI Roberto Simonsen");
attmenu = false;
EscreveTexto(" limpeza de placa ", 0,0,0);
EscreveTexto(" Solar ", 0,1,0);
EscreveTexto("SENAI Roberto Simon.", 0,2,0);
Serial.println("--------------------");
}
}
//escreve a hora e data no lcd
if(tempo == 50){
DateTime now = rtc.now();
EscreveNumero2d(rtc.now().hour() , 0,3,0);
EscreveTexto(":", 2,3,0);
EscreveNumero2d(rtc.now().minute(), 3,3,0);
EscreveTexto(":", 5,3,0);
EscreveNumero2d(rtc.now().second(), 6,3,0);
EscreveNumero2d(rtc.now().day() ,10,3,0);
EscreveTexto("/",12,3,0);
EscreveNumero2d(rtc.now().month() ,13,3,0);
EscreveTexto("/",15,3,0);
EscreveNumero2d(rtc.now().year() ,16,3,0);
tempo = 0;
}
if(tempo == 0)status++;
if(status == 21)status = 0;
//leitura dos botões
LerBotaoEinc(BT_UP , bt_up , sel, 0, 6, false, t_bt_up );
LerBotaoEinc(BT_DOWN, bt_down, sel, 0, 6, true , t_bt_down);
if(digitalRead(BT_CONFIR) && sel > 0)menu = 1;
if(!digitalRead(BT_EMG))digitalWrite(LED_FALHA, 1);else{digitalWrite(LED_FALHA, 0);}
}
//apresenta o menu de editar hora
void menu_edit_h(){
int time = 0;
int select = 0;
bool save = false;
int H = rtc.now().hour(), M = rtc.now().minute(), S = rtc.now().second();
int DAY = rtc.now().day(), MONTH = rtc.now().month(), Y = rtc.now().year();
lcd.clear();
bool att = false;
bool att1 = false;
DateTime now = rtc.now();
Serial.println("--------------------");
EscreveTexto("Hora: ", 0,0,2);
EscreveNumero2d(H, 6,0,2);
EscreveTexto(":" , 8,0,2);
EscreveNumero2d(M, 9,0,2);
EscreveTexto(":" ,11,0,2);
EscreveNumero2d(S, 12,0,1);
EscreveTexto("Data: ", 0,1,2);
EscreveNumero2d(DAY, 6,1,2);
EscreveTexto("/" , 8,1,2);
EscreveNumero2d(MONTH, 9,1,2);
EscreveTexto("/" ,11,1,2);
EscreveNumero2d(Y, 12,1,1);
Serial.println("Digite 6 valores separados por virgulas:");
Serial.println("exemplo: hh,mm,ss,dd,mm,aaaa");
EscreveTexto(" SALVAR",0,3,0);
EscreveTexto("CANCELAR",11,3,0);
Serial.println(" ");
Serial.println("--------------------");
while(menu == 1){
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n'); // Lê a linha completa
if(!digitalRead(BT_EMG))digitalWrite(LED_FALHA, 1);else{digitalWrite(LED_FALHA, 0);}
int commaIndex1 = data.indexOf(',');
int commaIndex2 = data.indexOf(',', commaIndex1 + 1);
int commaIndex3 = data.indexOf(',', commaIndex2 + 1);
int commaIndex4 = data.indexOf(',', commaIndex3 + 1);
int commaIndex5 = data.indexOf(',', commaIndex4 + 1);
if (commaIndex1 != -1 && commaIndex2 != -1 && commaIndex3 != -1 && commaIndex4 != -1 && commaIndex5 != -1) {
String var1 = data.substring(0, commaIndex1);
String var2 = data.substring(commaIndex1 + 1, commaIndex2);
String var3 = data.substring(commaIndex2 + 1, commaIndex3);
String var4 = data.substring(commaIndex3 + 1, commaIndex4);
String var5 = data.substring(commaIndex4 + 1, commaIndex5);
String var6 = data.substring(commaIndex5 + 1);
H = var1.toInt();
M = var2.toInt();
S = var3.toInt();
DAY = var4.toInt();
MONTH = var5.toInt();
Y = var6.toInt();
menu = 0;
save = true;
// Agora você pode usar valor1, valor2, valor3, valor4, valor5 e valor6 como inteiros
} else {
Serial.println("Formato invalido. Digite seis valores inteiros separados por virgulas.");
}
}
time++;
if(time > 49)time = 0;
// tela ----------------------------------------------------------
EscreveNumeroEditar( 6,0,H ,time,select,0);
EscreveNumeroEditar( 9,0,M ,time,select,1);
EscreveNumeroEditar(12,0,S ,time,select,2);
EscreveNumeroEditar( 6,1,DAY ,time,select,3);
EscreveNumeroEditar( 9,1,MONTH,time,select,4);
EscreveNumeroEditar(12,1,Y ,time,select,5);
// botoes -------------------------------------------------------------
switch(select){
case 0: LerBotaoEinc(BT_UP, bt_up, H , 0 , 23 , true, t_bt_up);break;
case 1: LerBotaoEinc(BT_UP, bt_up, M , 0 , 59 , true, t_bt_up);break;
case 2: LerBotaoEinc(BT_UP, bt_up, S , 0 , 59 , true, t_bt_up);break;
case 3: LerBotaoEinc(BT_UP, bt_up, DAY , 1 , diasNoMes[MONTH - 1], true, t_bt_up);break;
case 4: LerBotaoEinc(BT_UP, bt_up, MONTH, 1 , 12 , true, t_bt_up);break;
case 5: LerBotaoEinc(BT_UP, bt_up, Y , 2020, 2100 , true, t_bt_up);break;
}
if(bt_up)time = -1;
switch(select){
case 0: LerBotaoEinc(BT_DOWN, bt_down, H , 0 , 23 , false, t_bt_down);break;
case 1: LerBotaoEinc(BT_DOWN, bt_down, M , 0 , 59 , false, t_bt_down);break;
case 2: LerBotaoEinc(BT_DOWN, bt_down, S , 0 , 59 , false, t_bt_down);break;
case 3: LerBotaoEinc(BT_DOWN, bt_down, DAY , 1 , diasNoMes[MONTH - 1], false, t_bt_down);break;
case 4: LerBotaoEinc(BT_DOWN, bt_down, MONTH, 1 , 12 , false, t_bt_down);break;
case 5: LerBotaoEinc(BT_DOWN, bt_down, Y , 2020, 2100 , false, t_bt_down);break;
}
if(bt_down)time = -1;
if (select == 6){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = true;
}
if(!att){
att = true;
EscreveTexto(">", 0,3,0);
EscreveTexto(" ",10,3,0);
}
}
if (select == 7){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = false;
}
if(!att1){
att1 = true;
EscreveTexto(" ", 0,3,0);
EscreveTexto(">",10,3,0);
}
}
if(att && select < 6){
att = false;
att1 = false;
EscreveTexto(" ",0,3,0);
EscreveTexto(" ",10,3,0);
}
LerBotaoEinc(BT_TROCAR, bt_trocar, select, 0, 7, true, t_bt_trocar);
SuspencaoTela();
delay(10);
}
lcd.clear();
sel_s = 7;
sel = 0;
if(save)rtc.adjust(DateTime(Y, MONTH, DAY, H, M, S)); // Ajuste Manual (Ano, Mês, Dia, Hora, Min, Seg)
}
//apresenta o menu de editar a agenda
void agenda(){
lcd.clear();
int save = true;
bool att = false;
bool att1 = false;
//cria variaveis locais
int time = 0; //time para contagem de tempo
int select = 0; //para seleção do que vai ser editado
EEPROM.writeInt(S_H_agenda, H_agenda);
EEPROM.writeInt(S_M_agenda, M_agenda);
EEPROM.writeInt(S_intervalo, intervalo);
EEPROM.commit(); // Salvar na memória
//desenha a tela
Serial.println("--------------------");
EscreveTexto("Hora:",0,0,2);
EscreveNumero2d(H_agenda,6,0,2);
EscreveTexto(":",8,0,2);
EscreveNumero2d(M_agenda,9,0,1);
EscreveTexto("intervalo em dias:",0,1,2);
EscreveNumero2d(intervalo,9,2,1);
EscreveTexto(" SALVAR",0,3,0);
EscreveTexto("CANCELAR",11,3,0);
Serial.println("Digite tres valores inteiros separados por virgulas:");
Serial.println("exemplo: hh,mm,ii(intervalo)");
Serial.println("--------------------");
//cria um loop interno enquanto estiver editandoo
while(menu == 1){
time++;// conta uma volt
if(time > 49)time = 0; //se a contagem de tempo chegar a 50, ele volta para 0
// tela ----------------------------------------------------------
EscreveNumeroEditar(6,0,H_agenda,time,select,0);
EscreveNumeroEditar(9,0,M_agenda,time,select,1);
EscreveNumeroEditar(9,2,intervalo,time,select,2);
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n'); // Lê a linha completa
int commaIndex1 = data.indexOf(',');
int commaIndex2 = data.indexOf(',', commaIndex1 + 1);
if (commaIndex1 != -1 && commaIndex2 != -1) {
String var1 = data.substring(0, commaIndex1);
String var2 = data.substring(commaIndex1 + 1, commaIndex2);
String var3 = data.substring(commaIndex2 + 1);
H_agenda = var1.toInt(); // Converte para inteiro
M_agenda = var2.toInt(); // Converte para inteiro
intervalo = var3.toInt(); // Converte para inteiro
menu = 0;
save = true;
// Agora você pode usar valor1, valor2 e valor3 como inteiros
// Exemplo: int soma = valor1 + valor2 + valor3;
} else {
Serial.println("Formato invalido. Digite tres valores inteiros separados por virgulas.");
}
}
// botoes -------------------------------------------------------------
switch(select){
case 0: LerBotaoEinc(BT_UP, bt_up, H_agenda , 0 , 23, true, t_bt_up);break;
case 1: LerBotaoEinc(BT_UP, bt_up, M_agenda , 0 , 59, true, t_bt_up);break;
case 2: LerBotaoEinc(BT_UP, bt_up, intervalo, 1 , 99, true, t_bt_up);break;
}
if(bt_up)time = -1;
switch(select){
case 0: LerBotaoEinc(BT_DOWN, bt_down, H_agenda , 0 , 23, false, t_bt_down);break;
case 1: LerBotaoEinc(BT_DOWN, bt_down, M_agenda , 0 , 59, false, t_bt_down);break;
case 2: LerBotaoEinc(BT_DOWN, bt_down, intervalo, 1 , 99, false, t_bt_down);break;
}
if(bt_down)time = -1;
if (select == 3){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = true;
}
if(!att){
att = true;
EscreveTexto(">", 0,3,0);
EscreveTexto(" ",10,3,0);
}
}
if (select == 4){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = false;
}
if(!att1){
att1 = true;
EscreveTexto(" ", 0,3,0);
EscreveTexto(">",10,3,0);
}
}
if(att && select < 3){
att = false;
att1 = false;
EscreveTexto(" ",0,3,0);
EscreveTexto(" ",10,3,0);
}
LerBotaoEinc(BT_TROCAR, bt_trocar, select, 0, 4, true, t_bt_trocar);
SuspencaoTela();
delay(10);
}
lcd.clear();
sel_s = 7;
sel = 0;
if(save){
calcularProximoAlarme(rtc.now().day(), rtc.now().month(), rtc.now().year(), intervalo);
EEPROM.writeInt(S_H_agenda, H_agenda);
EEPROM.writeInt(S_M_agenda, M_agenda);
EEPROM.writeInt(S_intervalo, intervalo);
EEPROM.commit(); // Salvar na memória
Serial.println("Dados COMMITADOS na EEPROM.");
}else{
H_agenda = EEPROM.readInt(S_H_agenda);
M_agenda = EEPROM.readInt(S_M_agenda);
intervalo = EEPROM.readInt(S_intervalo);
}
}
//exibe o menu de configirar tempo de sistema
void config(){
lcd.clear();
int save = true;
bool att = false;
bool att1 = false;
int sus = suspencao/100;
//cria variaveis locais
int time = 0; //time para contagem de tempo
int select = 0; //para seleção do que vai ser editado
int save1 = tempo_bomba;
int save2 = tempo_escova;
int save3 = sus;
//desenha a tela
Serial.println("--------------------");
EscreveTexto("Tempo bomba: s",0,0,1);
EscreveNumero3d(tempo_bomba,16,0,1);
EscreveTexto("Tempo escova: s",0,1,1);
EscreveNumero3d(tempo_escova,16,1,1);
EscreveTexto("Suspencao LCD: s",0,2,1);
EscreveNumero3d(sus,16,2,1);
EscreveTexto(" SALVAR",0,3,0);
EscreveTexto("CANCELAR",11,3,0);
Serial.println("Digite tres valores inteiros separados por virgulas:");
Serial.println("exemplo: nnn,nnn,nnn");
Serial.println("--------------------");
//cria um loop interno enquanto estiver editandoo
while(menu == 1){
time++;// conta uma volt
if(time > 49)time = 0; //se a contagem de tempo chegar a 50, ele volta para 0
if(!digitalRead(BT_EMG))digitalWrite(LED_FALHA, 1);else{digitalWrite(LED_FALHA, 0);}
// tela ----------------------------------------------------------
EscreveNumeroEditar3(16,0,tempo_bomba,time,select,0);
EscreveNumeroEditar3(16,1,tempo_escova,time,select,1);
EscreveNumeroEditar3(16,2,sus,time,select,2);
if (Serial.available() > 0) {
String data = Serial.readStringUntil('\n'); // Lê a linha completa
int commaIndex1 = data.indexOf(',');
int commaIndex2 = data.indexOf(',', commaIndex1 + 1);
if (commaIndex1 != -1 && commaIndex2 != -1) {
String var1 = data.substring(0, commaIndex1);
String var2 = data.substring(commaIndex1 + 1, commaIndex2);
String var3 = data.substring(commaIndex2 + 1);
tempo_bomba = var1.toInt(); // Converte para inteiro
tempo_escova = var2.toInt(); // Converte para inteiro
sus = var3.toInt(); // Converte para inteiro
menu = 0;
save = true;
// Agora você pode usar valor1, valor2 e valor3 como inteiros
// Exemplo: int soma = valor1 + valor2 + valor3;
} else {
Serial.println("Formato invalido. Digite tres valores inteiros separados por virgulas.");
}
}
// botoes -------------------------------------------------------------
switch(select){
case 0: LerBotaoEinc(BT_UP, bt_up, tempo_bomba , 1 , 999, true, t_bt_up);break;
case 1: LerBotaoEinc(BT_UP, bt_up, tempo_escova , 1 , 999, true, t_bt_up);break;
case 2: LerBotaoEinc(BT_UP, bt_up, sus , 5 , 999, true, t_bt_up);break;
}
if(bt_up)time = -1;
switch(select){
case 0: LerBotaoEinc(BT_DOWN, bt_down, tempo_bomba , 1 , 999, false, t_bt_down);break;
case 1: LerBotaoEinc(BT_DOWN, bt_down, tempo_escova , 1 , 999, false, t_bt_down);break;
case 2: LerBotaoEinc(BT_DOWN, bt_down, sus , 5 , 999, false, t_bt_down);break;
}
if(bt_down)time = -1;
if (select == 3){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = true;
}
if(!att){
att = true;
EscreveTexto(">", 0,3,0);
EscreveTexto(" ",10,3,0);
}
}
if (select == 4){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = false;
}
if(!att1){
att1 = true;
EscreveTexto(" ", 0,3,0);
EscreveTexto(">",10,3,0);
}
}
if(att && select < 3){
att = false;
att1 = false;
EscreveTexto(" ",0,3,0);
EscreveTexto(" ",10,3,0);
}
LerBotaoEinc(BT_TROCAR, bt_trocar, select, 0, 4, true, t_bt_trocar);
SuspencaoTela();
delay(10);
}
lcd.clear();
sel_s = 7;
sel = 0;
if(save){
suspencao = sus*100;
EEPROM.writeInt(S_tempo_bomba, tempo_bomba);
EEPROM.writeInt(S_tempo_escova, tempo_escova);
EEPROM.writeInt(S_suspencao, sus);
EEPROM.commit(); // Salvar na memória
Serial.println("Dados COMMITADOS na EEPROM.");
}else{
tempo_bomba = save1;
tempo_escova = save2;
suspencao = save3*100;
}
}
//rotina para desligar o esp
void menu_reset(){
bool save = 0;
int select = 0;
bool att = false;
bool att1 = false;
lcd.clear();
EscreveTexto("Reiniciar?",0,0,0);
EscreveTexto(" Nao Sim ",0,3,0);
delay(300);
while(menu){
if(!digitalRead(BT_EMG))digitalWrite(LED_FALHA, 1);else{digitalWrite(LED_FALHA, 0);}
SuspencaoTela();
delay(10);
if (select == 0){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = false;
}
if(!att){
att = true;
att1 = false;
EscreveTexto(">", 0,3,0);
EscreveTexto(" ", 6,3,0);
}
}
if (select == 1){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = true;
}
if(!att1){
att1 = true;
att = false;
EscreveTexto(" ", 0,3,0);
EscreveTexto(">", 6,3,0);
}
}
LerBotaoEinc(BT_TROCAR, bt_trocar, select, 0, 1, true, t_bt_trocar);
}
lcd.clear();
sel = 0;
if (save){
EscreveTexto("Reiniciando...",0,0,1);
delay(1000);
lcd.clear();
ESP.restart();
}
}
//rotina para desligar o esp e apagar variaveis
void menu_hardreset(){
bool save = 0;
int select = 0;
bool att = false;
bool att1 = false;
lcd.clear();
EscreveTexto("Resetar de fabrica?",0,0,0);
EscreveTexto(" Nao Sim ",0,3,0);
delay(300);
while(menu){
if(!digitalRead(BT_EMG))digitalWrite(LED_FALHA, 1);else{digitalWrite(LED_FALHA, 0);}
SuspencaoTela();
delay(10);
if (select == 0){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = false;
}
if(!att){
att = true;
att1 = false;
EscreveTexto(">", 0,3,0);
EscreveTexto(" ", 6,3,0);
}
}
if (select == 1){
if(digitalRead(BT_CONFIR)){
menu = 0;
save = true;
}
if(!att1){
att1 = true;
att = false;
EscreveTexto(" ", 0,3,0);
EscreveTexto(">", 6,3,0);
}
}
LerBotaoEinc(BT_TROCAR, bt_trocar, select, 0, 1, true, t_bt_trocar);
}
lcd.clear();
sel = 0;
if (save){
EscreveTexto("Resetando...",0,0,1);
EEPROM.writeInt(S_H_agenda, 24);
EEPROM.writeInt(S_M_agenda, 0);
EEPROM.writeInt(S_intervalo, 1);
EEPROM.writeInt(S_proxima_limpeza, 0);
EEPROM.writeInt(S_proxima_limpeza_M, 0);
EEPROM.writeInt(S_proxima_limpeza_Y, 0);
EEPROM.writeInt(S_tempo_bomba, 20);
EEPROM.writeInt(S_tempo_escova, 5);
EEPROM.writeInt(S_suspencao, 30);
EEPROM.writeInt(42, 0);
EEPROM.commit(); // Salvar na memória
delay(1000);
lcd.clear();
ESP.restart();
}
}
//rotina de limpeza
void menu_limpeza(){
lcd.clear();
lcd.display();
EscreveTexto("iniciando ",0,0,2);
EscreveTexto("limpeza...",0,1,1);
int tempo_lim = 0;
int tempo_h = 0;
int tmepo_escova_cont = 0;
int tmepo_bomba_cont = 0;
int tmepo_escova_cont_reg = tempo_escova;
int tmepo_bomba_cont_reg = tempo_bomba;
int tempow = 0;
int refresh = 0;
bool falha;
menu = 0;
digitalWrite(LED_FUNCI, 1);
digitalWrite(M_BOMBA, 0);
EscreveTexto("ligando bomba ",0,2,1);
while(tmepo_bomba_cont < tempo_bomba){
delay(10);
tempow++;
emergencia();
if(reset)return;
if(tempow == 100){
tempow = 0;
tmepo_bomba_cont++;
tmepo_bomba_cont_reg--;
EscreveNumeroEditar3(16,3,tmepo_bomba_cont_reg,0,0,0);
EscreveTexto("s",19,3,0);
digitalWrite(LED_FUNCI, !digitalRead(LED_FUNCI));
}
}
tempow = 0;
digitalWrite(LED_FUNCI, 1);
digitalWrite(M_ESCOV, 0);
EscreveTexto("ligando escovas",0,2,1);
while(tmepo_escova_cont < tempo_escova){
delay(10);
tempow++;
emergencia();
if(reset)return;
if(tempow == 100){
tempow = 0;
tmepo_escova_cont++;
tmepo_escova_cont_reg--;
EscreveNumeroEditar3(16,3,tmepo_escova_cont_reg,0,0,0);
EscreveTexto("s",19,3,0);
digitalWrite(LED_FUNCI, !digitalRead(LED_FUNCI));
}
}
tempow = 0;
lcd.clear();
digitalWrite(LED_FUNCI, 1);
digitalWrite(M_ROBO, 0);
EscreveTexto("executando ",0,0,2);
EscreveTexto("limpeza... ",0,1,1);
EscreveTexto("movendo... ",0,2,1);
while(!digitalRead(FC_END) && tempo_lim <6000){
delay(10);
tempo_lim++;
if(digitalRead(BT_TROCAR)){
lcd.clear();
tempo_lim = 7000;
}
tempow++;
if(tempow == 100){
tempow = 0;
digitalWrite(LED_FUNCI, !digitalRead(LED_FUNCI));
}
emergencia();
if(reset)return;
}
lcd.clear();
if(tempo_lim == 7000)EscreveTexto("cancelado",0,3,1);
EscreveTexto("fim da ",0,0,2);
EscreveTexto("limpeza... ",0,1,1);
digitalWrite(M_BOMBA, 0);
digitalWrite(M_ESCOV, 0);
digitalWrite(M_ROBO, 1);
delay(1000);
lcd.clear();
EscreveTexto("voltando para",0,0,2);
EscreveTexto("posicao inicial",0,1,1);
digitalWrite(M_ROBO_REV, 0);
while(!digitalRead(FC_INI) && tempo_h <6000){
delay(10);
tempo_h++;
tempow++;
if(tempow == 100){
tempow = 0;
digitalWrite(LED_FUNCI, !digitalRead(LED_FUNCI));
}
emergencia();
if(reset)return;
}
menu = 0;
digitalWrite(LED_FUNCI, 1);
digitalWrite(M_ROBO_REV, 1);
digitalWrite(M_BOMBA, 1);
digitalWrite(M_ESCOV, 1);
lcd.clear();
sel_s = 10;
sel = 0;
calcularProximoAlarme(rtc.now().day(), rtc.now().month(), rtc.now().year(), intervalo);
}
//rotina de verificação de EMERGENCIA
void emergencia(){
if(digitalRead(BT_EMG))return;
lcd.clear();
EscreveTexto("!!! FALHA !!!", 0,0,1);
EscreveTexto("EMG Acionado", 0,1,1);
bool test = false;
int times = 0;
digitalWrite(M_ROBO, 0);
digitalWrite(M_ROBO_REV, 0);
digitalWrite(M_ESCOV, 0);
digitalWrite(M_BOMBA, 0);
digitalWrite(LED_FALHA, 1);
digitalWrite(LED_FUNCI, 0);
while(!digitalRead(BT_EMG)){
digitalWrite(M_ROBO, 1);
digitalWrite(M_ROBO_REV, 1);
digitalWrite(M_ESCOV, 1);
digitalWrite(M_BOMBA, 1);
digitalWrite(LED_FALHA, 1);
digitalWrite(LED_FUNCI, 0);
delay(10);
}
lcd.clear();
EscreveTexto("!!! FALHA !!!", 0,0,1);
EscreveTexto("Pressione qualqer ", 0,1,2);
EscreveTexto("botao", 0,2,1);
while(!test){
delay(10);
if(digitalRead(BT_UP ))test = 1;
if(digitalRead(BT_DOWN ))test = 1;
if(digitalRead(BT_CONFIR ))test = 1;
if(digitalRead(BT_TROCAR ))test = 1;
times++;
if(times == 6000)test = 1;
}
digitalWrite(LED_FALHA, 0);
digitalWrite(LED_FUNCI, 1);
lcd.clear();
reset = true;
}
//Calcula qual dia sera a próxima limpeza
void calcularProximoAlarme(int diaAtual, int mesAtual, int anoAtual, int intervaloDias) {
// Ajusta fevereiro se o ano for bissexto
if (ehBissexto(anoAtual)) {
diasNoMes[1] = 29;
} else {
diasNoMes[1] = 28;
}
int novoDia = diaAtual + intervaloDias;
int novoMes = mesAtual;
int novoAno = anoAtual;
// Se o dia ultrapassar o total do mês, passa para o próximo mês
while (novoDia > diasNoMes[novoMes - 1]) {
novoDia -= diasNoMes[novoMes - 1];
novoMes++;
// Se passar de dezembro, muda para janeiro do próximo ano
if (novoMes > 12) {
novoMes = 1;
novoAno++;
}
// Atualiza fevereiro caso o novo ano seja bissexto
if (ehBissexto(novoAno)) {
diasNoMes[1] = 29;
} else {
diasNoMes[1] = 28;
}
}
proxima_limpeza = novoDia;
proxima_limpeza_M = novoMes;
proxima_limpeza_Y = novoAno;
Serial.printf("Próxima limpeza será em: %02d/%02d/%d", novoDia, novoMes, novoAno);
Serial.printf(" às: %02d:%02d\n",H_agenda,M_agenda);
EscreveTexto("Proxima limpeza:",3,0,0);
EscreveTexto(String(proxima_limpeza)+"/"+String(proxima_limpeza_M)+"/"+String(proxima_limpeza_Y),3,1,0);
EscreveTexto("As: "+String(H_agenda)+":"+String(M_agenda),3,2,0);
delay(3000);
EEPROM.writeInt(S_proxima_limpeza, proxima_limpeza);
EEPROM.writeInt(S_proxima_limpeza_M, proxima_limpeza_M);
EEPROM.writeInt(S_proxima_limpeza_Y, proxima_limpeza_Y);
EEPROM.commit(); // Salvar na memória
Serial.println("Dados COMMITADOS na EEPROM.");
}
//função de verificar tela de suspencão
void SuspencaoTela(){
t_suspencao++;
if(digitalRead(BT_UP ))t_suspencao = 0;
if(digitalRead(BT_DOWN ))t_suspencao = 0;
if(digitalRead(BT_CONFIR ))t_suspencao = 0;
if(digitalRead(BT_TROCAR ))t_suspencao = 0;
if(t_suspencao > suspencao){
lcd.noDisplay();
lcd.noBacklight();
t_suspencao = suspencao;
sel = 0;
menu = 0;
}
if(suspencao < 500)suspencao = 3000;
if(t_suspencao == 0){
lcd.display();
lcd.backlight();
}
}
//escreve logo da empresa
void logoEmpresa(){
//----------------caracteres especiais logo da empresa------------------------
byte SIMB1[8] = {B00000,B00000,B00000,B00011,B00010,B00000,B00101,B01101};
byte SIMB2[8] = {B00000,B00100,B01110,B00000,B01110,B11111,B11111,B11111};
byte SIMB3[8] = {B00000,B00000,B00000,B11000,B01000,B00000,B10100,B10110};
byte SIMB4[8] = {B00101,B00000,B00010,B00011,B00000,B00000,B00000,B00000};
byte SIMB5[8] = {B11111,B11111,B01110,B00000,B01110,B00100,B00000,B00000};
byte SIMB6[8] = {B10100,B00000,B01000,B11000,B00000,B00000,B00000,B00000};
//declara caracters especiais
lcd.createChar(1, SIMB1);
lcd.createChar(2, SIMB2);
lcd.createChar(3, SIMB3);
lcd.createChar(4, SIMB4);
lcd.createChar(5, SIMB5);
lcd.createChar(6, SIMB6);
//escreve logo no lcd
lcd.setCursor(8,0);
lcd.write(1);
lcd.write(2);
lcd.write(3);
lcd.setCursor(8,1);
lcd.write(4);
lcd.write(5);
lcd.write(6);
EscreveTexto("SUN CLEAR",5,2,1);
EscreveTexto("R.A.L.P.S.",5,3,1);
analogWrite(BRILHO_TELA, 250);
lcd.display();
delay(2000);
lcd.clear();
}
//função de leitura de botões
void LerBotaoEinc(int bt, bool &bs, int &v, int vMim, int vMax, bool sinal, int &t) {
if (digitalRead(bt) && !bs) {
bs = true;
if (sinal) v++;
else v--;
}
if (!digitalRead(bt) && bs) {
bs = false;
t = 0;
}
if (bs){
t++;
if(t >= 50){
t = 49;
if (sinal) v++;
else v--;
}
}
if (v > vMax) v = vMim;
if (v < vMim) v = vMax;
}
//função escreve texto no lcd
void EscreveTexto(String Tex, int nc, int nl, int serial){
lcd.setCursor(nc,nl);
lcd.print(Tex);
switch(serial){
case 1: Serial.println(Tex); break;
case 2: Serial.print (Tex); break;
default:break;
}
}
//função escreve numero de 2 digitos no lcd
void EscreveNumero2d(int number, int nc, int nl, int serial){
if(number < 10 && number > -10){
lcd.setCursor(nc,nl);
lcd.print("0"+String(number));
switch(serial){
case 1: Serial.println("0"+String(number)); break;
case 2: Serial.print ("0"+String(number)); break;
default:break;
}
}else{
lcd.setCursor(nc,nl);
lcd.print(number);
switch(serial){
case 1: Serial.println(number); break;
case 2: Serial.print (number); break;
default:break;
}
}
}
//função escreve numero de 3 digitos no lcd
void EscreveNumero3d(int number, int nc, int nl, int serial){
if(number < 10 && number > -10){
lcd.setCursor(nc,nl);
lcd.print(" "+String(number));
switch(serial){
case 1: Serial.println("00"+String(number)); break;
case 2: Serial.print ("00"+String(number)); break;
default:break;
}
}else if (number > 9 && number < 100){
lcd.setCursor(nc,nl);
lcd.print(" "+String(number));
switch(serial){
case 1: Serial.println("0"+String(number)); break;
case 2: Serial.print ("0"+String(number)); break;
default:break;
}
}else{
lcd.setCursor(nc,nl);
lcd.print(number);
switch(serial){
case 1: Serial.println(number); break;
case 2: Serial.print (number); break;
default:break;
}
}
}
//função escreve numero de 2 digitos no lcd com piscada
void EscreveNumeroEditar(int NC, int NL, int number,int t,int setsel, int testsel){
// recebe as variaveis quando foi chamado
if(t <= 0){ //se a contagem de tempo for 0 ou menos ele escreve o numero na tela
// nessa parte ve se o numero tem 1 ou dois digitos e formata ele
if(number < 10 && number > -10){ //se tiver um digito
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print("0"); // coloca um 0 para mandar um digito pro lado
lcd.print(number); // escreve o numero na tela
}else{
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(number);// escreve o numero na tela
}
}
// essa parte é para fazer o numero picar na tela
// se a contagem de tempo for maior que 25 e o numero for menor que 100
if(t == 25 && number < 100 && setsel == testsel){
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(" ");// apaga o numero na tela
}
// se a contagem de tempo for maior que 25 e o numero for maior que 100
if(t == 25 && number >= 100 && setsel == testsel){
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(" ");// apaga o numero na tela
}
}
//função escreve numero de 3 digitos no lcd com piscada
void EscreveNumeroEditar3(int NC, int NL, int number,int t,int setsel, int testsel){
// recebe as variaveis quando foi chamado
if(t <= 0){ //se a contagem de tempo for 0 ou menos ele escreve o numero na tela
// nessa parte ve se o numero tem 1 ou dois digitos e formata ele
if(number < 10 && number > -10){ //se tiver um digito
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(" "); // coloca dois 0 para mandar um digito pro lado
lcd.print(number); // escreve o numero na tela
}else if (number > 9 && number < 100){
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(" "); // coloca um 0 para mandar um digito pro lado
lcd.print(number);// escreve o numero na tela
}else{
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(number);// escreve o numero na tela
}
}
// essa parte é para fazer o numero picar na tela
// se a contagem de tempo for maior que 25
if(t == 25 && setsel == testsel){
lcd.setCursor(NC, NL); //numero da linha e coluna escolhida no chamado da funcao
lcd.print(" ");// apaga o numero na tela
}
}