跳转至

04 AirVOC_1000

作者:沈园园

一、AirVOC_1000 概述

AirVOC_1000是合宙设计生产的一款I2C接口的VOC(挥发性有机化合物)气体传感器配件板,其中:

  1. 气体传感器,奥松AGS02MA;
  2. I2C接口;
  3. 适用于Air780E系列/Air8000系列/Air8101系列/Air6101系列;

二、演示功能概述

AirVOC_1000是合宙设计生产的一款I2C接口的VOC(挥发性有机化合物)气体传感器配件板;

主要用于检测甲醛、一氧化碳、可燃气体、酒精、氨气、硫化物、苯系蒸汽、烟雾、其它有害气体的监测;

本demo演示的核心功能为:

Air8000核心板+AirVOC_1000配件板,每隔1秒读取1次TVOC空气质量数据;

三、准备硬件环境

1、Air8000核心板一块

2、TYPE-C USB数据线一根

3、AirVOC_1000配件板

4、母对母的杜邦线4根

5、Air8000核心板和数据线的硬件接线方式为

  • Air8000核心板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
  • 核心板正面的 供电/充电 拨动开关 拨到供电一端;
  • 核心板背面的 USB ON/USB OFF 拨动开关 拨到USB ON一端;

Air8000核心板和AirVOC_1000配件板的硬件接线方式为

Air8000核心板 AirVOC_1000配件板
VDD_EXT 3V3
GND GND
I2C1_SDA SDA
I2C1_SCL SCL

四、准备软件环境

4.1 软件环境

在开始实践本示例之前,先筹备一下软件环境:

1、烧录工具:Luatools 下载调试工具

2、内核固件:Air8000 最新版本的内核固件

3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8000/demo/accessory_board/AirVOC_1000

4、lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件

准备好软件环境之后,接下来查看如何烧录项目文件到Air8000核心板,将本篇文章中演示使用的项目文件烧录到Air8000核心板中。

4.2 API 介绍

I2C库:https://docs.openluat.com/osapi/core/i2c/

五、程序结构

AirVOC_1000/
│── main.lua
│── voc_app.lua
│── AirVOC_1000.lua
│── readme.md

5.1 文件说明

  1. main.lua:主程序入口文件。
  2. voc_app.lua:每隔1秒读取1次TVOC空气质量数据。
  3. AirVOC_1000.lua:AirVOC_1000驱动文件。

六、代码详解

6.1 main.lua

主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。

6.2 voc_app.lua

每隔1秒读取1次TVOC空气质量数据。

6.2.1 每隔1秒读取一次TVOC数据

--每隔1秒读取一次TVOC数据
local function read_voc_task_func()
    --打开voc硬件
    air_voc.open(1)

    while true do
        --读取TVOC的ppb,ppm,quality_level值
        local ppb = air_voc.get_ppb()
        local ppm = air_voc.get_ppm()
        local level, description = air_voc.get_quality_level()

        --读取成功
        if ppb then
            log.info("空气质量", 
                string.format("TVOC: ppb %d, ppm %.3f, 等级 %d(%s)", 
                ppb, ppm, level, description))
        --读取失败
        else
            log.error("空气质量", "读取数据失败")
        end

        --等待1秒
        sys.wait(1000)
    end

    --关闭voc硬件
    air_voc.close()
end

6.3 AirVOC_1000.lua

AirVOC_1000驱动配置文件。

6.3.1 读取AirVOC_1000的寄存器中指定长度的数据

-- 从机地址为0x1A
local slave_address = 0x1A

-- TVOC数据的寄存器地址
local DATA_REG_ADDR = 0x00
-- TVOC数据的长度
local DATA_REG_LEN = 0x05


-- 计算数据表data中所有数据元素的crc8校验值
local function crc8(data)
    local crc = 0xFF
    for i = 1, #data do
        crc = bit.bxor(crc, data[i])
        for j = 1, 8 do
            crc = crc * 2
            if crc >= 0x100 then
                crc = bit.band(bit.bxor(crc, 0x31), 0xff)
            end
        end
    end
    return crc
end


-- 读取AirVOC_1000的寄存器中指定长度的数据

--reg:number类型;
--         表示AirVOC_1000上的寄存器地址;
--         必须传入,不允许为空;

--返回值:失败返回false;成功返回读取到的指定长度的数据(string类型)
local function read_register(reg, len)
    -- 发送寄存器地址
    i2c.send(AirVOC_1000.i2c_id, slave_address, reg)

    -- sys.wait(20)

    -- 读取应答的数据
    local data = i2c.recv(AirVOC_1000.i2c_id, slave_address, len)

    -- log.info("read_register", data:toHex())

    -- 读取到的数据为指定的长度,则表示读取成功
    -- 否则读取失败
    if type(data)=="string" and data:len()==len then
        return data
    else
        log.error("AirVOC_1000 read_register error", type(data), type(data)=="string" and data:len() or "invalid type", len)
        return false
    end
