Timbre escolar automático

Buenos días, soy Emanuel, es mi primera publicación en el foro y espero poder resolver mi problema jeje. Resulta que hace una semana comencé un proyecto en Arduino de un timbre escolar automático. Estoy usando un Arduino UNO , un modulo reloj DS3231 y un relé doble.

Resulta que he estado haciendo diferentes pruebas, con diferentes códigos, algunos escritos por mi y otros que encontré en la web, pero siempre tengo el mismo problema, el timbre no logra funcionar completamente en todos los horarios que le fijo. Quiero decir, tengo el horario de la tarde y el de la mañana, no he conseguido que mi timbre suene perfectamente en todos los horarios sin excepción por un día, y el objetivo es que funcione 24/7 a excepción de los fines de semana claro. Testeando algunas veces, con mis códigos anteriores llegué a la conclusión que, algunas veces el arduino, luego de sonar un timbre, quedaba atrapado o pegado y no volvía a correr el programa. En la última versión de mi código, esto no debería pasar ya que no uso un delay luego de apagar y prender el timbre, pero el problema que tengo actualmente es similar. Me gustaría saber que es lo que está fallando ahora, esta ultima versión, es una versión recortada del código del profe garcia, de su vídeo en YT de como hacer un timbre escolar. Adjunto este código y espero su respuesta:


// 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"

RTC_DS3231 RTC;                   // inicializa el modulo RTC
int r_diaSemana;                  // almacena el resultado del dia de la semana calculado
const int timbre = 13;             // Pin 13 encargado de activar el timbre, se conecta al Rele
int segundo;
int minuto;
int hora;
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=30;   int s1_c1=0;
int h2_c1=8;   int m2_c1=15;  int s2_c1=0;
int h3_c1=8;   int m3_c1=20;  int s3_c1=0;
int h4_c1=9;   int m4_c1=5;  int s4_c1=0;
int h5_c1=9;   int m5_c1=10;  int s5_c1=0;
int h6_c1=9;  int m6_c1=55;  int s6_c1=0;
int h7_c1=10;  int m7_c1=0;  int s7_c1=0;
int h8_c1=10;  int m8_c1=45;  int s8_c1=0;
int h9_c1=10;  int m9_c1=50;  int s9_c1=0;
int h10_c1=11; int m10_c1=35;  int s10_c1=0;
int h11_c1=11; int m11_c1=40;  int s11_c1=0;
int h12_c1=12; int m12_c1=25;  int s12_c1=0;
int h13_c1=12; int m13_c1=30;  int s13_c1=0;
int h14_c1=13; int m14_c1=15;  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=12;   int m1_c2=45;   int s1_c2=0;
int h2_c2=13;   int m2_c2=30;  int s2_c2=0;
int h3_c2=13;   int m3_c2=35;  int s3_c2=0;
int h4_c2=14;   int m4_c2=20;  int s4_c2=0;
int h5_c2=14;   int m5_c2=25;  int s5_c2=0;
int h6_c2=15;  int m6_c2=10;  int s6_c2=0;
int h7_c2=15;  int m7_c2=15;  int s7_c2=0;
int h8_c2=16;  int m8_c2=0;  int s8_c2=0;
int h9_c2=16;  int m9_c2=5;  int s9_c2=0;
int h10_c2=16; int m10_c2=50;  int s10_c2=0;
int h11_c2=16; int m11_c2=55;  int s11_c2=0;
int h12_c2=17; int m12_c2=40;  int s12_c2=0;
int h13_c2=17; int m13_c2=45;  int s13_c2=0;
int h14_c2=18; int m14_c2=30;  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;

