Call Ticker library from another class1

I need to execute the function "keyboard_control()" each 100ms.

I have tried several ways of calling function from inside a class, using a Ticker object, but it have not worked. It only works if I declare "keyboard_control()" as static "static void keyboard_control()" inside the class, but then it will not be able
to access "key_pressed" variable from this class. What can I do to run "keyboard_control()" using a Thicker object?

Thanks a lot for any helping!


.H file
include <Ticker.h>

class Keyb
{
public:

  bool key_pressed;  //true if any key was pressed


  Ticker keyboard_ticker; 
  
  Keyb(/*several input values...*/);
  int  inkey();
  void keyboard_control();	//This function must be called each 100ms
							//and uses "key_pressed" variable declared as public in this class


  void inittesta() {
    keyboard_ticker.attach_ms(100, keyboard_control);	//it shows error that it should be declared as static
									//it if keyboard_control is declared as static, it will not be able 
									//to access "key_pressed" variable from this class. What can I do?
  }
};


Provide a GitHub link to the "Ticker" library you're using.

Also, specify which Arduino board you're compiling for.

Hi friend! I´m Using:
[env:nodemcuv2]
platform = espressif8266
board = nodemcuv2

I´m using default Arduino Ticker lib, but it is not clear for me what version is.
It is very interesting that the Ticker object call the attached function without the need to put a ticker.update() at loop() from Arduino, it seems that it is calling through an interrupt timer.

The code bellow worked, but I do not know whether is it the better form to do it.
Please, comment if possible :slight_smile:


.H file
include <Ticker.h>

class Keyb
{
public:

  bool key_pressed;  //true if any key was pressed


  Ticker keyboard_ticker; 
  
  Keyb(/*several input values...*/);
  int  inkey();
  void keyboard_control();	//This function must be called each 100ms
							//and uses "key_pressed" variable declared as public in this class

  static void ticker_trigger(Keyb* callback_func) {		//I did use an intermediate function(needs to be public!)
	callback_func->keyboard_control();
  }
  
  void inittesta() {
    keyboard_ticker.attach_ms(100, &ticker_trigger, this);	//it finally worked like a charm ;-)
  }
};


I see at least two libraries in the Arduino Library manager with a "Ticker.h" header file. That's why I asked for a GitHub link to the one you're using. Why make me guess?

Hi. The problem is that I cannot locate Thicker.h file... I´ve looked at several folders. I´m using platformio instead of Arduino IDE.

But I found on github this, that must be that one I use:
https://github.com/esp8266/Arduino/tree/master/libraries/Ticker

That will work. But, sticking with good OOP practices, you should make all class members private unless they absolutely need to be public:

#include "Arduino.h"
#include <Ticker.h>

class Keyb {
  public:
    Keyb();

    int inkey();

    void inittesta() {
      keyboard_ticker.attach_ms(100, ticker_trigger, this);
    }

  private:
    bool key_pressed;

    Ticker keyboard_ticker;

    void keyboard_control();

    static void ticker_trigger(Keyb* objectPtr) {
      objectPtr->keyboard_control();
    }
};

void setup() {
}

void loop() {
}

However, since ESP boards support the Standard Template Library and the Ticker library has an overload for std::function, a slicker way would be:

#include "Arduino.h"
#include <Ticker.h>

class Keyb {
  public:
    Keyb();
    int inkey();

    void inittesta() {
      Ticker::callback_function_t f{std::bind(&Keyb::keyboard_control, this)};
      keyboard_ticker.attach_ms(100, f);
    }

  private:
    bool key_pressed;

    Ticker keyboard_ticker;

    void keyboard_control();
};

void setup() {
}

void loop() {
}

gfvalvo, Thank you a lot!
Would you like explain-me the meaning of the linecode bellow?

Ticker::callback_function_t f{std::bind(&Keyb::keyboard_control, this)};

It's kind of involved and, like most things in "Modern C++", any documentation you find online will be full of pedantic Mumbo-Jumbo. But, breaking it down ....

It's creating and initializing an object (i.e. variable) of type "callback_function_t". The variable name happens to be "f".

The callback_function_t type is defined in Ticker scope (i.e. Ticker::). So, looking in Ticker.h, you find:

typedef std::function<void(void)> callback_function_t;

So, callback_function_t is just an alias for an object of type std::function. This is a wrapper class that can be used to encapsulate different types of functions and give them a common "look".

In this case, f is being initialized to encapsulate a function of type std::bind. Here's were the Mumbo-Jumbo really starts. But, suffice it to say that it gives you a way to call the keyboard_control function on the object pointed to by the "this" pointer.

Finally, this line:

keyboard_ticker.attach_ms(100, f);

Calls the overload of the attach_ms function that accepts a std::function argument (aliased as type callback_function_t) . Again, from Ticker.h:

    void attach_ms(uint32_t milliseconds, callback_function_t callback)
    {
        _callback_function = std::move(callback);
        _attach_ms(milliseconds, true);
    }

Mr [gfvalvo], you´re great!

Thank you for all your helpping! I´m sure it will help other people too!

With Regards
Eduardo

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.