#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Key.h>
#include <Keypad.h>
#include <RTClib.h>
#include <EEPROM.h>
#define rele 2
#define buzzer 3
#define ledu 12
#define ledd 13
RTC_DS3231 rtc;
byte cond =0;
const byte nro_filas = 4;
const byte nro_columnas = 4;
char tecla;
char hor[5];
char hord[5];
int indice = 0;
int num = 0;
int cur=5; //contador de hasta n(2) errores
byte pines_fila[nro_filas] = {11,10,9,8};
byte pines_columna[nro_columnas] = {7,6,5,4};
char caracteres[nro_filas][nro_columnas] = { {'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};
int horaI = 0, minuI = 0;
int horaF = 0, minuF = 0;
bool estado = false;
// Direcciones de EEPROM
const int EEPROM_ON_HOUR = 0; // hora de inicio
const int EEPROM_ON_MINUTE = 1; // minuto de inicio
const int EEPROM_OFF_HOUR = 2; // hora final
const int EEPROM_OFF_MINUTE = 3;
//librerías
LiquidCrystal_I2C lcd(0x27, 16, 2);
Keypad teclado = Keypad(makeKeymap(caracteres), pines_fila, pines_columna, nro_filas, nro_columnas);
//Configuración************************************************
void setup() {
pinMode(ledu, OUTPUT);
pinMode(ledd, OUTPUT);
pinMode(rele, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(rele, LOW); // Apaga la bomba al inicio
digitalWrite(buzzer, LOW);
lcd.init();
lcd.backlight();
if (!rtc.begin()) {
lcd.print("RTC no encontrado!");
while (1);
}
// configurar fecha y hora actual módulo RTC****************
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
horaI = EEPROM.read(EEPROM_ON_HOUR);
minuI = EEPROM.read(EEPROM_ON_MINUTE);
horaF = EEPROM.read(EEPROM_OFF_HOUR);
minuF = EEPROM.read(EEPROM_OFF_MINUTE);
lcd.home();
lcd.print("Bienvenido");
for (int i = 0; i < 3; i++) {
digitalWrite(ledu, HIGH); // Encender el LED
delay(200); // Esperar 500 milisegundos (0.5 segundos)
digitalWrite(ledu, LOW); // Apagar el LED
delay(200); // Esperar 500 milisegundos
}
delay(2000);
lcd.clear();
}
//********************************************************************
// Programa Principal********************
void loop() {
DateTime now = rtc.now();
// Mostrar la hora actual en la LCD
lcd.setCursor(0, 0);
lcd.print("Hora: ");
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute());
lcd.print(":");
lcd.print(now.second());
lcd.setCursor(0, 1);
lcd.print("MODH ON OFF");
tecla = teclado.getKey();
switch(tecla){
case 'C':
buzz();
prog();
break;
case 'A':
buzz();
manualbomba(true);
break;
case 'B':
buzz();
manualbomba(false);
break;
case 'D':
buzz();
ver();
break;
}
if (now.hour() == horaI && now.minute() == minuI && !estado) {
digitalWrite(rele, HIGH); // Encender la bomba
estado = true;
}
if (now.hour() == horaF && now.minute() == minuF && estado) {
digitalWrite(rele, LOW); // Apagar la bomba
estado = false;
}
}
//********************************************
//Funciones *******************//////////////////**************
// Programar hora de inicio y apagado
void prog(){
cur = 5;
indice =0;
cond=0;
lcd.clear();
lcd.print("Inicio H:m(24h):");
strcpy(hor, ingresar());
delay(1000);
if(cond !=1){
cur = 5;
indice =0;
lcd.clear();
lcd.print("Fin H:m(24h):");
strcpy(hord, ingresar());
// Condición para guardar valores de manera segura
if(cond !=1){
horaI = extraer(hor, 0, 2);
minuI = extraer(hor, 2, 2);
horaF = extraer(hord, 0, 2);
minuF = extraer(hord, 2, 2);
if(horaI <=24 && minuI <=59 && horaF <=24 && minuF <=59){
EEPROM.write(EEPROM_ON_HOUR, horaI);
EEPROM.write(EEPROM_ON_MINUTE, minuF);
EEPROM.write(EEPROM_OFF_HOUR, horaF);
EEPROM.write(EEPROM_OFF_MINUTE, minuF);
lcd.clear();
lcd.home();
lcd.print("Guardando...");
msgic(1);
}
else{
lcd.clear();
lcd.home();
lcd.print("Hora o minuto");
lcd.setCursor(0,1);
lcd.print("Incorrectos");
msgic(0);
delay(500);
prog();
}
}
delay(1000);
}
lcd.clear();
cur = 5;
indice =0;
cond=0;
}
//Función obtener entero de cadena
int extraer(char* cadena, int inicio, int longitud) {
char subcadena[3]; // Subcadena para almacenar los caracteres extraídos (2 dígitos + '\0')
strncpy(subcadena, cadena + inicio, longitud); // Copiar los caracteres deseados
subcadena[longitud] = '\0'; // Asegurarse de que la subcadena esté terminada en '\0'
return atoi(subcadena); // Convertir la subcadena a un entero
}
// Funcíon agregar datos
char* ingresar(){
cur = 5;
char tecla;
static char datos[5];
while((tecla = teclado.getKey()) != '#' && cond != 1 ){
if(tecla){
buzz();
}
lcd.setCursor(7,1);
lcd.print(":");
if(tecla >= '0' && tecla <= '9' && cur < 9 && indice <4){
if(cur > 4 && cur < 9){
datos[indice] = tecla;
if(cur >=7){
lcd.setCursor(cur+1, 1);
lcd.print(tecla);
}
else{
lcd.setCursor(cur, 1);
lcd.print(tecla);
}
}
cur++;
indice++;
}
else if(tecla == '*' && cur >5 && indice >0){
if(cur <=7){
lcd.setCursor(cur-1, 1);
lcd.print(" ");
}
else{
lcd.setCursor(cur, 1);
lcd.print(" ");
}
indice--;
cur--;
}
else if(tecla == 'D' ){
lcd.clear();
lcd.home();
cond =1;
lcd.print("Saliendo");
delay(1000);
}
}
datos[indice] = '\0';
return datos;
}
////////////////////////////////////////////////
//Bomba Manual
void manualbomba(bool estad) {
if (estad) {
digitalWrite(rele, HIGH);
lcd.clear();
lcd.print("Bomba Encendida");
digitalWrite(ledu, HIGH);
} else {
digitalWrite(rele, LOW);
lcd.clear();
lcd.print("Bomba Apagada");
digitalWrite(ledu, LOW);
}
delay(2000);
lcd.clear();
}
// ver información
void ver(){
lcd.clear();
lcd.home();
lcd.print("Hora Ini: ");
lcd.setCursor(10,0);
lcd.print(horaI);
lcd.setCursor(12,0);
lcd.print(":");
lcd.setCursor(13,0);
lcd.print(minuI);
lcd.setCursor(0,1);
lcd.print("Hora Fin: ");
lcd.setCursor(10,1);
lcd.print(horaF);
lcd.setCursor(12,1);
lcd.print(":");
lcd.setCursor(13,1);
lcd.print(minuF);
delay(3000);
lcd.clear();
}
void buzz(){
digitalWrite(buzzer, HIGH); // Encender el LED
delay(50);
digitalWrite(buzzer, LOW); // Apagar el LED
delay(50);
}
void msgic(int msg){
if(msg ==1){
for (int i = 0; i < 2; i++) {
digitalWrite(ledu, HIGH);
digitalWrite(buzzer, HIGH);
delay(200); // Esperar 500 milisegundos (0.5 segundos)
digitalWrite(ledu, LOW);
digitalWrite(buzzer, LOW); // Apagar el LED
delay(200); // Esperar 500 milisegundos
}
}
if(msg == 0){
for (int i = 0; i < 3; i++) {
digitalWrite(ledd, HIGH);
digitalWrite(buzzer, HIGH);
delay(200); // Esperar 500 milisegundos (0.5 segundos)
digitalWrite(ledd, LOW);
digitalWrite(buzzer, LOW); // Apagar el LED
delay(200); // Esperar 500 milisegundos
}
}
}