////////////////////////////////// Void Setup() ///////////
void setup () { 
  
 pinMode(timbre, OUTPUT);                    // Configura como salida el pin 13
 Wire.begin();                               
 RTC.begin();                                // Inicia la comunicaci¢n con el RTC
 
// 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
} 
////////////////////////////////// Void loop() ///////////
void loop(){
 DateTime now = RTC.now();          // Obtiene la fecha y hora del RTC

 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();
 segundo=now.second();
 minuto=now.minute();
 hora=now.hour();

 
 int r_diaSemana= now.dayOfTheWeek();   // llama a la funcion que calcula el dia de la semana y lo almacena en r_diaSemana
 
 if (r_diaSemana == 6 || r_diaSemana == 0){  // si  fin de semana no hace nada
 }
 else {  
  if(hora >=7 && hora<14){
    horario_1();           // llama a la funcion que activa el horario 1
  }
     if(hora >=12 && hora<19){
    horario_2();           // llama a la funcion que activa el horario 1
  }  
 }
 
 digitalWrite(timbre, HIGH);     // apaga el timbre
 delay(1000);                    // La informaci¢n se actualiza cada 1 seg.
}   //////////////////////////////// Fin del void loop(), inician las Funciones/////////////////////////

/////////////////////////////// Funcion que activa el Timbre //////////////////////////////////
void activar_timbre(){
    digitalWrite(timbre, LOW); 
    Serial.println("Timbre Activo");
    delay(tiempo_timbre); 
}

/////////////////////Condicional del Horario 1  //////////////////////////////////
void horario_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(){ 
   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(); 
  
}

Cualquier comentario es de ayuda, espero su respuesta! Gracias!

Comparte una imagen que muestre las conexiones que estás utilizando

1 Like

Hola, posiblemente el problema venga de la carga del relé. como te ha pedido @mancera1979 sería conveniente que pusieras el conexionado.
Para poder simplificar tu código con menos variables te paso esto que me he tomado la libertad de modificar un poco para no cargar tantas variables:
https://wokwi.com/projects/379588049883422721

Obviamente es muy mejorable pero para punto de partida creo que está bien.
Además yo de ti miraría consejos para no usar "delay".

1 Like

Buenas tardes amigos, mañana cuando esté en el lugar le tomaré una foto y la subo al foro. Muchas gracias por su ayuda y el refaccionamiento del código. Cabe recalcar que estoy usando los pines de conexión que se utilizan para la protoboard, es decir los que se utilizan para testear, no diseñe un circuito integrado porque el timbre se mantendrá en un lugar seguro y sería más gasto para la institución.

Fijate si te sirve

Te he ajustado tu código para que funcione
Te agregué en el pin 2 un boton que esta con un pin al 2 y otro a GND
Cada vez que presionas cambia a 5 segundos antes del proximo horario asi puedes probar todos

// 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 "LibPrintf.h"

RTC_DS3231 RTC;                   // inicializa el modulo RTC
int r_diaSemana;                  // almacena el resultado del dia de la semana calculado
const int timbre = 13;             // Pin 13 encargado de activar el timbre, se conecta al Rele
int segundo;
int minuto;
int hora;
unsigned long tiempo_timbre=6000UL; // 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
struct _Horario {
  int hora; 
  int minutos;
  int segundos;
};

_Horario horario1[15]= {{ 7, 30,  0}, // Horario 1
                          { 8, 15,  0},
                          { 8, 20,  0},
                          { 9,  5,  0},
                          { 9, 10,  0},
                          { 9, 55,  0},
                          {10,  0,  0},
                          {10, 45,  0},
                          {10, 55,  0},
                          {11, 35,  0},
                          {11, 40,  0},
                          {12, 25,  0},
                          {12, 30,  0},
                          {13, 15,  0},  //13
                          {99,  0,  0}
                        };
                        
_Horario horario2[15] = { {12, 45,  0}, // 15 HORARIO 2
                          {13, 30,  0},
                          {13, 35,  0},
                          {14, 20,  0},
                          {14, 25,  0},                          
                          {15, 10,  0},
                          {15, 15,  0},
                          {16,  0,  0},
                          {16,  5,  0},
                          {16, 50,  0},
                          {16, 55,  0},                                                                                                        
                          {17, 40,  0},
                          {17, 45,  0},
                          {18, 30,  0}, // 28
                          {99,  0,  0}
                        };
