十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Tasmota 中的 AGS02MA TVOC 传感器库:0.4.x 版本演进、API 详解与 I2C 低速通信实践

Tasmota 中的 AGS02MA TVOC 传感器库:0.4.x 版本演进、API 详解与 I2C 低速通信实践 Tasmota 中的 AGS02MA TVOC 传感器库0.4.x 版本演进、API 详解与 I2C 低速通信实践【免费下载链接】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 仓库内置的 AGS02MA-0.4.3 库 为主线完整梳理该 Arduino 库 0.4.x 系列的核心变更、API 设计、I2C 低速通信机制、校准流程与 TVOC 空气分级知识并结合 Tasmota 驱动源码 说明它如何被集成到固件中。读完本文你将掌握 AGS02MA TVOC 传感器的接线与 I2C 地址、25 kHz 低速总线的实现原理、PPB/UGM3 双模式与空气分级表的实战用法以及如何在 Tasmota 中启用并读取该传感器数据。一、AGS02MA 库是什么TVOC 传感器与版本脉络AGS02MA 是测量空气中TVOC总挥发性有机物Total Volatile Organic Compounds浓度的传感器芯片它不针对某一种特定气体而是同时感知多种挥发性有机物。本仓库中对应的 Arduino 库为 lib/lib_i2c/AGS02MA-0.4.3由 Rob Tillaart、Viktor Balint 与 Beanow 维护当前版本 0.4.3。该库被 Tasmota 固件直接复用驱动实现位于 xsns_118_ags02ma.inoTasmota 中该传感器编号 XSNS_118、I2C 设备编号 XI2C_95对应 I2CDEVICES.md 的登记表。从源码看Tasmota 驱动直接调用库的begin()、getSensorVersion()、setPPBMode()、readPPB()、isHeated()等接口把传感器固件与固件框架解耦。1.1 0.4.x 版本演进一览依据 CHANGELOG0.4.02023-12-06重构 API 与begin()调用方式——破坏性变更不能再在begin()中传入引脚改为由用户先调用Wire.begin()并可选设置 Wire 引脚再调用begin()。这一改动降低了对各处理器 Wire 实现的依赖。0.4.12023-12-10修复 README 中第 #26 号 issue 指出的文档错误。0.4.22024-02-03功能较丰富的一次更新——README 增加 I2C 多路复用multiplexer章节、扩充 PPB health 表格清理示例重构条件编译代码新增setI2CLowSpeed()/setI2CHighSpeed()内部函数改进错误处理新增错误码AGS02MA_ERROR_REQUEST-14并重写readRegister()。0.4.32025-08-15更新 README、更新许可证、少量编辑为当前仓库所携带的稳定版本。更早的 0.3.x 线0.3.2 起正式加入 CHANGELOG0.3.3 起加入 keywords.txt 与 GitHub Actions0.3.4 增加 ESP32 的Wire1 支持以及 0.1.x/0.2.x 的历史版本在 CHANGELOG 中无详细记录。1.2 单元测试佐证库的公开契约库的 unit_test_001.cpp 用 Arduino-CI 框架固化了关键常量与默认值可作为版本行为的一致性证据错误码常量AGS02MA_OK 0、AGS02MA_ERROR -10、AGS02MA_ERROR_CRC -11、AGS02MA_ERROR_READ -12、AGS02MA_ERROR_NOT_READY -13、AGS02MA_ERROR_REQUEST -14I2C 工作时钟常量AGS02MA_I2C_CLOCK 2500025 kHz默认地址 260x1A默认 I2C 复位速度 100 kHz可用setI2CResetSpeed()改为如 400 kHz模式初值 255not set地址初值经构造函数设定lastRead()初始为 0。二、硬件接线、I2C 地址与低速总线警告2.1 引脚布局正面从左到右以数据手册为准引脚说明1VDD 5V2SDA 数据线3GND4SCL 时钟线2.2 固定地址 0x1A 与同地址冲突传感器 I2C 地址固定为260x1A无法像普通 I2C 芯片那样用地址引脚选择。仓库 README 明确指出多款 AGS 系列器件共用 0x1AAGS2616H2、AGS3870CH4、AGS3871CO、AGS02MATVOC。若要在同一条 I2C 总线上同时使用它们必须借助I2C 多路复用器如 TCA9548最多 8 通道。其代价是代码管理复杂需记录器件与通道的对应关系且切换通道会拖慢多路复用器之后的其他设备访问速度。2.3 低速总线警告传感器最高只支持 30 kHz这是 AGS02MA 最关键的工程约束。数据手册标称器件工作在 100 kHz 总线但实际最高只能以约 30 kHz 通信。库的处理策略见 AGS02MA.cpp每次 I2C 操作前调用_setI2CLowSpeed()将总线降速至25 kHz常量AGS02MA_I2C_CLOCK历史版本曾用 30 kHz 上限0.3.1 起统一用 25 kHz 换取稳定性操作结束后调用_setI2CHighSpeed()把时钟恢复到_I2CResetSpeed默认100 kHz以减少对同总线其他设备通信的干扰复位速度可用setI2CResetSpeed()改为 200/400 kHz在 AVR如 Arduino UNO上通过直接写TWBR 78; TWSR 0x01预分频 4实现 25 kHz在 ESP32/ESP8266 等非 AVR 平台通过_wire-setClock(AGS02MA_I2C_CLOCK)实现。注意AGS02MA::isConnected()与_readRegister()/_writeRegister()内部都包裹了降速—操作—恢复流程因此即使总线上挂着其他标准速度器件也只在 AGS02MA 操作期间短暂占用低速窗口。2.4 读取时序与 30 ms 寄存器节流源码_readRegister()与_writeRegister()开头均有while (millis() - _lastRegTime 30) yield();的节流逻辑保证两次寄存器操作至少间隔 30 ms。此外begin()会记录_startTimeisHeated()据此判断预热是否满 120 秒数据手册建议测量间隔至少 1.5 秒、优选 3 秒库内示例如 AGS02MA_PPB.ino普遍使用 3000 ms 间隔。三、库 API 全景从构造到数据读取API 定义集中在 AGS02MA.h以下按功能分组给出签名、默认值与使用要点。3.1 构造与初始化接口说明AGS02MA(uint8_t deviceAddress 26, TwoWire *wire Wire)构造器默认地址 26默认 Wire 实例支持传入其他 TwoWire如 ESP32 的 Wire1bool begin()初始化若 I2C 总线上找不到该地址返回 false。0.4.0 起不再接收引脚参数bool isConnected()地址探测降速后endTransmission(true) 0即为在线void reset()复位内部变量复位 I2C 复位速度为 100 kHz、清空缓存与错误码3.2 预热与读取节奏bool isHeated()begin()后是否满 2 分钟millis() - _startTime 120000UL。数据手册指出充分预热可提升测量质量若未先调用begin()该函数结果可能不准确。uint32_t lastRead()最近一次成功读取的时间戳毫秒从未读取过返回 0可用于实现异步等待——保持两次测量间隔 ≥1.5 秒优选 3 秒。3.3 器件管理地址 / 版本 / 生产日期bool setAddress(uint8_t addr)写入从机地址寄存器0x21。源码限制10 ≤ addr ≤ 119地址以地址 取反两两写入并经 CRC8 校验成功后立即生效且重启后保持。示例见 AGS02MA_setAddress.ino。uint8_t getAddress()返回当前设定地址默认 26。uint8_t getSensorVersion()读取版本寄存器0x11版本字节位于_buffer[3]读取失败或 CRC 错误时返回 255。多数器件报告版本 117社区也报告存在版本 118行为有差异见下文。uint32_t getSensorDate()实验性读取版本寄存器中前 3 字节经 BCD 转换拼成YYYYMMDD如Serial.println(dd, HEX)输出20210203疑似生产日期仅供调试。3.4 I2C 时钟复位速度控制void setI2CResetSpeed(uint32_t speed)/uint32_t getI2CResetSpeed()设置/读取每次 I2C 操作结束后总线要恢复的时钟速度默认 100 kHz。库文档建议可按需改为 200 或 400 kHz用于匹配同总线上其他器件的需求。3.5 测量模式PPB 与 ug/m³器件上电默认PPB十亿分率模式bool setPPBMode()写数据寄存器0x00使能 PPB成功后内部_mode 0。bool setUGM3Mode()切换为微克/立方米µg/m³模式成功后_mode 1。uint8_t getMode()返回当前模式0 PPB1 UGM3255 未设置。源码中两种模式写入的字节序列不同PPB00 FF 00 FF 30UGM302 FD 02 FD 00并统一经_writeRegister(AGS02MA_DATA)提交。PPB 与 UGM3 无固定换算关系二者之比取决于目标气体分子量PPB 更接近绝对指示UGM3 偏相对指示气体未知时建议以 PPB 为准。仅供参考的换算公式未经验证来源为μg/m3 ppb × M × 12.187 / (273.15 °C)在 1 atm、25 °C 下简化为μg/m3 ppb × M × 0.04087539829。常见气体换算系数M 为分子量气体常用名1 ppb ≈ μg/m³M (g/mol)SO2二氧化硫2.6264NO2二氧化氮1.8846NO一氧化氮1.2530O3臭氧2.0048CO一氧化碳1.14528C6H6苯3.19783.6 读取传感器uint32_t readPPB(); // PPB典型 1..999999 uint32_t readUGM3(); // 微克/立方米单次读取约耗时35 ms含内部 30 ms 节流与请求延迟源码中通过delay(30)等待器件就绪后requestFrom()取 5 字节。读取失败时返回上一次缓存值_lastPPB/_lastUGM3避免图表出现跳变应配合lastError()与lastStatus()判断真实成败。派生包装函数float readPPM() PPB × 0.001典型 0.01..999.99、float readMGM3() UGM3 × 0.001、float readUGF3() UGM3 × 0.0283168466微克/立方英尺。缓存读取lastPPB()、lastUGM3()、lastPPM()。3.7 错误码与状态字节错误码lastError()返回读取后自动清零宏值含义AGS02MA_OK0正常AGS02MA_ERROR-10通用错误AGS02MA_ERROR_CRC-11CRC8 校验失败AGS02MA_ERROR_READ-12读取字节数不足非 5 字节AGS02MA_ERROR_NOT_READY-13状态字节 RDY1器件忙AGS02MA_ERROR_REQUEST-14请求阶段错误0.4.2 新增状态字节lastStatus()需新一轮读取才会更新bit7-4 内部使用bit3-1 表示模式000 PPB001 ug/m³bit0 为 RDY0 就绪1 忙。dataReady()即返回_status 0x01。3.8 寄存器直读与校准数据结构bool readRegister(uint8_t address, RegisterData reg)将寄存器原始数据填入RegisterData{ data[4]; crc; crcValid; }主要用于排障分析不建议基于原始数据构建业务。与常规方法不同CRC 错误不会让本方法返回 false 或写入lastError()而是记录在reg.crcValid中。ZeroCalibrationData{ uint16_t status; uint16_t value; }由getZeroCalibrationData()填充。源码注释提示 status 疑似位掩码0x0C(12) 为典型值0x0D(13) 偶见于 v1170x7D(125) 见于 v118 断电后其数据与 12 不同。四、校准正确姿势与 v118 版本风险4.1 校准 APIbool zeroCalibration()等值于manualZeroCalibration(0)须在新鲜空气中至少 5 分钟后调用。bool manualZeroCalibration(uint16_t value 0)手动设定零点。v1170-65535 均视为自动校准v1180 自动校准1-65535 手动校准。bool getZeroCalibrationData(ZeroCalibrationData data)读取当前零点状态与数值成功返回 true。4.2 v118 版本的校准隐患README 与 CHANGELOG 多次强调切勿对版本 118 的器件执行校准社区 issue 报告 v118 在校准后出现数据异常已由第二颗 v118 复现重复校准无法修复而 v117 无此问题。0.2.0 起校准函数会先读取版本号拒绝校准任何非 117 版本v118 还可能存在仅支持 PPB、不支持 ug/m³ 模式的情况详见库 README 引用 issue 11、13 的说明且断电后数据表现不同。4.3 完整校准流程示例参考 AGS02MA_calibrate.ino默认预热 6 分钟、读取间隔 3000 ms#include AGS02MA.h #define WARMUP_MINUTES 6 #define READ_INTERVAL 3000 AGS02MA AGS(26); void setup() { Serial.begin(115200); Wire.begin(); bool b AGS.begin(); Serial.print(BEGIN:\t); Serial.println(b); uint8_t version AGS.getSensorVersion(); // 版本读取失败则不校准 if (AGS.lastError() ! AGS02MA_OK) { Serial.println(Wont attempt to calibrate.); return; } b AGS.setPPBMode(); Serial.print(MODE:\t); Serial.println(b); // 将器件置于户外新鲜空气中预热 WARMUP_MINUTES 分钟观察 PPB 值稳定 uint32_t start millis(); while (millis() - start WARMUP_MINUTES * 60000UL) { Serial.print([PRE]\tPPB:\t); Serial.println(AGS.readPPB()); delay(READ_INTERVAL); } AGS02MA::ZeroCalibrationData initialValue; if (!AGS.getZeroCalibrationData(initialValue)) { Serial.println(Read calib failed.); return; } Serial.print(OLD status/value:\t); Serial.print(initialValue.status); Serial.print(/); Serial.println(initialValue.value); b AGS.zeroCalibration(); // 执行零点校准 Serial.print(CALIB:\t); Serial.println(b); AGS02MA::ZeroCalibrationData zc; while (!AGS.getZeroCalibrationData(zc)) { delay(READ_INTERVAL); } Serial.print(NEW status/value:\t); Serial.print(zc.status); Serial.print(/); Serial.println(zc.value); // 若为 v118 或旧状态为 125提示断电后可能需重设校准值 }关键经验预热期间 PPB 应稳定允许噪声而非持续下降校准前先备份ZeroCalibrationDatav118 用户应避免自动校准。五、空气分级把读数翻译成健康指示库 README 给出了 TVOC(ppb) 的分级参考表源自 Kaiterra 的公开资料属指示性描述非专业监测结论TVOC (ppb)等级描述建议颜色≤ 2201良好绿≤ 6603中等黄≤ 14307差橙≤ 220010不健康红≤ 330015很不健康紫建议加脉冲效果≤ 550025危险深紫脉冲 550050极危险深紫脉冲其中等级是相对线性标度以 220 ≈ 1 为基准颜色为指示性映射若需连续色阶映射可参考同作者的 map2colour 思路。该表可用于将 AGS02MA 读数映射为指示灯、蜂鸣器或 Web 面板的告警级别。六、示例程序全景与 Tasmota 集成实践6.1 仓库内 15 个示例一览examples/ 目录示例用途AGS02MA_minimal不依赖库仅用 Wire 直接requestFrom(26,5)取 5 字节并手工解析状态/PPB/CRC展示协议本质AGS02MA_PPBPPB 模式读取 120 秒预热等待AGS02MA_UGM3µg/m³ 模式读取AGS02MA_calibrate / AGS02MA_calibrate_manual自动/手动零点校准全流程AGS02MA_setAddress改写 I2C 地址示例改为 42并验证AGS02MA_get_registers、AGS02MA_readRegister寄存器直读与排障AGS02MA_PPB_TIMING时序测试附 performance_0.3.0/0.3.1 文本记录AGS02MA_minimal_plotter配合 Arduino 串口绘图器可视化AGS02MA_test连通性 模式 版本 连续 PPB 冒烟测试AGS02MA_test_CRC8、test_CRC8CRC8 算法验证issue/issue.ino针对 GitHub issue 的复现脚本AGS02MA_minimal.ino特别值得一读它以最原始方式演示了数据帧格式——buffer[0]为状态字节、buffer[1..3]按b1*65536 b2*256 b3拼出 PPB、buffer[4]为 CRC8这也正是库内部_readSensor()的解析逻辑见 AGS02MA.cpp。6.2 在 Tasmota 固件中启用与读取Tasmota 侧驱动 xsns_118_ags02ma.ino 封装了完整状态机编译启用需同时开启USE_I2C与USE_AGS02MA两个宏可参考 my_user_config.h 与 user_config_override_sample.h 的覆盖方式并确认 I2C 设备号 95 已启用对应I2cEnabled(XI2C_95)检查。启动流程Ags02maInit()探测 0x1A 地址 →begin()→ 打印getSensorVersion()→ 强制setPPBMode()→ 登记I2cSetActiveFound()随后进入120 秒预热状态STATE_AGS02MA_HEATING由FUNC_EVERY_SECOND驱动、用isHeated()判定完成。正常运行每秒轮询readPPB()检查lastStatus()/lastError()并输出日志JSON 遥测FUNC_JSON_APPEND输出AGS02MA:{TVOC:ppb}Web 页面FUNC_WEB_SENSOR显示 AGS02MA TVOC: ppb预热期间 JSON 输出Status:Heating。可选集成开启USE_DOMOTICZ时遥测周期内会通过DomoticzSensor(DZ_AIRQUALITY, ppb)上报空气质量。因此在 Tasmota 控制台或 MQTT 中即可直接看到TVOC读数无需自行编写读取逻辑底层 I2C 低速切换与 30 ms 节流均由库透明处理。6.3 性能与稳定性记录UNO 平台TWBR25530.4 kHz实测 500 次读取失败率 1%0.3.1 起改为 25 kHz TWSR 预分频 4 后4 小时 6000 次读取0 错误。ESP32/ESP8266 在 30 kHz 下测试良好更低时钟尚未系统验证。AGS02MA_PPB_TIMING目录内保留 performance_0.3.0.txt 与 performance_0.3.1_10khz/25khz.txt 等历史性能记录可作参考。七、使用建议与已知限制基于源码与文档事实务必处理低速 I2C不要让 AGS02MA 长时间占用 25 kHz 总线——库的设计是在每次操作后恢复默认速度若自行绕过库请复制同样的降速-恢复策略。控制读取频率遵循 ≥1.5 秒优选 3 秒间隔库已内置 30 ms 寄存器节流与单次 ~35 ms 耗时高频调用会拖慢主循环。读取失败读缓存readPPB()/readUGM3()失败时返回上次值务必同时检查lastError()与lastStatus()避免把脏数据当真实测量。校准分版本对待v117 可正常自动校准v118 严禁校准存在社区确认的数据异常风险且 v118 可能不支持 ug/m³ 模式。多器件同地址需多路复用AGS02MA 与 AGS2616/AGS3870/AGS3871 共用 0x1A同总线共存必须使用 TCA9548 等 MUX。库仍标记为实验性Experimental文档明确说明不替代专业空气质量监测系统用于生产环境前应充分验证。Tasmota 集成确保编译宏与 I2C 设备号正确开启预热 120 秒后才输出 TVOC 数据Web 与 MQTT 均可消费该读数。本文全部技术事实均来自 Tasmota 仓库内 AGS02MA-0.4.3 库 的 CHANGELOG.md、README.md、AGS02MA.h、AGS02MA.cpp、单元测试 及 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表