Sensirion I2C SCD30 驱动库版本演进与 Tasmota 集成实战指南
2026/9/12 22:16:09 网站建设 项目流程

Sensirion I2C SCD30 驱动库版本演进与 Tasmota 集成实战指南

【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota

本文以 Tasmota 仓库内 arduino-i2c-scd30 驱动的 CHANGELOG 为主线,完整梳理该驱动从 2022 年初版到 2026 年 1.1.1 的功能演进轨迹,并结合驱动源码、示例程序与 Tasmota 的 SCD30 传感器模块(xsns_42_scd30.ino)展开源码级剖析。读完本文,你将掌握 SCD30(CO₂/温湿度三合一)驱动的全部 I²C 命令 API、Arduino 接入流程、Tasmota 中的编译开关与 Scd30 控制台命令,以及软复位等已知问题的规避方法。

一、库与 CHANGELOG 概览

arduino-i2c-scd30是 Sensirion 官方出品的 Arduino 驱动库,用于通过 I²C 总线驱动 SCD30 传感器(NDIR 原理的 CO₂ + 温湿度一体传感器)。本仓库中该库位于 lib/lib_i2c/arduino-i2c-scd30/,其 CHANGELOG.md 遵循 Keep a Changelog 格式与语义化版本号(Semantic Versioning)约定。

从 library.properties 可以看到当前发布版本为1.1.1,类别为 Sensors,依赖Sensirion Core(即 arduino-core),默认 I²C 地址为0x61(头文件中SCD30_I2C_ADDR_61 0x61)。metadata.yml 还记录了驱动由sensirion-driver-generator 1.6.1自动生成、模型版本 1.1.1、首次生成于 2022-04-07、最近一次生成于 2026-04-27,并标注is_manually_modified: true——这意味着代码虽由生成器产出,但经过了人工调整。

二、版本演进脉络(CHANGELOG 核心内容)

CHANGELOG 完整记录了 4 个已发布版本与一个 Unreleased 区段,是理解驱动能力增长的主线:

2.1 v0.1.0(2022-04-07):初始驱动发布

  • Added:Initial SCD30 driver release(首个 SCD30 驱动版本)。
  • 这是仓库 metadata.yml 中记录的首个生成日期,属于驱动的奠基版本,提供了通过 I²C 与 SCD30 通信的核心框架。

2.2 v1.0.0(2025-08-25):接入最新驱动框架

  • Changed:Updated to latest driver framework。
  • 该版本将底层通信层升级为 Sensirion 最新的驱动生成框架(generator 1.6.1 产物),SensirionI2CTxFrameSensirionI2CRxFrameSensirionI2CCommunication等封装统一了 I²C 帧的构造、校验与收发流程。这一框架升级是驱动 API 稳定化的分水岭,为后续功能增补奠定了基础。

2.3 v1.1.0(2026-04-24):新增序列号读取命令

  • Addedread_serial_numbercommand to read out the sensor's serial number。
  • 新增readSerialNumber()方法,对应命令 IDSCD30_READ_SERIAL_NUMBER_CMD_ID = 0xD033(见 SensirionI2cScd30.h)。该方法可读回最多 32 字符的以\0结尾的 ASCII 序列号,便于生产追溯与多传感器区分。

2.4 v1.1.1(2026-04-27):示例程序同步更新

  • Added:Addedread_serial_numberto example usage。
  • 该版本把序列号读取能力同步进 exampleUsage.ino 示例:setup()中在软复位后先读取序列号并打印,再读取固件版本号,最后启动周期测量。

2.5 Unreleased(未发布区段)

  • 当前 Unreleased 区段为空,说明维护者遵循"发布时再补记变更"的规范;后续新功能会先在此登记。

版本对比链接在 CHANGELOG.md 尾部以[x.y.z]:引用格式登记(0.1.0→1.0.0→1.1.0→1.1.1 的逐版本 diff 以及 1.1.1 之后的 HEAD 对比),读者可按标签名在托管平台回溯每次提交差异。

三、SCD30 传感器接线与硬件要点

3.1 引脚定义

根据 README.md,SCD30 共 7 个引脚,推荐供电电压 3.3V(允许范围 3.3V–5.5V):