////////////////////////////////// Void Setup() ///////////

// void rellenar(struct _Horarios *A, size_t len){
//     for (int k=0; k < len; k++) {
//         A[k].hora = 
//         scanf("%s", A[k].pregunta);
//         printf("\n");
//     }
// }

byte index = 0;
bool flagTimbre = false;
unsigned long lastMillis;
const int botonPin = 2;
int statusAnt = 0, status;

void chequeoPulsador() {
  static int hora, minu, secs;
  
  status = digitalRead(botonPin);
  if (status && !statusAnt) {
      if (index++ > 14) 
          index = 0;
      hora = horario1[index].minutos == 0? horario1[index].hora-1:horario1[index].hora;
      minu = horario1[index].minutos == 0? 59:horario1[index].minutos-1;
      secs = 55;
      printf("Prueba timbre %d Ajusto Hora:%2d Minuto:%2d seg:%2d", index, hora, minu, secs);
      RTC.adjust(DateTime(2023, 10, 25, hora, minu, secs));
  }
  statusAnt = status;
}


void setup () { 
  
 pinMode(timbre, OUTPUT);                    // Configura como salida el pin 13
 pinMode(botonPin, INPUT_PULLUP);
 Wire.begin();                               
 RTC.begin();                                // Inicia la comunicaci¢n con el RTC
 
 //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.
  RTC.adjust(DateTime(2023, 10, 25, horario1[0].hora, horario1[0].minutos, 55));                                             
 Serial.begin(9600);                         // Establece la velocidad de datos del puerto serie a 9600
} 
////////////////////////////////// Void loop() ///////////
void loop(){
  DateTime now = RTC.now();          // Obtiene la fecha y hora del RTC
  printf("\n%02d:%02d:%02d %02d/%02d/%02d ", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year(), now.day(), now.month(), now.year());

  segundo  = now.second();
  minuto   = now.minute();
  hora     = now.hour();

  chequeoPulsador();  
  

  int r_diaSemana= now.dayOfTheWeek();   // llama a la funcion que calcula el dia de la semana y lo almacena en r_diaSemana
  
  if (r_diaSemana == 6 || r_diaSemana == 0){  // si  fin de semana no hace nada
  }
  else {  
    if (hora >=7 && hora<14){
      horario_1();           // llama a la funcion que activa el horario 1
    }
    if (hora >=12 && hora<19){
      horario_1();           // llama a la funcion que activa el horario 1
    }  
  }
  if (flagTimbre) 
      if (millis() - lastMillis > tiempo_timbre) {
          lastMillis = millis();
          flagTimbre = false;
          digitalWrite(timbre, HIGH);
          Serial.println(" Timbre Desactivado"); 
      }
      else {
        printf(" Dif tiempo %ld", (millis() - lastMillis)); 
      }
  delay(1000);                    // La informaci¢n se actualiza cada 1 seg.
}   //////////////////////////////// Fin del void loop(), inician las Funciones/////////////////////////

/////////////////////////////// Funcion que activa el Timbre //////////////////////////////////
void activar_timbre(){
    digitalWrite(timbre, LOW); 
    printf(" Timbre Activo");
    flagTimbre = true;
}

/////////////////////Condicional del Horario 1  //////////////////////////////////
void horario_1(){ 
   //Serial.print("Horario_1 ");
   for (int i=0; i<14; i++) {
      if ((hora==horario1[i].hora) && 
           (minuto==horario1[i].minutos) && 
           (segundo==horario1[i].segundos))  {
            activar_timbre();   
            lastMillis = millis(); // si no ajusto esto no se cumplen el tiempo de la sirena
            printf(" lastMillis = %ld", lastMillis);
           } 
           
   }
   
}

// ////////////////////Condicional del Horario 2  //////////////////////////////////
// void horario_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(); 
  
