news 2026/9/13 2:47:05

Tasmota 中的 Sensirion SCD30 I²C 传感器库:从 Arduino 接线到固件集成的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Tasmota 中的 Sensirion SCD30 I²C 传感器库:从 Arduino 接线到固件集成的完整指南

Tasmota 中的 Sensirion SCD30 I²C 传感器库:从 Arduino 接线到固件集成的完整指南

【免费下载链接】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

本文围绕仓库 lib/lib_i2c/arduino-i2c-scd30/README.md 展开,完整讲解 Sensirion SCD30 双通道 NDIR CO₂ 传感器在 Arduino 与 Tasmota 平台下的 I²C 驱动用法。你将掌握:SCD30 的引脚定义与各主流开发板接线方法、库的安装与依赖处理、exampleUsage示例程序的运行流程、完整 API 方法语义,以及该库如何在 Tasmota 固件(tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino)中被封装为可直接使用的传感器驱动与Scd30系列控制命令。

SCD30 传感器与 I²C 驱动库概览

SCD30 是 Sensirion 推出的一款高精度 CO₂ 传感器模块,内置 NDIR(非色散红外)CO₂ 测量单元以及温度、湿度传感器,能够同时输出 CO₂ 浓度(ppm)、温度(℃)与相对湿度(%RH)三组数据。它支持 I²C 与 UART 两种接口,本库(Sensirion I2C SCD30,版本 1.1.1,见 library.properties)专门负责通过I²C总线与该传感器通信。

库在 SensirionI2cScd30.h 中定义了默认 I²C 地址:

#define SCD30_I2C_ADDR_61 0x61

SCD30 的默认 I²C 地址为0x61(7 位地址)。该地址固定在芯片内部,无法像部分传感器那样通过引脚跳线修改,因此在接线与代码中始终使用SCD30_I2C_ADDR_61即可。

从源码结构看,本库由sensirion-driver-generator 1.6.1自动生成(模型版本 1.1.1),基于 Sensirion Core 提供的SensirionI2CTxFrame/SensirionI2CRxFrame帧封装与SensirionI2CCommunication通信原语实现,因此必须安装依赖库 Sensirion Core

SCD30 传感器模块实物图

库的安装与依赖

方式一:通过 Arduino 库管理器安装

启动 Arduino IDE,依次打开:

Sketch(项目) ➔Include Library(加载库) ➔Manage Libraries...(库管理)

Filter your search...(筛选)输入框中搜索Sensirion I2C SCD30,找到后点击install(安装)按钮即可。

方式二:通过 ZIP 包安装

如果在库管理器中找不到该库,可下载最新 release 的 .zip 文件,然后通过:

SketchInclude LibraryAdd .ZIP Library...

将其添加进 Arduino IDE。

依赖项

安装完成后,不要忘记以同样方式安装依赖库

  • Sensirion Core:提供 I²C 帧构造、CRC 校验与总线通信的底层实现,是编译本库的必备前提。

这一点在 library.properties 中也有明确声明:depends=Sensirion Coreincludes=SensirionI2cScd30.h。同时architectures=*表示该库不限制具体单片机架构,AVR(Uno、Nano、Micro、Mega)、SAM(MKR 系列)、ESP32 等均可使用。

连接传感器:引脚定义与接线表

SCD30 引脚总览

SCD30 共有 7 个引脚,与 Arduino 标准 I²C 总线的连接关系如下(接线下图所示):

SCD30 引脚定义图

引脚线缆颜色名称描述备注
1VDD供电电压3.3V ~ 5.5V
2GND接地
3SCLI²C 串行时钟输入
4绿SDAI²C 串行数据输入/输出
5RDY数据就绪指示高电平表示数据可用——不要连接
6PWMPWM 输出不要连接
7SEL接口选择拉低或悬空选择 I²C 模式

接线要点:

  • 推荐供电电压为 3.3V(虽然 VDD 范围是 3.3V~5.5V,但为了与 I²C 电平兼容及降低自热误差,官方建议使用 3.3V)。
  • SEL 引脚必须拉低或悬空才能启用 I²C 接口;若接高电平则进入 UART 模式。
  • RDY 与 PWM 引脚在本库的 I²C 场景下不要连接

常见开发板接线对照表

原文档为以下 5 款开发板提供了官方验证过的接线示意,本文完整保留并转换为仓库内图片路径:

Arduino Uno
SCD30SCD30 引脚线缆颜色开发板引脚
VDD13.3V
GND2GND
SCL3D19/SCL
SDA4绿D18/SDA
RDY5
PWM6
SEL7GND

Arduino Nano
SCD30SCD30 引脚线缆颜色开发板引脚
VDD13.3V
GND2GND
SCL3A5
SDA4绿A4
RDY5
PWM6
SEL7GND

Arduino Micro
SCD30SCD30 引脚线缆颜色开发板引脚
VDD13.3V
GND2GND
SCL3~D3/SCL
SDA4绿D2/SDA
RDY5
PWM6
SEL7GND

Arduino Mega 2560
SCD30SCD30 引脚线缆颜色开发板引脚
VDD13.3V
GND2GND
SCL3D21/SCL
SDA4绿D20/SDA
RDY5
PWM6
SEL7GND

ESP32 DevKitC
SCD30SCD30 引脚线缆颜色开发板引脚
VDD13V3
GND2GND
SCL3GPIO 22
SDA4绿GPIO 21
RDY5
PWM6
SEL7GND

其中 ESP32 DevKitC 的接线与 Tasmota 默认 I²C GPIO 配置一致(SCL=GPIO22、SDA=GPIO21),这是将 SCD30 直接接入 ESP32 运行 Tasmota 时最常用的硬件方案。

快速开始:运行 exampleUsage 示例

按照原文档的快速开始流程,共 5 步:

  1. 按照上文「库的安装与依赖」安装库及其依赖;

  2. 按照「连接传感器」章节完成硬件接线;

  3. 在 Arduino IDE 中打开示例工程:

    File(文件) ➔Examples(示例) ➔Sensirion I2C SCD30exampleUsage

  4. 点击Upload(上传)按钮,或使用SketchUpload编译烧录;

  5. 烧录完成后,通过Tools(工具)菜单打开Serial Monitor(串口监视器)或Serial Plotter(串口绘图器)观察测量值。注意:串口波特率必须设置为115200 baud

示例程序完整解读

示例源码位于 examples/exampleUsage/exampleUsage.ino,其核心流程如下:

#include <SensirionI2cScd30.h> #include <Wire.h> // 保证 NO_ERROR 定义正确(避免与其它头文件冲突) #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); // 绑定 I²C 总线与 0x61 地址 sensor.stopPeriodicMeasurement(); // 先停止周期测量 sensor.softReset(); // 软复位(内部阻塞 delay(2000)) delay(2000); int8_t serialNumber[32] = {0}; error = sensor.readSerialNumber(serialNumber, 32); // 读取序列号(v1.1.0 新增) if (error != NO_ERROR) { Serial.print("Error trying to execute readSerialNumber(): "); errorToString(error, errorMessage, sizeof errorMessage); Serial.println(errorMessage); return; } Serial.print("serialNumber: "); Serial.print((const char*)serialNumber); Serial.println(); uint8_t major = 0; uint8_t minor = 0; error = sensor.readFirmwareVersion(major, minor); // 读取固件版本 if (error != NO_ERROR) { Serial.print("Error trying to execute readFirmwareVersion(): "); errorToString(error, errorMessage, sizeof errorMessage); Serial.println(errorMessage); return; } Serial.print("major: "); Serial.print(major); Serial.print("\t"); Serial.print("minor: "); Serial.print(minor); Serial.println(); error = sensor.startPeriodicMeasurement(0); // 启动周期测量,环境气压 0 = 关闭气压补偿 if (error != NO_ERROR) { Serial.print("Error trying to execute startPeriodicMeasurement(): "); errorToString(error, errorMessage, sizeof errorMessage); Serial.println(errorMessage); return; } } void loop() { float co2Concentration = 0.0; float temperature = 0.0; float humidity = 0.0; delay(1500); error = sensor.blockingReadMeasurementData(co2Concentration, temperature, humidity); if (error != NO_ERROR) { Serial.print("Error trying to execute blockingReadMeasurementData(): "); errorToString(error, errorMessage, sizeof errorMessage); Serial.println(errorMessage); return; } Serial.print("co2Concentration: "); Serial.print(co2Concentration); Serial.print("\t"); Serial.print("temperature: "); Serial.print(temperature); Serial.print("\t"); Serial.print("humidity: "); Serial.print(humidity); Serial.println(); }

