TimeAlarm isn't working sometimes

Hi,
i use an Arduino Mega which has a rtc module attached (v1.1 ds1307rtc) and working on it with the attached code. I have used the TimeAlarms library (downloaded it from TimeAlarms Library, Run Functions At Specific Times) to have an alarm every hour. The alarms should occur at different minutes every hour, but for testing i have set them all to the 12th minute. This code is waiting for a correct time, which i can set via usb, serial interface. The code is working fine most of the times. But sometimes the alarm is not activated and my leds are not flashing. I don't know why and when this happens, i didn't any changes between the working flashing and not working. Also i can't see any hours where it doesn't working correct, afaik it works correct, but fails sometimes. If it failes, it looks like all alarms are failing and they are not triggered. I know about the restriction of 6 alarms in TimeAlarms.h and set the variable dtNBR_ALARMS in this file to 25.

It looks like the Alarms are working if i flash the software to the arduino. But if i restart the arduino or shut it down for a while no alarm is triggered. But i still test, if it really depends on the flashing process.

As you can see i have implemented a printTime function which print out the rtc and the system time and always both are correct.

Has anyone an idea what i am doing wrong or why it fails sometimes?

#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include <DS1307RTC.h>

tmElements_t tm;

int pwm_2 = 2;
int pwm_3 = 3;
int pwm_4 = 4;
int pwm_5 = 5;
int pwm_6 = 6;
int pwm_7 = 7;
int pwm_8 = 8;
int pwm_9 = 9;
int pwm_10 = 10;
int pwm_11 = 11;
int pwm_12 = 12;
int pwm_13 = 13;
//delay in the for loops
int dly = 120;

// the setup routine runs once when you press reset:
void setup()  { 
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  RTC.read(tm);
  setTime(tm.Hour,tm.Minute,tm.Second,tm.Day,tm.Month,tm.Year);
  printTime();

  //wait for time input via serial, time must be set at every system boot
  while(tmYearToCalendar(tm.Year) < 2014) {
    Serial.println("wait in time loop, you have to set a time, current time is not correct:");
    printTime();
    if (Serial.available()) {
      time_t t = processSyncMessage();
      Serial.println("wait in time loop");
      if (t != 0) {
        RTC.set(t);   // set the RTC and the system time to the received value
        setTime(t); 
        Serial.println("time is succesfully set to");
        printTime(); 
        break;        
      }
    }
    delay(1000);
  }
  Serial.println("Time is already set to:");
  printTime();

  //set alarms for all hours in UTC, not in CET
  Alarm.alarmRepeat(0, 12, 0, shotAlarm);
  Alarm.alarmRepeat(1, 12, 0, shotAlarm);
  Alarm.alarmRepeat(2, 12, 0, shotAlarm);
  Alarm.alarmRepeat(3, 12, 0, shotAlarm);
  Alarm.alarmRepeat(4, 12, 0, shotAlarm);
  Alarm.alarmRepeat(5, 12, 0, shotAlarm);
  Alarm.alarmRepeat(6, 12, 0, shotAlarm);
  Alarm.alarmRepeat(7, 12, 0, shotAlarm);
  Alarm.alarmRepeat(8, 12, 0, shotAlarm);
  Alarm.alarmRepeat(9, 12, 0, shotAlarm);
  Alarm.alarmRepeat(10, 12, 0, shotAlarm);
  Alarm.alarmRepeat(11, 12, 0, shotAlarm);
  Alarm.alarmRepeat(12, 12, 0, shotAlarm);
  Alarm.alarmRepeat(13, 12, 0, shotAlarm);
  Alarm.alarmRepeat(14, 12, 0, shotAlarm);
  Alarm.alarmRepeat(15, 12, 0, shotAlarm);
  Alarm.alarmRepeat(16, 12, 0, shotAlarm);
  Alarm.alarmRepeat(17, 12, 0, shotAlarm);
  Alarm.alarmRepeat(18, 12, 0, shotAlarm);
  Alarm.alarmRepeat(19, 12, 0, shotAlarm);
  Alarm.alarmRepeat(20, 12, 0, shotAlarm);
  Alarm.alarmRepeat(21, 12, 0, shotAlarm);
  Alarm.alarmRepeat(22, 12, 0, shotAlarm);
  Alarm.alarmRepeat(23, 12, 0, shotAlarm);

  // declare pin 2-13 to be an output:
  pinMode(pwm_2, OUTPUT); //red
  pinMode(pwm_3, OUTPUT); //blue
  pinMode(pwm_4, OUTPUT); //green
  pinMode(pwm_5, OUTPUT);  //red
  pinMode(pwm_6, OUTPUT); //blue
  pinMode(pwm_7, OUTPUT);  //green
  pinMode(pwm_8, OUTPUT);  //red
  pinMode(pwm_9, OUTPUT); //blue
  pinMode(pwm_10, OUTPUT);  //green
  pinMode(pwm_11, OUTPUT); //red
  pinMode(pwm_12, OUTPUT);  //blue
  pinMode(pwm_13, OUTPUT);  //green  
} 