// }

Esta todo aca para que lo simules y pruebes.

Buenos días gente, hoy llegué a la institución y el timbre automático parece estar funcionando correctamente, por ahora viene tocando los timbres en horarios correctos. Lo voy a dejar el resto del día, si surgiese algún inconveniente mañana lo desinstalo y lo traigo conmigo para testearlo completamente. Cabe recalcar que esta usando mi código viejo, no le hice ningún cambio aún. Les adjunto fotos de las conexiones como me solicitaron el día de ayer, a su vez, quería mostrarles que está conectado a la corriente mediante su USB y en la punta tiene un cargador de celular de 5V, esto también podría generar problemas? Es uno genérico que encontré por ahí, debería preocuparme? O con ese está bien. Adjunto las fotos y en el correr del día les comento como funcionó.





Si se preguntan a que pines esta conectado el relé, son los siguientes:
VCC = 5V
IN2= PIN13
GND = GND

Los demás creo que se notan en la imagen, cualquier duda sobre las conexiones me lo escriben, gracias por su ayuda!

Aunque lo has documentado bien recuerda que la foto no es tan fácil de entender como un simple esquema a mano alzada.

Buenos días, adjunto el dibujo que realicé del esquema. Creo que es bastante entendible, al día de hoy me encuentro testeando el timbre con mi antiguo código, puse timbres cada 1 minuto, para ver si en algún momento el timbre queda atrapado en un bucle.


Actualizo el estado gente, lo estuve testeando toda la mañana, sonó correctamente en varios horarios, pero luego del timbre de 12:30 dejó de dar señales. En ese tramo, el timbre programado para las 12:45 no funcionó ya que el programa estaba muerto. Más tarde a las 12:54 el programa revivió y funcionó a las 13:15. Creo que es un problema de los delay? Algunas veces el programa se queda pegado y no toca los timbres. Adjunto el código que estoy usando ahora. Estoy intentando crear una función para usar millis() en lugar de delay. Pero no entiendo bien su funcionamiento. Cualquier comentario es de ayuda!
image

Adjunto el código:


// 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"

RTC_DS3231 RTC;                   // inicializa el modulo RTC
int r_diaSemana;                  // almacena el resultado del dia de la semana calculado
const int timbre = 13;             // Pin 13 encargado de activar el timbre, se conecta al Rele
int segundo;
int minuto;
int hora;
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=30;   int s1_c1=0;
int h2_c1=8;   int m2_c1=15;  int s2_c1=0;
int h3_c1=8;   int m3_c1=20;  int s3_c1=0;
int h4_c1=9;   int m4_c1=5;  int s4_c1=0;
int h5_c1=9;   int m5_c1=10;  int s5_c1=0;
int h6_c1=9;  int m6_c1=55;  int s6_c1=0;
int h7_c1=10;  int m7_c1=0;  int s7_c1=0;
int h8_c1=10;  int m8_c1=45;  int s8_c1=0;
int h9_c1=10;  int m9_c1=50;  int s9_c1=0;
int h10_c1=11; int m10_c1=35;  int s10_c1=0;
int h11_c1=11; int m11_c1=40;  int s11_c1=0;
int h12_c1=12; int m12_c1=25;  int s12_c1=0;
int h13_c1=12; int m13_c1=30;  int s13_c1=0;
int h14_c1=12; int m14_c1=45;  int s14_c1=0;
int h15_c1=13; int m15_c1=15;  int s15_c1=0;
//Horario de la tarde
int h16_c1=13; int m16_c1=30;  int s16_c1=0;
int h17_c1=13; int m17_c1=35;  int s17_c1=0;
int h18_c1=14; int m18_c1=20;  int s18_c1=0;
int h19_c1=14; int m19_c1=25;  int s19_c1=0;
int h20_c1=15; int m20_c1=10;  int s20_c1=0;
int h21_c1=15; int m21_c1=15;  int s21_c1=0;
int h22_c1=16; int m22_c1=0;  int s22_c1=0;
int h23_c1=16; int m23_c1=5;  int s23_c1=0;
int h24_c1=16; int m24_c1=50;  int s24_c1=0;
int h25_c1=16; int m25_c1=55;  int s25_c1=0;
int h26_c1=17; int m26_c1=40;  int s26_c1=0;
int h27_c1=17; int m27_c1=45;  int s27_c1=0;
int h28_c1=18; int m28_c1=20;  int s28_c1=0;
int h29_c1=18; int m29_c1=30;  int s29_c1=0;