引脚线色名称说明备注
1VDD供电3.3V–5.5V
2GND
3SCLI²C 时钟输入
4绿SDAI²C 数据输入/输出
5RDY数据就绪时拉高不要连接
6PWMPWM 输出不要连接
7SEL接口选择接地或悬空即选择 I²C

关键点:SEL 引脚接地(或悬空)时传感器工作于 I²C 模式,这是使用本驱动库的前提。

3.2 常见开发板接线

SCD30 引脚Arduino UnoArduino NanoArduino MicroMega 2560ESP32 DevKitC
VDD3.3V3.3V3.3V3.3V3V3
GNDGNDGNDGNDGNDGND
SCLD19/SCLA5~D3/SCLD21/SCLGPIO 22
SDAD18/SDAA4D2/SDAD20/SDAGPIO 21
SELGNDGNDGNDGNDGND

各板级的接线示意图存放在库的 images 目录(Arduino-Uno-Rev3-i2c-pinout-3.3V-SEL.pngArduino-Nano-i2c-pinout-3.3V-SEL.pngArduino-Micro-i2c-pinout-3.3V-SEL.pngArduino-Mega-2560-Rev3-i2c-pinout-3.3V-SEL.pngesp32-devkitc-i2c-pinout-3.3V-SEL.png),按 README 中的折叠块查阅对应板型即可。

四、驱动库 API 全景与命令映射

4.1 类结构与初始化

SensirionI2cScd30类(SensirionI2cScd30.h)只维护两个私有成员:TwoWire* _i2cBusuint8_t _i2cAddress。初始化流程为:

#include <SensirionI2cScd30.h> #include <Wire.h> SensirionI2cScd30 sensor; Wire.begin(); sensor.begin(Wire, SCD30_I2C_ADDR_61); // 0x61

begin()的实现(SensirionI2cScd30.cpp)仅保存总线与地址引用,真正通信依赖 Sensirion Core 的帧封装。

4.2 命令 ID 与 API 对照表

头文件中的SCD30CmdId枚举完整映射了 SCD30 数据手册的全部命令:

命令 ID宏定义库方法方向
0x0010SCD30_START_PERIODIC_MEASUREMENT_CMD_IDstartPeriodicMeasurement(ambientPressure)
0x0104SCD30_STOP_PERIODIC_MEASUREMENT_CMD_IDstopPeriodicMeasurement()
0x4600SCD30_SET/GET_MEASUREMENT_INTERVAL_CMD_IDsetMeasurementInterval/getMeasurementInterval写/读
0x0202SCD30_GET_DATA_READY_CMD_IDgetDataReady(dataReadyFlag)
0x0300SCD30_READ_MEASUREMENT_DATA_CMD_IDreadMeasurementData(co2, t, h)
0x5306SCD30_ACTIVATE/GET_AUTO_CALIBRATION_CMD_IDactivateAutoCalibration/getAutoCalibrationStatus写/读
0x5204SCD30_FORCE/GET_RECALIBRATION_CMD_IDforceRecalibration/getForceRecalibrationStatus写/读
0x5403SCD30_SET/GET_TEMPERATURE_OFFSET_CMD_IDsetTemperatureOffset/getTemperatureOffset写/读
0x5102SCD30_SET/GET_ALTITUDE_CMD_IDsetAltitudeCompensation/getAltitudeCompensation写/读
0xD100SCD30_READ_FIRMWARE_VERSION_CMD_IDreadFirmwareVersion(major, minor)
0xD304SCD30_SOFT_RESET_CMD_IDsoftReset()
0xD033SCD30_READ_SERIAL_NUMBER_CMD_IDreadSerialNumber(serialNumber[], size)

实现层面每个命令都走相同模式:用SensirionI2CTxFrame::createWithUInt16Command()构造帧 → 可选addUInt16()追加参数 →sendFrame()发送 → 延时 10ms → 需要回读时用SensirionI2CRxFrame+receiveFrame()解析。例如readMeasurementData()构造 18 字节读帧后依次getFloat()解出 CO₂、温度、湿度三个 IEEE754 浮点值。

4.3 便捷方法

  • awaitDataReady():以 100ms 间隔轮询getDataReady(),直到就绪标志为 1;注释明确警告这是阻塞操作(最短测量间隔 2s 时最多循环约 200 次)。
  • blockingReadMeasurementData()awaitDataReady()+readMeasurementData()的组合封装,同样是阻塞式便捷方法,示例程序即使用它。

