Problema extraño con TimeAlarms

Hola.

Tengo un problema con la librería TimeAlarms, muy, pero que muy raro.

Esta es la función de ajuste de las alarmas:

void alarmsSetUp() {
	//Horarios de conexion
	t = rtc.getTime(); // lee la hora del reloj RTC
	setTime(t.hour, t.min, t.sec, t.date, t.mon, t.year); //Ajusta la hora del arduino

	Alarm.alarmRepeat(9, 19, 0, sendIR_code); 
	Alarm.alarmRepeat(14, 22, 0, sendIR_code);
	Alarm.alarmRepeat(17, 15, 0, sendIR_code); 
	Alarm.alarmRepeat(23, 52, 15, sendIR_code);
}

Es decir que tiene que enviar un IR 4 veces al dia (por el momento).

Lo que es muy extraño es que las 2 primeras alarmas (9:19:0 y 14:22:0) no funcionan y las otras 2 (17:15:0 y 23:52:15) funcionan perfectamente.

La primera si la cambio a por las 10:01:00 tambien funciona.

A la hora de presentar la hora en la pantalla hay un Alarm.delay(1000); para que mire si tiene que saltar o no.
He probado a ponerlas en el setup, a cambiarlas de orden y mil cosas más, pero las de las 9:19 y la de las 14:22, no funcionan, llega la hora y salta sin entrar en sendIR_code.
¿el alguna limitación de la librería? La he visto por encima y no parece que sea ese el problema.

No he encontrado un patrón de las horas a las que funciona o no. He quitado las 2 primeras y he dejado las segundas y funcionan. Dejando sólo las primeras no saltan.

La presentación del reloj es la siguiente función:

void digitalClockDisplay() {
	// reloj en el LCD
	lcd.setCursor(0, 0);
	printDigits(hour());
	lcd.print(":");
	printDigits(minute());
	lcd.print(":");
	printDigits(second());
	Alarm.delay(1001);
}

void printDigits(int digits) {
	if (digits < 10)
		lcd.print('0');
	lcd.print(digits);
}

Muchas gracias por vuestra atención.

Como no veo el código completo no se bien si este puede o no ser el problema.
La librería tiene por defecto un límite de alarmas posibles según la SRAM del Arduino bajo uso.

En TimeAlarm.h puedes ver esto

#if !defined(dtNBR_ALARMS )
#if defined(__AVR__)
#define dtNBR_ALARMS 6   // max is 255
#elif defined(ESP8266)
#define dtNBR_ALARMS 20  // for esp8266 chip - max is 255
#else
#define dtNBR_ALARMS 12  // assume non-AVR has more memory
#endif
#endif

EN un AVR común tienes 6 alarmas máximo y eso puede ser un limitante.
No para que no responda a las primeras y si a las otras.

Edito: esa rutina me hace creer que intentas cambiar las alarmas de un modo dinámico y eso no es posible acer del modo que lo estas haciendo.

Postea todo el código.

Hola
Como siempre, un placer leerte Surbyte.

No, las alarmas no son dinámicas, están en una función aparte pero la llama desde el setup. Estaban directamente en el setup pero pasa exactamente igual.

Sólo hay 4 alarmas, pero pasa lo mismo si solo dejo una de la hora a la que no salta. Por lo que descarto la problema con tamaño de SRAM.

Investigando un poco, puede que cuando hace el Alarm.delay(x) se salte la lectura de que la alarma tiene que saltar. Por ejemplo si tiene se saltar a las 9:19:00, puede que al leer el reloj lo presente en la pantalla correctamente pero empiecee a leer una milesima de segundo despues y entonces ya lo toma como 9:19:01 y no capture el momento exacto. Porque si no he visto mal la hora es un unsigned long con toda la información de la fecha y la hora. Pero tambien se me hace raro pues he llegado a poner un Alarm.delay(1500); y tampoco funciona.

