//----------------inclusão de biblioteca---------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
#include <EEPROM.h>
//----------------Definições dos pinos-----------------------------------
const int M_ROBO = 13; // Motor de movimento do robô
const int M_ESCOV = 12; // Motor das escovas
const int M_BOMBA = 26; // Motor da bomba
const int FC_INI = 14; // Fim de curso do robô do lado inicial
const int FC_END = 27; // Fim de curso do robô do lado final
const int BT_A = 5; // Botão 1 (Esquerda)
const int BT_B = 16; // Botão 2 (Direita)
const int BT_C = 17; // Botão 3 (sel)
const int BT_D = 4; // Botão 4 (Voltar)
const int SD_MISO = 19;
const int SD_MOSI = 23;
const int SD_SCK = 18;
const int SD_CS = 25;
const int mem1 = 0;
const int mem2 = 1;
const int mem3 = 2;
//----------------Inicialização do LCD e RTC-----------------------------
LiquidCrystal_I2C lcd(0x27, 20, 4); // Endereço 0x27 para LCD 16x2
RTC_DS3231 rtc;
File myFile;
//----------------variaveis globais--------------------------------------
int H_agenda = 0; //usado para salvar a agenda definida pelo usuario
int M_agenda = 0; //usado para salvar a agenda definida pelo usuario
int S_agenda = 0; //usado para salvar a agenda definida pelo usuario
int intervalo = 1; //usado para salvar a agenda definida pelo usuario
bool menu = 0; //define quando algum menu foi acessado
int sel_s = 1; //esse valor e usado quando a variavel "sel" é alterado
int sel = 0; //diz ao código qual menu está selecionado
int m_s = 1; //sse valor e usado quando a variavel "menu" é alterado
int time_home = 0; //variavel usada para contar voltas loop para registrar tempo
int result; //variavel usada para dar resultado atravez de uma função(void)
int result_t ; //variavel usada para dar resultado atravez de uma função(void) e usado para registro de tempo
bool bt_s1 = 0; //usado para travar botao no seu estado
bool bt_s2 = 0; //usado para travar botao no seu estado
bool bt_s3 = 0; //usado para travar botao no seu estado
bool bt_s4 = 0; //usado para travar botao no seu estado
bool result_b; //usado para dar resultado atravez de uma função(void)
//----------------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 SIMB5[8] = {B00101,B00000,B00010,B00011,B00000,B00000,B00000,B00000};
byte SIMB6[8] = {B11111,B11111,B01110,B00000,B01110,B00100,B00000,B00000};
byte SIMB7[8] = {B10100,B00000,B01000,B11000,B00000,B00000,B00000,B00000};
//----------------------------------------------------------------------------------------------------------
void setup() {
// Inicializar comunicação
Serial.begin(115200);
Wire.begin();
lcd.begin(20, 4);
rtc.begin();
lcd.clear();
// Configuração de pinos
pinMode(M_ROBO, OUTPUT);
pinMode(M_ESCOV, OUTPUT);
pinMode(M_BOMBA, OUTPUT);
pinMode(FC_INI, INPUT);
pinMode(FC_END, INPUT);
pinMode(BT_A, INPUT);
pinMode(BT_B, INPUT);
pinMode(BT_C, INPUT);
pinMode(BT_D, INPUT);
//declara caracters especiais
lcd.createChar(6, SIMB3);
lcd.createChar(7, SIMB5);
lcd.createChar(8, SIMB6);
lcd.createChar(9, SIMB7);
lcd.createChar(4, SIMB1);
lcd.createChar(5, SIMB2);
//escreve logo da empresa
lcd.setCursor(8,0);
lcd.write(4);
lcd.write(5);
lcd.write(6);
lcd.setCursor(8,1);
lcd.write(7);
lcd.write(8);
lcd.write(9);
writeTexto("SUN CLEAR",5,2);
// verifica cartao SD
SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
if (!SD.begin(SD_CS)) {
Serial.println("Falha ao inicializar o cartão SD");
writeTexto("Falha no cartao SD",0,3);
delay(3000);
menu = 1;
sel = 3;
}
delay(3000); // Espera para mostrar mensagem inicial
recuperarVariaveis();
lcd.clear();
}
//----------------------------------------------------------------------------------------------------------
void loop() {
// Executa diferentes funções de acordo com o menu selecionado
if(menu){
switch(sel){
case 0:
menu_edit_h(); // menu de edição de hora
break;
case 1:
agenda(); //menu de edição de agenda
break;
case 2:
menu_limpeza(); //menu para ativar limpeza
break;
case 3:
menu_reset(); //menu para reiniciar o esp
break;
}
}
if(!menu)MENU_HOME(); //menu principal
if(menu && sel > 3)menu = 0;
delay(10);
}
//----------------------------------------------------------------------------------------------------------
void agenda(){
lcd.clear();
//cria variaveis locais
int time = 0; //time para contagem de tempo
int select = 0; //para seleção do que vai ser editado
//desenha a tela
writeTexto("Hora",0,0);
writeTexto(":",8,0);
writeTexto("intervalo em dias:",0,2);
//cria um loop interno enquanto estiver editandoo
while(menu == 1){
time++;// conta uma volta
if(time > 49)time = 0; //se a contagem de tempo chegar a 50, ele volta para 0
// tela ----------------------------------------------------------
// funcao "writeNumberEdit" explicação:
// (numero da coluna do lcd, numero da linha do lcd, variavel que vai aparecer na tela, ...
// ... conntagem de tempo, selecao atual do que esta editando, valor da selecao pra ser editado)
writeNumberEdit(6,0,H_agenda,time,select,0);
writeNumberEdit(9,0,M_agenda,time,select,1);
writeNumberEdit(9,3,intervalo,time,select,2);
// botoes -------------------------------------------------------------
// funcao "verificarBotao" explicação:
// (botao há ser verificado, set do botao, variavel que vai ser editado , ...
// ... numero minimo, numero maximo, escolhe se incrementa ou decrementa, contagem de tempo,...
// ... valor pra editar contagem de tempo)
// para trazer a variavel modificada são:
// result traz a variavel incrementada ou decrementada
// result_t traz o tempo resetado
// result_b traz o set do botao atualizado
switch(select){
case 0:
verificarBotao(BT_A, bt_s1, H_agenda, 0, 23, true, time, -1);
H_agenda = result;
break;
case 1:
verificarBotao(BT_A, bt_s1, M_agenda, 0, 59, true, time, -1);
M_agenda = result;
break;
case 2:
verificarBotao(BT_A, bt_s1, intervalo, 0, 59, true, time, -1);
intervalo = result;
break;
}
bt_s1 = result_b;
time = result_t;
switch(select){
case 0:
verificarBotao(BT_B,bt_s2,H_agenda,0,23,false,time,-1);
H_agenda = result;
break;
case 1:
verificarBotao(BT_B,bt_s2,M_agenda,0,59,false,time,-1);
M_agenda = result;
break;
case 2:
verificarBotao(BT_B,bt_s2,intervalo,0,59,false,time,-1);
intervalo = result;
break;
}
time = result_t;
bt_s2 = result_b;
verificarBotao(BT_C,bt_s3,select,0,2,true,time,-1);
select = result;
time = result_t;
bt_s3 = result_b;
verificarBotao(BT_D,bt_s4,menu,0,1,false,time,-1);
menu = result;
time = result_t;
bt_s4 = result_b;
delay(10);
}
lcd.clear();
m_s = 4;
gravarVariaveis(H_agenda, M_agenda, intervalo);
//EEPROM.put(mem1, H_agenda);
//EEPROM.put(mem2, M_agenda);
//EEPROM.put(mem3, intervalo);
}
//----------------------------------------------------------------------------------------------------------
void MENU_HOME(){
time_home++;
if(menu == 0 && sel != m_s){
m_s = sel;
if(sel < 3){
if(sel == 0)writeTexto(">Hora<(Editar) 1/2",0,0);
if(sel != 0)writeTexto(" Hora 1/2",0,0);
if(sel == 1)writeTexto(">Agenda<(Editar) ",0,1);
if(sel != 1)writeTexto(" Agenda ",0,1);
if(sel == 2)writeTexto(">Limpeza<(Ativar) ",0,2);
if(sel != 2)writeTexto(" Limpeza ",0,2);
}
if(sel > 2){
if(sel == 3)writeTexto(">Reiniciar< 2/2",0,0);
if(sel != 3)writeTexto(" Reiniciar 2/2",0,0);
if(sel == 4)writeTexto("> ",0,1);
if(sel != 4)writeTexto(" ",0,1);
if(sel == 5)writeTexto("> ",0,2);
if(sel != 5)writeTexto(" ",0,2);
}
}
if(time_home == 45){
DateTime now = rtc.now();
writeNumberEdit(0,3,rtc.now().hour(),0,0,0);
writeNumberEdit(3,3,rtc.now().minute(),0,0,0);
writeNumberEdit(6,3,rtc.now().second(),0,0,0);
writeNumberEdit(10,3,rtc.now().day(),0,0,0);
writeNumberEdit(13,3,rtc.now().month(),0,0,0);
writeNumberEdit(16,3,rtc.now().year(),0,0,0);
writeTexto(":",2,3);
writeTexto(":",5,3);
writeTexto("/",12,3);
writeTexto("/",15,3);
}
if(time_home == 90)time_home = 0;
//CONFIG DO BOTÕES
verificarBotao(BT_A,bt_s1,sel,0,5,true, 0,0);sel = result;bt_s1 = result_b;
verificarBotao(BT_B,bt_s2,sel,0,5,false, 0,0);sel = result;bt_s2 = result_b;
verificarBotao(BT_C,bt_s3,menu,0,1,true, 0,0);menu = result;bt_s3 = result_b;
verificarBotao(BT_D,bt_s4,menu,0,1,false, 0,0);menu = result;bt_s4 = result_b;
}
//----------------------------------------------------------------------------------------------------------
void menu_edit_h(){
int time = 0;
int select = 0;
int diasNoMes[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
lcd.clear();
DateTime now = rtc.now();
writeTexto("Hora: ",0,0);
writeTexto(":",8,0);
writeTexto(":",11,0);
writeTexto("Data: ",0,1);
writeTexto("/",8,1);
writeTexto("/",11,1);
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();
while(menu == 1){
time++;
if(time > 49)time = 0;
// tela ----------------------------------------------------------
writeNumberEdit(6,0,H,time,select,0);
writeNumberEdit(9,0,M,time,select,1);
writeNumberEdit(12,0,S,time,select,2);
writeNumberEdit(6,1,DAY,time,select,3);
writeNumberEdit(9,1,MONTH,time,select,4);
writeNumberEdit(12,1,Y,time,select,5);
// botoes -------------------------------------------------------------
if (select == 0){verificarBotao(BT_A,bt_s1,H,0,23,true,time,-1);H = result; time = result_t;bt_s1 = result_b;}
if (select == 1){verificarBotao(BT_A,bt_s1,M,0,59,true,time,-1);M = result; time = result_t;bt_s1 = result_b;}
if (select == 2){verificarBotao(BT_A,bt_s1,S,0,59,true,time,-1);S = result; time = result_t;bt_s1 = result_b;}
if (select == 3){verificarBotao(BT_A,bt_s1,DAY,1,diasNoMes[MONTH - 1],true,time,-1);DAY = result; time = result_t;bt_s1 = result_b;}
if (select == 4){verificarBotao(BT_A,bt_s1,MONTH,1,12,true,time,-1);MONTH = result; time = result_t;bt_s1 = result_b;}
if (select == 5){verificarBotao(BT_A,bt_s1,Y,2020,2100,true,time,-1);Y = result; time = result_t;bt_s1 = result_b;}
if (select == 0){verificarBotao(BT_B,bt_s2,H,0,23,false,time,-1);H = result; time = result_t;bt_s2 = result_b;}
if (select == 1){verificarBotao(BT_B,bt_s2,M,0,59,false,time,-1);M = result; time = result_t;bt_s2 = result_b;}
if (select == 2){verificarBotao(BT_B,bt_s2,S,0,59,false,time,-1);S = result; time = result_t;bt_s2 = result_b;}
if (select == 3){verificarBotao(BT_B,bt_s2,DAY,1,diasNoMes[MONTH - 1],false,time,-1);DAY = result; time = result_t;bt_s2 = result_b;}
if (select == 4){verificarBotao(BT_B,bt_s2,MONTH,1,12,false,time,-1);MONTH = result; time = result_t;bt_s2 = result_b;}
if (select == 5){verificarBotao(BT_B,bt_s2,Y,2020,2100,false,time,-1);Y = result; time = result_t;bt_s2 = result_b;}
verificarBotao(BT_C,bt_s3,select,0,5,true,time,-1);select = result; time = result_t;bt_s3 = result_b;
verificarBotao(BT_D,bt_s4,menu,0,1,false,time,-1);menu = result; time = result_t;bt_s4 = result_b;
delay(10);
}
lcd.clear();
m_s = 4;
rtc.adjust(DateTime(Y, MONTH, DAY, H, M, S)); // Ajuste Manual (Ano, Mês, Dia, Hora, Min, Seg)
}
void menu_limpeza(){
lcd.clear();
writeTexto("Em breve",0,0);
writeTexto("presione D",0,2);
writeTexto("para voltar",0,3);
while(menu == 1){
verificarBotao(BT_D,bt_s4,menu,0,1,false,0,0);menu = result;bt_s4 = result_b;
delay(10);
}
lcd.clear();
m_s = 4;
}
void menu_reset(){
bool teste = 0;
lcd.clear();
writeTexto("Reiniciar?",0,0);
writeTexto(" D C ",0,2);
writeTexto("Nao Sim ",0,3);
while(menu == 1){
verificarBotao(BT_D,bt_s4,menu,0,1,false,0,0);menu = result;bt_s4 = result_b;
delay(10);
verificarBotao(BT_C,bt_s3,teste,0,1,true,0,0);teste = result;bt_s3 = result_b;
if(teste)menu = 0;
}
lcd.clear();
m_s = 4;
if (teste){
writeTexto("Reiniciando...",0,0);
delay(1000);
lcd.clear();
ESP.restart();
}
}
//----------------------------------------------------------------------------------------------------------
void writeTexto(String texto,int NC,int NL){
lcd.setCursor(NC, NL);
lcd.print(texto);
}
//----------------------------------------------------------------------------------------------------------
void writeNumberEdit(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{//se tiver 2 digitos
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
}
}
//----------------------------------------------------------------------------------------------------------
void verificarBotao(int botao, bool setB,int V,int limite_M,int limite, bool sinal, int time,int time_set){ //
result_t = time;
if (digitalRead(botao) == HIGH && setB == 0){
setB = 1;
if(sinal){V++;if (V > limite)V = limite_M;}
if(!sinal){V--;if (V < limite_M)V = limite;}
result_t = time_set;
}
if (digitalRead(botao) == LOW && setB == 1)setB = 0;
result = V;
result_b = setB;
}
//------------------------------------------------------------------------------------------------------------
void gravarVariaveis(int a, int b,int c) {
SD.remove("/variaveis.txt");
File arquivo = SD.open("/variaveis.txt", FILE_WRITE);
if (!arquivo) {
Serial.println("Falha ao abrir o arquivo para escrita");
return;
}
arquivo.printf("%d\n%d\n%d\n", a, b, c);
arquivo.close();
Serial.println("Variáveis gravadas com sucesso!");
}
void recuperarVariaveis() {
File arquivo = SD.open("/variaveis.txt", FILE_READ);
if (!arquivo) {
Serial.println("Erro ao abrir o arquivo para leitura!");
return;
}
int variavel1 = arquivo.parseInt();
int variavel2 = arquivo.parseInt();
int variavel3 = arquivo.parseInt();
H_agenda = variavel1;
M_agenda = variavel2;
intervalo = variavel3;
arquivo.close();
//EEPROM.get(mem1, H_agenda);
//EEPROM.get(mem2, M_agenda);
//EEPROM.get(mem3, intervalo);
Serial.println("Variáveis recuperadas com sucesso!");
}
A
B
C
D