Page 1 of 1

Basic Timer Question

Posted: Thu Mar 03, 2022 6:21 pm
by Andrew1234
I am using a pyboard and trying to figure out how to use the timer. I expect the below code to use Timer 1 and call function 'light' at the rate of once per second, and so I expect the LED(4) to toggle each second. The actual result is that the blue LED toggles state once. Can someone tell me why, and how to correct the code?

Code: Select all

def light(led):
    led.toggle()

import pyb 
led = pyb.LED(4)

tim = pyb.Timer(1, freq=1)    # freq in Hz
tim.callback(light(led))

Re: Basic Timer Question

Posted: Thu Mar 03, 2022 6:40 pm
by dhylands
You're passing the results of calling light(led) (which is None) to callback, instead of passing the function light to callback.

Use this instead: tim.callback(light)

The light callback needs to take a single argument, which is the timer its associated with. So you'll either need to make led be a global or perhaps make the callback be a method that's part of a class.

Here's an example that uses a class: https://github.com/dhylands/upy-example ... eat_irq.py and a variant that uses a regular function (much like what you were trying to do): https://github.com/dhylands/upy-example ... _irq_fn.py

It also occured to me that you could so this with a closure, by coding it like this:

Code: Select all

def light(led):
    def light_callback(tim):
        led.toggle()
    return light_callback

tim = pyb.Timer(1, freq=1)
tim.callback(light(led))

Re: Basic Timer Question

Posted: Thu Mar 03, 2022 6:58 pm
by dhylands
Here's a link to my tested example using a closure:
https://github.com/dhylands/upy-example ... closure.py

It looks like tick needs to be a global. I couldn't get it to work as a local to the light function (I suspect that this is a microptyonism).

Re: Basic Timer Question

Posted: Thu Mar 03, 2022 9:27 pm
by Andrew1234
Hi Dave
I adjusted the code based on your response and the example you provided as below:

Code: Select all

import pyb

def light(tim):
    led = pyb.LED(4)
    led.toggle()

tim = pyb.Timer(1, freq=10)    # freq in Hz
tim.callback(light)     
This now works as expected. I left led as a local variable for now.

I'm a little confused about the function light needing a parameter of the timer object. Is this just the way to properly connect the callback to the function?

Regards
Andy

Re: Basic Timer Question

Posted: Fri Mar 04, 2022 6:04 pm
by dhylands
Andrew1234 wrote:
Thu Mar 03, 2022 9:27 pm
Hi Dave
I adjusted the code based on your response and the example you provided as below:

Code: Select all

import pyb

def light(tim):
    led = pyb.LED(4)
    led.toggle()

tim = pyb.Timer(1, freq=10)    # freq in Hz
tim.callback(light)     
This now works as expected. I left led as a local variable for now.

I'm a little confused about the function light needing a parameter of the timer object. Is this just the way to properly connect the callback to the function?
It allows the same timer callback to be used for multiple timers, and the callback can then distinguish which timer its being called for.

It turns out you can do something similar by using a callback method inside a class and create what's know as a "bound function", which is what this example does: https://github.com/dhylands/upy-example ... eat_irq.py