1. 本章学习目标掌握SHT45温湿度传感器的硬件接线方法理解SHT45特有的“命令式”通信机制使用两种不同的Python方式读取SHT45的温度和湿度数据掌握原始数据的解析和换算方法2. SHT45传感器简介SHT45是瑞士Sensirion公司出品的一款高精度数字温湿度传感器属于SHT4x系列中的旗舰型号。其主要特性如下参数规格温度精度±0.1 °C0~75 °C湿度精度±1.0% RH25~75% RH供电电压1.08 V ~ 3.6 VI2C地址0x44工作温度范围-40°C ~ 125°C平均电流0.4 μA小知识SHT45基于“电容式湿度传感带隙温度传感”的双核心技术内部集成了信号处理电路可将物理量直接转换为数字信号通过I2C接口输出-。SHT40、SHT41、SHT45三款传感器的接线方式和代码完全通用本教程可直接用于SHT40和SHT41。3. 硬件接线3.1 引脚连接对照表将SHT45模块与树莓派进行连接请按照下表操作SHT45模块引脚树莓派GPIO物理引脚号VCC3.3V引脚1GNDGND引脚6SDAGPIO2引脚3SCLGPIO3引脚53.2 接线注意事项电源选择SHT45的供电电压范围为1.08V至3.6V请连接至树莓派的3.3V引脚切勿连接5V引脚以免损坏传感器。线路检查完成接线后请再次确认SDA接GPIO2、SCL接GPIO3GND和VCC不要接反。上拉电阻树莓派的GPIO引脚内部已集成I2C上拉电阻一般情况下无需外接上拉电阻。4. 启用树莓派I2C接口在进行Python编程之前需要确保树莓派的I2C接口已正确启用如未启用才考我树莓派学习笔记1。4.1 安装I2C工具和Python库重启后打开终端安装所需的工具和库# 更新软件包列表 sudo apt update # 安装I2C工具和Python SMBus库 sudo apt install i2c-tools python3-smbus -y说明i2c-tools提供了i2cdetect、i2cget等命令行调试工具python3-smbus则提供了Python中操作I2C的底层接口-53。4.2 验证设备识别安装完成后执行以下命令扫描I2C总线上的设备sudo i2cdetect -y 1结果如图⚠️注意SHT4x系列的I2C地址出厂时固定为0x44无法更改-。如果扫描不到该地址请重新检查接线。5. 理解SHT45的通信方式在编写Python代码之前需要先理解SHT45独特的通信机制。这与传统的寄存器型I2C设备有很大不同。5.1 SHT45没有寄存器地址SHT45与传统的I2C设备如EEPROM、PCF8591等不同它没有寄存器地址的概念。SHT45的通信是通过发送“命令码Command Code”来完成的不同的命令码对应不同的操作-。5.2 常用命令码SHT45支持以下测量命令码-命令码十六进制功能说明等待时间0xFD高精度测量推荐约10 ms0xF6中精度测量约5 ms0xE0低精度测量约2 ms5.3 I2C通信时序读取SHT45数据的完整通信流程如下步骤1: 主机发送START信号 步骤2: 主机发送设备地址0x44 写标志位0x88 步骤3: 主机发送命令码如0xFD 步骤4: 主机发送STOP信号 步骤5: 等待传感器完成测量10~20毫秒 步骤6: 主机发送START信号 步骤7: 主机发送设备地址0x44 读标志位0x89 步骤8: 从机返回6字节数据温湿度各2字节CRC各1字节 步骤9: 主机发送STOP信号提示步骤3发送命令码时需要注意SHT45没有寄存器地址因此不能使用write_byte_data()这类带寄存器地址的函数而应使用write_byte()函数直接发送命令码。6. 方法一使用smbus2库手动读取6.1 安装smbus2库sudo apt install python3-smbus26.2 完整代码实现创建Python脚本文件read_sht45.py输入以下代码#!/usr/bin/env python3 # -*- coding: utf-8 -*- import smbus2 import time # 配置常量 I2C_BUS 1 # 树莓派I2C总线编号 SHT45_ADDRESS 0x44 # SHT45的I2C设备地址 # SHT45命令码定义 CMD_MEASURE_HIGH_PRECISION 0xFD # 高精度测量 CMD_MEASURE_MEDIUM_PRECISION 0xF6 # 中精度测量 CMD_MEASURE_LOW_PRECISION 0xE0 # 低精度测量 def crc8(data): 计算SHT45使用的CRC-8校验值 多项式: x^8 x^5 x^4 1 (0x31) 初始值: 0xFF crc 0xFF for byte in data: crc ^ byte for _ in range(8): if crc 0x80: crc (crc 1) ^ 0x31 else: crc 1 crc 0xFF return crc def read_sht45_data(bus, cmdCMD_MEASURE_HIGH_PRECISION): 从SHT45读取温湿度数据 参数: bus: smbus2总线对象 cmd: 测量命令码可选高/中/低精度 返回: (温度, 湿度) 元组失败时返回(None, None) try: # 步骤1: 发送测量命令注意SHT45没有寄存器地址直接发送命令码 bus.write_byte(SHT45_ADDRESS, cmd) # 步骤2: 等待传感器完成测量 # 根据不同的命令码等待不同时间 if cmd CMD_MEASURE_HIGH_PRECISION: time.sleep(0.015) # 高精度约15ms elif cmd CMD_MEASURE_MEDIUM_PRECISION: time.sleep(0.007) # 中精度约7ms else: time.sleep(0.003) # 低精度约3ms # 步骤3: 读取6字节数据温度2字节CRC1字节湿度2字节CRC1字节 # 注意SHT45没有寄存器地址所以第二个参数使用0x00作为占位符 data bus.read_i2c_block_data(SHT45_ADDRESS, 0x00, 6) # 数据格式: data[0]温度高8位, data[1]温度低8位, data[2]温度CRC # data[3]湿度高8位, data[4]湿度低8位, data[5]湿度CRC # 验证温度数据的CRC校验 temp_crc crc8(data[0:2]) if temp_crc ! data[2]: print(温度数据CRC校验失败) return None, None # 验证湿度数据的CRC校验 hum_crc crc8(data[3:5]) if hum_crc ! data[5]: print(湿度数据CRC校验失败) return None, None # 解析原始数值 temp_raw (data[0] 8) | data[1] humidity_raw (data[3] 8) | data[4] # 转换为实际物理值 # 温度转换公式: T -45 175 * (temp_raw / 65535) temperature -45.0 175.0 * (temp_raw / 65535.0) # 湿度转换公式: RH -6 125 * (humidity_raw / 65535) humidity -6.0 125.0 * (humidity_raw / 65535.0) # 湿度限制在0~100%范围内 humidity max(0.0, min(100.0, humidity)) return temperature, humidity except Exception as e: print(f读取数据失败: {e}) return None, None def main(): # 初始化I2C总线 bus smbus2.SMBus(I2C_BUS) print(fSHT45温湿度传感器已初始化地址: 0x{SHT45_ADDRESS:02X}) print(开始读取数据...) print(- * 40) try: while True: # 读取温湿度数据 temp, hum read_sht45_data(bus, CMD_MEASURE_HIGH_PRECISION) if temp is not None and hum is not None: print(f温度: {temp:.2f} °C | 相对湿度: {hum:.1f} %RH) else: print(读取数据失败请检查传感器连接) # 每隔1秒读取一次 time.sleep(1) except KeyboardInterrupt: print(\n程序已停止) finally: bus.close() if __name__ __main__: main()6.3 代码逐行解析导入模块import smbus2 # 提供I2C通信功能 import time # 提供延时功能定义常量I2C_BUS 1 # 树莓派I2C总线编号 SHT45_ADDRESS 0x44 # SHT45的I2C设备地址 CMD_MEASURE_HIGH_PRECISION 0xFD # 高精度测量命令注意SHT45的命令码是直接通过I2C总线发送的不需要像传统I2C设备那样指定寄存器地址-。 CRC-8校验函数def crc8(data): crc 0xFF for byte in data: crc ^ byte for _ in range(8): if crc 0x80: crc (crc 1) ^ 0x31 else: crc 1 crc 0xFF return crcSHT45返回的6字节数据中包含两个CRC校验字节分别校验温度数据和湿度数据的完整性。CRC多项式为x^8 x^5 x^4 10x31初始值为0xFF。在数据解析时验证CRC可以确保通信过程中没有发生错误。 数据读取与解析# 步骤1: 发送测量命令 bus.write_byte(SHT45_ADDRESS, cmd) # 步骤2: 等待测量完成 time.sleep(0.015) # 步骤3: 读取6字节数据 data bus.read_i2c_block_data(SHT45_ADDRESS, 0x00, 6)⚠️关键点read_i2c_block_data()的第二个参数是寄存器地址由于SHT45没有寄存器我们使用0x00作为占位符。实际通信时该函数会先发送设备地址写标志准备读取然后发送一个寄存器地址字节0x00最后再重新发送设备地址读标志来读取数据。对于SHT45中间的0x00字节会被传感器忽略。 数据转换公式# 温度转换: T -45 175 * (原始值 / 65535) temperature -45.0 175.0 * (temp_raw / 65535.0) # 湿度转换: RH -6 125 * (原始值 / 65535) humidity -6.0 125.0 * (humidity_raw / 65535.0)这是SHT4x系列传感器的标准转换公式其中65535是16位无符号整数的最大值。6.4 运行代码在终端中执行python3 read_sht45.py预期输出示例SHT45温湿度传感器已初始化地址: 0x44 开始读取数据... ---------------------------------------- 温度: 24.56 °C | 相对湿度: 45.2 %RH 温度: 24.58 °C | 相对湿度: 45.3 %RH 温度: 24.55 °C | 相对湿度: 45.1 %RH ...按Ctrl C可停止程序。7. 方法二使用Adafruit CircuitPython库推荐如果你希望代码更简洁可以使用Adafruit官方提供的CircuitPython库它将底层细节封装得更加完善。7.1 安装Adafruit库# 安装Adafruit BlinkaCircuitPython的Linux兼容层 sudo pip3 install adafruit-blinka # 安装SHT4x传感器库 sudo pip3 install adafruit-circuitpython-sht4x7.2 简洁版代码创建脚本read_sht45_simple.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- import time import board import adafruit_sht4x # 初始化I2C总线 i2c board.I2C() # 自动使用board.SCL和board.SDA # 初始化SHT45传感器 sht adafruit_sht4x.SHT4x(i2c) print(SHT45传感器已初始化) # 可选设置测量模式 # sht.mode adafruit_sht4x.Mode.NO_HEAT_HIGH # 高精度模式默认 while True: # 读取温湿度数据 temperature, relative_humidity sht.measurements print(f温度: {temperature:.2f} °C) print(f相对湿度: {relative_humidity:.1f} %RH) print() time.sleep(1)7.3 两种方法的对比特性smbus2手动实现Adafruit库代码复杂度较高需手动处理CRC和转换极低仅3行核心代码可控性完全可控适合学习底层原理底层细节已封装CRC校验需要手动实现库内部已处理适用场景教学演示、深度定制项目开发、快速原型建议如果你是初学者或希望快速完成项目开发推荐使用方法二Adafruit库如果你是希望深入学习I2C通信原理建议仔细研究第一种方法的实现细节。8. 故障排查指南8.1 扫描不到0x44地址故障现象可能原因解决方法i2cdetect输出全是--I2C未启用执行sudo raspi-config重新启用I2C扫描不到0x44接线错误检查SDA/SCL是否接反或接触不良扫描不到0x44供电问题确认SHT45连接的是3.3V引脚不是5V扫描到其他地址地址冲突SHT45地址固定为0x44若有冲突需更换设备8.2 读取数据时返回错误错误信息可能原因解决方法[Errno 121] Remote I/O error通信超时检查接线增加等待时间CRC校验失败数据传输错误检查是否有电磁干扰缩短连线长度温度值异常如-45°C未正确发送测量命令确认使用的是write_byte()而非write_byte_data()湿度值为负数数据解析错误检查转换公式中的除数和乘数是否正确8.3 数据读取不稳定的解决方法增加等待时间将time.sleep(0.015)适当增加至20~30毫秒检查电源稳定性使用树莓派自带的3.3V供电避免与其他大功率设备共用降低I2C速率某些SHT45模块对时钟频率敏感可在/boot/config.txt中添加dtparami2c_arm_baudrate100000将速率降至100kHz9. 本章小结本章围绕SHT45温湿度传感器详细介绍了树莓派通过I2C接口读取温湿度数据的完整流程。主要知识点包括SHT45硬件接线VCC→3.3V、GND→GND、SDA→GPIO2、SCL→GPIO3I2C接口启用通过raspi-config配置和i2c-tools验证SHT45通信机制命令码式通信无寄存器地址先发命令再读数据Python编程方法底层手动实现使用smbus2库掌握CRC校验和数据转换高层库实现使用Adafruit CircuitPython库快速上手数据转换公式温度T -45 175×(原始值/65535)湿度RH -6 125×(原始值/65535)如欲继续学习可参考本书后续章节关于将温湿度数据写入数据库、搭建Web监控界面或结合机器学习进行环境预测等内容。