程序的关键节点:

  • sensor.begin(Wire, SCD30_I2C_ADDR_61):绑定 ArduinoTwoWire对象与传感器地址,其实现仅保存总线与地址指针(见 SensirionI2cScd30.cpp 的begin())。
  • setup()阶段完成「停止测量 → 软复位 → 读序列号 → 读固件版本 → 启动周期测量」的完整初始化链路,每一步都通过返回的int16_t errorNO_ERROR (0)比对来判错。
  • loop()中调用blockingReadMeasurementData()阻塞等待数据就绪并一次性读出 CO₂、温度、湿度三个浮点值;串口输出格式为co2Concentration: xxx temperature: xx.x humidity: xx.x

库 API 全景:方法与命令码

库的公开接口全部声明在 SensirionI2cScd30.h 中,并在 SensirionI2cScd30.cpp 中实现。下表汇总了所有方法及其对应的 SCD30 I²C 命令码(命令码定义见头文件中的SCD30CmdId枚举):

库方法功能命令码
begin(TwoWire&, uint8_t)绑定 I²C 总线与从机地址
startPeriodicMeasurement(ambientPressure)启动周期测量,可选环境气压补偿(mBar)0x0010
stopPeriodicMeasurement()停止周期测量0x0104
setMeasurementInterval(interval)设置测量间隔(秒),默认 2s,掉电不丢失0x4600
getMeasurementInterval(interval)读取当前测量间隔0x4600
getDataReady(dataReadyFlag)查询数据就绪标志(1=可读)0x0202
readMeasurementData(co2, temp, hum)读取 CO₂/温度/湿度测量数据0x0300
blockingReadMeasurementData(co2, temp, hum)轮询就绪标志后读取(阻塞)组合
awaitDataReady()阻塞轮询数据就绪标志组合
activateAutoCalibration(doActivate)开启/关闭自动自校准 ASC0x5306
getAutoCalibrationStatus(isActive)读取 ASC 状态0x5306
forceRecalibration(co2RefConcentration)强制校准 FRC(400~2000 ppm)0x5204
getForceRecalibrationStatus(co2RefConcentration)读取 FRC 参考浓度(默认 400 ppm)0x5204
setTemperatureOffset(temperatureOffset)设置温度偏移(单位 ℃×100)0x5403
getTemperatureOffset(temperatureOffset)读取温度偏移0x5403
setAltitudeCompensation(altitude)设置海拔补偿(米),设定气压后失效0x5102
getAltitudeCompensation(altitude)读取海拔补偿值0x5102
readFirmwareVersion(major, minor)读取固件主/次版本号0xD100
softReset()软复位(设备约 2 秒不可用)0xD304
readSerialNumber(serialNumber[], size)读取序列号(最多 32 字符,v1.1.0 新增)0xD033

关键方法语义详解(来自头文件文档)

  • startPeriodicMeasurement(ambientPressure):启动 CO₂/湿度/温度的连续测量。未被读取的测量数据会被覆盖;ambientPressure单位 mBar,传入 0 表示关闭环境气压补偿(默认气压 1013.25 mBar);设置气压会覆盖此前设置的海拔补偿;测量运行中若需更新气压,必须完整重发该命令。
  • awaitDataReady():反复轮询get_data_ready()直到就绪标志为 1。最小测量间隔为 2s 时最多轮询 200 次,会长时间阻塞系统。在 SensirionI2cScd30.cpp 中体现为每 100ms 轮询一次getDataReady()的循环。
  • getDataReady():查询传感器内部缓冲区是否有新测量;读走数据后标志自动归 0。注意:读序列应在写序列之后延迟 >3ms 再发送,实现中统一使用delay(10)
  • activateAutoCalibration(doActivate):ASC 首次激活后需要至少 7 天才能建立初始参数集,期间传感器需每天暴露于新鲜空气至少 1 小时不得断电,否则校准流程中止并需重新开始;参数存入非易失存储,掉电后仍然生效。ASC 只在连续测量模式下工作,默认关闭。
  • forceRecalibration(co2RefConcentration):用于存在参考 CO₂ 浓度时的漂移补偿。最佳做法是:先在 2s 间隔连续模式下稳定运行至少 2 分钟,再发送 FRC 与参考值;参考值范围400 ppm ≤ cref ≤ 2000 ppm;FRC 会永久更新校准曲线并掉电保持,最近一次参考值保存在易失内存中,重新上电后读回为 400 ppm;FRC 与 ASC 相互覆盖。
  • setTemperatureOffset(temperatureOffset):SCD30 板载温湿度传感器会受到芯片自热与周边器件发热影响,通过写入在连续运行中实测得到的偏移值(单位 ℃×100,如 2.0℃ 写 200)进行补偿;值保存在非易失存储中。
  • setAltitudeCompensation(altitude):NDIR 原理的 CO₂ 测量受海拔影响,此命令按米设置海拔补偿;一旦设置了环境气压则该设置失效;同样非易失保存。
  • softReset():强制传感器回到上电状态(重启内部系统控制器),会重新加载全部校准数据;设备约 2 秒不可用(实现中delay(2000))。传感器在任何内部状态下都能接收该命令。

