Timer Callback executed just once

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
Sokrates
Posts: 15
Joined: Mon Dec 14, 2015 11:24 pm

Timer Callback executed just once

Post by Sokrates » Sun Dec 20, 2015 6:35 pm

Hello,

I'm at a very early stage of python programming language so please be patient :)

I'm trying to make my timer working and should be quite straight forward following the tutorial...but it is not :(

Basically my problem is that the callback function seems to be executed just 1 time, so that the updateLed flag is not updated to true any more and the if statement is always false.
I think I'm doing some very basic error.

Could you please have a look?

In general I need to have 2 or 3 timers running simultaneously and I'm trying to set just flags values into their related callbacks in order to not block the stack and execute the code in the main loop. Is that the current approach?

Code: Select all

import pyb

updateLed = False
led = pyb.LED(4)

def statusLed():
    global updateLed
    updateLed=True
    led.toggle()

tim1 = pyb.Timer(1)
tim1.init(freq=1)
tim1.callback(statusLed())

while True:
    i = 0;
    if updateLed == True:
       updateLed=False
       print('Test: ',i)
       i = i+1

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Timer Callback executed just once

Post by dhylands » Sun Dec 20, 2015 7:00 pm

Try changing this line:

Code: Select all

tim1.callback(statusLed())
to look like:

Code: Select all

tim1.callback(statusLed)
When you create timer callbacks, they also need to take a single argument, which is the timer, so you'll also need to modify:

Code: Select all

def statusLed():
to look like:

Code: Select all

def statusLed(tim):
What your original code did was to call statusLed() and pass the results of calling that function to tim1.callback. In python if a function doesn't explicitly return anything, then it behaves as if you had returned None. So your original code was equivalent to the following code snippet:

Code: Select all

statusLed()
tim1.callback(None)
By removing the () you pass the statusLed function. With the parenthese you call the statusLed function and pass what statusLed() returns. A subtle, but very important distinction.

You probably want to move your i = 0 outside of the while loop, otherwise it will reassigned 0 each time through the loop.

Sokrates
Posts: 15
Joined: Mon Dec 14, 2015 11:24 pm

Re: Timer Callback executed just once

Post by Sokrates » Sun Dec 20, 2015 7:17 pm

dhylands wrote:Try changing this line:

Code: Select all

tim1.callback(statusLed())
to look like:

Code: Select all

tim1.callback(statusLed)
When you create timer callbacks, they also need to take a single argument, which is the timer, so you'll also need to modify:

Code: Select all

def statusLed():
to look like:

Code: Select all

def statusLed(tim):
What your original code did was to call statusLed() and pass the results of calling that function to tim1.callback. In python if a function doesn't explicitly return anything, then it behaves as if you had returned None. So your original code was equivalent to the following code snippet:

Code: Select all

statusLed()
tim1.callback(None)
By removing the () you pass the statusLed function. With the parenthese you call the statusLed function and pass what statusLed() returns. A subtle, but very important distinction.

You probably want to move your i = 0 outside of the while loop, otherwise it will reassigned 0 each time through the loop.
Thanks Dave! You saved me :)

Initially I didn't put the () on the function call, but since the code wasn't working I tried to change some stuffs. Anyway I think the biggest error I made is not passing tim1 as argument to the callback. Now everything is working fine.

Thanks a million!

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Timer Callback executed just once

Post by dhylands » Sun Dec 20, 2015 7:29 pm

Also, if you're using interrupts (a timer callback is an interrupt) then I highly recommend than you add these lines to your code:

Code: Select all

import micropython
micropython.alloc_emergency_exception_buf(100)
then when you do have errors in your callback code, you'll get a much better error report rather than just MemoryError.

Post Reply