1. 从选型到点亮SHT 系列 I2C 温湿度传感器上手验证全流程温湿度传感器选型这件事说简单也简单说容易翻车也是真的容易翻车。我见过太多项目在选型阶段拍脑袋定了 SHT30结果板子打回来发现 I2C 死活读不出数据或者读出来的湿度永远是 100% RH。问题往往不在传感器本身而在于供电、上拉电阻、地址配置和 CRC 校验这几个环节没有逐一验证。Sensirion 的 SHT 系列SHT20/SHT30/SHT31/SHT35/SHT40/SHT41/SHT45是目前嵌入式项目里最常用的数字温湿度传感器之一I2C 接口、出厂标定、低功耗适合从消费电子到工业控制的各类场景。这篇文章面向已经选好型号、准备动手验证的嵌入式工程师把从硬件连接到软件读数再到异常排查的完整链路拆开讲清楚让你拿到板子后能快速判断传感器到底有没有正常工作。选型阶段的核心逻辑其实不复杂SHT20 是经典入门款湿度精度 ±3% RH适合对成本敏感、精度要求不高的场景SHT30 是性价比之王±2% RH / ±0.2°C大多数物联网项目选它不会错SHT31 和 SHT30 精度标称相同但在高湿环境下的稳定性和重复性更好适合有结露风险的应用SHT35 和 SHT45 属于高精度档位分别做到 ±1.5% RH 和 ±1.0% RH面向工业控制和实验室设备。SHT40/SHT41 是新一代产品低电压下性能优异还带可编程加热器能通过加热去除冷凝和灰尘适合恶劣环境。如果你在选型阶段还在纠结可以先确定三个问题精度要求多少、供电电压是 3.3V 还是 5V、是否需要加热功能。这三个问题回答完型号基本就锁定了。硬件连接部分有几个容易踩的坑。SHT 系列芯片本身是 3.3V 供电的但市面上常见的 GY-SHT30 这类第三方模块通常集成了电平转换和上拉电阻可以直接接 5V 单片机。如果你用的是裸芯片那就必须注意VDD 范围一般是 2.4V 到 5.5V但 I2C 电平要跟主控匹配。上拉电阻方面SHT3x 和 SHT4x 的 SDA/SCL 都需要上拉典型值是 4.7kΩ 到 10kΩ。很多新手直接用单片机内部上拉结果在长导线或高速率下波形上升沿太慢通信失败。我建议在模块上确认是否有板载上拉如果没有自己在 SDA 和 SCL 到 VDD 之间各焊一个 4.7kΩ 电阻。地址配置方面SHT3x 默认地址是 0x447 位地址SHT4x 默认也是 0x44部分型号可以通过 ADDR 引脚切换到 0x45。如果你总线上挂了多个同型号传感器必须通过 ADDR 引脚区分地址否则会冲突。软件层面的第一步是确认 I2C 总线能扫描到设备。以 STM32 HAL 库为例初始化 I2C 后调用HAL_I2C_IsDeviceReady(hi2c1, 0x44 1, 3, 100)如果返回 HAL_OK说明设备在线。接下来是发送测量命令。SHT3x 的单次测量命令分两种时钟拉伸模式Clock Stretching和非时钟拉伸模式。时钟拉伸模式下主机发起读操作后传感器会拉低 SCL 直到测量完成代码简单但会阻塞总线非时钟拉伸模式下主机发送测量命令后需要等待一段时间再读取推荐用后者因为不占用总线。SHT3x 非时钟拉伸高重复性测量命令是 0x2400发送后等待约 15ms然后读取 6 个字节温度高字节、温度低字节、温度 CRC、湿度高字节、湿度低字节、湿度 CRC。SHT4x 的命令格式不同高精度测量命令是 0xFD等待约 8.3ms同样读 6 字节。CRC 校验是必须做的Sensirion 用的是 CRC-8 多项式 0x31初始值 0xFF。如果 CRC 校验失败说明通信受到干扰或时序有问题读出的数据不可信。温度换算公式SHT3x 的原始温度值 T_raw 是 16 位无符号整数实际温度 -45 175 * (T_raw / 65535)。湿度换算RH 100 * (RH_raw / 65535)。SHT4x 的公式略有不同温度 -45 175 * (T_raw / 65535)湿度 -6 125 * (RH_raw / 65535)注意湿度有 -6% 的偏移。这些公式在数据手册里都有但很多人直接抄代码忽略了型号差异导致读数偏差。验证阶段建议用串口打印原始值和换算值对照室温环境判断是否合理。如果室温 25°C 左右湿度 40% 到 60% RH读出来温度 25.3°C、湿度 48.2% RH基本就正常了。如果温度读出来 80°C 或者湿度 0% RH先检查 CRC 和命令是否匹配型号。后续如果需要把传感器数据上报到云端或接入大模型做环境分析可以通过 TaoToken 的统一 Key/API 通道来管理数据链路。TaoToken 提供模型对话、Coding Plan、API Keys 等入口适合在验证完成后快速搭建上报和智能分析流程。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 入口是 https://taotoken.net/api。这部分不是本文重点但如果你后续要做数据上报和智能告警可以先把 Key 申请好备用。2. TaoToken 前置准备统一 Key 与 API 通道配置在传感器验证完成后下一步通常是把数据接入上报链路或做智能分析。TaoToken 在这里的角色是提供一个统一的 Key 和 API 通道让你不用为每个模型或服务单独管理鉴权。前置准备分三步注册账号、创建 API Key、确认 Base URL 和可用模型 ID。这三件事做完后面无论是用 Python 脚本上报数据还是接入 Claude Code 做代码辅助都能直接复用同一套凭证。第一步是访问官网并注册。打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 完成账号注册和登录。登录后进入控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。控制台里可以看到当前账号的额度、已创建的 Key 列表和调用统计。如果你是第一次使用建议先看一下文档页面地址是 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面列出了支持的模型和接口格式。第二步是创建 API Key。在控制台左侧菜单找到 API Keys 页面地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。点击创建新 Key系统会生成一串以sk-开头的密钥。这个 Key 只会在创建时完整显示一次务必复制保存到安全的地方。如果你在团队里协作建议为每个项目或每个开发者单独创建 Key方便后续排查调用来源和额度消耗。Key 的权限默认是全部模型可用如果你需要限制到特定模型可以在创建时选择。第三步是确认 Base URL 和模型 ID。TaoToken 的 API Base URL 是 https://taotoken.net/api 注意这个地址不带 UTM 参数直接用于代码里的base_url配置。模型 ID 方面常用的有gpt-4o、claude-3-5-sonnet、claude-3-opus等具体以文档页面列出的为准。如果你要用 Claude Code 做编码辅助需要配置 Anthropic 兼容的 Base URL地址是 https://taotoken.net/api 然后在 Claude Code 的设置里填入 Key 和模型 ID。Coding Plan 的入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 适合长期做编码和 Agent 开发的场景。这里给一个 Python 环境变量配置的示例把 Key 和 Base URL 写进.env文件避免硬编码在代码里# .env 文件内容 TAOTOKEN_API_KEYsk-你的实际Key TAOTOKEN_BASE_URLhttps://taotoken.net/api TAOTOKEN_MODELgpt-4o然后在 Python 代码里用os.getenv读取import os from openai import OpenAI client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL) ) response client.chat.completions.create( modelos.getenv(TAOTOKEN_MODEL), messages[ {role: user, content: 把这段温湿度数据转成 JSON温度25.3C湿度48.2%RH} ] ) print(response.choices[0].message.content)如果你用的是 Claude Code 或 Cline 这类工具配置方式略有不同。Claude Code 需要在~/.claude/settings.json或项目级的.claude/settings.json里配置环境变量。Cline 的 MCP 配置则是在 VS Code 的设置里填入 Base URL 和 Key。无论哪种工具核心三件套都是Base URL、API Key、Model ID。这三个填对了基本就能跑通。验证 Key 是否可用可以用 curl 发一个最简单的请求curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { model: gpt-4o, messages: [{role: user, content: ping}], max_tokens: 10 }如果返回 JSON 里包含choices字段和内容说明 Key 和 Base URL 配置正确。如果返回 401检查 Key 是否复制完整、是否有多余空格。如果返回 404检查 Base URL 是否写成了https://taotoken.net/api而不是其他路径。这一步验证通过后就可以把传感器数据和 TaoToken 的 API 串起来了。3. 可复制配置SHT3x/SHT4x 初始化与读数代码这一节给出可以直接复制到 STM32 HAL 工程里的 SHT3x 和 SHT4x 驱动代码。代码分三部分I2C 初始化配置、传感器命令定义、读数与 CRC 校验函数。你只需要把 I2C 句柄替换成自己的hi2c1或hi2c2就能直接编译运行。先看 I2C 初始化配置。以 STM32CubeMX 生成的代码为例标准模式 100kHz 或快速模式 400kHz 都可以SHT3x 支持最高 1MHz但建议先用 100kHz 验证稳定性。配置片段如下/* I2C1 init function */ void MX_I2C1_Init(void) { hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 100000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(hi2c1) ! HAL_OK) { Error_Handler(); } }注意NoStretchMode要设为I2C_NOSTRETCH_DISABLE因为 SHT3x 在时钟拉伸模式下会拉低 SCL如果主机禁用了时钟拉伸通信会失败。如果你用的是非时钟拉伸模式这个配置不影响。接下来是传感器命令定义和 CRC 校验函数。SHT3x 的默认 7 位地址是 0x44左移一位后是 0x88。SHT4x 的地址也是 0x44但命令不同。下面代码同时兼容 SHT3x 和 SHT4x通过宏定义切换#include main.h #include stdint.h #include stdbool.h extern I2C_HandleTypeDef hi2c1; #define SHT_I2C_ADDR (0x44 1) #define SHT3X_CMD_MEAS_HIGH 0x2400 #define SHT4X_CMD_MEAS_HIGH 0xFD /* CRC-8 校验多项式 0x31初始值 0xFF */ static uint8_t sht_crc8(const uint8_t *data, uint8_t len) { uint8_t crc 0xFF; for (uint8_t i 0; i len; i) { crc ^ data[i]; for (uint8_t bit 0; bit 8; bit) { if (crc 0x80) { crc (crc 1) ^ 0x31; } else { crc 1; } } } return crc; } /* 发送 16 位命令 */ static bool sht_send_cmd(uint16_t cmd) { uint8_t buf[2]; buf[0] (uint8_t)(cmd 8); buf[1] (uint8_t)(cmd 0xFF); return HAL_I2C_Master_Transmit(hi2c1, SHT_I2C_ADDR, buf, 2, 100) HAL_OK; } /* 读取 6 字节原始数据并校验 CRC */ bool sht_read_raw(uint16_t *temp_raw, uint16_t *hum_raw, bool is_sht4x) { uint8_t data[6]; uint16_t cmd is_sht4x ? SHT4X_CMD_MEAS_HIGH : SHT3X_CMD_MEAS_HIGH; if (!sht_send_cmd(cmd)) { return false; } /* SHT3x 高重复性测量约 15msSHT4x 约 8.3ms统一延时 20ms 保险 */ HAL_Delay(20); if (HAL_I2C_Master_Receive(hi2c1, SHT_I2C_ADDR, data, 6, 100) ! HAL_OK) { return false; } /* 校验温度 CRC */ if (sht_crc8(data[0], 2) ! data[2]) { return false; } /* 校验湿度 CRC */ if (sht_crc8(data[3], 2) ! data[5]) { return false; } *temp_raw ((uint16_t)data[0] 8) | data[1]; *hum_raw ((uint16_t)data[3] 8) | data[4]; return true; } /* 换算为实际温湿度 */ void sht_convert(uint16_t temp_raw, uint16_t hum_raw, bool is_sht4x, float *temperature, float *humidity) { *temperature -45.0f 175.0f * ((float)temp_raw / 65535.0f); if (is_sht4x) { *humidity -6.0f 125.0f * ((float)hum_raw / 65535.0f); } else { *humidity 100.0f * ((float)hum_raw / 65535.0f); } }这段代码里有两个关键点。第一CRC 校验必须做而且要对温度和湿度分别校验。如果只校验温度不校验湿度湿度数据出错时你无法发现。第二SHT4x 的湿度换算公式有 -6% 的偏移这是数据手册里明确写的很多人直接套用 SHT3x 的公式导致湿度读数偏低 6 个百分点。如果你用的是 SHT40/SHT41还需要注意加热器功能。加热器命令是 0x39开启后传感器会升温到约 200°C 持续 1 秒用于去除冷凝和灰尘。加热完成后需要等待冷却再测量否则读数会偏高。加热器不是必须开启的只在结露或污染环境下才需要。对于使用 GY-SHT30 模块的场景模块上通常已经集成了 4.7kΩ 上拉电阻和电平转换你可以直接接 5V 单片机的 I2C 引脚。但要注意部分廉价模块的上拉电阻是 10kΩ在 400kHz 快速模式下可能波形上升沿不够陡建议降到 100kHz 使用。如果你在总线上挂了多个 I2C 设备总电容会增加上拉电阻需要相应减小一般总线电容不超过 400pF。配置完成后在主循环里调用读数函数并打印int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); uint16_t temp_raw, hum_raw; float temperature, humidity; while (1) { if (sht_read_raw(temp_raw, hum_raw, false)) { sht_convert(temp_raw, hum_raw, false, temperature, humidity); printf(Temp: %.2f C, Hum: %.2f %%RH\r\n, temperature, humidity); } else { printf(SHT read failed\r\n); } HAL_Delay(1000); } }这段代码烧进去后串口应该每秒打印一次温湿度。如果打印的是SHT read failed说明 I2C 通信或 CRC 校验有问题下一节会详细排查。4. 验证请求与成功结果从串口打印到数据上报烧录完成后第一步是确认串口有输出。打开串口助手波特率设置成 115200跟你的MX_USART1_UART_Init配置一致你应该能看到类似这样的输出Temp: 25.34 C, Hum: 48.21 %RH Temp: 25.36 C, Hum: 48.19 %RH Temp: 25.35 C, Hum: 48.23 %RH如果读数稳定在室温附近波动在 ±0.1°C 和 ±0.5% RH 以内说明传感器工作正常。你可以用手捂住传感器或者对着它哈气观察湿度和温度是否快速上升。SHT3x 的响应时间大约是 8 秒达到 63% 阶跃变化SHT4x 更快一些。如果哈气后湿度几分钟都不变可能是传感器没有真正测量或者读的是缓存数据。验证阶段建议同时打印原始值方便对照printf(Raw T: %u, Raw H: %u, Temp: %.2f C, Hum: %.2f %%RH\r\n, temp_raw, hum_raw, temperature, humidity);原始值在室温 25°C 时温度原始值大约在 26000 到 27000 之间因为 25°C 对应 (2545)/175*65535 ≈ 26214。湿度 50% RH 时原始值大约在 32767 左右。如果你看到原始值是 0 或 65535说明 I2C 读取失败但 CRC 恰好通过了概率极低或者传感器没有响应。接下来验证数据上报链路。假设你要把温湿度数据通过 TaoToken 的 API 上报并做简单分析可以用 Python 写一个脚本从串口读取数据后调用 APIimport serial import os import json from openai import OpenAI ser serial.Serial(COM3, 115200, timeout1) client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL) ) while True: line ser.readline().decode(utf-8, errorsignore).strip() if Temp: in line: response client.chat.completions.create( modelos.getenv(TAOTOKEN_MODEL), messages[ {role: system, content: 你是一个环境数据分析助手只输出 JSON。}, {role: user, content: f把这条数据转成 JSON{line}} ], max_tokens100 ) print(response.choices[0].message.content)运行这个脚本你应该能看到类似{temperature: 25.34, humidity: 48.21, unit: C/%RH}的输出。这说明从传感器读数到 API 调用的完整链路已经打通。如果你在验证模型对话功能可以访问 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 直接在网页上测试模型响应。成功结果的判断标准有三个串口读数稳定且合理、CRC 校验通过率 100%、API 返回正常 JSON。如果这三个都满足说明你的 SHT 传感器验证流程已经完成。接下来可以进入产品化阶段比如加滤波算法、做多点校准、或者接入更复杂的数据分析流程。5. 本篇常见错误排查401、CRC 失败与 I2C 无响应这一节列出验证过程中最常见的几类报错和对应的排查方法。每个问题都给出具体现象、原因分析和解决步骤。问题一I2C 扫描不到设备HAL_I2C_IsDeviceReady返回 HAL_ERROR现象是代码卡在初始化阶段或者串口打印SHT read failed用逻辑分析仪看 SDA/SCL 都是高电平没有波形。原因通常是接线错误或上拉电阻缺失。排查步骤先用万用表测 VDD 和 GND 之间电压确认是 3.3V 还是 5V然后测 SDA 和 SCL 对 VDD 的电阻正常应该在 4.7kΩ 到 10kΩ 之间如果测出来是无穷大说明没有上拉电阻需要外接最后确认 SDA 和 SCL 没有接反SHT 模块的引脚顺序通常是 VDD、GND、SDA、SCL但不同厂家的 GY 模块可能顺序不同以丝印为准。问题二CRC 校验失败读数偶尔正常偶尔失败现象是串口打印的数据时有时无CRC 校验函数返回 false。原因可能是 I2C 速率过高、导线过长、或者电源噪声。解决方法是把 I2C 速率从 400kHz 降到 100kHz缩短导线长度到 10cm 以内在 VDD 和 GND 之间加一个 100nF 去耦电容。如果用的是 GY 模块检查板载上拉电阻是否焊接良好。另外SHT3x 在测量期间如果主机发送其他 I2C 命令会导致测量中断所以测量期间不要操作同一条总线上的其他设备。问题三API 返回 401 Unauthorized现象是 Python 脚本调用 TaoToken API 时抛出AuthenticationErrorHTTP 状态码 401。原因是 API Key 无效或未正确传递。排查步骤检查.env文件里的TAOTOKEN_API_KEY是否以sk-开头是否有多余空格或换行检查代码里api_key参数是否正确读取用 curl 命令单独测试 Key 是否有效。如果 Key 刚创建确认没有复制错字符。如果 Key 被删除或过期需要到控制台重新创建。问题四API 返回 404 Not Found 或local proxy failed现象是请求发出去后返回 404或者报错信息里出现local proxy failed。原因是 Base URL 配置错误。TaoToken 的 Base URL 是 https://taotoken.net/api 注意不要写成https://taotoken.net/api/v1或https://taotoken.net。如果你用的是 OpenAI SDKbase_url参数应该设为https://taotoken.net/apiSDK 会自动拼接/v1/chat/completions。如果你用的是 Claude Code 或 Cline检查配置文件里的 Base URL 是否一致。问题五返回结果里reading choices报错或choices字段为空现象是 API 返回了 JSON但choices数组为空或者报错reading choices。原因通常是模型 ID 写错了或者请求参数不合法。检查model参数是否在文档列出的可用模型列表里注意大小写和连字符。如果模型 ID 正确但choices为空检查messages数组是否为空或者max_tokens是否设得太小导致没有输出。另外部分模型对temperature参数有范围限制超出范围会报错。问题六OAuth 相关报错如果你在用 Claude Code 的 OAuth 登录方式可能会遇到OAuth token expired或invalid_grant报错。解决方法是重新执行登录流程或者改用 API Key 方式配置。在 Claude Code 里可以通过claude config set命令切换认证方式。如果你同时配置了 OAuth 和 API Key可能会冲突建议只保留一种。问题七SHT4x 湿度读数偏低 6%现象是 SHT4x 读出的湿度比 SHT3x 或参考仪表低 6 个百分点。原因是 SHT4x 的湿度换算公式有 -6% 的偏移代码里如果用了 SHT3x 的公式就会偏低。检查sht_convert函数里的is_sht4x分支是否正确执行。如果你不确定用的是 SHT3x 还是 SHT4x可以看芯片丝印SHT3x 通常标SHT30或SHT31SHT4x 标SHT40或SHT41。问题八加热器开启后读数异常现象是调用加热器命令后温度读数飙升到 60°C 以上湿度降到 10% 以下。这是正常现象因为加热器会把传感器加热到 200°C 去除冷凝。解决方法是加热完成后等待至少 10 秒让传感器冷却到环境温度再测量。如果你不需要加热功能不要发送加热器命令。排查完这些问题后如果你的传感器仍然无法正常工作建议用逻辑分析仪抓 I2C 波形对照数据手册的时序图检查起始条件、地址字节、ACK/NACK 和停止条件。大多数问题都能从波形上直接看出来。6. 从验证到落地数据上报与 Coding Plan 接入建议传感器验证通过后下一步通常是把它接入实际的数据链路。如果你只是做单点测量串口打印就够了但如果你要做多点部署、远程监控或智能告警就需要一个稳定的上报通道。TaoToken 的 API 通道可以在这里发挥作用传感器数据通过 MCU 采集后经由网关或直接通过 WiFi 模块上报到 TaoToken再由模型做异常检测或趋势分析。API 入口是 https://taotoken.net/api Key 在控制台的 API Keys 页面创建地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。如果你在做长期编码和 Agent 开发比如要写一个自动采集温湿度并生成日报的 AgentCoding Plan 会更合适。入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它提供了更适合持续调用和批量任务的额度方案。模型对话功能可以直接在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 测试适合快速验证提示词和输出格式。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面列出了所有支持的模型 ID、请求格式和错误码说明。Claude Code 的 Anthropic 兼容配置可以参考 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里的说明Base URL 统一用 https://taotoken.net/api 。实际落地时建议把传感器读数、时间戳、设备 ID 一起打包成 JSON 再上报方便后续做数据分析和多设备管理。如果数据量不大可以直接用 HTTP 请求如果要做实时监控可以考虑 WebSocket 或 MQTT 网关转发。无论哪种方式TaoToken 的统一 Key 都能简化鉴权管理不用为每个服务单独维护凭证。最后提醒一点传感器验证阶段一定要用真实环境数据做对照不要只看代码跑通就认为没问题。我见过太多案例是代码能跑但读数偏差很大原因是 CRC 校验被注释掉了或者换算公式用错了。把原始值、换算值、CRC 校验结果都打印出来对照数据手册逐一确认才能真正判断传感器是否正常工作。
阅读完成 · 觉得有帮助?