-->
Page 1 of 1

Carrying parameters to a timer callback

PostPosted: Fri Sep 08, 2017 1:11 am
by blavery
I am wishing there were a way to carry a "miscellaneous baggage" parameter to a timer callback or a node.task.post callback.

Currently node.task.post() gives a "priority" argument to its callback function. That seems rather useless, unless I am missing something obvious. And a callback from myTimer.alarm() is given one argument, the ID of the timer.

I have a stepper motor application with two myStepper1 and myStepper2, constructed as objects. They each own a OO timer, and the two timers call the SAME class Stepper "step" function. When Stepper.step(timr) callback is called by the timer, the only thing the callback can know is the timer. It doesn't know who OO "itself" is! I have needed to use a lookup table of timerID-vs-stepperID to find my own OO "self". In the Stepper constructor [ myStepper1 = Stepper.new(pin, pin, pin, pin) ] I add a new entry to a lookup table: Stepper.identifyMe[self.timer]=self
And then as step() starts I need to retrieve my own identity like this: local self = Stepper.identifyMe[timr]

Unnecessarily convoluted. Again, am I missing something easy?

Re: Carrying parameters to a timer callback

PostPosted: Sat Sep 09, 2017 1:25 pm
by devsaurus
I don't know how to achieve what you asked for, but why not identify the stepper by control flow rather than data flow: register dedicated callback functions for the tmr objects?

E.g. an anonymous function which calls the step() method of the specific Stepper object. Like in

Code: Select allt = tmr.create()
t:register(100, tmr.ALARM_AUTO, function (timr) self:step(timr) end)

Just a guess, haven't tried the code myself though.

Re: Carrying parameters to a timer callback

PostPosted: Sat Sep 09, 2017 11:35 pm
by blavery
devsaurus,
Thank you. Once you point it out, it's obvious.
I changed my step() from

Code: Select allfunction Stepper.step(timr)
    local self = Stepper.identifyMe[timr] 


into simply
Code: Select allfunction Stepper.step(self)



And then changed my timer call from

Code: Select allself.timer:alarm( 1, 0, self.step)


into

Code: Select allself.timer:alarm( 1, 0, function(t) self:step() end)   


And it all works fine now without the cumbersome lookup.

Thank you, thank you, thank you.

(Incidentally, I use 1-shot timer, re-armed repetitively, to avoid a growing stack of still-pending callbacks. Otherwise I can crash lua on fastest callrate (1 msec) each running code using 1msec or more)

Re: Carrying parameters to a timer callback

PostPosted: Sun Sep 10, 2017 5:09 am
by devsaurus
Glad to learn that you solved this!
blavery wrote:(Incidentally, I use 1-shot timer, re-armed repetitively, to avoid a growing stack of still-pending callbacks. Otherwise I can crash lua on fastest callrate (1 msec) each running code using 1msec or more)

Yes, the task post-queue (I assume you still use node.task.post) has a limited size and can overrun quite quickly when more posts are produced than consumed on average. It's an elegant solution that you re-arm the timer in the callback.