|
1 | 1 | # This example makes two LEDs blink at different intervals, |
2 | | -# showcasing how `asyncio` can handle multiple tasks concurrently |
3 | | -# without blocking the execution of other task(s). |
| 2 | +# showcasing how `asyncio` can handle multiple tasks |
| 3 | +# concurrently without blocking the execution of other task(s). |
4 | 4 | # |
5 | | -# See: |
6 | | -# https://docs.micropython.org/en/latest/library/asyncio.html |
7 | | -# https://bbc.github.io/cloudfit-public-docs/asyncio/asyncio-part-2.html |
8 | | -# https://gpiocc.github.io/learn/micropython/esp/2020/06/13/martin-ku-asynchronous-programming-with-uasyncio-in-micropython.html |
9 | | -# https://randomnerdtutorials.com/micropython-esp32-esp8266-asynchronous-programming/ |
| 5 | +# See also: |
| 6 | +# https://docs.micropython.org/en/latest/library/asyncio.html |
| 7 | +# https://bbc.github.io/cloudfit-public-docs/asyncio/asyncio-part-2.html |
| 8 | +# https://gpiocc.github.io/learn/micropython/esp/2020/06/13/martin-ku-asynchronous-programming-with-uasyncio-in-micropython.html |
| 9 | +# https://randomnerdtutorials.com/micropython-esp32-esp8266-asynchronous-programming/ |
10 | 10 |
|
11 | | -import asyncio |
| 11 | +import uasyncio as asyncio |
| 12 | +from machine import Pin |
| 13 | +import time |
| 14 | + |
| 15 | +# Get the starting time in milliseconds |
| 16 | +start = time.ticks_ms() |
| 17 | + |
| 18 | +# Setup LED pins |
| 19 | +red_led = Pin(7, Pin.OUT) |
| 20 | +green_led = Pin(5, Pin.OUT) |
| 21 | + |
| 22 | +# Elapsed time helper |
| 23 | +def get_elapsed(): |
| 24 | + return time.ticks_diff(time.ticks_ms(), start) |
| 25 | + |
| 26 | +# Define coroutine functions |
| 27 | +async def blink_red_led(): |
| 28 | + while True: |
| 29 | + print(f"[{get_elapsed()}] Red toggling") |
| 30 | + red_led.value(not red_led.value()) |
| 31 | + |
| 32 | + # Non-blocking async sleep |
| 33 | + # Pauses only the current coroutine for 0.5 seconds and |
| 34 | + # keeps other tasks running during this time |
| 35 | + await asyncio.sleep(.5) |
12 | 36 |
|
13 | | -async def blink(led, period_ms): |
| 37 | +async def blink_green_led(): |
14 | 38 | while True: |
15 | | - print(f"[{led}] loop start") |
16 | | - led.on() |
17 | | - print(f"[{led}] on") |
18 | | - await asyncio.sleep_ms(20) # Non-blocking delay |
19 | | - led.off() |
20 | | - print(f"[{led}] off") |
21 | | - await asyncio.sleep_ms(period_ms) |
| 39 | + print(f"[{get_elapsed()}] Green toggling") |
| 40 | + green_led.value(not green_led.value()) |
| 41 | + await asyncio.sleep(2) |
22 | 42 |
|
23 | 43 | async def main(): |
24 | | - t1 = asyncio.create_task(blink(led1, 700)) |
25 | | - t2 = asyncio.create_task(blink(led2, 400)) |
26 | | - print(t1) |
27 | | - print(t2) |
28 | | - await asyncio.sleep_ms(5_000) |
29 | | - |
30 | | -from machine import Pin |
| 44 | + # Log elapsed time |
| 45 | + print(f"[{get_elapsed()}] Starting tasks...") |
| 46 | + |
| 47 | + # Create tasks for blinking two LEDs concurrently |
| 48 | + task1 = asyncio.create_task(blink_red_led()) |
| 49 | + task2 = asyncio.create_task(blink_green_led()) |
| 50 | + |
| 51 | + # Run async tasks concurrently, wait for all of them to complete, |
| 52 | + # and keep main() alive while tasks run |
| 53 | + await asyncio.gather(task1, task2) |
31 | 54 |
|
32 | | -led1 = Pin(2, Pin.OUT) |
33 | | -led2 = Pin(5, Pin.OUT) |
| 55 | +try: |
| 56 | + # Gets the async "scheduler", the "brain" that controls |
| 57 | + # and runs asynchronous code |
| 58 | + loop = asyncio.get_event_loop() |
| 59 | + |
| 60 | + # Runs that coroutine until it's completely done |
| 61 | + loop.run_until_complete(main()) |
| 62 | + |
| 63 | +except KeyboardInterrupt: |
| 64 | + # This part runs when Ctrl+C is pressed |
| 65 | + print("Program stopped. Exiting...") |
| 66 | + |
| 67 | + # Optional cleanup code |
| 68 | + red_led.off() |
| 69 | + green_led.off() |
34 | 70 |
|
35 | | -asyncio.run(main()) |
| 71 | + loop.stop() # Not available in all uasyncio versions |
0 commit comments