I’m loving the ease of use when developing code for the Photon, but I’m seeing a little lack in the documentation. No biggie for something that’s growing this fast, but as such I need a little help with the Timer class.
I’d like to add a Timer to my Door class, but I can’t get the timer to call another function in the class.
Door::Door(int pin) {
_timer = new Timer(OPEN_DOOR_TIME, &Door::alarm);
}
This is based on the interrupts which would use the following code (from the reference)…
Door.cpp:17:52: error: no matching function for call to 'Timer::Timer(unsigned int, void (Door::*)())'
_timer = new Timer(OPEN_DOOR_TIME, &Door::alarm);
^
Door.cpp:17:52: note: candidates are:
In file included from ./inc/application.h:52:0,
from Door.h:5,
from Door.cpp:2:
../wiring/inc/spark_wiring_timer.h:34:5: note: Timer::Timer(unsigned int, Timer::timer_callback_fn)
Timer(unsigned period, timer_callback_fn callback_) : handle(nullptr), callback(callback_) {
^
../wiring/inc/spark_wiring_timer.h:34:5: note: no known conversion for argument 2 from 'void (Door::*)()' to 'Timer::timer_callback_fn {aka void (*)(Timer&)}'
../wiring/inc/spark_wiring_timer.h:32:5: note: Timer::Timer(unsigned int, void (*)())
Timer(unsigned period, void (*callback)()) : Timer(period, timer_callback_fn(callback)) {}
^
../wiring/inc/spark_wiring_timer.h:32:5: note: no known conversion for argument 2 from 'void (Door::*)()' to 'void (*)()'
After going down the rabbit hole and reading everything on the subject of non-static member functions I could find, the solution turns out to be quite simple.
This allows me to initiate Timer from inside an instance and callback a method inside of my class:
The downside is that the this pointer will be invalid in the member function since the caller isn’t pushing that to the stack. So then you might as well make it a static member function to ensure the this pointer isn’t used, then the cast isn’t necessary.
Thanks @peekay123, I didn’t realize there was a new system firmware release.
I’m trying to use Timer from INSIDE one of my non-static member functions so I don’t have to block for pin timing delays. I also need to delay for a substantial amount of time in order to allow the device I’m controlling to go through it’s cycle.
I’m trying:
Timer(delay,&Device::pinsLow,this,true);
but it will not compile.
Another question I have is:
When I’m using Particle Dev, how does it know what system firmware version to target? Does it read the Photon I’m targeting?
@mdma You are correct! I tested my program for DAYS and all the debug statements seemed to indicate that I was actually manipulating an instance of my class. And I was getting good behavior. But once you raised the gotcha I re-scrutinized my logs and sure enough, there were a couple of times an increment did not occur on my instance. And one where an increment showed as a decrement. So I’ve been running along happily poking random memory without a crash. Wow. Thanks for straitening me out. Now I just have to figure out how to use the new Timer…
Here’s a solution I just worked up and tested. Seems to work. Created a “leds” class that blinks leds connected to gpio pins and some methods to control them, based on Timers:
Leds.h:
#include "application.h"
class Leds
{
private:
int led_state;
int r;
int p;
Timer *tp;
void blink (void);
public:
Leds (int pin, int rate, int state);
void changePeriod (int t);
void start (void);
void stop (int s);
};
Just a note on my last example, in case you wondered, there is some “noise” code left over from testing, like in leds.cpp the sprintf() I used when I published events to see if the blink() method was called. Needs cleaning up…
I have read the library, but I’m just confused when testing it in the real world…
the LED seems to continuously run although I put it in the setup (where it should be run one time).
There is where I’m confused…
The whole reason for that blink class is to have the LEDs running independent of your code.
After all the thread topic does explicitly deal with independent Timers.
If you don’t just copy the code but read the discussion in this tread, you see the reason behind the code.