init: Air780EPM 官方 LuatOS 项目代码基线

- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码
- 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等)
- 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
wangfq
2026-08-31 08:53:49 +08:00
commit 173dd6874f
813 changed files with 125484 additions and 0 deletions
@@ -0,0 +1,62 @@
--[[
@module main
@summary VL6180X 飞行时间(ToF)测距传感器 Demo 入口
@version 1.0
@date 2026.08.08
@author 江访
]]
--[[
=== 演示内容 ===
本 demo 演示 exs_vl6180x 扩展库的完整功能,顺序为:
HELLO→[1/2]→[2/2]→End
1、标准测距演示([1/2]
2、持续测距演示([2/2]
更多说明参考本目录下的 readme.md 文件
]]
--[[
VERSION:项目版本号,ascii string类型
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
]]
-- main.lua - 程序入口文件
PROJECT = "VL6180X_Demo" -- 项目命名
VERSION = "001.999.000" -- 项目版本号
-- 在日志中打印项目名和项目版本号
log.info("main", PROJECT, VERSION)
-- 设置日志输出风格为样式2(建议调试时开启)
-- log.style(2)
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
-- 启动errDump日志存储并且上传功能,600秒上传一次
-- if errDump then
-- errDump.config(true, 600)
-- end
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
-- 可以使用合宙的iot.openluat.com平台进行远程升级
-- 也可以使用客户自己搭建的平台进行远程升级
-- 远程升级的详细用法,可以参考fota的demo进行使用
-- 加载 vl6180x_app.lua 演示模块
require "vl6180x_app"
-- 用户代码已结束
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
@@ -0,0 +1,219 @@
# VL6180X 飞行时间(ToF)测距传感器演示
## 一、功能模块介绍
### 1.1 核心主程序模块
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
2. **vl6180x_app.lua** - VL6180X 功能演示模块,包含标准测距、持续测距等所有功能的演示用例
### 1.2 扩展库模块
1. **exs_vl6180x** - VL6180X 扩展库,提供初始化、测距数据读取、睡眠/唤醒/关闭等 API
### 1.3 I2C 模式说明
**推荐使用软件 I2C 模式**VL6180X 使用标准 I2C 接口通信,软件 I2C 模式无需指定 I2C 控制器,任意 GPIO 均可模拟 I2C 时序,灵活性更高。本 demo 默认使用软件 I2C 模式(SCL=GPIO31, SDA=GPIO30)演示,也可通过 `vl6180x_app.lua` 中的 `MODE` 变量切换为硬件 I2C 模式。
## 二、演示流程介绍
本 demo 按顺序演示 exs_vl6180x 扩展库的 2 项功能:HELLO → [1/2] → [2/2] → End
### 2.1 功能演示项说明
1. **[1/2] 标准测距** - 初始化传感器,连续读取 5 次距离数据
2. **[2/2] 持续测距** - 每隔 1 秒读取一次距离数据,共 5 次
## 三、演示硬件环境
### 3.1 硬件清单
- Air780EPM 核心板 × 1
- VL6180X 飞行时间测距传感器模块(如 GY-VL6180X 等) × 1
demo所演示的 VL6180X 飞行时间测距传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=583699439059&mi_id=0000ftVCg3WGnMAvz4efKE6nBbeZruB15ngNbwYKbhrQsRw&ns=1&priceTId=214781b017847853977586144e1012&skuId=6173431898563&spm=a21n57.1.hoverItem.6&utparam=%7B%22aplus_abtest%22%3A%2211ba2879882e2dc210ad662f97fd02e0%22%7D&xxc=taobaoSearch)
- 母对母杜邦线 × 4
- TYPE-C 数据线 × 1
### 3.2 接线配置
#### 3.2.1 I2C 模式接线
<table>
<tr>
<td>Air780EPM 核心板<br/></td><td>VL6180X 模块<br/></td></tr>
<tr>
<td>32/GPIO31<br/></td><td>SCL<br/></td></tr>
<tr>
<td>31/GPIO30<br/></td><td>SDA<br/></td></tr>
<tr>
<td>VDD_EXT<br/></td><td>VCC3.3V<br/></td></tr>
<tr>
<td>GND<br/></td><td>GND<br/></td></tr>
</table>
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。VL6180X 模块上的 SCL/SDA 通常已集成上拉电阻,无需额外配置。
![](https://docs.openluat.com/cdn/image/Air780EHM_VL6180X.png)
## 四、演示软件环境
### 4.1 开发工具
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/) - 固件烧录和代码调试
### 4.2 内核固件
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/)demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
### 4.3 脚本文件
1. **main.lua** - 程序入口
2. **vl6180x_app.lua** - VL6180X 功能演示模块
3. **exs_vl6180x** - VL6180X 扩展库
## 五、演示核心步骤
### 5.1 硬件准备
1. 按照接线表将 VL6180X 模块连接到核心板
2. 确保电源连接正确,通过 TYPE-C USB 口供电
3. 检查所有接线无误,避免短路
### 5.2 软件配置
`main.lua` 中加载对应的演示模块:
```lua
-- 加载 vl6180x_app.lua 演示模块
require "vl6180x_app"
```
如需切换通信模式,修改 `vl6180x_app.lua` 中的 `MODE` 变量(1=软件 I2C2=硬件 I2C)。
### 5.3 软件烧录
1. 使用 Luatools 选择最新内核固件
2. 下载本项目所有脚本文件
3. 将固件和脚本一起烧录到设备
4. 烧录成功后设备自动重启后开始运行
### 5.4 功能测试
#### 5.4.1 标准测距演示
1. 设备启动后打印 "HELLO",随后自动进入 [1/2] 标准测距
2. 观察日志输出,确认初始化成功(应看到 `芯片识别成功 Model ID=0xB4`
3. 观察距离数据(单位 mm)的连续读取,共 5 次
#### 5.4.2 持续测距演示
1. 自动进入 [2/2] 持续测距演示
2. 每隔 1 秒读取一次距离数据,共 5 次
3. 观察数据稳定性与状态码
### 5.5 预期效果
- **标准测距**:初始化成功,距离数据正常输出(0~255mm 范围)
- **持续测距**:每秒一帧数据,状态码 0(测距成功)
- **日志如下:**
```lua
[2026-08-20 21:30:06.039][000000000.246] I/user.main BME680_Demo 001.999.000
[2026-08-20 21:30:06.044][000000000.263] D/user.exs_bme680 version -> 202608080000
[2026-08-20 21:30:06.048][000000000.265] I/user.bme680_demo HELLO
[2026-08-20 21:30:06.172][000000001.265] I/user.bme680_demo ===== [1/5] =====
[2026-08-20 21:30:06.176][000000001.271] I/user.exs_bme680 I2C总线恢复完成
[2026-08-20 21:30:06.181][000000001.334] I/user.exs_bme680 BME680 @ I2C 0x77, CHIP_ID=0x61
[2026-08-20 21:30:06.194][000000001.347] I/user.exs_bme680 raw_T1=25923 raw_P1=36006 raw_T2=26603 raw_P2=-10347
[2026-08-20 21:30:06.215][000000001.347] I/user.exs_bme680 : T1=25923 T2=26603 T3=3 P1=36006 P2=-10347 H1=667 H2=1031 GH1=-34 GH2=-6023 GH3=18
[2026-08-20 21:30:06.233][000000001.355] I/user.exs_bme680 BME680 , os_temp=4 os_pres=3 os_hum=2 filter=3 heater_temp=320°C heater_dur=150ms
[2026-08-20 21:30:06.241][000000001.355] I/user.exs_bme680 : res_heat_range=1 res_heat_val=40 range_sw_err=1 heatr_res=0x76
[2026-08-20 21:30:06.250][000000001.355] I/user.exs_bme680 : MOX 20~30
[2026-08-20 21:30:06.258][000000001.355] I/user.exs_bme680 gas_resistance 0
[2026-08-20 21:30:06.270][000000001.355] I/user.bme680_demo BME680 : 202608080000
[2026-08-20 21:30:06.390][000000002.048] I/user.bme680_demo =24.12°C =1008.40hPa 湿=66.6%RH =2.4
[2026-08-20 21:30:09.534][000000005.241] I/user.bme680_demo 1: =24.12°C =1008.4hPa 湿=66.4%RH =3.4
[2026-08-20 21:30:11.735][000000007.434] I/user.bme680_demo 2: =24.14°C =1008.4hPa 湿=66.3%RH =4.6
[2026-08-20 21:30:13.922][000000009.627] I/user.bme680_demo 3: =24.16°C =1008.4hPa 湿=66.1%RH =5.9
[2026-08-20 21:30:13.929][000000009.628] I/user.bme680_demo ---- [1/5] 完成 ----
[2026-08-20 21:30:14.421][000000010.128] I/user.bme680_demo ===== [2/5] IIR =====
[2026-08-20 21:30:14.427][000000010.128] I/user.bme680_demo filter=0
[2026-08-20 21:30:14.437][000000010.136] I/user.exs_bme680 IIR 0 (0)
[2026-08-20 21:30:14.716][000000010.428] I/user.bme680_demo filter=0: =24.58°C =1008.42hPa 湿=66.1%RH
[2026-08-20 21:30:15.723][000000011.429] I/user.bme680_demo filter=1
[2026-08-20 21:30:15.729][000000011.436] I/user.exs_bme680 IIR 1 (1)
[2026-08-20 21:30:16.019][000000011.729] I/user.bme680_demo filter=1: =24.45°C =1008.44hPa 湿=65.8%RH
[2026-08-20 21:30:17.026][000000012.730] I/user.bme680_demo filter=2
[2026-08-20 21:30:17.033][000000012.737] I/user.exs_bme680 IIR 2 (3)
[2026-08-20 21:30:17.322][000000013.030] I/user.bme680_demo filter=2: =24.45°C =1008.40hPa 湿=65.5%RH
[2026-08-20 21:30:18.330][000000014.031] I/user.bme680_demo filter=3
[2026-08-20 21:30:18.336][000000014.038] I/user.exs_bme680 IIR 3 (7)
[2026-08-20 21:30:18.628][000000014.331] I/user.bme680_demo filter=3: =24.43°C =1008.40hPa 湿=65.3%RH
[2026-08-20 21:30:19.620][000000015.332] I/user.bme680_demo filter=4
[2026-08-20 21:30:19.634][000000015.339] I/user.exs_bme680 IIR 4 (15)
[2026-08-20 21:30:19.930][000000015.632] I/user.bme680_demo filter=4: =24.42°C =1008.36hPa 湿=65.0%RH
[2026-08-20 21:30:20.921][000000016.633] I/user.bme680_demo filter=5
[2026-08-20 21:30:20.937][000000016.640] I/user.exs_bme680 IIR 5 (31)
[2026-08-20 21:30:21.231][000000016.933] I/user.bme680_demo filter=5: =24.43°C =1008.40hPa 湿=64.9%RH
[2026-08-20 21:30:22.234][000000017.934] I/user.bme680_demo filter=6
[2026-08-20 21:30:22.240][000000017.941] I/user.exs_bme680 IIR 6 (63)
[2026-08-20 21:30:22.527][000000018.234] I/user.bme680_demo filter=6: =24.44°C =1008.42hPa 湿=64.7%RH
[2026-08-20 21:30:23.534][000000019.235] I/user.bme680_demo filter=7
[2026-08-20 21:30:23.540][000000019.242] I/user.exs_bme680 IIR 7 (127)
[2026-08-20 21:30:23.829][000000019.535] I/user.bme680_demo filter=7: =24.46°C =1008.40hPa 湿=64.7%RH
[2026-08-20 21:30:24.831][000000020.536] I/user.bme680_demo ---- [2/5] 完成 ----
[2026-08-20 21:30:25.326][000000021.036] I/user.bme680_demo ===== [3/5] =====
[2026-08-20 21:30:25.331][000000021.036] I/user.bme680_demo 1X过采样
[2026-08-20 21:30:25.342][000000021.043] I/user.exs_bme680 1
[2026-08-20 21:30:25.349][000000021.051] I/user.exs_bme680 1
[2026-08-20 21:30:25.357][000000021.058] I/user.exs_bme680 湿 1
[2026-08-20 21:30:25.621][000000021.326] I/user.bme680_demo : =24.46°C =1008.40hPa 湿=64.7%RH
[2026-08-20 21:30:26.621][000000022.327] I/user.bme680_demo 16X过采样
[2026-08-20 21:30:26.626][000000022.334] I/user.exs_bme680 5
[2026-08-20 21:30:26.636][000000022.342] I/user.exs_bme680 5
[2026-08-20 21:30:26.642][000000022.349] I/user.exs_bme680 湿 5
[2026-08-20 21:30:26.993][000000022.705] I/user.bme680_demo : =24.46°C =1008.40hPa 湿=64.7%RH
[2026-08-20 21:30:26.998][000000022.706] I/user.bme680_demo ---- [3/5] 完成 ----
[2026-08-20 21:30:27.504][000000023.206] I/user.bme680_demo ===== [4/5] =====
[2026-08-20 21:30:27.512][000000023.206] I/user.bme680_demo 250°C/100ms
[2026-08-20 21:30:27.518][000000023.214] I/user.exs_bme680 250°C, 100ms
[2026-08-20 21:30:27.919][000000023.620] I/user.bme680_demo =32.2 =24.46°C 湿=64.7%RH
[2026-08-20 21:30:28.909][000000024.621] I/user.bme680_demo 320°C/150ms
[2026-08-20 21:30:28.925][000000024.628] I/user.exs_bme680 320°C, 150ms
[2026-08-20 21:30:29.374][000000025.085] I/user.bme680_demo =16.6 =24.46°C 湿=64.6%RH
[2026-08-20 21:30:30.382][000000026.086] I/user.bme680_demo 350°C/200ms
[2026-08-20 21:30:30.389][000000026.093] I/user.exs_bme680 350°C, 200ms
[2026-08-20 21:30:30.894][000000026.600] I/user.bme680_demo =14.4 =24.46°C 湿=64.6%RH
[2026-08-20 21:30:31.888][000000027.601] I/user.bme680_demo ---- [4/5] 完成 ----
[2026-08-20 21:30:32.387][000000028.101] I/user.bme680_demo ===== [5/5] =====
[2026-08-20 21:30:32.700][000000028.409] I/user.bme680_demo =24.46°C =1008.4hPa 湿=64.6%RH =16.8 =40.5
[2026-08-20 21:30:32.706][000000028.409] I/user.exs_bme680
[2026-08-20 21:30:32.712][000000028.410] I/user.bme680_demo ---- [5/5] 完成 ----
[2026-08-20 21:30:33.210][000000028.910] I/user.bme680_demo ===== [] =====
[2026-08-20 21:30:33.215][000000028.910] I/user.bme680_demo End
```
### 5.6 故障排除
1. **传感器初始化失败**
- 检查 VL6180X 接线是否正确(SCL、SDA、VCC、GND
- 确认 GPIO 引脚配置与接线一致
- 检查电源电压是否稳定(3.3V
- 确认 exs_vl6180x 扩展库已正常加载
2. **读取数据始终为 0 或异常**
- 检查传感器供电是否正常
- 确认 I2C 地址是否正确(默认 0x29)
- 确认接线无松动
3. **测距状态码异常**
- 状态码 1/5(系统错误):芯片异常,可尝试重新上电
- 状态码 7(未检测到目标):目标超出 255mm 量程或反射率过低
- 状态码 11(环境光过强):环境光太强影响测量,可遮挡环境光
### 5.7 扩展功能建议
exs_vl6180x 更多接口的使用可以查看 [exs_vl6180x 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_vl6180x/)
@@ -0,0 +1,127 @@
--[[
@module vl6180x_app
@summary VL6180X 飞行时间测距传感器演示模块,包含测距演示用例
@version 1.0
@date 2026.08.20
@author 江访
@usage
本文件包含 VL6180X 的逐项功能演示。
通过 exs_vl6180x 扩展库的 API 逐一演示标准测距、持续测距等功能。
通过 MODE 变量选择通信模式(改 MODE 的值即可,无需注释/取消注释代码):
MODE = 1 软件 I2C(默认推荐,仅需 scl/sda 引脚,任意 GPIO 均可,接线最灵活)
MODE = 2 硬件 I2C(指定 i2c_id,占用 CPU 少)
]]
-- 加载 exs_vl6180x 扩展库
local exs_vl6180x = require "exs_vl6180x"
-- ==================== 通信模式选择 ====================
-- 改 MODE 的值选择通信模式:
-- 1 = 软件 I2C(默认) 2 = 硬件 I2C
-- 各模式所需引脚/参数见下方 init_config,接线说明见 readme.md
local MODE = 1
local init_config
if MODE == 1 then
-- 软件 I2CSCL/SDA 用任意 GPIOAir780EPM 接线示例用 GPIO31/GPIO30
init_config = {scl = 31, sda = 30}
elseif MODE == 2 then
-- 硬件 I2Ci2c_id 为总线号(Air780EPM 用 1),不传 scl/sda 时无总线恢复能力
init_config = {i2c_id = 1}
else
log.error("vl6180x_app", "MODE 取值错误,应为 1/2")
return
end
--------------------------------------------------------------
-- [1/2] 标准测距演示
-- - setup() 自动完成芯片 ID 校验、I2C 总线恢复、测距参数配置
-- - get_range() 返回距离(mm)与测量状态 status_str
--------------------------------------------------------------
local function demo_standard_ranging()
log.info("vl6180x_app", "===== [1/2] 标准测距 =====")
local result = exs_vl6180x.setup(init_config)
if not result then
log.error("vl6180x_app", "初始化失败")
log.error("vl6180x_app", "检查接线: VCC=3.3V GND SCL SDAI2C 地址是否正确(如 0x29)")
return false -- 初始化失败必须返回 false
end
log.info("vl6180x_app", "VL6180X 初始化成功,版本:", exs_vl6180x.version())
sys.wait(200) -- 等待系统稳定,200ms
for i = 1, 5 do
local data = exs_vl6180x.get_range()
if data then
log.info("vl6180x_app", string.format("第%d次: 距离=%dmm 状态=%s",
i, data.range_mm, data.status_str))
else
log.error("vl6180x_app", "读取测距数据失败")
end
sys.wait(1000) -- 每隔 1 秒读取一次
end
exs_vl6180x.close()
log.info("vl6180x_app", "---- [1/2] 完成 ----")
return true
end
--------------------------------------------------------------
-- [2/2] 持续测距演示
-- - 每隔 1 秒读取一次距离数据,观察数据稳定性与状态码
--------------------------------------------------------------
local function demo_continuous_ranging()
log.info("vl6180x_app", "===== [2/2] 持续测距演示 =====")
local result = exs_vl6180x.setup(init_config)
if not result then
log.error("vl6180x_app", "初始化失败")
log.error("vl6180x_app", "检查接线: VCC=3.3V GND SCL SDAI2C 地址是否正确(如 0x29)")
return false -- 初始化失败必须返回 false
end
log.info("vl6180x_app", "每隔 1 秒读取一次距离数据,共 5 次")
for i = 1, 5 do
sys.wait(1000) -- 每隔 1 秒读取一次
local data = exs_vl6180x.get_range()
if data then
log.info("vl6180x_app", string.format("持续测距[%d]: 距离=%dmm 状态=%s",
i, data.range_mm, data.status_str))
else
log.warn("vl6180x_app", string.format("持续测距[%d] 读取失败", i))
end
end
exs_vl6180x.close()
log.info("vl6180x_app", "---- [2/2] 完成 ----")
return true
end
--------------------------------------------------------------
-- 主任务:按 [1/2]~[2/2] 顺序执行全部演示
--------------------------------------------------------------
local function vl6180x_demo_task_func()
log.info("vl6180x_app", "HELLO")
sys.wait(1000) -- 等待系统稳定,1000ms
-- HELLO 开始 → [1/2] → [2/2] → End
local ok = demo_standard_ranging()
if not ok then
log.error("vl6180x_app", "初始化失败,演示终止")
return
end
sys.wait(500) -- 步骤间隔,500ms
ok = demo_continuous_ranging()
if not ok then
log.error("vl6180x_app", "初始化失败,演示终止")
return
end
sys.wait(500) -- 步骤间隔,500ms
log.info("vl6180x_app", "===== [演示完毕] =====")
log.info("vl6180x_app", "End")
end
sys.taskInit(vl6180x_demo_task_func)