Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calls which wait block all other events #27

Open
martinohanlon opened this issue Mar 11, 2022 · 5 comments
Open

Calls which wait block all other events #27

martinohanlon opened this issue Mar 11, 2022 · 5 comments
Labels
bug Something isn't working wontfix This will not be worked on

Comments

@martinohanlon
Copy link
Collaborator

Consider the following program:

from picozero import LED, Button

led = LED(1)
led.off()
button = Button(3)

def blink_2_times():
    led.blink(on_time=0.5, n=2, wait=True)

button.when_pressed = blink_2_times
button.when_released = led.off

The expected behaivour would be for the LED to blink twice, but as soon as button is released the LED should turn off.

In practice the LED will continue to blink until it has finished.

This issue affects all calls which use wait. It becomes more apparent functions like PWMBuzzer.play which wait by default and it isnt an explicit action by the user to set wait to True.

@martinohanlon martinohanlon added the bug Something isn't working label Mar 11, 2022
@martinohanlon
Copy link
Collaborator Author

First noted in #25

@martinohanlon
Copy link
Collaborator Author

Without significant refactoring and the introduction of lower level control (maybe even PIO) I am not sure there is anything can be be done to avoid this.

While micropython is waiting for a wait call to complete, no other processing will take place.

You cant block and wait for the completion of a Timer because for the same reason - no other processing can take place while its waiting.

uasyncio isnt a solution as it requires that anything which calls the API also uses uasyncio, which doesnt fit with the aims of picozero (e.g. its easy to use)

The use of micropython _thread might be a solution but it is described as highly experimental.

I think the choices are:

  1. live with it, and make sure the documentation states very clearly that using wait=True will stop all processing including events. I worry about the implications for methods such as play

  2. remove the functionality to wait and move the accountability to block execution outside of picozero (e.g. the user has to do it!)

@martinohanlon
Copy link
Collaborator Author

@tracygardner I would appreciate your thoughts on this.

@tracygardner
Copy link
Contributor

@martinohanlon I think live with it and document it as current behaviour. There are workarounds when you do want the behaviour that you expected. For that situation we would use wait=False and for more complex ones you'd use polling. The convenience of having this as an option seems to outweigh this issue.

We can provide plenty of best practice recipes so that beginners go down paths that work well.

@tracygardner
Copy link
Contributor

tracygardner commented Mar 14, 2022

Just adding in this example to separate the issue from wait=True

from picozero import LED, Button, pico_led
from time import sleep

led = LED(13)
led.off()
button = Button(18)
pico_led.off()

def change_colour():
    led.on()
    sleep(5)
    led.brightness = 0.25
    
def stopped():
    pico_led.on()
    led.off()

button.when_pressed = change_colour
button.when_released = stopped

A callback will run to completion, we said this was a limitation at the beginning. Your example just seems to be an instance of this behaviour. At the moment we provide wait=False options for the times when you want to be able to cancel a running blink/pulse/cycle/play.

In future it would be nice to be able to 'cancel' user-defined callbacks but I see that as a new feature.

@martinohanlon martinohanlon added the wontfix This will not be worked on label Apr 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants