树莓派3B+使用WiringPi读取SI7021温湿度报错求助
问题原因及修正方案
你的代码核心问题是对WiringPi的I2C函数用法理解错误,同时没搞清楚SI7021的指令交互逻辑,具体问题和修正如下:
核心错误点
- 误用
wiringPiI2CWriteReg8:这个函数的作用是「向已打开的I2C设备的指定寄存器写入8位数据」,参数格式为(fd, 寄存器地址, 数据)。但SI7021的测量指令(比如0xF3触发温度测量)是直接发送的命令字节,不是写入寄存器,因此应该用wiringPiI2CWrite(fd, 命令字节)。你把设备地址0x40当成寄存器地址传入,完全不符合函数要求,必然返回错误。 - 误用
wiringPiI2CReadReg8:这个函数是「读取指定寄存器的值」,参数为(fd, 寄存器地址)。但SI7021完成测量后,是直接返回测量结果字节,不是读取寄存器,因此要用wiringPiI2CRead(fd)读取字节,且需要读取两个字节(温湿度均为16位数据)。你传入的0x40是设备地址而非寄存器地址,这也是错误根源。
修正后的代码
import sys import time import wiringpi I2C_ADDR = 0x40 SI7021_CMD_NO_HOLD_TEMP = 0xF3 SI7021_CMD_NO_HOLD_HUMI = 0xF5 # 初始化WiringPi和I2C设备 wiringpi.wiringPiSetup() fd = wiringpi.wiringPiI2CSetup(I2C_ADDR) if fd < 0: print("I2C设备初始化失败") sys.exit(1) def read_temperature(): # 发送温度测量指令 wiringpi.wiringPiI2CWrite(fd, SI7021_CMD_NO_HOLD_TEMP) time.sleep(0.1) # 等待测量完成(SI7021最长测量时间约29ms) # 读取两个字节的测量结果 high_byte = wiringpi.wiringPiI2CRead(fd) low_byte = wiringpi.wiringPiI2CRead(fd) # 组合成16位数值并转换为实际温度 raw_temp = (high_byte << 8) | low_byte temperature = (175.72 * raw_temp / 65536) - 46.85 return temperature def read_humidity(): # 发送湿度测量指令 wiringpi.wiringPiI2CWrite(fd, SI7021_CMD_NO_HOLD_HUMI) time.sleep(0.1) high_byte = wiringpi.wiringPiI2CRead(fd) low_byte = wiringpi.wiringPiI2CRead(fd) raw_humi = (high_byte << 8) | low_byte humidity = (125.0 * raw_humi / 65536) - 6.0 return humidity try: while True: temp = read_temperature() humi = read_humidity() print(f"温度: {temp:.2f}°C, 湿度: {humi:.2f}%") time.sleep(2) except KeyboardInterrupt: sys.exit(0)
额外说明
- 你用
i2cget能拿到正确值,说明硬件连接和I2C功能都是正常的,问题完全出在代码逻辑。 - SI7021非握手指令发送后,不需要等待0.3秒,0.1秒已经足够覆盖最长测量时间(手册标注温度最长29ms,湿度最长12ms)。
- 读取的原始字节需要按照官方手册提供的公式转换,才能得到实际可用的温湿度数值。
内容的提问来源于stack exchange,提问作者someonewating
相关产品推荐
相关产品推荐