////////////////////////////////// Void Setup() ///////////
void setup () { 
  
 pinMode(timbre, OUTPUT);                    // Configura como salida el pin 13
 Wire.begin();                               
 RTC.begin();                                // Inicia la comunicaci¢n con el RTC
 
// 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
} 
////////////////////////////////// Void loop() ///////////
void loop(){
 DateTime now = RTC.now();          // Obtiene la fecha y hora del RTC

 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();
 segundo=now.second();
 minuto=now.minute();
 hora=now.hour();

 
 int r_diaSemana= now.dayOfTheWeek();   // llama a la funcion que calcula el dia de la semana y lo almacena en r_diaSemana
 
 if (r_diaSemana == 6 || r_diaSemana == 7){  // si  es fin de semana no hace nada
 }
 else {  
  if(hora >=7 && hora<19){
    horario_1();           // llama a la funcion que activa el horario 1
  }  
 }
 
 digitalWrite(timbre, HIGH);     // apaga el timbre
 delay(1000);                    // La informaci¢n se actualiza cada 1 seg.
}   //////////////////////////////// Fin del void loop(), inician las Funciones/////////////////////////

/////////////////////////////// Funcion que activa el Timbre //////////////////////////////////
void activar_timbre(){
    digitalWrite(timbre, LOW); 
    Serial.println("Timbre Activo");
    delay(tiempo_timbre); 
}

/////////////////////Condicional del Horario 1  //////////////////////////////////
void horario_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();
   if ((hora==h17_c1) && (minuto==m17_c1) && (segundo==s17_c1))  activar_timbre();
    if ((hora==h18_c1) && (minuto==m18_c1) && (segundo==s18_c1))  activar_timbre();
    if ((hora==h19_c1) && (minuto==m19_c1) && (segundo==s19_c1))  activar_timbre();
    if ((hora==h20_c1) && (minuto==m20_c1) && (segundo==s20_c1))  activar_timbre();
    if ((hora==h21_c1) && (minuto==m21_c1) && (segundo==s21_c1))  activar_timbre();
    if ((hora==h22_c1) && (minuto==m22_c1) && (segundo==s22_c1))  activar_timbre();
    if ((hora==h23_c1) && (minuto==m23_c1) && (segundo==s23_c1))  activar_timbre();
    if ((hora==h24_c1) && (minuto==m24_c1) && (segundo==s24_c1))  activar_timbre();
    if ((hora==h25_c1) && (minuto==m25_c1) && (segundo==s25_c1))  activar_timbre();
    if ((hora==h26_c1) && (minuto==m26_c1) && (segundo==s26_c1))  activar_timbre();
    if ((hora==h27_c1) && (minuto==m27_c1) && (segundo==s27_c1))  activar_timbre();
    if ((hora==h28_c1) && (minuto==m28_c1) && (segundo==s28_c1))  activar_timbre();
    if ((hora==h29_c1) && (minuto==m29_c1) && (segundo==s29_c1))  activar_timbre();
}


Vuelvo a actualizar, cambié mi código para nunca usar delay pero igualmente el arduino sigue trancandose, ya no sé que podría ser.

image

Codigo nuevo:


// 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"

RTC_DS3231 RTC;                   // inicializa el modulo RTC
int r_diaSemana;                  // almacena el resultado del dia de la semana calculado
const int timbre = 13;             // Pin 13 encargado de activar el timbre, se conecta al Rele
int segundo;
int minuto;
int hora;
int tiempo_timbre=6000; // Tiempo continuo que dura el timbre sonando, en milisegundos 5000 = 5 segundos