4.4 校准与补偿参数要点(来自头文件注释)

  • ASC 自动自校准activateAutoCalibration):默认关闭;首次启用后至少需 7 天找到初始参数集,期间传感器需每天接触新鲜空气至少 1 小时且不能断电;参数存入非易失存储,断电重启后仍生效;仅在连续测量模式下工作。
  • FRC 强制校准forceRecalibration):参考 CO₂ 浓度范围400 ≤ cref ≤ 2000 ppm;施加前建议在 2s 测量率下稳定运行至少 2 分钟;FRC 与 ASC 互相覆盖,且 FRC 会永久更新校准曲线(断电保留);最近一次参考值存于易失内存,重新上电后读回默认 400 ppm。
  • 温度偏移setTemperatureOffset):单位 ℃×100,用于补偿板级自热导致的温湿度偏移,存入非易失存储。
  • 高度补偿setAltitudeCompensation):单位米,用于修正海拔对 NDIR 测量的影响;一旦在startPeriodicMeasurement()中传入环境气压,高度补偿即被忽略。
  • 环境气压补偿startPeriodicMeasurement(ambientPressure)):气压单位为 mBar,传 0 关闭补偿(默认 1013.25 mBar);连续测量运行中修改气压必须重发整条命令。

五、Arduino 快速上手:完整示例代码

官方示例 exampleUsage.ino 是 1.1.1 的产物(已包含 1.1.0/1.1.1 新增的序列号读取),其流程可作为任何项目的接入模板:

#include <Arduino.h> #include <SensirionI2cScd30.h> #include <Wire.h> #ifdef NO_ERROR #undef NO_ERROR #endif #define NO_ERROR 0 SensirionI2cScd30 sensor; static char errorMessage[64]; static int16_t error; void setup() { Serial.begin(115200); while (!Serial) { delay(100); } Wire.begin(); sensor.begin(Wire, SCD30_I2C_ADDR_61); sensor.stopPeriodicMeasurement(); sensor.softReset(); delay(2000); int8_t serialNumber[32] = {0}; // v1.1.0 新增的序列号读取 error = sensor.readSerialNumber(serialNumber, 32); if (error != NO_ERROR) { Serial.print("Error trying to execute readSerialNumber(): "); errorToString(error, errorMessage, sizeof errorMessage); Serial.println(errorMessage); return; } Serial.print("serialNumber: "); Serial.println((const char*)serialNumber); uint8_t major = 0, minor = 0; error = sensor.readFirmwareVersion(major, minor); if (error != NO_ERROR) { /* 打印错误并返回 */ } Serial.printf("major: %d\tminor: %d\n", major, minor); error = sensor.startPeriodicMeasurement(0); // 0 = 不启用环境气压补偿 if (error != NO_ERROR) { /* 打印错误并返回 */ } } void loop() { float co2Concentration = 0.0, temperature = 0.0, humidity = 0.0; delay(1500); error = sensor.blockingReadMeasurementData(co2Concentration, temperature, humidity); if (error != NO_ERROR) { /* 打印错误并返回 */ } Serial.printf("co2Concentration: %.2f\ttemperature: %.2f\thumidity: %.2f\n", co2Concentration, temperature, humidity); }

运行要点(来自 README.md 的 Quick Start):

  1. 通过 Arduino IDE 的 Library Manager 搜索Sensirion I2C SCD30安装,或下载 zip 后Sketch → Include Library → Add .ZIP Library...
  2. 务必同步安装依赖Sensirion Core;
  3. 打开File → Examples → Sensirion I2C SCD30 → exampleUsage,上传后在 Serial Monitor / Serial Plotter 中观察数据,波特率设为 115200

示例的完整错误处理模式(errorToString(error, errorMessage, sizeof errorMessage))同样适用于驱动内其他所有 API,因为 Sensirion 驱动统一以int16_t返回非零错误码。

六、在 Tasmota 中的深度集成

6.1 编译开关

SCD30 支持由USE_SCD30宏控制,定义于 tasmota_configurations.h(标注[I2cDriver29],约 +3.3k 代码),ESP32 配置在 tasmota_configurations_ESP32.h 中默认启用,用户可在 my_user_config.h 中自行启用/禁用。功能位掩码登记在 support_features.ino(0x00400000),用于固件功能自检。

