在 RT-Thread 中快速使用 CCS811 气体传感器

1、CCS811 传感器

ccs811 软件包是 CCS811 气体传感器的驱动软件包。CCS811 是一款低功耗数字气体传感器,用于检测室内低水平的挥发性有机化合物和二氧化碳浓度,内部集成微控制器单元 (MCU) 和模数转换器(ADC),并提供通过标准 I2C 数字接口获取 CO2 或 TVOC 数据。

CCS811 模块支持 I2C 接口,IIC 地址可配置为 0x5A 或 0X5B。

在这里插入图片描述

CCS811 支持多种模式:每1秒、10秒、1分钟、250毫秒测量一次以及休眠模式,这些模式在传感器测量期间进行了低功耗优化,因此 CCS811 适用于便携式应用。CCS811 支持浓度报警,当浓度超过用户设置的阈值时,INT 引脚就会触发。

注意:该芯片对 IIC 进行了时钟延展,有些控制器不支持时钟延展,例如树莓派。

1.1 技术规格

  • 供电电压:3.3V~5.5 V
  • 预热时间:<15s
  • IIC地址:0x5A 或 0X5B
  • 工作温度范围:-40℃~85℃
  • 工作湿度范围:10%RH~95%RH
  • eCO2测量范围:400ppm~8000ppm
  • TVOC测量范围:0ppb~1100ppb
  • 产品尺寸:22*31mm

1.2 功能特性

  • 集成 MCU
  • 板载处理
  • 标准数字接口
  • 优化的低功耗模式
  • IAQ 阈值报警
  • 可编程基线-2.7mm x 4.0mm LGA 封装
  • 低元件数
  • 成熟的技术平台

1.3 应用场景

  • 车内空气质量检测
  • 室内空气质量检测
  • 空气净化器
  • 家庭控制器
  • 新风系统

2、使用 ccs811 软件包

2.1 添加软件包

为了在项目中快速集成 CCS811 传感器进行应用开发,笔者制作了基于 RT-Thread 的 ccs811 软件包。GitHub 地址: https://github.com/luhuadong/rtt-ccs811

使用 ccs811 软件包,需要在 RT-Thread 的包管理器中选择它,具体路径如下:

RT-Thread online packages --->
    peripheral libraries and drivers --->
        [*] sensors drivers  --->
            [*] CCS811: Digital Gas Sensor for Monitoring Indoor Air Quality..

打开 Env 工具,执行 pkgs --upgrade 更新 RT-Thread 软件包索引。更新完成后,在你的 BSP 工程目录中执行 menuconfig 进行配置,添加 ccs811 软件包,如下图所示。

在这里插入图片描述

然后让 RT-Thread 的包管理器自动更新,或者使用 pkgs --update 命令更新包到 BSP 中。

2.2 配置选项