unsigned long inicioTimbre = 0; // Variable para almacenar el tiempo de inicio del timbre


//////////////////////////////// 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=30;   int s1_c1=0;
int h2_c1=8;   int m2_c1=15;  int s2_c1=0;
int h3_c1=8;   int m3_c1=20;  int s3_c1=0;
int h4_c1=9;   int m4_c1=5;  int s4_c1=0;
int h5_c1=9;   int m5_c1=10;  int s5_c1=0;
int h6_c1=9;  int m6_c1=55;  int s6_c1=0;
int h7_c1=10;  int m7_c1=0;  int s7_c1=0;
int h8_c1=10;  int m8_c1=45;  int s8_c1=0;
int h9_c1=10;  int m9_c1=50;  int s9_c1=0;
int h10_c1=11; int m10_c1=35;  int s10_c1=0;
int h11_c1=11; int m11_c1=40;  int s11_c1=0;
int h12_c1=12; int m12_c1=25;  int s12_c1=0;
int h13_c1=12; int m13_c1=30;  int s13_c1=0;
int h14_c1=12; int m14_c1=45;  int s14_c1=0;
int h15_c1=13; int m15_c1=15;  int s15_c1=0;
//Horario de la tarde
int h16_c1=13; int m16_c1=30;  int s16_c1=0;
int h17_c1=13; int m17_c1=35;  int s17_c1=0;
int h18_c1=14; int m18_c1=20;  int s18_c1=0;
int h19_c1=14; int m19_c1=25;  int s19_c1=0;
int h20_c1=15; int m20_c1=10;  int s20_c1=0;
int h21_c1=15; int m21_c1=15;  int s21_c1=0;
int h22_c1=16; int m22_c1=0;  int s22_c1=0;
int h23_c1=16; int m23_c1=5;  int s23_c1=0;
int h24_c1=16; int m24_c1=50;  int s24_c1=0;
int h25_c1=16; int m25_c1=55;  int s25_c1=0;
int h26_c1=17; int m26_c1=40;  int s26_c1=0;
int h27_c1=17; int m27_c1=45;  int s27_c1=0;
int h28_c1=18; int m28_c1=20;  int s28_c1=0;
int h29_c1=18; int m29_c1=30;  int s29_c1=0;


void setup() {

  pinMode(timbre, OUTPUT);
  Wire.begin();
  RTC.begin();
  Serial.begin(9600);
}

void loop() {
  DateTime now = RTC.now();
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
  segundo = now.second();
  minuto = now.minute();
  hora = now.hour();

  int r_diaSemana = now.dayOfTheWeek();

  if (r_diaSemana == 6 || r_diaSemana == 7) {
  } else {
    if (hora >= 7 && hora < 19) {
      horario_1();
    }
  }

  digitalWrite(timbre, HIGH);
  // No uses delay(1000); aquí, la información se actualizará automáticamente.

}

void activar_timbre() {
  digitalWrite(timbre, LOW);
  Serial.println("Timbre Activo");
  inicioTimbre = millis(); // Guarda el tiempo de inicio del timbre

  while (millis() - inicioTimbre < tiempo_timbre) {
    // Puedes hacer otras tareas aquí si es necesario
  }

  digitalWrite(timbre, HIGH);
}

