1. 开发环境:
硬件:使用的开发板为合宙esp32c3,板载两个led,对应的io为12/13。
软件:MicroPython v1.18 on 2022-01-17; ESP32C3 module with ESP32C3
2. 实现代码
import uasyncio as asyncio
from machine import Pin
async def blink_led(led_pin, interval):
while True:
led_pin.on()
await asyncio.sleep_ms(interval)
led_pin.off()
await asyncio.sleep_ms(interval)
async def foo():
#在两个led闪烁的基础上,增加了打印数字,如果没有堵塞,实现的效果是一边打印一边闪烁
for i in range(8000):
print(i:=i+1)
await asyncio.sleep_ms(50)
async def main():
#合宙esp32的两个板载led,12,13
led_pin1 = Pin(13, Pin.OUT) # 第一个LED引脚号
led_pin2 = Pin(12, Pin.OUT) # 第二个LED引脚号
while True:
await asyncio.gather(
blink_led(led_pin1, 200),
blink_led(led_pin2, 1200),
foo()
)
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
3. 实现异步的要点
按照gpt3.5给的例程,大概猜了一下异步的使用方法:
1、用async def定义需要异步的功能
2、如果异步中需要等待,要使用await asyncio.sleep_ms(时间),这样才不会堵塞,如果没有await,即使用了asyncio.sleep_ms(时间),也是会堵塞,不知道这样堵住,与用time.sleep有何区别。
3、用 await asyncio.gather把各个异步的函数汇总
4、实现异步循环
loop = asyncio.get_event_loop()
loop.create_task(main())
loop.run_forever()
4. 循环异步的不同方式
loop.create_task(main())
loop.run_forever()
loop.run_until_complete(main())
一种是forever,一种是until complete,不知道差别在哪里,实现效果都是一样,就是不停的循环
如果不循环,应该是使用 asyncio.run
5. 使用多线程实现异步
import machine
import _thread
import time
# 定义LED1闪烁函数
def blink1(thread_name, delay):
while True:
pin1 = machine.Pin(12, machine.Pin.OUT)
pin1.on()
time.sleep(1)
pin1.off()
time.sleep(1)
# 定义LED2闪烁函数
def blink2(thread_name, delay):
while True:
pin2 = machine.Pin(13, machine.Pin.OUT)
pin2.on()
time.sleep(2)
pin2.off()
time.sleep(2)
_thread.start_new_thread(blink1, ("Thread 1", 1))
_thread.start_new_thread(blink2, ("Thread 1", 1))
while True:
pass
5. 线程与协程的区别
借用一张图片来表示,对于多核cpu来说,线程是完全并行的,也就是同时做某件事情。
协程只是并发的关系,就是给cpu几个任务,如果第一个任务在等待导致cpu闲置,只是可以插入其他任务,等待时间结束了,再切换回第一个任务。
总体来说,协程更节省系统资源。但是单片机往往是单核,不知道协程与线程能有多大差别。