Python中NRF24L01读取数据阻塞问题:如何设置超时?
我之前在做NRF24L01项目时也踩过这个坑!默认的radio.read()确实是阻塞式的,没数据就会一直挂着不动,完全符合你说的情况。给你两种实用的解决办法,都能实现20秒超时的需求:
方案1:用available()检查数据+自定义超时逻辑
这个方法兼容性最好,几乎所有NRF24L01的Python库都支持available()方法——它会立即返回是否有数据在接收缓冲区,不会阻塞程序。我们可以在循环里定期检查数据,同时记录时间,超过20秒就自动退出:
import time def recv(): global dictt # 替换成你实际使用的管道地址 pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2] radio.openWritingPipe(pipes[0]) radio.openReadingPipe(1, pipes[1]) radio.startListening() radio.printDetails() start_time = time.time() timeout_duration = 20 # 设置20秒超时 data_received = False # 循环直到超时或收到数据 while time.time() - start_time < timeout_duration: if radio.available(): revc_buffer = [] # 读取数据 radio.read(revc_buffer, radio.getPayloadSize()) # 这里处理你的数据,比如存入全局字典dictt dictt["received_data"] = revc_buffer data_received = True break # 拿到数据就退出循环 time.sleep(0.1) # 避免循环占用过多CPU资源 if not data_received: print("超时警告:20秒内未收到任何无线电信号") radio.stopListening()
小提示:
time.sleep(0.1)的间隔可以调整:如果对实时性要求高,就设成0.01秒;如果想节省CPU,设成0.5秒也没问题。- 测试时可以断开发送端,验证程序是否会在20秒后正常退出,而不是卡住。
方案2:直接给read()方法设置超时参数
如果你用的是pyRF24这类比较新的库,read()方法本身支持传入timeout参数(单位是毫秒),可以一步到位实现超时:
def recv(): global dictt pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2] radio.openWritingPipe(pipes[0]) radio.openReadingPipe(1, pipes[1]) radio.startListening() radio.printDetails() revc_buffer = [] # 设置20秒超时(20000毫秒) is_success = radio.read(revc_buffer, radio.getPayloadSize(), timeout=20000) if is_success: dictt["received_data"] = revc_buffer print(f"成功收到数据:{revc_buffer}") else: print("超时:未接收到有效数据") radio.stopListening()
注意:
不同NRF24L01库的API可能有差异,如果你用的是老版本的库(比如基于RPi.GPIO的旧实现),可能没有这个超时参数,这时方案1就是最优选择。
另外还要确认收发双方的管道地址、频道、传输速率完全匹配,不然也可能出现收不到数据的情况哦!
内容的提问来源于stack exchange,提问作者KyluAce
相关产品推荐
相关产品推荐