底层通信实现特征

从 SensirionI2cScd30.cpp 可以看到所有方法统一遵循「构造命令帧 → 发送 →delay(10)(softReset 为 2000ms)→ 接收应答帧」的模式,例如readMeasurementData()先以SCD30_READ_MEASUREMENT_DATA_CMD_ID (0x0300)发送 2 字节命令帧,再接收 18 字节数据帧,依次解析出 CO₂(float)、温度(float)、湿度(float)三个 IEEE-754 浮点值;命令与应答均通过 Sensirion Core 的SensirionI2CCommunication::sendFrame / receiveFrame完成,内部自带 CRC 校验。帧数据复用静态缓冲区communication_buffer[48],不涉及动态内存分配。

在 Tasmota 固件中的集成:xsns_42 驱动

该库在 Tasmota 中被封装为第 42 号传感器驱动 tasmota/tasmota_xsns_sensor/xsns_42_scd30.ino,通过编译开关启用:

// tasmota/my_user_config.h // #define USE_SCD30 // [I2cDriver29] Enable Sensiron SCd30 CO2 sensor (I2C address 0x61) (+3k3 code)

取消 tasmota/my_user_config.h 中USE_SCD30的注释并重新编译即可启用(需同时启用USE_I2C)。I²C 设备编号为 29,对应 I2CDEVICES.md 中的条目:29 | USE_SCD30 | xsns_42 | SCD30 | 0x61 | Yes | CO2 sensor

驱动初始化与轮询机制

驱动在 Tasmota 启动 3 秒后通过FUNC_EVERY_SECOND触发Scd30Init()完成初始化:

  1. PowerOnDelay(2000)等待传感器上电启动(上电到 I²C 可通信时间 < 2s);
  2. 在全部 I²C 总线上以50 kHz 波特率SCD30_I2C_BUS_SPEED 50000)扫描SCD30_I2C_ADDR_61——Sensirion 官方建议 SCD30 在50 kHz 或更低速率下运行,且主机必须支持时钟拉伸(最大 150ms/天);
  3. 依次执行stopPeriodicMeasurement()softReset()readFirmwareVersion()readSerialNumber()getMeasurementInterval()startPeriodicMeasurement(0),全部成功后才登记设备并分配SCD30DATA结构体。

运行期Scd30Update()按测量间隔(默认 2s)轮询getDataReady(),数据就绪后调用readMeasurementData()读取并缓存;若连续错过SCD30_MAX_MISSED_READS (3)个周期则判定数据无效,自动执行停止测量 → 软复位 → 重新启动测量的恢复流程(ESP8266 平台还会先执行I2cClearBus清总线,规避下文已知问题)。

Scd30 控制命令

驱动通过FUNC_COMMAND注册了 6 条控制命令(前缀Scd30):

