Error passing function to TimeAlarms library

I am trying to use Timealarms library in my project.

I want to execute a function every time the alarm is fired.

All my code is inside a library I am developing. So, in arduino sketch, I import and initialize an object.

MyLib myLib = new MyLib();

Ok, my problem comes when I want to pass a function to Alarm.alarmRepeat. This is how I do it:

void MyLib::MorningAlarm1(){
  Serial.println("Alarm1");
  MorningAlarm(0);
}

void MyLib::MorningAlarm(int pos){
  int alarm_fired = Alarm.getTriggeredAlarmId();
  Serial.println(alarm_fired);
}

In another function, I have this:

Alarm.alarmRepeat(hour,
              minute,0, MorningAlarm1); //hour and minute, are int values 10 and 30 for example

//Example code in sketch from library: Alarm.alarmRepeat(8,30,0, MorningAlarm);

Then I got some errors:

C:\Users\myuser\Documents\Arduino\libraries\MyLib\MyLib.cpp: In member function 'void MyLib::loadRelayListValues()':
C:\Users\myuser\Documents\Arduino\libraries\MyLib\MyLib.cpp:416:191: error: no matching function for call to 'TimeAlarmsClass::alarmRepeat(int, int, int, <unresolved overloaded function type>)'
               relayList[i].alarm_id[ii-1] = Alarm.alarmRepeat(hour, minute, 0, MorningAlarm1); //change loop by desired function
                                                                                                                                                                                               ^
C:\Users\myuser\Documents\Arduino\libraries\MyLib\MyLib.cpp:416:191: note: candidates are:
In file included from C:\Users\myuser\Documents\Arduino\libraries\MyLib\MyLib.cpp:13:0:
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:69:13: note: AlarmID_t TimeAlarmsClass::alarmRepeat(time_t, OnTick_t)
   AlarmID_t alarmRepeat(time_t value, OnTick_t onTickHandler);                    // trigger daily at given time of day
             ^
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:69:13: note:   candidate expects 2 arguments, 4 provided
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:70:13: note: AlarmID_t TimeAlarmsClass::alarmRepeat(int, int, int, OnTick_t)
   AlarmID_t alarmRepeat(const int H,  const int M,  const int S, OnTick_t onTickHandler); // as above, with hms arguments
             ^
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:70:13: note:   no known conversion for argument 4 from '<unresolved overloaded function type>' to 'OnTick_t {aka void (*)()}'
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:71:13: note: AlarmID_t TimeAlarmsClass::alarmRepeat(timeDayOfWeek_t, int, int, int, OnTick_t)
   AlarmID_t alarmRepeat(const timeDayOfWeek_t DOW, const int H,  const int M,  const int S, OnTick_t onTickHandler); // as above, with day of week 
             ^
C:\Users\myuser\Documents\Arduino\libraries\TimeAlarms/TimeAlarms.h:71:13: note:   candidate expects 5 arguments, 4 provided
Error compiling.

And I don’t understand what they mean. Can you point me about how to solve them?

So, in arduino sketch, I import and initialize an object.

That is wrong. You never invoke a constructor directly.

MyLib myLib;

Is the correct way.

And I don't understand what they mean.

Suppose you have:

MyLib inst1;
MyLib inst2;

Now, the alarm goes off. Which instance should deal with the alarm? The Alarm class has no idea, rightfully so.

Your class must be the one that decides which instance is to be called. You do that my making the function to be called part of the class, not part of an instance, by making the method static.

Since you didn't post your header file, it is impossible to determine whether MorningAlarm1() is static, or not, but it seems unlikely.

Thank you PaulS.

Yes, I declared the instance as you said. I was doing a java code at the same time and I wrote it wrong.

I read about the static method in this case. My “MorningAlarm” method wasn’t static in header file, just a normal method.

I added static to its declaration in my header file. Now, having this header file:

...
class MyClass{
public:
...
void Morningalarm(int pos);
static void Morningalarm1();
...
}

And in my cpp file:

void MyLib::MorningAlarm1(){
  Serial.println("Alarm1");
  //MorningAlarm(0); //COMMENTED
}

void MyLib::MorningAlarm(int pos){
  int alarm_fired = Alarm.getTriggeredAlarmId();
  Serial.println(alarm_fired);
}

It works. But if I try to execute MorningAlarm1, it crashes because it is not a static method and MorningAlarm doesn’t know which one is the selected.

In my class (Which will exist just 1 instance in my program), I have an array (int alarmID_value[4]) in which I want to keep the alarmId of 4 differents alarms. I tried declaring static alarmID_value array so I can access from MorningAlarm and set the alarmId. But then, I get this error in a for loop I have in another place:

for(int i=0;i<=sizeof(alarmID_value)/sizeof(int);i++){

}

undefined reference to `MyLib::alarmID_value’

I think there are something I am not aware. How can I pass data from a static method to a non static? Or, is it possible to make the static method which instance I want it to use?

Maybe my questions are stupid but I have never tried to do something similar before.

But if I try to execute MorningAlarm1, it crashes because it is not a static method and MorningAlarm doesn't know which one is the selected.

"It crashes" is wrong, since attempting to call a non-static member from a static member is not allowed, so the code won't even compile.

In my class (Which will exist just 1 instance in my program),

Is your class written as a singleton? Can you enforce that there will ever only be once instance of the class?

If the answer is yes, then having a class serves no real purpose.

Lets consider an analogy. You have a high-end hotel that employs doormen to greet arriving patrons. You have 8 doormen in your employ, so that they can take vacations, get sick, not work 24 hours a day, etc.

A customer drives up - that is an interrupt; you need to drop everything and make that customer feel welcome.

So, you need to dispatch a doorman to greet the customer. Which one do you send?

Now, you are arguing that you will ever only employ one doorman. But, someone else might make a different decision with respect to how many instances of the class to create (how many doormen to employ).

Now, clearly, as a hotel owner you have some process for deciding which doorman to deploy to service the interrupt. There might be a doorman-of-the-day (which is a pointer to an instance of the doorman class that is to handle any interrupts). A doorman coming on duty would report, be assigned doorman-of-the-day status, and the previous doorman-of-the-day would go off duty.

The doorman class handles the doorman-of-the-day registration and dispatching of the doorman (of the day) to handle interrupts.

You can get around having the class maintain a list of instances (know who is able to register as doorman of the day) and having it dispatch the interrupt to the correct instance (notify the doorman of the day) by making all methods and data static (belonging to the class, not an instance of the class). But, a class that has only static instances and methods is useless AS A CLASS.

You could use a namespace to encapsulate the functionality, but that seems unnecessary.

Why do you think you need a class? A library consists of a header file defining what can be done, and a source file implementing the stuff that can be done. The header file does NOT have to define a class.

Thank you PaulS. Now I understand it, I will keep this post for future references.

I created my class following the next tutorial: https://www.arduino.cc/en/Hacking/LibraryTutorial My class is similar, some public methods, some privates, same with variables.

I guess I don't need a class, it would work fine just with functions and some global variables. but I tried to write all functions in a simple file (with its .h) and I get some errors related to "not declared in this scope" and "multiple definition of..." variables.

I am looking for a tutorial about how to do this before coming back for timeAlarm solution.

I tried to write all functions in a simple file (with its .h) and I get some errors related to "not declared in this scope" and "multiple definition of..." variables.

I am looking for a tutorial about how to do this before coming back for timeAlarm solution.

By far, the simplest thing to do is post your code here, along with the error messages. We'll help you fix it, and understand why what you did was wrong.