Page 1 of 1

Without delay(), how hard is it?

Posted: Sun Apr 02, 2017 9:05 am
by unory
Hi uPy Forum

Just got my pyboard v1.0 2 days ago and fall in love with it.
Here is what i want to do:
Auto move the servo from -90 to 90 repeatedly
The button input from 'X17' which is the on board button when pressed will turn the LED(1) on which is red.

However i could not get it to work the way i want. Can anyone give me some guide? Thanks

And here is my code:

import pyb
sw = pyb.Pin('X17', pyb.Pin.IN, pyb.Pin.PULL_UP)
le = pyb.LED(1)
servo1 = pyb.Servo(1)
while True:
servo1.angle(-90)
pyb.delay(500)
servo1.angle(90)
pyb.delay(500)
if sw.value == 0:
le.on()
else:
le.off()

The button is not working during the pyb.delay periods. I know the problem but doesnt know how to get around this.
Thanks first guys.

Re: Without delay(), how hard is it?

Posted: Sun Apr 02, 2017 10:21 am
by deshipu
The standard trick to do this is called "blink without a delay" and involves running the loop without any delays, but only doing things inside it if the time elapsed since the last time is greater than some value. For example:

Code: Select all

last_button = last_servo = utime.ticks_ms()
servo_angle = 90
led_state = False
while True:
    now = utime.ticks_ms()
    if utime.ticks_diff(now, last_servo) > 500:
        servo1.angle(servo_angle)
        servo_angle = -servo_angle
        last_servo = now
    if utime.ticks_diff(now, last_button) > 200 and not sw.value():
        led_state = not led_state
        le.value(led_state)
        last_button = now

Re: Without delay(), how hard is it?

Posted: Sun Apr 02, 2017 10:23 am
by deshipu
There are also other ways, such as interrupts, asyncio or even threads, but I think this is an important trick to have up your sleeve.

Re: Without delay(), how hard is it?

Posted: Sun Apr 02, 2017 10:42 am
by unory
Thanks for the info and the code. I trying the code atm but its said ticks_ms is not define
I try to look up the library from this link but i cant find any library for utime https://pypi.python.org/pypi?%3Aaction= ... icropython

Did i miss step somewhere?

Re: Without delay(), how hard is it?

Posted: Sun Apr 02, 2017 3:15 pm
by deshipu
utime is built-in, you just have to import it

Re: Without delay(), how hard is it?

Posted: Mon May 27, 2019 8:26 am
by lepi
>> "blink without a delay" (...) For example:

Deshipu, thank you for this implementation, sth exactly like this should be in utime module docs.

Perhaps instead of this:
# Calculate deadline for operation and test for it
deadline = ticks_add(time.ticks_ms(), 200)
while ticks_diff(deadline, time.ticks_ms()) > 0:
do_a_little_of_something()

Cheers!

Re: Without delay(), how hard is it?

Posted: Tue May 28, 2019 10:25 am
by pythoncoder
This approach is fine for very simple programs but the event loop soon gets convoluted as the number of events to be handled increases. You can write more modular and object oriented code using asyncio. Consider this code which flashes the four Pyboard LED's asynchronously for ten seconds:

Code: Select all

import pyb
import uasyncio as asyncio

async def killer(duration):
    await asyncio.sleep(duration)

async def toggle(objLED, time_ms):
    while True:
        await asyncio.sleep_ms(time_ms)
        objLED.toggle()

loop = asyncio.get_event_loop()
leds = [pyb.LED(x) for x in range(1,5)]  # Initialise all four on board LED's
for x, led in enumerate(leds):  # Create a coroutine for each LED
    t = int((0.2 + x/2) * 1000)
    loop.create_task(toggle(leds[x], t))
loop.run_until_complete(killer(10))  # Run for 10s
If you had, say, 16 LED's all you'd need to change is a single number. With a hand crafted event loop, the loop code would increase substantially. For anyone unfamiliar with asyncio async repo includes a tutorial.

Re: Without delay(), how hard is it?

Posted: Thu May 30, 2019 10:55 am
by lepi
Thank you Peter!

I'll sit down to understand this in the evening : )
I'll look into uasyncio tutorial as well.

Cheers! : )