You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:48:58