ccs811 软件包目前提供两个配置选项:

  • 选择 I2C 地址(PKG_USING_CCS811_I2C_ADDRESS
  • 是否使用示例程序(PKG_USING_CCS811_SAMPLE

用户可根据 CCS811 实际的硬件连接,选择 I2C 地址为 0x5A 或 0x5B。

3 测试

3.1 编译下载

ccs811 软件包中提供了测试示例,只需在 menuconfig 配置中勾选 “Enable ccs811 sample” 即可。为了完成测试,还需要开启 “Sensor cmd” 功能。

在这里插入图片描述

对了,别忘了配置 I2C 总线!ccs811 软件包的示例默认使用 i2c1,因此需要在 menuconfig 中配置好 I2C1 Bus。

在这里插入图片描述

配置完成后即可编译,下载到开发板中进行下一步实验。

3.2 初始化示例代码

因为 RT-Thread 提供了 Sensor 驱动框架,并且 ccs811 已经接入 Sensor 框架了,因此只需要向下面这样注册传感器设备,即可完成初始化工作。

static int rt_hw_ccs811_port(void)
{
    struct rt_sensor_config cfg;
    
    cfg.intf.type = RT_SENSOR_INTF_I2C;
    cfg.intf.dev_name = CCS811_I2C_BUS_NAME;
    rt_hw_ccs811_init("cs8", &cfg);
    
    return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_ccs811_port);

实际上,这一步在 sensor_ccs811_sample.c 示例中已经有了。因此,我们不用敲一行代码!

3.3 使用 sensor 命令

如果一切正常,我们就可以来到 msh 终端。

3.3.1 检查传感器是否初始化成功

输入 list_device 查看 CCS811 传感器是否已经注册。如果看到如下信息,说明已经注册上了,并且传感器初始化成功。

msh >list_device
device           type         ref count
-------- -------------------- ----------
tvoc_cs8 Sensor Device        0
eco2_cs8 Sensor Device        0

这里会看到两个设备 tvoc_cs8 和 eco2_cs8,这是因为 CCS811 模块能检测两类气体数据(TVOC 和 CO2),所以在 RT-Thread 中会注册为两个设备。

3.3.2 查看 CCS811 信息

传感器初始化成功后,我们就可以使用 sensor 命令进行测试了!sensor probe 命令用于探测传感器设备,命令后面接上设备名称即可。

msh >sensor probe tvoc_cs8
[4774993] I/sensor.cmd: device id: 0x81!

同时 sensor probe 命令还会选中该传感器设备,之后可以使用 sensor infosensor read 等命令对该设备进行操作。

比如查看设备信息:

msh >sensor info
vendor    :AMS
model     :ccs811
unit      :ppb
range_max :32768
range_min :0
period_min:250ms
fifo_max  :1

3.3.3 读取 TVOC 数据

执行 sensor read 即可读取 TVOC 的值。

msh >sensor read
[4794468] I/sensor.cmd: num:  0, tvoc:  184 ppb, timestamp:4794468
[4794586] I/sensor.cmd: num:  1, tvoc:  184 ppb, timestamp:4794586
[4794704] I/sensor.cmd: num:  2, tvoc:  184 ppb, timestamp:4794704
[4794822] I/sensor.cmd: num:  3, tvoc:  184 ppb, timestamp:4794822
[4794940] I/sensor.cmd: num:  4, tvoc:  184 ppb, timestamp:4794940

3.3.4 读取 CO2 数据

由于前面选中的是 tvoc_cs8 设备,为了读取 CO2 的值,我们需要先执行 sensor probe eco2_cs8 切换设备,再执行 sensor read 读取传感数据。

msh >sensor read
[4957632] I/sensor.cmd: num:  0, eco2:  871 ppm, timestamp:4957632
[4957850] I/sensor.cmd: num:  1, eco2:  865 ppm, timestamp:4957850
[4957968] I/sensor.cmd: num:  2, eco2:  865 ppm, timestamp:4957968
[4958086] I/sensor.cmd: num:  3, eco2:  871 ppm, timestamp:4958086
[4958303] I/sensor.cmd: num:  4, eco2:  871 ppm, timestamp:4958303

3.4 使用自定义接口测试

ccs811 为我们提供了两种接口,一种是自定义的接口,另一种是对接 RT-Thread Sensor 框架的接口。在 ccs811 软件包的示例代码中还提供了一个 cat_ccs811 示例,其使用的就是自定义接口,测试结果如下。

msh >cat_ccs811
[20] TVOC: 0 ppb, eCO2: 0 ppm
[19] TVOC: 9 ppb, eCO2: 465 ppm
[18] TVOC: 11 ppb, eCO2: 475 ppm
[17] TVOC: 11 ppb, eCO2: 475 ppm
[16] TVOC: 11 ppb, eCO2: 477 ppm
==> baseline: 0x8484
...

4、API 说明

4.1 自定义接口

创建和删除对象

要操作传感器模块,首先需要创建一个传感器对象。

ccs811_device_t ccs811_create(const char *i2c_bus_name);

调用这个函数时,会从动态堆内存中分配一个 ccs811_device_t 句柄,并按给定参数初始化。

参数 描述
i2c_bus_name 设备挂载的 IIC 总线名称
返回 ——
ccs811_device_t 创建成功,返回传感器对象句柄
RT_NULL 创建失败

对于使用 ccs811_create() 创建出来的对象,当不需要使用,或者运行出错时,请使用下面的函数接口将其删除,避免内存泄漏。

void ccs811_delete(ccs811_device_t dev);
参数 描述
ccs811_device_t 要删除的传感器对象句柄
返回 ——

初始化对象

如果需要使用静态内存分配,则可调用 ccs811_init() 函数。

rt_err_t ccs811_init(struct ccs811_device *dev, const char *i2c_bus_name);

使用该函数前需要先创建 ccs811_device 结构体。

参数 描述
dev 传感器对象结构体
i2c_bus_name 设备挂载的 IIC 总线名称
返回 ——
RT_EOK 初始化成功
-RT_ERROR 初始化失败

测量数据

测量 eTVOC 和 eCO2 浓度值,并将数据保存在传感器对象中。

rt_bool_t ccs811_measure(ccs811_device_t dev);
参数 描述
dev 传感器对象句柄
返回 ——
RT_TRUE 读取成功
RT_FALSE 读取失败

由于 CCS811 传感器支持多种模式和测量周期,为成功获取数据,建议在调用 ccs811_measure() 前使用 ccs811_check_ready() 函数检查传感器是否准备好了。

读取 baseline

rt_uint16_t ccs811_get_baseline(ccs811_device_t dev);
参数 描述
dev 传感器对象句柄
返回 ——
16位的基线值 读取成功
0 读取失败

设置 baseline

rt_bool_t ccs811_set_baseline(ccs811_device_t dev, rt_uint16_t baseline);
参数 描述
dev 传感器对象句柄
baseline 16位的 baseline 设置值
返回 ——
RT_TRUE 设置成功
RT_FALSE 设置失败

设置环境数据

rt_bool_t ccs811_set_envdata(ccs811_device_t dev, float temperature, float humidity);
参数 描述
dev 传感器对象句柄
temperature 当前环境的温度值
humidity 当前环境的湿度值
返回 ——
RT_TRUE 设置成功
RT_FALSE 设置失败

在测量过程中定期设置环境温度和湿度值,有利于获取更准确的数据。

设置测量周期

rt_bool_t  ccs811_set_measure_cycle(ccs811_device_t dev, ccs811_cycle_t cycle);
参数 描述
dev 传感器对象句柄
cycle 测量周期
返回 ——
RT_TRUE 设置成功
RT_FALSE 设置失败

测量周期包括 250ms、1s、10s 和 60s,具体可配置项如下:

typedef enum
{
    CCS811_CLOSED,
    CCS811_CYCLE_1S,
    CCS811_CYCLE_10S,
    CCS811_CYCLE_60S,
    CCS811_CYCLE_250MS

} ccs811_cycle_t;

设置工作模式

rt_bool_t ccs811_set_measure_mode(ccs811_device_t dev, 
                                  rt_uint8_t thresh, 
                                  rt_uint8_t interrupt, 
                                  ccs811_mode_t mode);
参数 描述
dev 传感器对象句柄
thresh 0:不检测阈值,1:检测阈值
interrupt 0:不使能中断,1:使能中断
mode 工作模式(就是设置测量周期)
返回 ——
RT_TRUE 设置成功
RT_FALSE 设置失败

工作模式可选项如下:

typedef enum
{
    CCS811_MODE_0,
    CCS811_MODE_1,
    CCS811_MODE_2,
    CCS811_MODE_3,
    CCS811_MODE_4

} ccs811_mode_t;

读取工作模式

rt_uint8_t ccs811_get_measure_mode(ccs811_device_t dev);
参数 描述
dev 传感器对象句柄
返回 ——
MEAS_MODE 寄存器值 读取成功
0xFF 读取失败

设置报警阈值

rt_bool_t ccs811_set_thresholds(ccs811_device_t dev, 
                                rt_uint16_t low_to_med, 
                                rt_uint16_t med_to_high);
参数 描述
dev 传感器对象句柄
low_to_med 低范围到中范围的阈值,默认为 1500ppm
med_to_high 中范围到高范围的阈值,默认为 2500ppm
返回 ——
RT_TRUE 设置成功
RT_FALSE 设置失败

注意:阈值设置只针对 CO2 气体浓度。

4.2 Sensor 接口

ccs811 软件包已对接 sensor 驱动框架,操作传感器模块之前,只需调用下面接口注册传感器设备即可。

rt_err_t rt_hw_ccs811_init(const char *name, struct rt_sensor_config *cfg);
参数 描述
name 传感器设备名称
cfg sensor 配置信息
返回 ——
RT_EOK 创建成功
-RT_ERROR 创建失败

5、注意事项

  1. 为传感器对象提供静态创建和动态创建两种方式,如果使用动态创建,请记得在使用完毕释放对应的内存空间。
  2. 由于 CCS811 模块包含一个 TVOC 传感器和一个 eCO2 传感器,因此在 sensor 框架中会注册两个设备,内部提供1位 FIFO 缓存进行同步,缓存空间在调用 rt_device_open 函数时创建,因此 read 之前务必确保两个设备都开启成功。
  3. 由于使用 I2C 接口进行操作,因此注册时需指定具体的 I2C 总线名称,对应的句柄存放在 user_data 中。
  4. CCS811 传感器需要预热,预热时间小于15秒,此前的数据一直是 eTVOC 为 0,eCO2 为 400。
  5. 数据手册建议在第一次使用传感器时,先运行48小时。
  6. CCS811 传感器会自动校准基线,但是这个过程非常缓慢。数据手册对基线校准的建议:在运行传感器的第一周,建议每24小时保存一个新的基线,运行1周后,可以每1-28天保存一次。
  7. 如需使用中断功能,请将传感器的 INT 引脚连接到主控板相应的中断引脚。

猜你喜欢

转载自blog.csdn.net/luckydarcy/article/details/107130346