void shotAlarm() {
  Serial.println("SHOTALARM");
  analogWrite(pwm_2, 255);
  analogWrite(pwm_5, 255);
  analogWrite(pwm_8, 255);
  analogWrite(pwm_11, 255);
  analogWrite(pwm_3, 255); 
  analogWrite(pwm_4, 255); 
  analogWrite(pwm_6, 255); 
  analogWrite(pwm_7, 255); 
  analogWrite(pwm_9, 255);
  analogWrite(pwm_10, 255); 
  analogWrite(pwm_12, 255); 
  analogWrite(pwm_13, 255); 
  for(int a = 0; a < 60; a = a+1) {
    for (int i = 0; i < 255; i = i + 1) {
      analogWrite(pwm_2, i); //red
      analogWrite(pwm_5, i); //red
      analogWrite(pwm_8, i); //red
      analogWrite(pwm_11, i); //red
      delay (5);
    }
    for (int i = 255; i > 0; i = i - 1) {
      analogWrite(pwm_2, i); //red
      analogWrite(pwm_5, i); //red
      analogWrite(pwm_8, i); //red
      analogWrite(pwm_11, i); //red
      delay (5);
    }
  }
}
void loop() {
  Alarm.delay(0);
  Serial.println("new loop");
  printTime();
  analogWrite(pwm_2, 0);
  analogWrite(pwm_5, 0);
  analogWrite(pwm_8, 0);
  analogWrite(pwm_11, 0);
  analogWrite(pwm_3, 255); 
  analogWrite(pwm_4, 255); 
  analogWrite(pwm_6, 255); 
  analogWrite(pwm_7, 255); 
  analogWrite(pwm_9, 255);
  analogWrite(pwm_10, 255); 
  analogWrite(pwm_12, 255); 
  analogWrite(pwm_13, 255); 
  for (int i = 255; i > 0; i = i - 1) {
    analogWrite(pwm_4, i); //green
    analogWrite(pwm_7, i); //green
    analogWrite(pwm_10, i); //green
    analogWrite(pwm_13, i); //green  
    Alarm.delay (dly);
  }
  for (int i = 0; i < 255; i = i + 1) {
    analogWrite(pwm_2, i); //red
    analogWrite(pwm_5, i); //red
    analogWrite(pwm_8, i); //red
    analogWrite(pwm_11, i); //red
    Alarm.delay (dly);
  } 
  for (int i = 255; i > 0; i = i - 1) {
    analogWrite(pwm_3, i); //blue
    analogWrite(pwm_6, i); //blue
    analogWrite(pwm_9, i); //blue
    analogWrite(pwm_12, i); //blue      
    Alarm.delay (dly);
  }
  for (int i = 0; i < 255; i = i + 1) {
    analogWrite(pwm_4, i); //green
    analogWrite(pwm_7, i); //green
    analogWrite(pwm_10, i); //green
    analogWrite(pwm_13, i); //green  
    Alarm.delay (dly);
  }  
  for (int i = 255; i > 0; i = i - 1) {
    analogWrite(pwm_2, i); //red
    analogWrite(pwm_5, i); //red
    analogWrite(pwm_8, i); //red
    analogWrite(pwm_11, i); //red
    Alarm.delay (dly);
  }
  for (int i = 0; i < 255; i = i + 1) {
    analogWrite(pwm_3, i); //blue
    analogWrite(pwm_6, i); //blue
    analogWrite(pwm_9, i); //blue
    analogWrite(pwm_12, i); //blue 
    Alarm.delay (dly);
  }
  Alarm.delay(0);
}