/////////////////////Condicional del Horario 1  //////////////////////////////////
void horario_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();
   if ((hora==h17_c1) && (minuto==m17_c1) && (segundo==s17_c1))  activar_timbre();
    if ((hora==h18_c1) && (minuto==m18_c1) && (segundo==s18_c1))  activar_timbre();
    if ((hora==h19_c1) && (minuto==m19_c1) && (segundo==s19_c1))  activar_timbre();
    if ((hora==h20_c1) && (minuto==m20_c1) && (segundo==s20_c1))  activar_timbre();
    if ((hora==h21_c1) && (minuto==m21_c1) && (segundo==s21_c1))  activar_timbre();
    if ((hora==h22_c1) && (minuto==m22_c1) && (segundo==s22_c1))  activar_timbre();
    if ((hora==h23_c1) && (minuto==m23_c1) && (segundo==s23_c1))  activar_timbre();
    if ((hora==h24_c1) && (minuto==m24_c1) && (segundo==s24_c1))  activar_timbre();
    if ((hora==h25_c1) && (minuto==m25_c1) && (segundo==s25_c1))  activar_timbre();
    if ((hora==h26_c1) && (minuto==m26_c1) && (segundo==s26_c1))  activar_timbre();
    if ((hora==h27_c1) && (minuto==m27_c1) && (segundo==s27_c1))  activar_timbre();
    if ((hora==h28_c1) && (minuto==m28_c1) && (segundo==s28_c1))  activar_timbre();
    if ((hora==h29_c1) && (minuto==m29_c1) && (segundo==s29_c1))  activar_timbre();
}


Bueno diré lo mismo que le acabo de responder a otra persona.
Vienen al foro, piden ayuda, se las brindamos, aportamos un código completamente nuevo, con opciones para probarlo incluso simulado y no se recibe un "lo probé pero sigo con el mío.".
En realidad no se cual es la palabra, pero desalienta mucho ayudar.

Incluso de ver como esta hecho el mio podrías aprender a simplificar el tuyo.
Al menos eso te daría un salto de calidad en el código.
Diferente es ver si funciona o no. Eso parece que esta logrado.

Lo mismo digo porque imagino que ni miraste lo que te pasé en el post #5.

Hacer cambios en la impresión puede ayudar a corregir el problema. Aumentar la velocidad de 9600 a 115200 es una opción (recuerda cambiar la velocidad en el monitor del IDE)

Imprimir la hora una sola vez por segundo me parece un cambio de mayor impacto. Aunque mi preferencia personal sería imprimir la hora solamente dentro de activar_timbre()

Buenos días gente, primero que nada, pido disculpas si en algún momento ofendí a alguien con mis respuestas.
Quiero recalcar que si probé los códigos que me enviaron y la verdad si sirven, pero preferí utilizar el mío propio, puesto que lo entiendo mejor y sentía que le faltaba algún ajuste para funcionar. Aunque ustedes digan que no, me basé en sus códigos y en sus consejos, por ejemplo, siguiendo sus tips, borré completamente los delays de mi código y pase a utilizar la función millis para administrar la duración del timbre.
Les vengo a confirmar que desde el viernes pasado, hice una última corrección, que fue reiniciar la variable inicioTimbre a 0 cada vez que se reproducía el timbre. Y al parecer, esta fue la solución! Al día de hoy continúa funcionando a la perfección sin bloqueos ni fallas.

Agradezco completamente a todos ustedes por sus aportes y aprecio mucho toda su ayuda!
Este viernes se cumplirá una semana del timbre funcionando perfectamente. Si es así, publicaré aquí la confirmación y cerraré el hilo. Muchas gracias a todos y disculpen.

PD: Dejé toda las variables que creé porque ya que todo funciona correcto pero no quiero mover más nada jaja. Pero sé que se puede simplificar de otra manera, con arrays o demás. En un principio yo lo había realizado asi jeje.

Me da gusto que alguno de los consejos que te hemos dado te haya servido.
Solo aprende de esto para que si alguien te responde a tus consultas, tu tmb le des una devolución.

Me alegro que el código funcione bien y que se haya vuelto estable.
1 semana es mas que suficiente ya que no tienes cosas raras como en otros caso como en aplicaciones WIFI por ejemplo.

Bueno, hay cosas para mejorar porque la mirada de otro siempre es diferente, pero operativamente esta bien.

2 posts were split to a new topic: Timbre escolar Consejos