He puesto tambien un Alarm.delay(1000) antes de presentar el reloj y otro después, entonces hace cosas raras, salta 2 segundos, va bien, vuelve a saltar un segundo pero rápidamente, vuelve a saltar otros 2… pero no salta ninguna alarma.

Y por descontado esto me retrasa el resto del programa y hace que no funcione del todo bien, como por ejemplo el botón de activación/desactivación de las alarmas, botones de ajuste del reloj, etc.

El código es largo, y en varios archivos, por eso lo subo en un zip. Está un poco caótico porque estoy con pruebas.

Voy a investigar si hay alternativa.

Muchas gracias

Programador.zip (5.64 KB)

Con semejante código tienes que indicar que arduino usas y agregar aparte las librerías.
No podré compilarlo porque usas

#include <DS1302.h>
#include <dht11.h>

Rescato esto que esta bien indicado

#include <LiquidCrystal_I2C.h> //http://www.naylampmechatronics.com/blog/35_Tutorial--LCD-con-I2C-controla-un-LCD-con-so.html https://github.com/marcoschwartz/LiquidCrystal_I2C.git

Me arriesgo a pensar que te quedas sin RAM

Corre esta rutina

int freeRam () {
 extern int __heap_start, *__brkval;
 int v;
 return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

y agregala asi

Serial.println F("==================================================");
          Serial.println(freeRam());
          Serial.println F("==================================================");

de modo de ver en cada ciclo cual es el esado de tu SRAM.

Muchas gracias Surbyte,

Probaré el código en cuanto llegue a casa, estoy fuera y no tengo acceso al montaje.

Tmabién postearé el origen de las librerías. Tienes toda la razón que es buena práctica lo que tengo con la I2C no sólo para otros, si no para mi mismo dentro de un tiempo.

Ya te cuento.

Un saludo

Buenas tardes,

Efectivamente parece que me quedo sin RAM para el programa y por eso unas veces funciona y otras no. Así que deberé cambiar de estrategia.
Por lo que he leido, la libería de timers se come mucha memoria y es lo que hace que no salten.

No veo una solución clara, limitar el uso del programa y eliminar lo que no sea imprescindible, y que se pueda realizar desde el exterior, por ejemplo el ajuste de la hora.
También veo un problema añadido, ya que pretendía que las alarmas fueran dinámicas, es decir, que por programa se pudieran reajustar, pero teniendo en cuenta que siempre sería el mismo número de ellas, "n" alarmas y por lo que he podido ver, con esta libería no es posible.

¿sabeis de alguna otra libería que pueda hacer lo que necesito? He buscado pero no he encontrado nada.

Otra cosa que se me ocurre es hacer una rutina que compruebe la hora y comparala con la de las alarmas, y así actuar en consecuencia. Tengo que echarle un rato de pensamiento ya que veo alguna dificultad con la comparación de los tiempos (o hacerlo día, hora y minuto por separado) y levantar un flag para que no haya rebote dentro del mismo minuto.

Muchas gracias por vuestra ayuda.

No hay que yo sepa otra liberia para manejar alarmas diarias.
Porque no pegas o adjuntas todo el código e indicas que Arduino estas usando como para ver donde esta el problema?

Hola,

El código ya lo puse en un post anterior y me lo revisaste. El arduino es un arduino pro mini para que entre en la caja que necesito.
Como estoy parado con este montaje, lo voy a dejar por un tiempo porque lo necesito para otros menesteres y creo que es necesario que me replantee el proyecto para que sea menos "ambicioso". De cualquier manera, ya la librería Timealarm y Time se comen bastante SRAM.

En las vacaciones espero poder retomarlo de nuevo.

Por lo menos he aprendido que la memoria hay que mimarla más de lo que pensaba. :slight_smile:

Muchas gracias por vuestra ayuda, siempre aprendiendo algo de los mejores.

Cuando te quedes limitado de memoria y de espacio, andate a comprar un STM 32.

Casi del mismo tamaño del Pro-mini, dejas la limitante de la memoria y eres feliz.

Saludos.

-Alex.