void printTime() {
  if (RTC.read(tm)) {
    Serial.print("Ok, RTC Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.print(", Date (D/M/Y) = ");
    Serial.print(tm.Day);
    Serial.write('/');
    Serial.print(tm.Month);
    Serial.write('/');
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.println();
  } 
  else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } 
    else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
  }
  Serial.print("Ok, System Time = ");
  print2digits(hour());
  Serial.write(':');
  print2digits(minute());
  Serial.write(':');
  print2digits(second());
  Serial.print(", Date (D/M/Y) = ");
  Serial.print(day());
  Serial.write('/');
  Serial.print(month());
  Serial.write('/');
  Serial.print(year());
  Serial.println();
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}
/*  code to process time sync messages from the serial port   */
#define TIME_HEADER  "T"   // Header tag for serial time sync message
unsigned long processSyncMessage() {
  unsigned long pctime = 0L;
  const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013 

  if(Serial.find(TIME_HEADER)) {
    pctime = Serial.parseInt();
    return pctime;
    if( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
      pctime = 0L; // return 0 to indicate that the time is not valid
    }
  }
  return pctime;
}

You have 24 alarms set.
Have you noted and acted upon this from the TimeAlarms readme ?

Q: How many alarms can be created?
A: Up to six alarms can be scheduled.
The number of alarms can be changed in the TimeAlarms header file (set by the constant dtNBR_ALARMS,
note that the RAM used equals dtNBR_ALARMS * 11)

I know about the restriction of 6 alarms in TimeAlarms.h and set the variable dtNBR_ALARMS in this file to 25.

As i mentioned in my first post, yes i have observed this. Can it be a memory Problem? How can i check if my code is using too much memory?
The arduino IDE says:

Binary sketch size: 13,334 bytes (of a 258,048 byte maximum)

I don't know if i'm right with the following calculation, please help me if i am wrong.
The arduino has 258bytes, the program code use 13 bytes and 24 alarms will use 2411bytes (=264bytes). So we need 277 (13+2411) bytes, but my arduino has only 258.
This could be the problem and i should be fine with ~20 (13+20*11=233bytes) alarms, right?

Is the value 11 in "note that the RAM used equals dtNBR_ALARMS * 11)" in bytes? There is no unit in the Readme :confused:

Sorry, I missed your reference to having adjusted the number of alarms in the .h file. Did you stop and start the IDE after making the change and is it possible that you have more than one copy of the .h file on your PC and that you edited the wrong one ?

The arduino has 258bytes, the program code use 13 bytes

That is 258K and 13K bytes not 258 and 13 bytes so memory does not seem to be a problem.

Try reading and printing the alarm ID for each alarm as it is created. Do you get 24 different and sensible IDs ?

Sorry for my late answer.
I checked the Alarm IDs and every Alarm has its own, unique Alarm ID. When an Alarm is triggered, the correct ID is triggered and i get the correct Alarm ID.
Sometimes a Alarm is triggered and sometimes not. I have tested it a littlebit and in my test the first three alarms got triggered but the 4th, 5th and 6th not. The 7th got triggered. I don't know why some Alarms are working and some alarms are not working. Any ideas?

  Alarm.delay(0);

Calling delay() with a value of 0 is not a good idea. Try NOT doing this, and see if it has any affect.

Thanks for this hint, i got this from the Readme of TimeAlarm. But also without the delay(0) not all aralms got triggered.
During my last test the first 4 alarms (id 0,1,2,3) got triggered and the 5th alarm which was set to " Alarm.alarmRepeat(17, 01, 0, shotAlarm);" was triggered 17:02:21 and not on 17:01:00, i don't know why this happened, the rtc and the system time are both correct.

After an alarm the callback function is ended and i don't know at which point of our loop() function is continued. Sometimes we have glitches in the colour spectrum after an alarm and don't know to which point the process jumps.

But also without the delay(0) not all aralms got triggered.

You do need to call Alarm.delay(). Just NOT with a value of 0.

For all who read this thread later:
I found the mistake in my code. The following line was wrong:

setTime(tm.Hour,tm.Minute,tm.Second,tm.Day,tm.Month,tm.Year);

The correct version is:

setTime(tm.Hour,tm.Minute,tm.Second,tm.Day,tm.Month,tmYearToCalendar(tm.Year));

Unfortunately i forgot to convert the year value to the expected format. The code from above is working very fine with this correction. I checked the alarms for more then a week and it is working very stable.

Thanks all for their help.