命令参数范围说明
Scd30Alt <米>≥0设置/读取海拔补偿(如Scd30Alt 440
Scd30Auto <0/1>0~1开启/关闭自动自校准 ASC,无参时读取状态
Scd30Cal <ppm>400~2000强制校准 FRC(如Scd30Cal 420),无参时读取当前参考值
Scd30Int <秒>2~1800设置/读取测量间隔(如Scd30Int 4
Scd30Pres <mBar>0 或 700~1400设置/读取环境气压补偿(0 表示关闭)
Scd30TOff <℃>0~20.00设置/读取温度偏移(内部换算为 ℃×100)

测量结果通过FUNC_JSON_APPEND输出为 JSON 中的"SCD30":{"CO2":…}字段并附带温湿度(ResponseAppendTHD),同时支持 Web 界面传感器页展示;启用USE_DOMOTICZ时还可推送空气质量与温湿度到 Domoticz(见Scd30Show())。若启用USE_LIGHT,CO₂ 读数还会驱动灯光信号指示(LightSetSignal(CO2_LOW, CO2_HIGH, co2))。

已知问题与注意事项

原文档记录了一个已知问题,Tasmota 驱动中也有对应处理:

  • softReset()在 Arduino MKR WIFI 1010 上的问题:调用softReset()后,后续命令不再被应答,I²C 线在收到第一个命令字节后保持低电平(该板使用软件 I²C)。解决方法:在该平台上移除示例中的softReset()调用及紧随其后的delay()。 与之呼应,Tasmota 的 xsns_42_scd30.ino 在 ESP8266 平台执行软复位后主动调用I2cClearBus(scd30_bus)清理总线状态,以规避同类软件 I²C 的挂死问题。

其他实操注意事项汇总:

  • 串口监视器波特率务必为115200
  • SCD30 上电后约 2 秒内无法进行 I²C 通信,初始化前需要足够的启动延时(示例与 Tasmota 驱动均有体现);
  • I²C 总线速率建议 ≤ 50 kHz 且主机需支持时钟拉伸;
  • 库的代码风格统一使用clang-format管理(见 README「Contributing」章节),提交.cpp/.h前可用clang-format -i src/*.cpp src/*.h自动格式化,否则 CI 构建会因格式差异失败。

许可证

本库采用 BSD 3-Clause 许可证,完整条款见 lib/lib_i2c/arduino-i2c-scd30/LICENSE;Tasmota 侧的 xsns_42_scd30.ino 驱动则遵循 GPL-3.0 许可。库的版本演进记录(从 0.1.0 初始发布到 1.1.1 增加readSerialNumber)可查阅 lib/lib_i2c/arduino-i2c-scd30/CHANGELOG.md。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 2:47:04

四川土壤类型Shp数据处理全流程:从文件结构到空间布点

简介&#xff1a;四川土壤类型空间分布标准矢量数据以shapefile格式组织&#xff0c;面向GIS、土壤与农业生态领域的研究者、规划人员和高校师生&#xff0c;用于土壤类型空间查询、专题制图和区域分析。数据依据1:400万中国土壤图编制&#xff0c;采用三位数字编码标识土类和亚…

作者头像 李华
网站建设 2026/9/13 2:47:03

STM32C542R启动配置详解:BOOT_SEL选项字节与BOOT_ADD实战指南

1. 先说清楚&#xff1a;BOOT_SEL到底管什么闲事 拿到STM32C542R这颗料&#xff0c;很多人第一反应是打开CubeMX把外设配好、点一下生成代码、编译下载&#xff0c;结果发现程序完全不理你——复位之后跑的不是你的代码&#xff0c;调试器连上了也一脸懵&#xff0c;或者干脆进…

作者头像 李华
网站建设 2026/9/13 2:45:58

Bun 运行时深度解析:JS/TS 工具链的性能革命与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 2:44:31

基于高阶累积量与模拟退火的地震子波相位恢复方法

简介&#xff1a;面向地震资料数字处理中的子波提取需求&#xff0c;这份资源提供基于模拟退火的高阶累积量子波提取方法的全套MATLAB源代码。算法将高阶累积量作为目标函数&#xff0c;利用模拟退火策略在解空间内进行全局寻优&#xff0c;避开局部极值&#xff0c;适用于地震…

作者头像 李华
网站建设 2026/9/13 2:44:19

汽车评论情感分析:LDA主题建模+NB-SVM-LR融合实战

简介&#xff1a;本资源是面向计算机、数学及电子信息等专业大学生的CCF大数据竞赛实战项目&#xff0c;聚焦汽车行业用户评论的情感分析任务&#xff0c;提供从数据预处理、特征工程到机器学习与深度学习模型实现的完整技术方案。压缩包共7个文件&#xff0c;含3份Markdown说明…

作者头像 李华
网站建设 2026/9/13 2:42:10

MySQL 5.7升级8.0实战:完整路径、踩坑记录与备份方案

我上周刚帮朋友把一套跑了三年的MySQL 5.7实例升到了8.0&#xff0c;整个过程比预想的要顺&#xff0c;但中间也踩了软件源、认证插件、sql_mode几个坑。MySQL 8.0发布好几年&#xff0c;社区版和企业版都已经非常稳定&#xff0c;5.7官方维护也进入了末期&#xff0c;从安全补…

作者头像 李华