// Timbre Automatizado para Colegio, empresa, cultivo, etc.
// Con Arduino UNO,(RTC), Modulo Rele, Modulo I2C para LCD 2x16
// Conexion i2C :Arduino UNO SCL-> A5 SDA->A4 VCC->5V GND->GND
// Conexion RTC :Arduino UNO GND->GND VCC->5V SCL-> SCL SDA->SDA los dos pines despues del ...12,13,GND,AREF,SDA,SCL
// Conexion Rele:Arduino UNO GND->GND VCC->5V IN->7
// NOTA: se debe cargar dos veces este programa 1. Con la linea RTC.adjust(DateTime(__DATE__, __TIME__));
// 2. Sin esa linea
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // inicializa la interfaz I2C del LCD 16x2
RTC_DS3231 RTC; // inicializa el modulo RTC
int r_diaSemana; // almacena el resultado del dia de la semana calculado
const int timbre = 7; // Pin 7 encargado de activar el timbre, se conecta al Rele
int segundo;
int minuto;
int hora;
int x_dia;
int x_mes;
int tiempo_timbre = 6000; // Tiempo continuo que dura el timbre sonando, en milisegundos 5000 = 5 segundos
//////////////////////////////// Horario 1 /////////////////////////
// Hora en la que suena el timbre escrito h1=Hora, m1=Minutos, s1=Segundos
// Cuando no se programa ninguna hora se debe dejar escrito el numero 99
// se pueden programar 16 timbres por cada horario, _c1 indica que es el horario 1
int h1_c1 = 7; int m1_c1 = 0; int s1_c1 = 0;
int h2_c1 = 7; int m2_c1 = 2; int s2_c1 = 0;
int h3_c1 = 7; int m3_c1 = 3; int s3_c1 = 0;
int h4_c1 = 7; int m4_c1 = 4; int s4_c1 = 0;
int h5_c1 = 7; int m5_c1 = 5; int s5_c1 = 0;
int h6_c1 = 7; int m6_c1 = 6; int s6_c1 = 0;
int h7_c1 = 7; int m7_c1 = 7; int s7_c1 = 0;
int h8_c1 = 11; int m8_c1 = 0; int s8_c1 = 0;
int h9_c1 = 12; int m9_c1 = 0; int s9_c1 = 0;
int h10_c1 = 99; int m10_c1 = 0; int s10_c1 = 0;
int h11_c1 = 99; int m11_c1 = 0; int s11_c1 = 0;
int h12_c1 = 99; int m12_c1 = 0; int s12_c1 = 0;
int h13_c1 = 99; int m13_c1 = 0; int s13_c1 = 0;
int h14_c1 = 99; int m14_c1 = 0; int s14_c1 = 0;
int h15_c1 = 99; int m15_c1 = 0; int s15_c1 = 0;
int h16_c1 = 99; int m16_c1 = 0; int s16_c1 = 0;
//////////////////////////////// Horario 2 /////////////////////////
int h1_c2 = 7; int m1_c2 = 0; int s1_c2 = 0;
int h2_c2 = 7; int m2_c2 = 1; int s2_c2 = 0;
int h3_c2 = 7; int m3_c2 = 2; int s3_c2 = 0;
int h4_c2 = 7; int m4_c2 = 3; int s4_c2 = 0;
int h5_c2 = 7; int m5_c2 = 4; int s5_c2 = 0;
int h6_c2 = 7; int m6_c2 = 5; int s6_c2 = 0;
int h7_c2 = 7; int m7_c2 = 6; int s7_c2 = 0;
int h8_c2 = 7; int m8_c2 = 7; int s8_c2 = 0;
int h9_c2 = 7; int m9_c2 = 8; int s9_c2 = 0;
int h10_c2 = 12; int m10_c2 = 0; int s10_c2 = 0;
int h11_c2 = 99; int m11_c2 = 0; int s11_c2 = 0;
int h12_c2 = 99; int m12_c2 = 0; int s12_c2 = 0;
int h13_c2 = 99; int m13_c2 = 0; int s13_c2 = 0;
int h14_c2 = 99; int m14_c2 = 0; int s14_c2 = 0;
int h15_c2 = 99; int m15_c2 = 0; int s15_c2 = 0;
int h16_c2 = 99; int m16_c2 = 0; int s16_c2 = 0;
//////////////////////////////// Horario 3 /////////////////////////
int h1_c3 = 99; int m1_c3 = 0; int s1_c3 = 0;
int h2_c3 = 99; int m2_c3 = 0; int s2_c3 = 0;
int h3_c3 = 99; int m3_c3 = 0; int s3_c3 = 0;
int h4_c3 = 99; int m4_c3 = 0; int s4_c3 = 0;
int h5_c3 = 99; int m5_c3 = 0; int s5_c3 = 0;
int h6_c3 = 99; int m6_c3 = 0; int s6_c3 = 0;
int h7_c3 = 99; int m7_c3 = 0; int s7_c3 = 0;
int h8_c3 = 99; int m8_c3 = 0; int s8_c3 = 0;
int h9_c3 = 99; int m9_c3 = 0; int s9_c3 = 0;
int h10_c3 = 99; int m10_c3 = 0; int s10_c3 = 0;
int h11_c3 = 99; int m11_c3 = 0; int s11_c3 = 0;
int h12_c3 = 99; int m12_c3 = 0; int s12_c3 = 0;
int h13_c3 = 99; int m13_c3 = 0; int s13_c3 = 0;
int h14_c3 = 99; int m14_c3 = 0; int s14_c3 = 0;
int h15_c3 = 99; int m15_c3 = 0; int s15_c3 = 0;
int h16_c3 = 99; int m16_c3 = 0; int s16_c3 = 0;
// ******************************** Void Setup() ****************************************
void setup () {
pinMode(timbre, OUTPUT); // Configura como salida el pin 7
Wire.begin();
RTC.begin(); // Inicia la comunicaci¢n con el RTC
RTC.adjust(DateTime(2024, 2, 6, 6, 59, 30)); // Poner arbitrariamente una fecha para hacer pruebas
// RTC.adjust(DateTime(__DATE__, __TIME__)); // Lee la fecha y hora del PC (Solo en la primera carga)
// el anterior se usa solo en la configuracion inicial luego se pone como comentario
// y se vuelve a cargar el programa sin esa linea.
Serial.begin(9600); // Establece la velocidad de datos del puerto serie a 9600
lcd.init();
lcd.backlight(); // Coloca luz de fondo al LCD
lcd.clear(); // Borra el LCD
}
//********************************* Void loop() ****************************************
void loop() {
DateTime now = RTC.now(); // Obtiene la fecha y hora del RTC
segundo = now.second();
minuto = now.minute();
hora = now.hour();
x_dia = now.day();
x_mes = now.month();
int contacto1 = analogRead(A0); //Lee el valor de los contactos para escoger el horario
int contacto2 = analogRead(A1);
int contacto3 = analogRead(A2);
int contacto4 = analogRead(A3); // contacto que activa o desactiva los fines de semana
//Serial.print(now.year(), DEC); // Año
//Serial.print('-');
//Serial.print(now.month(), DEC); // Mes
//Serial.print('-');
//Serial.print(now.day(), DEC); // Dia
//Serial.print(' ');
//Serial.print(now.hour(), DEC); // Horas
//Serial.print(':');
//Serial.print(now.minute(), DEC); // Minutos
//Serial.print(':');
//Serial.print(now.second(), DEC); // Segundos
//Serial.println();
lcd.setCursor(4, 1); //CURSOR EN CUARTA POSICION LINEA INFERIOR
if (x_dia < 10) { //SI EL DIA ES DE UN SOLO DIGITO, AGREGARA UN CERO A LA IZQUIERDA
lcd.print("0");
}
lcd.print(x_dia);
lcd.print("/");
lcd.setCursor(7, 1); //CURSOR EN SEPTIMA POSICION LINEA INFERIOR
// ********************* CONDICIONANTES PARA CAMBIAR EL FORMATO DEL MES POR LETRAS *********
char *meses[] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"};
lcd.print(meses[x_mes]);
lcd.print("/");
lcd.print(now.year(), DEC);
/////////////////////////////// AJUSTES DE HORA /////////////////////////////////////////
lcd.setCursor(0, 0);
if (hora < 10) { //SI LA HORA ES DE UN SOLO DIGITO, AGREGARA UN CERO A LA IZQUIERDA
lcd.print(" ");
}
lcd.print(hora);
lcd.print(":");
lcd.setCursor(3, 0);
if (minuto < 10) { //SI LOS MINUTOS ES DE UN SOLO DIGITO, AGREGARA UN CERO A LA IZQUIERDA
lcd.print("0");
}
lcd.print(minuto);
lcd.print(":");
lcd.setCursor(6, 0); //POSICIONA EL CURSOR PARA LOS SEGUNDOS
if (segundo < 10) { //SI LOS SEGUNDOS ES DE DOS DIGITOS, AGREGARA UN CERO A LA IZQUIERDA
lcd.print("0");
}
lcd.print(segundo);
// **************** CONDICIONES PARA ACTIVAR ALGUNOS HORARIOS Y OTROS NO **************
if (contacto4 <= 1000) { // si el contacto 4 esta desactivado, despliega -e- entre semana funciona el timbre
lcd.setCursor(15, 1);
lcd.print("e");
//Serial.print("-e-");
}
else { // si el contacto 4 esta activado, despliega -F- el Fin de semana funciona el timbre
lcd.setCursor(15, 1);
lcd.print("F");
//Serial.print("-F-");
}
int r_diaSemana = dia_de_semana(); // llama a la funcion que calcula el dia de la semana y lo almacena en r_diaSemana
lcd.setCursor(15, 0);
lcd.print(r_diaSemana);
//Serial.print(r_diaSemana);
if ((r_diaSemana == 6 || r_diaSemana == 0) && (contacto4 <= 1000)) { // si el contacto4 de Fin de semana esta apagado y es fin de semana no hace nada (OFF)
}
else {
if (contacto1 >= 1000 && r_diaSemana == 1) // Si el contacto 1 esta activo y es lunes usa (Horario 1)
horario_1(); // llama a la funcion que activa el horario 1
if ((contacto1 >= 1000) && (r_diaSemana == 2 || r_diaSemana == 3 || r_diaSemana == 4 || r_diaSemana == 5)) // Si el contacto 1 esta activo y es Martes a viernes (Horario 2)
horario_2(); // llama a la funcion que activa el horario2
if (contacto2 >= 1000) // Si el contacto 2 esta activo (Horario 2)
horario_2(); // llama a la funcion que activa el horario2
if (contacto3 >= 1000) // Si el contacto 3 esta activo (Horario 3)
horario_3(); // llama a la funcion que activa el horario 3
}
digitalWrite(timbre, HIGH); // apaga el timbre
delay(500); // La informacion se actualiza cada 1/2 seg.
lcd.setCursor(15, 1); // Borra parte de la pantalla del LCD
lcd.print(" ");
lcd.setCursor(8, 0);
lcd.print(" ");
} //////////////////////////////// Fin del void loop(), inician las Funciones/////////////////////////
/////////////////////////////// Funcion que activa el Timbre //////////////////////////////////
void activar_timbre() {
digitalWrite(timbre, LOW);
lcd.setCursor(0, 1);
lcd.print("-TIMBRE ACTIVO-");
//Serial.println("Timbre Activo");
delay(tiempo_timbre);
lcd.clear();
}
/////////////////////////////// Calcula el dia de la Semana //////////////////////////////////
int dia_de_semana() {
// Encuentar el dia de la semana de una fecha
int n_dia;
int r_dia;
int n_mes;
int t_mes;
int n_anno;
int d_anno;
int t_siglo = 5;
DateTime now = RTC.now(); //fecha y hora del RTC
lcd.setCursor(0, 1);
n_anno = (now.year() - 2000);
d_anno = n_anno / 4;
n_dia = now.day();
n_mes = now.month();
switch (n_mes) {
case 1:
t_mes = 0;
break;
case 2:
t_mes = 3;
break;
case 3:
t_mes = 3;
break;
case 4:
t_mes = 6;
break;
case 5:
t_mes = 1;
break;
case 6:
t_mes = 4;
break;
case 7:
t_mes = 6;
break;
case 8:
t_mes = 2;
break;
case 9:
t_mes = 5;
break;
case 10:
t_mes = 0;
break;
case 11:
t_mes = 3;
break;
case 12:
t_mes = 5;
break;
default:
t_mes = t_mes;
break;
}
r_dia = n_dia + t_mes + n_anno + d_anno + t_siglo;
r_dia = r_dia % 7;
switch (r_dia) {
case 1:
lcd.print("Lun");
//Serial.print(" Lun ");
break;
case 2:
lcd.print("Mar");
//Serial.println(" Mar ");
break;
case 3:
lcd.print("Mie");
//Serial.print(" Mie ");
break;
case 4:
lcd.print("Jue");
//Serial.print(" Jue ");
break;
case 5:
lcd.print("Vie");
//Serial.print(" Vie ");
break;
case 6:
lcd.print("Sab");
//Serial.print(" Sab ");
break;
case 0:
lcd.print("Dom");
//Serial.print(" Dom ");
break;
default:
lcd.print("---");
//Serial.print(" ---");
break;
}
return r_dia;
}
/////////////////////Condicional del Horario 1 //////////////////////////////////
void horario_1() {
lcd.setCursor(10, 0);
lcd.print("1");
//Serial.print("Horario_1 ");
if ((hora == h1_c1) && (minuto == m1_c1) && (segundo == s1_c1)) activar_timbre();
if ((hora == h2_c1) && (minuto == m2_c1) && (segundo == s2_c1)) activar_timbre();
if ((hora == h3_c1) && (minuto == m3_c1) && (segundo == s3_c1)) activar_timbre();
if ((hora == h4_c1) && (minuto == m4_c1) && (segundo == s4_c1)) activar_timbre();
if ((hora == h5_c1) && (minuto == m5_c1) && (segundo == s5_c1)) activar_timbre();
if ((hora == h6_c1) && (minuto == m6_c1) && (segundo == s6_c1)) activar_timbre();
if ((hora == h7_c1) && (minuto == m7_c1) && (segundo == s7_c1)) activar_timbre();
if ((hora == h8_c1) && (minuto == m8_c1) && (segundo == s8_c1)) activar_timbre();
if ((hora == h9_c1) && (minuto == m9_c1) && (segundo == s9_c1)) activar_timbre();
if ((hora == h10_c1) && (minuto == m10_c1) && (segundo == s10_c1)) activar_timbre();
if ((hora == h11_c1) && (minuto == m11_c1) && (segundo == s11_c1)) activar_timbre();
if ((hora == h12_c1) && (minuto == m12_c1) && (segundo == s12_c1)) activar_timbre();
if ((hora == h13_c1) && (minuto == m13_c1) && (segundo == s13_c1)) activar_timbre();
if ((hora == h14_c1) && (minuto == m14_c1) && (segundo == s14_c1)) activar_timbre();
if ((hora == h15_c1) && (minuto == m15_c1) && (segundo == s15_c1)) activar_timbre();
if ((hora == h16_c1) && (minuto == m16_c1) && (segundo == s16_c1)) activar_timbre();
}
////////////////////Condicional del Horario 2 //////////////////////////////////
void horario_2() {
lcd.setCursor(11, 0);
lcd.print("2");
//Serial.print("Horario_2 ");
if ((hora == h1_c2) && (minuto == m1_c2) && (segundo == s1_c2)) activar_timbre();
if ((hora == h2_c2) && (minuto == m2_c2) && (segundo == s2_c2)) activar_timbre();
if ((hora == h3_c2) && (minuto == m3_c2) && (segundo == s3_c2)) activar_timbre();
if ((hora == h4_c2) && (minuto == m4_c2) && (segundo == s4_c2)) activar_timbre();
if ((hora == h5_c2) && (minuto == m5_c2) && (segundo == s5_c2)) activar_timbre();
if ((hora == h6_c2) && (minuto == m6_c2) && (segundo == s6_c2)) activar_timbre();
if ((hora == h7_c2) && (minuto == m7_c2) && (segundo == s7_c2)) activar_timbre();
if ((hora == h8_c2) && (minuto == m8_c2) && (segundo == s8_c2)) activar_timbre();
if ((hora == h9_c2) && (minuto == m9_c2) && (segundo == s9_c2)) activar_timbre();
if ((hora == h10_c2) && (minuto == m10_c2) && (segundo == s10_c2)) activar_timbre();
if ((hora == h11_c2) && (minuto == m11_c2) && (segundo == s11_c2)) activar_timbre();
if ((hora == h12_c2) && (minuto == m12_c2) && (segundo == s12_c2)) activar_timbre();
if ((hora == h13_c2) && (minuto == m13_c2) && (segundo == s13_c2)) activar_timbre();
if ((hora == h14_c2) && (minuto == m14_c2) && (segundo == s14_c2)) activar_timbre();
if ((hora == h15_c2) && (minuto == m15_c2) && (segundo == s15_c2)) activar_timbre();
if ((hora == h16_c2) && (minuto == m16_c2) && (segundo == s16_c2)) activar_timbre();
}
//////////////////////Condicional del Horario 3 //////////////////////////////////
void horario_3() {
lcd.setCursor(12, 0);
lcd.print("3");
//Serial.print("Horario_3 ");
if ((hora == h1_c3) && (minuto == m1_c3) && (segundo == s1_c3)) activar_timbre();
if ((hora == h2_c3) && (minuto == m2_c3) && (segundo == s2_c3)) activar_timbre();
if ((hora == h3_c3) && (minuto == m3_c3) && (segundo == s3_c3)) activar_timbre();
if ((hora == h4_c3) && (minuto == m4_c3) && (segundo == s4_c3)) activar_timbre();
if ((hora == h5_c3) && (minuto == m5_c3) && (segundo == s5_c3)) activar_timbre();
if ((hora == h6_c3) && (minuto == m6_c3) && (segundo == s6_c3)) activar_timbre();
if ((hora == h7_c3) && (minuto == m7_c3) && (segundo == s7_c3)) activar_timbre();
if ((hora == h8_c3) && (minuto == m8_c3) && (segundo == s8_c3)) activar_timbre();
if ((hora == h9_c3) && (minuto == m9_c3) && (segundo == s9_c3)) activar_timbre();
if ((hora == h10_c3) && (minuto == m10_c3) && (segundo == s10_c3)) activar_timbre();
if ((hora == h11_c3) && (minuto == m11_c3) && (segundo == s11_c3)) activar_timbre();
if ((hora == h12_c3) && (minuto == m12_c3) && (segundo == s12_c3)) activar_timbre();
if ((hora == h13_c3) && (minuto == m13_c3) && (segundo == s13_c3)) activar_timbre();
if ((hora == h14_c3) && (minuto == m14_c3) && (segundo == s14_c3)) activar_timbre();
if ((hora == h15_c3) && (minuto == m15_c3) && (segundo == s15_c3)) activar_timbre();
if ((hora == h16_c3) && (minuto == m16_c3) && (segundo == s16_c3)) activar_timbre();
}