I need to call a function in a Class using a Timer

I have run into a problem using SimpleTimer. I need to call a function this is a private member of a class I am using.
The definition of the function is:

void MyClass::a() {
  ...
}

Since it is not just

void a() {
...
}

I am unable to pass the name of the function to SimpleTimer.setTimeout() method.
I have tried:

//TimID = Tim.setTimeout(10000L,a);

which results in the error: 'a' was not declared in this scope

and I have tried:

TimID = Tim.setTimeout(10000L,MyClass::a)

; which results in the error: error: invalid use of non-static member function 'void MyClass::a()'
I have created a bare-bones script that contains just the code to define a class and some functions to demonstarte the problem:

#include <SimpleTimer.h>
SimpleTimer Tim;
int TimID = -1;
class MyClass {
  private:
    void thing(String t);
    void a();
 public:
    MyClass();
    void begin();
    
};

MyClass::MyClass() {
}
void MyClass::thing(String t){
  Serial.println(t);
}
void MyClass::a() {
  thing("hello");
} 
  
void b(){
  // Start a timer to call function a() after 10s
  //Since function a() is part of MyClass, the setTimeout code cannot find it
  // Both lines below fail to compile with the error in the respective comments
  
  //TimID = Tim.setTimeout(10000L,a);   // 'a' was not declared in this scope
  //TimID = Tim.setTimeout(10000L,MyClass::a); // error: invalid use of non-static member function 'void MyClass::a()'
  
} 
void MyClass::begin() {
  Serial.println();
  Serial.println("Started");
  MyClass::a(); // prints Hello as expected
  b();
}
MyClass Sample;
void setup() {
  Serial.begin(115200);
  Sample.begin();
}
void loop() {
}

I have also tried to create a 'helper' function such as:

void helper() {
  MyClass::a();
}

And then defining helper in the setTimeout method, but a() is private, so helper won't compile.

I have spent hours trying to understand some posts that look like they may be related, especially:
https://forum.arduino.cc/index.php?topic=86758.0
But I can't understand how to solve the problem.

Is there some way of doing what I need to do?
Is there a different Timer library that does not have this issue?

I may have to do my own 'timer' and check for them in .run method of my main class.

Class member functions have a different signature than regular functions and class static functions. Here's a good article on the subject: Standard C++

The easiest thing to do would be to make the class function static.

If I make a() static, then it can't call other private functions.

void MyClass::a() {
  MyClass::thing("hello");
}

fails to compile with:
error: cannot call member function 'void MyClass::thing(String)' without object
MyClass::thing("hello");

Yes, you'd need to specify the specific instance of the class in order to call a member function (private or public) from the static class function. Otherwise, how would it be known?

Look at the C++ keyword “this”. You may be able to use it here case to specify the instance of the class.

Ask yourself, why are these functions I'm trying to call "private"?

Maybe you are on the wrong track?

-jim lee

6v6gt:
Look at the C++ keyword “this”. You may be able to use it here case to specify the instance of the class.

yes, thanks, I did try that too, but it seems the issue is that the voids in a Class are not that same as non-class functions.

jimLee:
Ask yourself, why are these functions I'm trying to call "private"?

indeed, this is a good question, and I had wondered why I had got into having private functions in my Class.
I suspect that my inexperience in coding found that was a way to make implicit forward declarations, but I am no longer sure.
Since I already call my .run method in my void loop() I have simply implemented my own timer in my run() code.

So this class with the private methods.. You wrote it?

-jim lee

jimLee:
So this class with the private methods.. You wrote it?

yes, indeed I did, so I should know why.... right!
Problem, is my (wetware) memory is failing and even though I add comments like crazy, I still manage to lose track of some things. The class is complex, as I can can it from my own .ino (obviously) but can also call it from Blynk code - and it has callbacks to helper functions in order to do things in Blynk. It also uses u8g2, a TCP/IP stack, WifiManager... etc. Some of those libraries define things that are not constrained to their own libs so getting the interdependence between them all to work was tough for me. Sometimes I don't know why things worked, and attempts to understand things often drop me into arcane nuances of C compilers that would take me years to fully grok.

I am doing this as a hobby, I am not writing code for a living, and sometimes I don't touch C++ code for months, and work on some Visual Basic code in between. It takes a few days to get rid of finger memory that types ' instead of // to create a comment!

Since it has its own run() loop I call often, I suspect that rolling my own timers (as I ended up doing in this case) is probably more efficient and elegant. I may convert my existing SimpleTimers into simple longs that I can check against millis() in each iteration.

As for docs, I once worked with an assembly programmer that regarded the raw assembly code as the software documentation. If one asked how to use some feature, he would say "Read the asm source it's all there!" So I have learnt to try and balance enough learning to write decent code vs. developing my own CPU, compiler and OS! :slight_smile:

Ah, this is getting clearer..

You want some sort of object that can be used as a timer? Like, for example an egg timer?

Oh, as for your original question. If you haven't sorted it out yet. You could just add a public method that calls your private one in the original class. Its a hack, but I'm pretty sure it'll work. Or, just make the private one public. Or.. If your the only one using this stuff, make the entire thing public and watch your step a bit.

-jim lee