树莓派3温湿度传感器报Remote I/O error(Python)问题咨询
解决I2C温湿度传感器「OSError: [Errno 121] Remote I/O error」问题
嘿,我来帮你搞定这个头疼的I2C错误!首先明确一点:你遇到的这个问题不是因为没提前给传感器发读取通知,而是你的读操作逻辑不对——大部分I2C温湿度传感器(比如你这个地址0x40的,大概率是HTU21D/Si7021这类),不能直接用read_byte读设备地址,得先给它发一个命令字节,让它知道要触发温度测量,之后才能读取有效数据。
问题出在哪?
你现在的代码直接调用bus.read_byte(TEMP),这相当于试图从传感器的默认寄存器里读数据,但这类传感器需要先收到测量指令,才会开始采集数据并准备返回结果,直接读的话就会触发I2C通信错误。另外注意:你代码里的SMbus(1)是拼写错误,应该是SMBus(1)(大写B),这个小错误也可能埋下隐患!
修正后的代码(以HTU21D/Si7021为例)
下面是适配这类传感器的代码,已经包含了正确的命令发送、等待测量和数据转换逻辑:
import smbus import time # 传感器I2C地址 TEMP_SENSOR_ADDR = 0x40 # 触发温度测量的命令(保持总线控制,适合单设备场景) TRIGGER_TEMP_MEASURE = 0xE3 # 初始化SMBus,注意是大写B! bus = smbus.SMBus(1) state = 1 while state: print("1. Read temperature") print("2. Exit") choice = input("Enter your choice: ") if choice == '1': try: # 第一步:给传感器发送温度测量命令 bus.write_byte(TEMP_SENSOR_ADDR, TRIGGER_TEMP_MEASURE) # 等待传感器完成测量(这类传感器需要约50ms,留0.1秒足够) time.sleep(0.1) # 第二步:读取3个字节(2个温度数据字节 + 1个校验字节) data = bus.read_i2c_block_data(TEMP_SENSOR_ADDR, 0, 3) # 解析原始数据:把两个字节拼成16位数值,去掉最后两位状态位 temp_raw = (data[0] << 8) + data[1] temp_raw &= 0xFFFC # 转换为实际摄氏度(公式来自传感器 datasheet) c_temp = -46.85 + (175.72 * temp_raw / 65536.0) print(f"Temperature: {c_temp:.2f} °C") except OSError as e: print(f"Error occurred: {e}") elif choice == '2': state = 0
额外要检查的点
- 确认传感器型号:如果你的传感器不是HTU21D/Si7021,去查它的 datasheet,找到对应的温度测量命令和数据转换公式,替换代码里的命令字节和计算逻辑就行。
- 接线稳定性:SDA/SCL引脚有没有松动?如果传感器没有内置上拉电阻,虽然树莓派默认有上拉,但线缆太长或者接触不良也会触发121错误,不妨重新插拔一下接线试试。
内容的提问来源于stack exchange,提问作者Raging Burek
相关产品推荐
相关产品推荐

