Current Lua downloadable firmware will be posted here

User avatar
By blavery
#69803 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?
Last edited by blavery on Sat Sep 09, 2017 11:08 pm, edited 1 time in total.
User avatar
By devsaurus
#69835 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.
User avatar
By blavery
#69851 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)
User avatar
By devsaurus
#69853 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.