[SOLVED]Alarm.alarmRepeat doesn't work

Hi everybody, I'm trying to make this function working, all timers in this library work, but not Alarm.alarm.Repeat().
I look the serial if the event prints but none. Anyone knows why?

I took the main example of this library and just added some things.

here's my code

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

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

void setup()
{
  Serial.begin(9600);
  //setTime(8,29,0,1,1,10); // set time to 8:29:00am Jan 1 2010
  // create the alarms 
  Alarm.alarmRepeat(8,30,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(21,34,0,EveningAlarm);  // 5:45pm every day 
 
  //Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  //Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  if(Serial.available() ) 
  {
    processSyncMessage();
  }
  if(timeStatus() == timeNotSet) 
    Serial.println("waiting for sync message");
  else     
      digitalClockDisplay();
  Alarm.delay(1000);
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}  

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

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of header & 10 ASCII digits
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

hope someone could help :slight_smile:

I noticed that moving the alarmRepeat functions to the loop gives the alert on the serial, but it prints 3 times. I would know why...

1:13:57 19/6/2013
1:13:58 19/6/2013
1:13:59 19/6/2013
Alarm: - turn lights off
Alarm: - turn lights off
Alarm: - turn lights off
1:14:00 19/6/2013
1:14:01 19/6/2013
1:14:02 19/6/2013
1:14:03 19/6/2013

It doesn't seem a nice workaround but seems to work.

UPDATE:

I edited the code. Moved all time sync stuff in setup() and it works.

waiting for sync message
T1:36:57 19/6/2013
1:36:58 19/6/2013
1:36:59 19/6/2013
Alarm: - turn lights off
1:37:01 19/6/2013
1:37:02 19/6/2013
1:37:03 19/6/2013

here's the code

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

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 

void setup()
{
  Serial.begin(9600);

  while(timeStatus() == timeNotSet){
    if(Serial.available() && timeStatus() == timeNotSet){
      processSyncMessage();
    }
    if(timeStatus() == timeNotSet) 
      Serial.println("waiting for sync message");
    else     
        digitalClockDisplay();
    Alarm.delay(1000);
  }
  
  Alarm.alarmRepeat(1,37,0, MorningAlarm);  // 8:30am every day
  //Alarm.delay(1000);
  Alarm.alarmRepeat(21,34,0,EveningAlarm);  // 5:45pm every day 
   
   
  //Alarm.alarmRepeat(1,12,0, MorningAlarm);  // 8:30am every day
  //Alarm.alarmRepeat(21,34,0,EveningAlarm);  // 5:45pm every day 
 
  //Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  //Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){
  if(timeStatus() == timeNotSet) 
      Serial.println("waiting for sync message");
    else     
        digitalClockDisplay();
    Alarm.delay(1000);
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");
  Alarm.delay(1000);
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");
  Alarm.delay(1000);
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print("/");
  Serial.print(month());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println(); 
}  

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

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of header & 10 ASCII digits
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

(still thinking it's not very nice, but it works! if anyone knows how to improve this code and want to share his knowledge... :slight_smile:

Putting each { on a new line, and using Tools + Auto Format would greatly improve the readability of your code.

Deleting the commented out code would too.

Why are you calling Alarm.delay() in the callback functions?

what is a callback function? I use alarm.delay because I've read that I need it instead of normal delay for use the alarms functions

here's my code updated and cleaned

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

#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by Unix time_t as ten ASCII digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message
#define TIME_REQUEST  7    // ASCII bell character requests a time sync message 


int relePin = 8;

void setup()
{
  pinMode(relePin, OUTPUT);

  Serial.begin(9600);

  // test relè and motors
  int a=0;
  while(!Serial.available()){
    Alarm.delay(10);
  }
  if(Serial.available() && a==0){
    testMotors();
    a++;
  }

  while(timeStatus() == timeNotSet){
    if(Serial.available() && timeStatus() == timeNotSet){
      processSyncMessage();
    }
    if(timeStatus() == timeNotSet) 
      Serial.println("waiting for sync message");
    else     
      digitalClockDisplay();
    Alarm.delay(1000);
  }

  Alarm.alarmRepeat(18,10,0, MorningAlarm);    // 7:00am every day
  Alarm.alarmRepeat(7,10,0, MorningAlarm);   // 7:10am every day
  //Alarm.alarmRepeat(20,0,0,EveningAlarm);  // 20pm every day 
  //Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  //Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){
  if(timeStatus() == timeNotSet) 
    Serial.println("waiting for sync message");
  else     
    digitalClockDisplay();
  Alarm.delay(1000);
}

void testMotors(){
  int i, reduce;
  Serial.println("armando il motore...");
  Alarm.delay(3000);
  for(i=0, reduce=2000;i<10, reduce>=400;i++){
    digitalWrite(relePin, HIGH);
    Alarm.delay(reduce);
    digitalWrite(relePin, LOW);
    Alarm.delay(reduce);
    digitalWrite(relePin, HIGH);
    Alarm.delay(reduce);
    digitalWrite(relePin, LOW);
    Alarm.delay(reduce);
    reduce/=2;
  }
  Serial.println("motore armato!");
}  

void accendiMotori(){
  digitalWrite(relePin, HIGH);
  Alarm.delay(40000);
  digitalWrite(relePin, LOW);
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");
  Alarm.delay(1000);
  accendiMotori();
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");
  Alarm.delay(1000);
  accendiMotori();
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print("/");
  Serial.print(month());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println(); 
}  

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

void processSyncMessage() {
  // if time sync available from serial port, update time and return true
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of header & 10 ASCII digits
    char c = Serial.read() ; 
    Serial.print(c);  
    if( c == TIME_HEADER ) {       
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){   
        c = Serial.read();          
        if( c >= '0' && c <= '9'){   
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number    
        }
      }   
      setTime(pctime);   // Sync Arduino clock to the time received on the serial port
    }  
  }
}

what is a callback function?

It's a delegate - a way to tell another function to do something using code you write. When the alarm goes off, you want the Alarm class to call your function (MorningAlarm or EveningAlarm). So, you tell the instance which function to call(back) when it has something to do.

So, for example, MorningAlarm is a callback function? right?

You need to call Alarm.delay in your loop once to update the alarms. If you already have some delay like a millis counter use Alarm.delay(0)

So, for example, MorningAlarm is a callback function? right?

Exactly.