end

6.3.2 打开AirVOC_1000

--打开AirVOC_1000;

--i2c_id:number类型;
--        主机使用的I2C ID,用来控制AirVOC_1000;
--        取值范围:仅支持0和1;
--        如果没有传入此参数,则默认为0;

--返回值:成功返回true,失败返回false
function AirVOC_1000.open(i2c_id)
    --如果i2c_id为nil,则赋值为默认值0
    if i2c_id==nil then i2c_id=0 end

    --检查参数的合法性
    if not (i2c_id == 0 or i2c_id == 1) then
        log.error("AirVOC_1000.open", "invalid i2c_id", i2c_id)
        return false
    end

    AirVOC_1000.i2c_id = i2c_id

    --初始化I2C
    if i2c.setup(i2c_id, i2c.FAST) ~= 1 then
        log.error("AirVOC_1000.open", "i2c.setup error", i2c_id)
        return false
    end

    return true
end

6.3.3 读取TVOC的ppb值

--读取TVOC的ppb值;
--ppb: 代表 parts per billion,即 十亿分之一。 1 ppb TVOC 表示在每 10 亿个体积单位的空气中,含有 1 个体积单位的 TVOC

--返回值:失败返回false;
--       成功返回ppb值(number类型)
function AirVOC_1000.get_ppb()
    --从寄存器DATA_REG_ADDR中读取DATA_REG_LEN长度的数据
    local raw = read_register(DATA_REG_ADDR, DATA_REG_LEN)

    --读取数据出错
    if not raw then
        log.error("AirVOC_1000.get_ppb", "read_register error")
        return false
    end

    --检查校验值
    if crc8({raw:byte(1), raw:byte(2), raw:byte(3), raw:byte(4)}) ~= raw:byte(5) then
        log.error("AirVOC_1000.get_ppb", "crc error")
        return false
    end

    --解析数据: 大端格式
    local tvoc = (raw:byte(2) << 16) | 
                 (raw:byte(3) << 8) | 
                 raw:byte(4)

    return tvoc
end

6.3.4 读取TVOC的ppm值

--读取TVOC的ppm值;
--ppm: 代表 parts per million,即 百万分之一。 1 ppm TVOC 表示在每 100 万个体积单位的空气中,含有 1 个体积单位的 TVOC

--返回值:失败返回false;
--       成功返回ppb值(number类型)
function AirVOC_1000.get_ppm()
    --读取ppb值
    local ppb = AirVOC_1000.get_ppb()

    --如果ppb读取失败
    if not ppb then
        log.error("AirVOC_1000.get_ppm", "get_ppb error")
        return false
    end

    --ppb = ppm*1000
    return ppb/1000

end

6.3.5 读取TVOC的空气质量等级

--读取TVOC的空气质量等级;
-- 根据 TVOC 浓度(通常以 ppb 或 ppm 表示)划分的等级,用于评估室内空气质量的优劣和对人体健康的潜在风险;
-- 不同国家、地区或机构的标准可能略有差异,但核心划分逻辑相似:浓度越低,等级越好,风险越低。

--返回值:失败返回false;
--       成功返回空气质量等级值(number类型,数值越小,表示空气质量越好)和空气质量描述(string类型,例如优、良好、轻度污染、中度污染、重度污染)
--           1:表示优
--           2:表示良好
--           3:表示轻度污染
--           4:表示中度污染
--           5:表示重度污染
function AirVOC_1000.get_quality_level()
    --读取ppb值
    local ppb = AirVOC_1000.get_ppb()

    --如果ppb读取失败
    if not ppb then
        log.error("AirVOC_1000.get_qulity_level", "get_ppb error")
        return false
    end

    --根据ppb值计算空气质量等级
    if ppb < 200 then
        return 1,"优"
    elseif ppb < 1000 then
        return 2,"良好"
    elseif ppb < 3000 then
        return 3,"轻度污染"
    elseif ppb < 5000 then
        return 4,"中度污染"
    else
        return 5,"重度污染"
    end 
end

6.6.6 关闭AirVOC_1000

--关闭AirVOC_1000

--返回值:成功返回true,失败返回false
function AirVOC_1000.close()
    --close接口没有返回值,理论上不会关闭失败
    i2c.close(AirVOC_1000.i2c_id)

    return true
end

七、运行结果展示

通过观察Luatools的运行日志,每隔1秒出现一次类似于下面的打印,就表示测试正常:

[2025-09-25 11:28:01.193][000002293.756] I/user.空气质量 TVOC: ppb 93, ppm 0.093, 等级 1()
[2025-09-25 11:28:02.194][000002294.761] I/user.空气质量 TVOC: ppb 91, ppm 0.091, 等级 1()

八、总结

通过本章内容的学习,你可以学习到Air8000核心板+AirVOC_1000配件板,通过I2C读取TVOC空气质量数据的应用。