如何在Raspberry Pi Pico的CircuitPython中实现亚毫秒级延迟?
在CircuitPython(Raspberry Pi Pico)中突破time.sleep()的毫秒级精度限制
问题背景
- 硬件:Raspberry Pi Pico
- 语言:Adafruit CircuitPython
- 核心问题:
time.sleep()的默认精度仅为0.001秒(1毫秒),无法实现更精细的延迟;且MicroPython的utime库不适用于CircuitPython。
测试情况
测试代码
import time x = time.monotonic_ns() for i in range(10): time.sleep(1.0005) print(time.monotonic_ns() - x)
预期输出
- 1000500000
- 2001000000
- 3001500000
- 4002000000
- ...
实际输出
- 1000976563(接近1001000000)
- 2000976563(接近2001000000)
- 3000976563(接近3001000000)
- 4000976563(接近4001000000)
- 5000976563(接近5001000000)
原因分析
CircuitPython的time.sleep()底层以毫秒为最小单位处理延迟:传入的浮点数会被转换为整数毫秒(如1.0005秒会被向上取整为1001毫秒),这直接导致了精度无法突破1毫秒。你观察到的976562.5(1e9/1024)是Pico硬件定时器的刻度特性,但核心限制来自time.sleep()的实现逻辑。
解决方案
方法1:基于纳秒时钟手动实现高精度延迟
利用CircuitPython提供的time.monotonic_ns()(纳秒级单调时钟),编写自定义延迟函数,直接通过纳秒计数实现精细控制:
import time def sleep_ns(duration_ns): """延迟指定的纳秒数""" start_time = time.monotonic_ns() # 循环等待直到达到目标时长 while time.monotonic_ns() - start_time < duration_ns: pass # 测试自定义延迟函数 x = time.monotonic_ns() for i in range(10): sleep_ns(1000500000) # 对应1.0005秒 print(time.monotonic_ns() - x)
方法2:异步非阻塞版本(适合多任务场景)
如果程序需要同时处理其他任务(如传感器读取、IO操作),可以结合CircuitPython的asyncio框架实现非阻塞的高精度延迟:
import time import asyncio async def sleep_ns_async(duration_ns): """异步版本的纳秒延迟""" start_time = time.monotonic_ns() while time.monotonic_ns() - start_time < duration_ns: # 让出CPU给其他任务 await asyncio.sleep(0) async def main(): x = time.monotonic_ns() for i in range(10): await sleep_ns_async(1000500000) print(time.monotonic_ns() - x) asyncio.run(main())
内容的提问来源于stack exchange,提问作者Ofir Gaash
相关产品推荐
相关产品推荐