6.2 Tasmota 驱动的关键设计(xsns_42_scd30.ino)

  • I²C 总线降速SCD30_I2C_BUS_SPEED = 50000(50kHz)。Sensirion 官方建议 SCD30 运行在 50kHz 或更低,且主机必须支持时钟拉伸——传感器读写帧的时钟拉伸期为 30ms,内部校准过程可能触发每天一次最长 150ms 的拉伸。Tasmota 通过Scd30BusSpeed()在访问前后切换总线时钟。
  • 慢启动:传感器上电后需约 2s 才能通信(PowerOnDelay(2000)),初始化被推迟到FUNC_EVERY_SECONDuptime > 3时执行一次(scd30_init_once防重复)。
  • 初始化链stopPeriodicMeasurement()softReset()(内部延时 2000ms)→readFirmwareVersion()readSerialNumber()getMeasurementInterval()startPeriodicMeasurement(0),任一步失败不中断,继续尝试下一个 I²C 总线(MAX_I2C循环)。
  • 数据更新与容错Scd30Update()按测量间隔节流读取,连续丢失SCD30_MAX_MISSED_READS(3 次)读数后标记data_valid=false并触发"停测量→软复位→重启测量"的自动恢复;ESP8266 平台额外调用I2cClearBus()清理总线(对应驱动库已知问题)。
  • 遥测输出:JSON 上报"SCD30":{"CO2":...,"Temperature":...,"Humidity":...},支持 Domoticz 空气质量/温湿度传感器与 Web UI 展示;启用USE_LIGHT时 CO₂ 数值还会驱动LightSetSignal(CO2_LOW, CO2_HIGH, co2)做灯光指示。

6.3 Scd30 控制台命令

驱动注册了 6 条前缀命令(kScd30Commands),参数范围直接映射驱动库 API 的约束:

命令示例说明(取值范围)
Scd30AltScd30Alt 440设置/读取高度补偿(米)
Scd30AutoScd30Auto 1开启/关闭 ASC 自动校准(0/1)
Scd30CalScd30Cal 420强制校准参考 CO₂(400–2000 ppm)
Scd30IntScd30Int 4设置/读取测量间隔(2–1800 秒)
Scd30PresScd30Pres 1013设置/读取环境气压补偿(0 或 700–1400 mBar)
Scd30TOffScd30TOff 4.2设置/读取温度偏移(0–20.00 ℃,内部 ×100 存储)

其中Scd30Pres的实现印证了 4.4 节的结论:气压变化时通过重发startPeriodicMeasurement(payload)整条命令生效,且会覆盖此前的高度补偿设置。

七、已知问题与规避(README 与源码共同确认)

  • softReset() 与 Arduino MKR WIFI 1010:在 MKR WIFI 1010(软件 I²C)上调用softReset()后,后续命令不再被应答,I²C 线保持低电平。规避方式:删除示例中的softReset()调用及随后的delay()。该问题同样被 Tasmota 的 ESP8266 分支引用,作为I2cClearBus()兜底的依据。
  • 阻塞式 API 的时延awaitDataReady()/blockingReadMeasurementData()会阻塞系统较长时间(最短 2s 间隔下轮询最多约 200 次 × 100ms),在 RTOS 或无阻塞应用(如 Tasmota 的循环调度模型)中应改用getDataReady()+readMeasurementData()的组合——这正是 xsns_42_scd30.ino 没有使用便捷方法、而是手动轮询数据就绪标志的原因。

八、总结

从 2022 年 0.1.0 的初始发布,到 2025 年 1.0.0 的驱动框架升级,再到 2026 年 1.1.0/1.1.1 连续补入序列号读取并同步示例,arduino-i2c-scd30的演进始终围绕"完整覆盖 SCD30 寄存器命令、严格遵循 Sensirion 生成框架、保证 Arduino 与 Tasmota 双生态可用"展开。开发者若需在自有固件中接入 SCD30,可直接以 exampleUsage.ino 为起点;若使用 Tasmota 固件,则编译期启用USE_SCD30、运行期使用Scd30*命令即可获得完整的测量、校准、容错与 Web/JSON 输出能力。

【免费下载链接】TasmotaAlternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at项目地址: https://gitcode.com/GitHub_Trending/ta/Tasmota

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询