Cannot get TimeAlarms to trigger [Solved]

I have create a simple program for setting a time based alarm. I can check the current time with my variable “currTme” then set an alarm for a few minutes in the future using the function “times”.
The creation of the alarm seems to work correctly, but it will not trigger the callback function “runTime1”.

Not sure what I am missing.

Here is the entire code:

// This #include statement was automatically added by the Particle IDE.
#include "TimeAlarms/TimeAlarms.h"
#undef now()

int led = D7; // Instead of writing D7 over and over again, we'll write led2

char timeQuery[27]{0x00};
char currTime[25];

AlarmID_t alarm1 = 255;
 
struct TimeObj
{
    bool    active = false;
    int     hour = 0;
    int     minute = 0;
};

//EEPROM Addresses
int CalibAddr = 0;
int TimeZoneAddr = 1;
int Cat1Addr = 2;

// The STARTUP call is placed outside of any other function
// What goes inside is any valid code that can be executed. Here, we use a function call.
// Using a single function is preferable to having several `STARTUP()` calls.
STARTUP( setInitalValues() );

void setup() {
    Particle.variable("timeQuery", timeQuery, STRING);
    Particle.variable("currTime", currTime, STRING);
    
    Particle.function("times",timeSet);
    
    setTimeVariable();
    while( Time.now() < 10000) {
        Particle.process();
    }
}

void loop() {
    Time.timeStr().toCharArray(currTime, 25);
    
    Alarm.delay(1000);
}

int timeSet(String command) {
    debug(String::format("timeSet: %s", command.c_str()));
    
    String action = command.substring(0, 2);
    String arg = command.substring(2);

    if (action=="up") {
        
        int act = atoi(arg.substring(0,1));
        int hour = atoi(arg.substring(1,3));
        int min = atoi(arg.substring(3,5));
        
        TimeObj obj;
        
        EEPROM.get(Cat1Addr, obj);
        
        obj.active = act;
        obj.hour = hour;
        obj.minute = min;
        
        
        if(act){
            if(alarm1 == 255){
                alarm1 = Alarm.alarmRepeat(hour, min, 0, runTime1);
            }else{
                Alarm.write(alarm1, AlarmHMS(hour, min, 0));
            }
        }else{
            if(alarm1 != 255){
                Alarm.disable(alarm1);
            }
        }
        
        EEPROM.put(Cat1Addr, obj);
        
        setTimeVariable();
        return 0;
    }
    else if (action=="zn") {
        int8_t num = atoi(arg);
        EEPROM.write(TimeZoneAddr, num);
        Time.zone(num);
        return 1;
    }
    else {
        return -1;
    }
}

void runTime1(){
    debug("Timer1");
    
    digitalWrite(led, HIGH);
    TimeObj obj;
    EEPROM.get(Cat1Addr, obj);
    if(obj.active){
        ///
    }
}

void setTimeVariable(){
    TimeObj obj1;
    EEPROM.get(Cat1Addr, obj1);
    
    String str = String::format("%i%02i%02i ", obj1.active, obj1.hour, obj1.minute);
    
    str.toCharArray(timeQuery, sizeof(timeQuery));
}

void setInitalValues(){
    
    int8_t zone = (int8_t)EEPROM.read(TimeZoneAddr);
    Time.zone(zone); // gmt offset
    
    TimeObj obj1;
    EEPROM.get(Cat1Addr, obj1);
    
    if(obj1.active){
        alarm1 = Alarm.alarmRepeat(obj1.hour, obj1.minute, 0, runTime1);
        EEPROM.put(Cat1Addr, obj1);
    }
    
    Serial1.begin(9600); 
    
    pinMode(led, OUTPUT);
}

// Log message to cloud, message is a printf-formatted string
void debug(String message) {
    char msg [50];
    sprintf(msg, message.c_str());
    Particle.publish("DEBUG", msg);
}

Hi @HauptmannEck

I am not sure I fully understand your code–can you try a truly simple example that just uses fixed constant values and avoids the EEPROM and Particle variable stuff to just make sure the alarm part works?

In your setInitialValues() function, you get the TimeObj struct out of EEPROM and start to use it if it is marked “active” but I don’t see where you check the validity of the EEPROM data. The EEPROM function is likely to return data with all 1’s based on the underlying flash technology, so that would be active (0xff) with hours and minutes of -2147483648 (all 1’s). I would try to validate the EEPROM data so you can tell if has ever been written with correct data.

I did not know that about EEPROM, I added a ‘valid’ field to the struct with a random known value that I can check for.

But it seems my Alarm issue was the fact that the time was not set before I created the Alarm. by moving the alarm creation to the setup() function after the “while(Time.now() < 1000)”, it started working as intended.

Thanks for your help.

1 Like

Can you post the HTML and JS associated with this sketch?