# DFRobot_IntelligentGasSensor **Repository Path**: dfrobot/DFRobot_IntelligentGasSensor ## Basic Information - **Project Name**: DFRobot_IntelligentGasSensor - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: official-main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-20 - **Last Updated**: 2026-07-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DFRobot_IntelligentGasSensor * [English Version](./README.md) 面向 **DFRobot SEN07xx 智能气体传感器** 的 Arduino Modbus RTU 主机库,基于 **[DFRobot_RTU](https://github.com/DFRobot/DFRobot_RTU)**。主要能力:
* **0x04**:读气体测量输入寄存器(`readGasMeasurementData`); * 主机侧根据 **GAS_CODE** 译码气体类型与单位; * **0x06** + COMMIT:修改 Modbus 从站地址(`setDeviceAddress`); * **0x06**:写波特率保持寄存器 `0x0003`(`writeDeviceBaudCode` / `setDeviceBaudCode`); * **0x06**:写保持 `0x0005` 控制探头 RUN/SLEEP(`setProbeSleep` / `getProbeWorkMode`,不落 EEPROM); * `setClientSlaveAddr()`:仅切换主机侧目标从站号(不写传感器 EEPROM)。 ## 产品链接([https://www.dfrobot.com.cn](https://www.dfrobot.com.cn)) ```text SKU: SEN0738 / SEN0739 / SEN0740 / SEN0741 ``` ## 目录 * [概要](#概要) * [接线](#接线) * [库安装](#库安装) * [CDC 配置命令](#cdc-配置命令) * [方法](#方法) * [兼容性](#兼容性) * [历史](#历史) * [创作者](#创作者) ## 概要 本库将 SEN07xx 作为 Modbus RTU 从机进行读写,在 **DFRobot_RTU** 之上解析输入寄存器并填充 `lastMeasure`。默认链路:**9600 8N1**,从站地址 **1**。
例程见 `examples/`(如 `readGasRS485`、`readGasUART`、`changeDeviceAddress`、`changeDeviceBaudrate`)。寄存器表:[REGISTERMAP_MODBUS_CN.md](./docs/REGISTERMAP_MODBUS_CN.md)。 ## 接线 硬件接线图(以 ESP32 为例;传感器对外可使用 **RS-485 A/B**,TX/RX/DE 接 **UART 转 RS485 模块**,也可以直连传感器)
| ESP32 引脚 | UART 转 RS485 模块 | |------------|-------------------| | 3.3V | VCC | | GND | GND | | GPIO17 (TX) | DI | | GPIO36 (RX) | RO | | GPIO16 | DE/RE(方向控制,对应构造函数的 `dePin`) | | UART 转 RS485 模块 | 传感器 (SEN07xx) | |-------------------|------------------| | A | A | | B | B | ESP32 引脚 | 传感器 (SEN07xx) | |------------|-------------------| | 5.0V | VCC | | GND | GND | | GPIO17 (TX) | RX | | GPIO36 (RX) | TX | ## 库安装 1. 先将依赖库 **[DFRobot_RTU](https://github.com/DFRobot/DFRobot_RTU)** 放入 `Arduino/libraries`。 2. 下载本库到 `Arduino/libraries`,重启 IDE。 3. 打开 `examples` 文件夹,运行对应例程(如 `readGasRS485`)。 ## CDC 配置命令 SEN07xx 模块除 **Modbus RTU 主机口**(TTL / RS-485)外,还提供 **USB CDC** 虚拟串口,用于本地配置与状态查看(**不是** RS-485 总线上的 Modbus 帧)。 | 项目 | 说明 | |------|------| | 连接 | USB 接 PC,在设备管理器中打开对应 **COM 口** | | 串口监视器 | 建议 **115200 8N1**(与模块 SenLog/CDC 一致;与 Modbus 线速 9600 无关) | | 换行 | 发送命令后回车;输入 `help` 可打印完整列表 | 上电后串口输出示例: ```text === available commands === help show this help status print sensor + RTC + Modbus summary settime YYYY-MM-DD HH:MM:SS set RTC time setinterval <1-60> CSV every N minutes (saved) logger on|off enable/disable CSV recorder (saved, default off) repairfs read-write USB disk for PC filesystem repair (power cycle -> read-only default; stops logging) sensor sleep SMX100 probe SLEEP sensor wake SMX100 probe RUN modbus show host UART / slave settings setaddr <1-247> set Modbus slave ID (saved to EEPROM) setbaud <2400|4800|9600|...> set host UART baud (saved) setparity <8N1|8E1|8O1|8N2> set host UART format (saved) modbus default restore slave=1, 9600 8N1 (saved) ``` ### 命令说明 | 命令 | 作用 | |------|------| | `help` | 打印命令列表 | | `status` | 传感器浓度/有效性、探头 RUN/SLEEP、RTC、Modbus 从站号与线参数摘要 | | `settime YYYY-MM-DD HH:MM:SS` | 设置 RTC(例:`settime 2026-05-21 11:15:00`) | | `setinterval <1-60>` | 设置 CSV 记录间隔(分钟),**写入 EEPROM** | | `logger on/off` | 开启/关闭 CSV 记录(**写入 EEPROM**) | | `repairfs` | 读-写 USB 存储设备,用于修复文件系统 | | `sensor sleep` | SMX100 探头 **休眠**(CS 拉低),立即生效 | | `sensor wake` | SMX100 探头 **运行**(CS 拉高),立即生效 | | `modbus` | 显示当前 Modbus 从站地址、主机 UART 波特率与帧格式 | | `setaddr <1-247>` | 修改 Modbus 从站号并 **写入 EEPROM** | | `setbaud <速率>` | 修改主机口波特率并保存;支持 `2400` `4800` `9600` `14400` `19200` `38400` `57600` `115200` | | `setparity <格式>` | 修改主机口帧格式并保存;`8N1` `8E1` `8O1` `8N2` | | `modbus default` | 恢复出厂:**从站 1、9600 8N1**,并写入 EEPROM | ### 与 Modbus 寄存器 / 本库 API 的对应关系 | CDC 命令 | 保持寄存器 | 本库(Arduino 主机) | |----------|------------|----------------------| | `setaddr` | `0x0006` 从站地址 + `0x0007` COMMIT | `setDeviceAddress()` | | `setbaud` | `0x0003` 波特率编码 + COMMIT | `writeDeviceBaudCode()` + `Serial.begin` + `commitConfiguration()`(见 `changeDeviceBaudrate`) | | `setparity` | `0x0004` 校验/停止位 + COMMIT | 写保持 `0x0004` 后 COMMIT(库未封装专用 API) | | `sensor sleep` / `sensor wake` | `0x0005` 探头休眠(**不落 EEPROM**) | `setProbeSleep(true/false)` / `getProbeWorkMode()` | | `modbus` / `status` | — | 读输入寄存器 / `readGasMeasurementData()` 等 | 说明: * **CDC 与 Modbus 是两条通道**:PC 用 CDC 改配置;ESP32 等主控通过 RS-485/TTL 发 Modbus 读浓度。 * 改波特率后,Arduino 侧 `HOST_SERIAL.begin(...)` 必须与模块新线速一致,否则读不到数据。 * 探头 RUN/SLEEP **仅保持寄存器 0x0005**;输入寄存器 `0x0006` 为保留,无板型字段。 ## 方法 ```C++ /** * @brief 构造气体传感器驱动对象。 * @param s: 用于 Modbus RTU 的串口 Stream 指针。 * @param slaveAddr: Modbus 从站地址,范围 1~247 (0x01~0xF7)。 * @param dePin: RS485 流控引脚,拉低接收、拉高发送;-1 表示 TTL UART(无 DE)。 */ DFRobot_IntelligentGasSensor(Stream *s, uint8_t slaveAddr, int dePin = -1); /** * @brief 设置后续读写使用的从站地址(仅主机侧,不写 EEPROM)。 * @param addr: Modbus 从站地址,范围 1~247 (0x01~0xF7)。 */ void setClientSlaveAddr(uint8_t addr); /** * @brief 获取当前对象使用的 Modbus 从站地址。 * @return 从站地址 (1~247)。 */ uint8_t getClientSlaveAddr(void) const; /** * @brief 将输入寄存器表解析为测量结构体。 * @param out: 输出测量结构体。 * @param t: 输入寄存器数组(从地址 0 起)。 * @param regCount: 寄存器个数(不含时间戳 12,含时间戳 18)。 */ static void fillLastMeasureFromInputRegs(DFRobot_IntelligentGasSensorMeasure_t *out, const uint16_t *t, uint16_t regCount); /** * @brief 读取气体测量值(FC04 输入寄存器)。 * @param withTimestamp: false:读 0~11;true:读 0~17(含时间戳)。 * @return Exception code: * @n 0 : sucess. * @n 1 or eRTU_EXCEPTION_ILLEGAL_FUNCTION : 非法功能. * @n 2 or eRTU_EXCEPTION_ILLEGAL_DATA_ADDRESS: 非法数据地址. * @n 3 or eRTU_EXCEPTION_ILLEGAL_DATA_VALUE: 非法数据值. * @n 4 or eRTU_EXCEPTION_SLAVE_FAILURE: 从机故障. * @n 8 or eRTU_EXCEPTION_CRC_ERROR: CRC校验错误. * @n 9 or eRTU_RECV_ERROR: 接收包错误. * @n 10 or eRTU_MEMORY_ERROR: 内存错误. * @n 11 or eRTU_ID_ERROR:广播地址或错误ID(因为主机无法收到从机广播包的应答) */ uint8_t readGasMeasurementData(bool withTimestamp = false); /** * @brief 根据 lastMeasure 中小数位将浓度原始值转为 float。 * @return 浓度浮点值;decimalPoint>12 时返回 NAN。 */ float getConcentrationFloat(void) const; DFRobot_IntelligentGasSensorMeasure_t lastMeasure; /** * @brief 修改传感器 Modbus 从站地址(写保持 0x0006 并 COMMIT 至 EEPROM)。 * @param newAddr: 新从站地址,范围 1~247 (0x01~0xF7)。 * @return Exception code: * @n 0 : sucess. * @n 3 or eRTU_EXCEPTION_ILLEGAL_DATA_VALUE: 地址非法或未变化。 * @n 其余同 DFRobot_RTU 写/COMMIT 错误码。 */ uint8_t setDeviceAddress(uint8_t newAddr); /** * @brief 仅写传感器波特率保持寄存器 0x0003(FC06),COMMIT 前不落 EEPROM。 * @param code: 波特率编码:1=2400 … 8=115200。 * @return Exception code: * @n 0 : sucess. * @n 3 or eRTU_EXCEPTION_ILLEGAL_DATA_VALUE: 非法波特率编码。 * @n 其余同 DFRobot_RTU 写错误码。 * @note 固件可能在应答后立即切换从站线速;主机须在 COMMIT 前 begin(新波特率),见 changeDeviceBaudrate 例程。 */ uint8_t writeDeviceBaudCode(uint16_t code); /** * @brief 连续写波特率并 COMMIT(不改变主机串口波特率;SEN07xx 立即切线速时请用例程三步)。 * @param code: 波特率编码 (DFROBOT_IGS_BAUD_CODE_*)。 * @return 异常码(同 writeDeviceBaudCode() / commitConfiguration())。 */ uint8_t setDeviceBaudCode(uint16_t code); /** * @brief 写保持 0x0005 设置探头 RUN/SLEEP(立即生效,不写 EEPROM)。 * @param sleep: true=休眠,false=运行。 * @return 异常码(同 writeHoldingReg())。 */ uint8_t setProbeSleep(bool sleep); /** * @brief 读保持 0x0005 获取探头 RUN/SLEEP 状态。 * @param outSleep: true 表示休眠模式。 * @return Exception code: * @n 0 : sucess. * @n 3 or eRTU_EXCEPTION_ILLEGAL_DATA_VALUE: outSleep 为 NULL。 * @n 其余同 DFRobot_RTU 读错误码。 */ uint8_t getProbeWorkMode(bool *outSleep); /** * @brief 根据 measure 中 gasCode 译码 gasType、unit(主机侧表)。 * @param m: 测量结构体,须已填入 gasCode。 */ static void applyGasToMeasure(DFRobot_IntelligentGasSensorMeasure_t *m); /** * @brief 从输入寄存器表填充时间戳字段。 * @param m: 测量结构体。 * @param t: 输入寄存器数组(须含时间戳寄存器)。 */ static void applyTimestampToMeasure(DFRobot_IntelligentGasSensorMeasure_t *m, const uint16_t *t); /** * @brief 气体码映射为类型名字符串。 * @param gasCode: 输入寄存器 GAS_CODE。 * @param buf: 输出缓冲区。 * @param bufLen: 缓冲区长度。 * @return 已知码返回 true,未知返回 false(buf 清空)。 */ static bool gasCodeToTypeName(uint8_t gasCode, char *buf, size_t bufLen); /** * @brief 气体码映射为默认单位字符串。 * @param gasCode: 输入寄存器 GAS_CODE。 * @param buf: 输出缓冲区。 * @param bufLen: 缓冲区长度。 * @return 已知码返回 true,未知返回 false(buf 清空)。 */ static bool gasCodeToDefaultUnit(uint8_t gasCode, char *buf, size_t bufLen); /** * @brief 将未知气体码格式化为十六进制字符串(如 "0x1A")。 * @param gasCode: 气体码。 * @param buf: 输出缓冲区。 * @param bufLen: 缓冲区长度。 */ static void gasCodeFormatUnknown(uint8_t gasCode, char *buf, size_t bufLen); /** * @brief 写当前从站的一个保持寄存器。 * @param reg: 保持寄存器地址。 * @param value: 写入值。 * @return 异常码(同 DFRobot_RTU writeHoldingRegister())。 */ uint8_t writeHoldingReg(uint16_t reg, uint16_t value); /** * @brief 将配置 COMMIT 到传感器 EEPROM(向保持 COMMIT 写 0xA501)。 * @return 异常码(同 DFRobot_RTU writeHoldingRegister())。 */ uint8_t commitConfiguration(void); ``` ## 兼容性 MCU | RS-485(经转接模块) | TTL UART(5V) | ------------------ | :------------------: | :-----------------: | ESP32 | √ | √ | Mega2560 (5V) | √ | √ | Leonardo | √ | √ | micro:bit | X | X | 须安装 **[DFRobot_RTU](https://github.com/DFRobot/DFRobot_RTU)**,并使用硬件串口(`Serial1` / `Serial2`)。 ## 历史 - 日期 2026-05-21 - 版本 V1.0.0 ## 创作者 Written by wxzed (xiao.wu@dfrobot.com), 2026. (Welcome to our [website](https://www.dfrobot.com/))