init: Air780EPM 官方 LuatOS 项目代码基线
- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码 - 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等) - 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
--[[
|
||||
@module ads1115_demo
|
||||
@summary ADS1115 16位ADC传感器演示模块,包含所有功能的演示用例
|
||||
@version 2.0
|
||||
@date 2026.08.24
|
||||
@author 王城钧
|
||||
@usage
|
||||
本文件包含 ADS1115 的逐项功能演示。
|
||||
通过 exs_ads1115 扩展库的 API 逐一演示数据读取、多通道扫描、比较器中断、PGA 增益切换等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_ads1115 扩展库
|
||||
local exs_ads1115 = require "exs_ads1115"
|
||||
|
||||
-- ==================== 通信模式选择 ====================
|
||||
-- 改 MODE 的值选择通信模式:
|
||||
-- 1 = 软件 I2C(任意 GPIO,接线最灵活)
|
||||
-- 2 = 硬件 I2C(占用 CPU 少,稳定可靠,推荐)
|
||||
local MODE = 2
|
||||
|
||||
-- ALERT/RDY 中断引脚:ADS1115 模块 ALERT/RDY 接到核心板 GPIO22(按实际接线修改)
|
||||
local ALERT_GPIO = 22
|
||||
|
||||
-- 中断消息 topic:GPIO 中断回调发布,主任务等待后读取数据清除锁存报警
|
||||
local ALERT_TOPIC = "ADS1115_ALERT"
|
||||
|
||||
-- 按 MODE 组装初始化配置
|
||||
local init_config
|
||||
if MODE == 1 then
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO(示例 GPIO31/GPIO30)
|
||||
-- 不传 addr:扩展库自动探测 0x48~0x4B,读 Config 校验命中即锁定
|
||||
init_config = {scl = 31, sda = 30, channel = 0, pga = 1, sps = 128, mode = 1, alert_pin = ALERT_GPIO}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_id 为总线号(Air780EPM 用 1:PIN66=SDA, PIN67=SCL)
|
||||
init_config = {i2c_id = 1, channel = 0, pga = 1, sps = 128, mode = 1, alert_pin = ALERT_GPIO}
|
||||
else
|
||||
log.error("ads1115_demo", "MODE 取值错误,应为 1/2")
|
||||
return
|
||||
end
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("ads1115_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_ads1115.setup(init_config)
|
||||
if not result then
|
||||
log.error("ads1115_demo", "ADS1115 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
|
||||
log.info("ads1115_demo", "ADS1115 初始化成功,版本:", exs_ads1115.version())
|
||||
|
||||
sys.wait(200)
|
||||
local data = exs_ads1115.get_data()
|
||||
if data then
|
||||
log.info("ads1115_demo", string.format("AIN0 = %.4f V (raw=%d)", data.voltage, data.raw))
|
||||
else
|
||||
log.error("ads1115_demo", "读取数据失败")
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500)
|
||||
local d = exs_ads1115.get_data()
|
||||
if d then
|
||||
log.info("ads1115_demo", string.format("第%d次读取: AIN0 = %.4f V (raw=%d)", i, d.voltage, d.raw))
|
||||
end
|
||||
end
|
||||
|
||||
log.info("ads1115_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] 多通道扫描
|
||||
local function demo_channel_scan()
|
||||
log.info("ads1115_demo", "===== [2/4] 多通道扫描 =====")
|
||||
|
||||
for ch = 0, 3 do
|
||||
local ok = exs_ads1115.set_config({channel = ch})
|
||||
if not ok then
|
||||
log.warn("ads1115_demo", "通道", ch, "切换失败")
|
||||
return false
|
||||
end
|
||||
local data = exs_ads1115.get_data()
|
||||
if data then
|
||||
log.info("ads1115_demo", string.format("AIN%d = %.4f V (raw=%d)", ch, data.voltage, data.raw))
|
||||
end
|
||||
sys.wait(50)
|
||||
end
|
||||
|
||||
-- 扫描结束显式切回 AIN0 通道,避免通道停留在 AIN3 影响后续步骤
|
||||
exs_ads1115.set_config({channel = 0})
|
||||
|
||||
log.info("ads1115_demo", "---- [2/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- ALERT 中断回调:只发布消息,不直接做 I2C 操作(避免打断通信时序)
|
||||
local function alert_cb_func()
|
||||
sys.publish(ALERT_TOPIC)
|
||||
end
|
||||
|
||||
-- [3/4] 比较器中断报警
|
||||
local function demo_comparator_int()
|
||||
log.info("ads1115_demo", "===== [3/4] 比较器中断报警 =====")
|
||||
|
||||
-- 切回 AIN0 通道并切换到连续模式(多通道扫描后通道停在 AIN3,必须先切回)
|
||||
local ok = exs_ads1115.set_config({channel = 0, mode = 0})
|
||||
if not ok then
|
||||
return false
|
||||
end
|
||||
|
||||
-- 窗口比较器(高于 3.0V 或低于 2.0V 都报警),1 次越界报警,锁存
|
||||
ok = exs_ads1115.set_comparator(1, 0, true)
|
||||
if not ok then
|
||||
return false
|
||||
end
|
||||
|
||||
-- 阈值:低于 2.0V 或高于 3.0V 触发报警
|
||||
ok = exs_ads1115.set_threshold(2.0, 3.0)
|
||||
if not ok then
|
||||
return false
|
||||
end
|
||||
|
||||
-- 注册 ALERT 引脚下降沿中断(覆盖 setup 时的输入模式)
|
||||
gpio.setup(ALERT_GPIO, alert_cb_func, gpio.PULLUP, gpio.FALLING)
|
||||
|
||||
-- 读取当前电压并提示(帮助判断电压是否已在阈值外)
|
||||
local cur = exs_ads1115.get_data()
|
||||
if cur then
|
||||
log.info("ads1115_demo", string.format("当前 channel=%d, 电压 %.3f V(阈值 2.0V~3.0V)", cur.channel, cur.voltage))
|
||||
if cur.voltage > 3.0 or cur.voltage < 2.0 then
|
||||
log.info("ads1115_demo", "当前电压已在阈值外!请先调回 2.5V 左右,再越过阈值触发下降沿中断")
|
||||
end
|
||||
end
|
||||
log.info("ads1115_demo", "请调节输入电压越过 3.0V 或低于 2.0V,等待 ALERT 中断(30 秒内)...")
|
||||
|
||||
-- 等待中断消息,同时每 500ms 轮询电压与 ALERT 电平辅助检测(总时长约 30 秒)
|
||||
-- 轮询检测不依赖 ALERT 下降沿:即使操作方式不产生下降沿,也能验证比较器逻辑是否正常
|
||||
local got = false
|
||||
for i = 1, 60 do
|
||||
-- 每 500ms 轮询一次电压与 ALERT 电平,实时观察比较器状态
|
||||
cur = exs_ads1115.get_data()
|
||||
if cur then
|
||||
local alert = exs_ads1115.get_alert()
|
||||
log.info("ads1115_demo", string.format("电压 %.3f V,ALERT=%s", cur.voltage, tostring(alert)))
|
||||
if cur.voltage > 3.0 or cur.voltage < 2.0 then
|
||||
-- 先检查 ALERT 中断消息,优先验证硬件中断链路
|
||||
if sys.waitUntil(ALERT_TOPIC, 200) then
|
||||
log.warn("ads1115_demo", "收到 ALERT 中断:电压超阈值报警!")
|
||||
else
|
||||
log.warn("ads1115_demo", string.format("轮询检测到电压越界!当前 AIN0 = %.3f V", cur.voltage))
|
||||
end
|
||||
got = true
|
||||
break
|
||||
end
|
||||
end
|
||||
-- 等待中断消息(500ms 超时,超时后继续轮询)
|
||||
if sys.waitUntil(ALERT_TOPIC, 500) then
|
||||
log.warn("ads1115_demo", "收到 ALERT 中断:电压超阈值报警!")
|
||||
got = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if got then
|
||||
-- 中断刚结束,延迟 100ms 再读数据(避开 GPIO 中断打断 I2C 传输后的总线敏感期)
|
||||
sys.wait(100)
|
||||
-- 锁存模式下读取数据可清除报警(扩展库内置失败重试与总线重建)
|
||||
cur = exs_ads1115.get_data()
|
||||
if cur then
|
||||
log.info("ads1115_demo", string.format("当前电压 = %.3f V (raw=%d)", cur.voltage, cur.raw))
|
||||
else
|
||||
log.warn("ads1115_demo", "读取当前电压失败(扩展库已自动重试并重建 I2C 总线)")
|
||||
end
|
||||
else
|
||||
log.info("ads1115_demo", "30 秒内未触发报警(可调节输入电压验证中断功能)")
|
||||
end
|
||||
|
||||
log.info("ads1115_demo", "---- [3/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [4/4] PGA 增益切换演示
|
||||
local function demo_pga_switch()
|
||||
log.info("ads1115_demo", "===== [4/4] PGA 增益切换演示 =====")
|
||||
|
||||
-- 切回 AIN0 通道、单次模式(比较器演示后处于连续模式,此处恢复)
|
||||
exs_ads1115.set_config({channel = 0, mode = 1})
|
||||
|
||||
log.info("ads1115_demo", "切换 PGA 为 1(满量程 ±4.096V,分辨率 125μV)")
|
||||
exs_ads1115.set_config({channel = 0, pga = 1})
|
||||
sys.wait(300)
|
||||
|
||||
local data = exs_ads1115.get_data()
|
||||
if data then
|
||||
log.info("ads1115_demo", string.format("PGA=1 下: AIN0 = %.4f V (raw=%d)", data.voltage, data.raw))
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("ads1115_demo", "切换 PGA 为 2(满量程 ±2.048V,分辨率 62.5μV,输入超过 ±2.048V 会钳位)")
|
||||
exs_ads1115.set_config({channel = 0, pga = 2})
|
||||
sys.wait(300)
|
||||
|
||||
data = exs_ads1115.get_data()
|
||||
if data then
|
||||
log.info("ads1115_demo", string.format("PGA=2 下: AIN0 = %.4f V (raw=%d)", data.voltage, data.raw))
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
-- 恢复默认 PGA=1
|
||||
log.info("ads1115_demo", "恢复 PGA 为 1(满量程 ±4.096V)")
|
||||
exs_ads1115.set_config({channel = 0, pga = 1})
|
||||
sys.wait(300)
|
||||
|
||||
log.info("ads1115_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function ads1115_demo_task_func()
|
||||
log.info("ads1115_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("ads1115_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
|
||||
sys.wait(500)
|
||||
demo_channel_scan()
|
||||
sys.wait(500)
|
||||
demo_comparator_int()
|
||||
sys.wait(500)
|
||||
demo_pga_switch()
|
||||
sys.wait(500)
|
||||
|
||||
log.info("ads1115_demo", "===== [演示完毕] =====")
|
||||
exs_ads1115.close()
|
||||
log.info("ads1115_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(ads1115_demo_task_func)
|
||||
@@ -0,0 +1,60 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary ADS1115 16位ADC传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.08.24
|
||||
@author 王城钧
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_ads1115 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化与数据读取([1/4])
|
||||
2、多通道扫描([2/4])
|
||||
3、比较器中断报警([3/4])
|
||||
4、PGA 增益切换([4/4])
|
||||
|
||||
更多说明参考本目录下的 readme.md 文件
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己的项目的需求,自定义格式即可
|
||||
]]
|
||||
|
||||
PROJECT = "ADS1115_Demo" -- 项目命名
|
||||
VERSION = "001.000.000" -- 项目版本号
|
||||
|
||||
-- 在日志中打印项目名和项目版本号
|
||||
log.info("main", PROJECT, VERSION)
|
||||
|
||||
-- 设置日志输出风格为样式2(建议调试时开启)
|
||||
-- log.style(2)
|
||||
|
||||
|
||||
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
|
||||
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息
|
||||
-- if errDump then
|
||||
-- errDump.config(true, 600)
|
||||
-- end
|
||||
|
||||
|
||||
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
|
||||
-- 可以使用合宙的iot.openluat.com平台进行远程升级
|
||||
-- 也可以使用客户自己搭建的平台进行远程升级
|
||||
|
||||
|
||||
-- 加载 ads1115_demo.lua 演示模块
|
||||
-- 通信模式通过 ads1115_demo.lua 中的 MODE 变量选择(1=软件I2C / 2=硬件I2C)
|
||||
require "ads1115_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,220 @@
|
||||
# ADS1115 16位ADC传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **ads1115_demo.lua** - ADS1115 功能演示模块,包含数据读取、多通道扫描、比较器中断、PGA 增益切换等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_ads1115** - ADS1115 扩展库,提供初始化、电压读取、通道切换、PGA 增益配置、数据速率配置、比较器中断、校准等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用硬件 I2C 模式**:Air780EPM 使用 I2C1(PIN66=SDA, PIN67=SCL),占用 CPU 少、通信稳定。本 demo 默认使用硬件 I2C 模式演示,也支持软件 I2C 模式(任意 GPIO 接线,通过 `ads1115_demo.lua` 中 `MODE` 变量切换)。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_ads1115 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 ADS1115 传感器并读取 AIN0 电压数据(单位 V)
|
||||
2. **[2/4] 多通道扫描** - 依次切换 AIN0~AIN3 四路单端通道读取电压
|
||||
3. **[3/4] 比较器中断报警** - 窗口比较器(阈值 2.0V~3.0V),电压越界时 ALERT/RDY 引脚下降沿中断触发
|
||||
4. **[4/4] PGA 增益切换** - 在 PGA=1(±4.096V)和 PGA=2(±2.048V)之间切换,观察分辨率与满量程变化
|
||||
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- ADS1115 16 位 I2C ADC 传感器模块 × 1
|
||||
- 母对母杜邦线 × 7根
|
||||
- TYPE-C 数据线 × 1
|
||||
- 直流稳压源 × 1
|
||||
|
||||

|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 ADS1115 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>ADS1115 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>3.3V(VDD_EXT)<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
<tr>
|
||||
<td>PIN67(I2C1_SCL)<br/></td><td>SCL<br/></td></tr>
|
||||
<tr>
|
||||
<td>PIN66(I2C1_SDA)<br/></td><td>SDA<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>ADDR(设备地址 0x48)<br/></td></tr>
|
||||
<tr>
|
||||
<td>GPIO22<br/></td><td>ALERT/RDY(比较器中断,[3/4] 使用)<br/></td></tr>
|
||||
<tr>
|
||||
<td>被测电压(0~3.3V)<br/></td><td>AIN0<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。被测电压超过 3.3V 时必须电阻分压后接入 AIN 引脚(芯片模拟输入上限为 VDD+0.3V)。
|
||||
|
||||
#### 3.2.2 外部电源接线(AIN0 测试电压源)
|
||||
|
||||
使用可调直流电源给 AIN0 提供测试电压时,**外部电源的负极(-)必须接到核心板 GND(共地)**,否则 AIN0 与 ADS1115 之间没有参考电位,读数会乱飘、无意义。
|
||||
|
||||
完整接线图(含外部电源):
|
||||
|
||||
```
|
||||
外部电源(+) ────────────────→ ADS1115 模块: AIN0
|
||||
外部电源(-) ────────────────→ Air780EPM 核心板: GND ← 共地!
|
||||
|
||||
核心板 3.3V (VDD_EXT) ──────→ ADS1115 模块: VCC
|
||||
核心板 GND ─────────────────→ ADS1115 模块: GND
|
||||
核心板 PIN67 (I2C1_SCL) ────→ ADS1115 模块: SCL
|
||||
核心板 PIN66 (I2C1_SDA) ────→ ADS1115 模块: SDA
|
||||
核心板 GND ─────────────────→ ADS1115 模块: ADDR(地址 0x48)
|
||||
核心板 GPIO22 ──────────────→ ADS1115 模块: ALERT/RDY(比较器中断)
|
||||
```
|
||||
|
||||
| 接线对象 | 接到哪里 | 说明 |
|
||||
|---|---|---|
|
||||
| 外部电源正极(+) | ADS1115 模块 AIN0 | 测试电压 0~3.3V(超出需分压) |
|
||||
| 外部电源负极(-) | 核心板 GND | **必须共地**,与模块 GND 同一点 |
|
||||
|
||||
> 共地关系:外部电源负极 → 核心板 GND → 模块 GND,三者是同一电位。若使用电池做测试源,电池负极同样要接到核心板 GND。
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 4.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/),demo所使用的是 LuatOS@Air780EPM base 26.04 bsp V2050
|
||||
|
||||
### 4.3 脚本文件
|
||||
|
||||
1. **main.lua** - 程序入口
|
||||
2. **ads1115_demo.lua** - ADS1115 功能演示模块
|
||||
3. **exs_ads1115** - ADS1115 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 ADS1115 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 ads1115_demo.lua 演示模块
|
||||
require "ads1115_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察 AIN0 电压数据(单位 V)的连续读取
|
||||
|
||||
#### 5.4.2 多通道扫描演示
|
||||
|
||||
1. 自动进入 [2/4] 多通道扫描
|
||||
2. 依次观察 AIN0~AIN3 四路通道的电压数据
|
||||
3. 未接信号的通道读数接近 0V(悬空漂移属正常现象)
|
||||
|
||||
#### 5.4.3 比较器中断报警演示
|
||||
|
||||
1. 自动进入 [3/4] 比较器中断报警
|
||||
2. 先将输入电压调到 2.5V(阈值窗口内),观察日志提示
|
||||
3. 保持电源开启,调节电压越过 3.0V 或低于 2.0V,观察 ALERT 中断触发
|
||||
|
||||
#### 5.4.4 PGA 增益切换演示
|
||||
|
||||
1. 自动进入 [4/4] PGA 增益切换
|
||||
2. 观察 PGA=1(满量程 ±4.096V)下的电压读数
|
||||
3. 观察 PGA=2(满量程 ±2.048V)下的电压读数(若输入电压超过 ±2.048V,读数会钳位到满量程)
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:ADS1115 初始化成功,AIN0 电压数据正常输出
|
||||
- **多通道扫描**:4 路通道均能正常读取电压
|
||||
- **比较器中断报警**:电压越过阈值(>3.0V 或 <2.0V)时 ALERT 中断触发
|
||||
- **PGA 增益切换**:PGA 切换后分辨率与满量程随之变化
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-08-24 15:39:43.507][000000000.216] I/user.main ADS1115_Demo 001.000.000
|
||||
[2026-08-24 15:39:48.659][000000006.640] I/user.ads1115_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-08-24 15:39:48.689][000000006.661] I/user.ads1115_demo ADS1115 初始化成功,版本: 202608241540
|
||||
[2026-08-24 15:39:48.705][000000006.679] I/user.ads1115_demo AIN0 = 2.7818 V (raw=22254)
|
||||
[2026-08-24 15:39:50.255][000000008.230] I/user.ads1115_demo 第1次读取: AIN0 = 2.7828 V (raw=22262)
|
||||
[2026-08-24 15:39:50.749][000000008.731] I/user.ads1115_demo 第2次读取: AIN0 = 2.7819 V (raw=22255)
|
||||
[2026-08-24 15:39:51.274][000000009.248] I/user.ads1115_demo 第3次读取: AIN0 = 2.7818 V (raw=22254)
|
||||
[2026-08-24 15:39:51.290][000000009.264] I/user.ads1115_demo ---- [1/4] 完成 ----
|
||||
[2026-08-24 15:39:51.433][000000009.416] I/user.ads1115_demo ===== [2/4] 多通道扫描 =====
|
||||
[2026-08-24 15:39:51.546][000000009.516] I/user.ads1115_demo AIN0 = 2.7828 V (raw=22262)
|
||||
[2026-08-24 15:39:51.561][000000009.533] I/user.ads1115_demo AIN1 = 0.5946 V (raw=4757)
|
||||
[2026-08-24 15:39:51.563][000000009.534] I/user.ads1115_demo AIN2 = 0.6086 V (raw=4869)
|
||||
[2026-08-24 15:39:51.565][000000009.534] I/user.ads1115_demo AIN3 = 0.6180 V (raw=4944)
|
||||
[2026-08-24 15:39:51.567][000000009.534] I/user.ads1115_demo ---- [2/4] 完成 ----
|
||||
[2026-08-24 15:39:51.274][000000009.248] I/user.ads1115_demo ===== [3/4] 比较器中断报警 =====
|
||||
[2026-08-24 15:39:51.290][000000009.264] I/user.ads1115_demo 电压 2.782 V,ALERT=1
|
||||
[2026-08-24 15:39:51.433][000000009.416] I/user.ads1115_demo 收到 ALERT 中断:电压超阈值报警!
|
||||
[2026-08-24 15:39:51.546][000000009.516] I/user.ads1115_demo 当前电压 = 3.077 V (raw=24618)
|
||||
[2026-08-24 15:39:51.561][000000009.533] I/user.ads1115_demo ---- [3/4] 完成 ----
|
||||
[2026-08-24 15:39:51.563][000000009.534] I/user.ads1115_demo ===== [4/4] PGA 增益切换 =====
|
||||
[2026-08-24 15:39:51.565][000000009.534] I/user.ads1115_demo 切换 PGA 为 1(满量程 ±4.096V,分辨率 125μV)
|
||||
[2026-08-24 15:39:51.567][000000009.534] I/user.ads1115_demo PGA=1 下: AIN0 = 2.7818 V (raw=22254)
|
||||
[2026-08-24 15:39:51.574][000000009.534] I/user.ads1115_demo 切换 PGA 为 2(满量程 ±2.048V,分辨率 62.5μV,输入超过 ±2.048V 会钳位)
|
||||
[2026-08-24 15:39:51.575][000000009.534] I/user.ads1115_demo PGA=2 下: AIN0 = 2.0479 V (raw=32767)
|
||||
[2026-08-24 15:39:51.577][000000009.534] I/user.ads1115_demo 恢复 PGA 为 1(满量程 ±4.096V)
|
||||
[2026-08-24 15:39:51.579][000000009.534] I/user.ads1115_demo ---- [4/4] 完成 ----
|
||||
[2026-08-24 15:39:51.581][000000009.534] I/user.ads1115_demo ===== [演示完毕] =====
|
||||
[2026-08-24 15:39:51.583][000000009.534] I/user.exs_ads1115 已关闭
|
||||
[2026-08-24 15:39:51.585][000000009.534] I/user.ads1115_demo End
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 ADS1115 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 ADDR 引脚接 GND(地址 0x48),不能悬空
|
||||
- 确认 SCL/SDA 上拉电阻已接(4.7kΩ 到 3.3V)
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查输入信号是否接入(AIN 悬空时读数漂移,属正常现象)
|
||||
- 检查传感器供电是否正常
|
||||
- 确认接线无松动
|
||||
|
||||
3. **比较器中断不触发**:
|
||||
|
||||
- 确认 ALERT/RDY 引脚已接 GPIO22,并核对 `ALERT_GPIO` 常量
|
||||
- 确认电压真正越过阈值(先用万用表确认 AIN0 实际电压)
|
||||
- 若进入 [3/4] 时电压已在阈值外,先调回 2.5V 左右再越过阈值(下降沿触发)
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_ads1115 更多接口的使用可以查看 [exs_ads1115 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_ads1115/)
|
||||
@@ -0,0 +1,146 @@
|
||||
--[[
|
||||
@module adxl34x_demo
|
||||
@summary ADXL345/ADXL346 三轴加速度传感器演示模块,包含所有功能的演示用例
|
||||
@version 2.0
|
||||
@date 2026.07.17
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 ADXL345/ADXL346 的逐项功能演示。
|
||||
通过 exs_adxl34x 扩展库的 API 逐一演示数据读取、量程切换、输出速率切换、休眠唤醒等功能。
|
||||
]]
|
||||
|
||||
local exs_adxl34x = require "exs_adxl34x"
|
||||
|
||||
local function adxl34x_int1_cb(data)
|
||||
log.info("adxl34x_demo", string.format("int1: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("adxl34x_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_adxl34x.setup("I2C", {
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
int1 = { int_gpio = 29, tap = true, cb = adxl34x_int1_cb },
|
||||
})
|
||||
|
||||
if not result then
|
||||
log.error("adxl34x_demo", "ADXL345/ADXL346 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
|
||||
log.info("adxl34x_demo", "ADXL345/ADXL346 初始化成功,版本:", exs_adxl34x.version())
|
||||
|
||||
sys.wait(200)
|
||||
local data = exs_adxl34x.get_data()
|
||||
if data then
|
||||
log.info("adxl34x_demo", string.format("X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
else
|
||||
log.error("adxl34x_demo", "读取数据失败")
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500)
|
||||
local d = exs_adxl34x.get_data()
|
||||
if d then
|
||||
log.info("adxl34x_demo", string.format("第%d次读取: X=%.3f Y=%.3f Z=%.3f g", i, d.x, d.y, d.z))
|
||||
end
|
||||
end
|
||||
|
||||
log.info("adxl34x_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] 量程切换演示
|
||||
local function demo_range_switch()
|
||||
log.info("adxl34x_demo", "===== [2/4] 量程切换演示 =====")
|
||||
|
||||
log.info("adxl34x_demo", "切换量程为 4g")
|
||||
exs_adxl34x.set_range("4g")
|
||||
sys.wait(300)
|
||||
|
||||
local data = exs_adxl34x.get_data()
|
||||
if data then
|
||||
log.info("adxl34x_demo", string.format("4g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("adxl34x_demo", "切换量程为 2g(高精度)")
|
||||
exs_adxl34x.set_range("2g")
|
||||
sys.wait(300)
|
||||
|
||||
data = exs_adxl34x.get_data()
|
||||
if data then
|
||||
log.info("adxl34x_demo", string.format("2g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("adxl34x_demo", "---- [2/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/4] 输出速率切换
|
||||
local function demo_odr_switch()
|
||||
log.info("adxl34x_demo", "===== [3/4] 输出速率切换 =====")
|
||||
|
||||
local odr_list = { 25, 50, 100, 200 }
|
||||
for _, odr in ipairs(odr_list) do
|
||||
log.info("adxl34x_demo", string.format("设置输出速率为 %dHz", odr))
|
||||
exs_adxl34x.set_odr(odr)
|
||||
sys.wait(500)
|
||||
|
||||
local data = exs_adxl34x.get_data()
|
||||
if data then
|
||||
log.info("adxl34x_demo", string.format("%dHz 下: X=%.3f Y=%.3f Z=%.3f g", odr, data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
exs_adxl34x.set_odr(100)
|
||||
log.info("adxl34x_demo", "---- [3/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/4] 休眠与唤醒演示
|
||||
local function demo_sleep_wakeup()
|
||||
log.info("adxl34x_demo", "===== [4/4] 休眠与唤醒演示 =====")
|
||||
log.info("adxl34x_demo", "进入待机模式(低功耗)")
|
||||
exs_adxl34x.sleep(); sys.wait(10000)
|
||||
sys.wait(500)
|
||||
log.info("adxl34x_demo", "从待机模式唤醒")
|
||||
exs_adxl34x.wakeup()
|
||||
sys.wait(200)
|
||||
local data = exs_adxl34x.get_data()
|
||||
if data then
|
||||
log.info("adxl34x_demo", string.format("唤醒后数据: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
log.info("adxl34x_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function adxl34x_demo_task_func()
|
||||
log.info("adxl34x_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("adxl34x_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
|
||||
sys.wait(500)
|
||||
demo_range_switch()
|
||||
sys.wait(500)
|
||||
demo_odr_switch()
|
||||
sys.wait(500)
|
||||
demo_sleep_wakeup()
|
||||
sys.wait(500)
|
||||
|
||||
log.info("adxl34x_demo", "===== [演示完毕] =====")
|
||||
exs_adxl34x.close()
|
||||
log.info("adxl34x_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(adxl34x_demo_task_func)
|
||||
@@ -0,0 +1,69 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary ADXL345/ADXL346 三轴加速度传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.14
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_adxl34x 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/3]→[2/3]→[3/3]→End
|
||||
1、初始化和数据读取([1/3])
|
||||
2、量程切换演示([2/3])
|
||||
3、输出速率切换([3/3])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "ADXL34X_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 adxl34x_demo.lua 演示模块
|
||||
require "adxl34x_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,243 @@
|
||||
# ADXL345/ADXL346 三轴加速度传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **adxl34x_demo.lua** - ADXL345/ADXL346 功能演示模块,包含数据读取、量程切换、输出速率切换等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_adxl34x** - ADXL345/ADXL346 扩展库,提供初始化、三轴加速度数据读取、量程切换、输出速率切换、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:ADXL345/ADXL346 在异常 I2C 通信后可能锁死 SDA 总线。本库已内置 I2C 总线卡死自动检测与恢复功能。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_adxl34x 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 ADXL345/ADXL346 传感器并读取三轴加速度数据(X/Y/Z,单位 g)
|
||||
2. **[2/4] 量程切换演示** - 在 ±2g(高精度)和 ±4g(宽范围)量程之间切换,观察数据变化
|
||||
3. **[3/4] 输出速率切换** - 依次切换 25Hz / 50Hz / 100Hz / 200Hz 输出速率
|
||||
4. **[4/4] 休眠与唤醒演示** - 演示 sleep()/wakeup() 待机与唤醒
|
||||
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- ADXL345/ADXL346 三轴加速度传感器模块 × 1
|
||||
demo所演示的ADXL346 三轴加速度传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=674652805487&mi_id=0000HelRiVcJXLoq8Fq6jNLiArUvUR3J2pup2XI5jGtyLC8&ns=1&priceTId=2147849c17839172022585398e11c7&spm=a21n57.1.hoverItem.12&utparam=%7B%22aplus_abtest%22%3A%22418b653a98a5ab0b5f0ba7b791f3d489%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 5
|
||||
- 母对母杜邦线 × 5
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||

|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 ADXL345/ADXL346 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>ADXL345/ADXL346 模块<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>30/GPIO29<br/></td><td>INT1<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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. **adxl34x_demo.lua** - ADXL345/ADXL346 功能演示模块
|
||||
3. **exs_adxl34x** - ADXL345/ADXL346 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 ADXL345/ADXL346 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 adxl34x_demo.lua 演示模块
|
||||
require "adxl34x_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴加速度数据(X/Y/Z,单位 g)的连续读取
|
||||
|
||||
#### 5.4.2 量程切换演示
|
||||
|
||||
1. 自动进入 [2/4] 量程切换演示
|
||||
2. 观察 ±4g 宽范围量程下的数据
|
||||
3. 观察 ±2g 高精度量程下的数据
|
||||
|
||||
#### 5.4.3 输出速率切换演示
|
||||
|
||||
1. 自动进入 [3/4] 输出速率切换演示
|
||||
2. 依次观察 25Hz / 50Hz / 100Hz / 200Hz 下的数据读取
|
||||
3. 最终恢复为 100Hz
|
||||
|
||||
#### 5.4.4 休眠与唤醒演示
|
||||
|
||||
1. 自动进入 [4/4] 休眠与唤醒演示
|
||||
2. 观察 sleep() 进入待机模式
|
||||
3. 观察 wakeup() 唤醒后数据恢复
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:ADXL345/ADXL346 初始化成功,三轴加速度数据正常输出
|
||||
- **量程切换**:量程切换后数据范围随之变化,灵敏度不同
|
||||
- **输出速率切换**:不同速率下均能正常读取数据
|
||||
- **休眠与唤醒**:sleep 后进入低功耗,wakeup 后数据读取正常
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:26:41.222][000000000.177] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:26:41.225][000000000.177] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:26:41.228][000000000.179] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:26:41.231][000000000.181] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:26:41.233][000000000.181] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:26:41.234][000000000.182] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:26:41.237][000000000.199] I/user.main ADXL34X_Demo 001.999.000
|
||||
[2026-07-21 10:26:41.240][000000000.213] D/user.exs_adxl34x version -> 202607170900
|
||||
[2026-07-21 10:26:41.242][000000000.214] I/user.adxl34x_demo HELLO
|
||||
[2026-07-21 10:26:41.524][000000001.214] I/user.adxl34x_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-07-21 10:26:41.527][000000001.235] I/user.exs_adxl34x ADXL346 @ 0x53
|
||||
[2026-07-21 10:26:41.530][000000001.302] I/user.exs_adxl34x INT1 已注册, int_gpio=29
|
||||
[2026-07-21 10:26:41.532][000000001.303] I/user.exs_adxl34x 初始化完成 mode=I2C range=2g odr=100Hz
|
||||
[2026-07-21 10:26:41.535][000000001.303] I/user.adxl34x_demo ADXL345/ADXL346 初始化成功,版本: 202607170900
|
||||
[2026-07-21 10:26:41.701][000000001.506] I/user.adxl34x_demo X=0.984 Y=0.098 Z=0.156 g
|
||||
[2026-07-21 10:26:41.718][000000001.626] I/user.adxl34x_demo int1: X=1.086 Y=-0.156 Z=0.223 g
|
||||
[2026-07-21 10:26:41.727][000000001.768] I/user.adxl34x_demo int1: X=0.988 Y=-0.039 Z=0.184 g
|
||||
[2026-07-21 10:26:41.734][000000002.030] I/user.adxl34x_demo int1: X=1.004 Y=-0.043 Z=0.172 g
|
||||
[2026-07-21 10:26:42.468][000000002.789] I/user.adxl34x_demo int1: X=0.457 Y=0.152 Z=0.566 g
|
||||
[2026-07-21 10:26:42.575][000000002.910] I/user.adxl34x_demo int1: X=0.363 Y=0.535 Z=0.832 g
|
||||
[2026-07-21 10:26:42.685][000000003.009] I/user.adxl34x_demo 第1次读取: X=0.895 Y=0.297 Z=-0.352 g
|
||||
[2026-07-21 10:26:42.690][000000003.020] I/user.adxl34x_demo int1: X=0.422 Y=0.336 Z=0.020 g
|
||||
[2026-07-21 10:26:42.905][000000003.231] I/user.adxl34x_demo int1: X=0.617 Y=0.156 Z=0.133 g
|
||||
[2026-07-21 10:26:42.982][000000003.303] I/user.adxl34x_demo int1: X=0.434 Y=0.133 Z=1.035 g
|
||||
[2026-07-21 10:26:43.182][000000003.397] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:26:43.191][000000003.398] D/mobile cid1, state0
|
||||
[2026-07-21 10:26:43.197][000000003.399] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:26:43.203][000000003.399] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:26:43.209][000000003.449] D/mobile TIME_SYNC 0 tm 1784600806
|
||||
[2026-07-21 10:26:43.214][000000003.498] I/user.adxl34x_demo int1: X=0.430 Y=0.320 Z=1.234 g
|
||||
[2026-07-21 10:26:43.219][000000003.512] I/user.adxl34x_demo 第2次读取: X=0.742 Y=0.230 Z=0.738 g
|
||||
[2026-07-21 10:26:43.312][000000003.632] I/user.adxl34x_demo int1: X=0.012 Y=0.043 Z=0.840 g
|
||||
[2026-07-21 10:26:43.360][000000003.679] I/user.adxl34x_demo int1: X=0.387 Y=0.246 Z=0.844 g
|
||||
[2026-07-21 10:26:43.501][000000003.825] I/user.adxl34x_demo int1: X=-0.008 Y=-0.039 Z=1.012 g
|
||||
[2026-07-21 10:26:43.687][000000004.015] I/user.adxl34x_demo 第3次读取: X=-0.035 Y=-0.020 Z=0.973 g
|
||||
[2026-07-21 10:26:43.694][000000004.015] I/user.adxl34x_demo ---- [1/4] 完成 ----
|
||||
[2026-07-21 10:26:44.110][000000004.438] I/user.adxl34x_demo int1: X=0.152 Y=0.496 Z=0.930 g
|
||||
[2026-07-21 10:26:44.172][000000004.499] I/user.adxl34x_demo int1: X=0.113 Y=0.414 Z=0.652 g
|
||||
[2026-07-21 10:26:44.188][000000004.515] I/user.adxl34x_demo ===== [2/4] 量程切换演示 =====
|
||||
[2026-07-21 10:26:44.193][000000004.515] I/user.adxl34x_demo 切换量程为 4g
|
||||
[2026-07-21 10:26:44.199][000000004.518] I/user.exs_adxl34x 量程切换为 4g
|
||||
[2026-07-21 10:26:44.267][000000004.589] I/user.adxl34x_demo int1: X=-0.281 Y=0.711 Z=0.906 g
|
||||
[2026-07-21 10:26:44.501][000000004.821] I/user.adxl34x_demo int1: X=0.867 Y=1.242 Z=0.547 g
|
||||
[2026-07-21 10:26:44.505][000000004.824] I/user.adxl34x_demo 4g 量程: X=0.867 Y=1.242 Z=0.547 g
|
||||
[2026-07-21 10:26:44.564][000000004.898] I/user.adxl34x_demo int1: X=-0.078 Y=2.055 Z=0.359 g
|
||||
[2026-07-21 10:26:44.611][000000004.942] I/user.adxl34x_demo int1: X=-0.508 Y=1.648 Z=1.047 g
|
||||
[2026-07-21 10:26:44.658][000000004.991] I/user.adxl34x_demo int1: X=-0.227 Y=1.477 Z=0.352 g
|
||||
[2026-07-21 10:26:44.706][000000005.041] I/user.adxl34x_demo int1: X=0.297 Y=1.891 Z=0.914 g
|
||||
[2026-07-21 10:26:44.815][000000005.139] I/user.adxl34x_demo int1: X=-0.445 Y=2.031 Z=0.180 g
|
||||
[2026-07-21 10:26:44.863][000000005.191] I/user.adxl34x_demo int1: X=0.281 Y=1.812 Z=0.688 g
|
||||
[2026-07-21 10:26:44.925][000000005.254] I/user.adxl34x_demo int1: X=0.219 Y=1.953 Z=0.336 g
|
||||
[2026-07-21 10:26:44.987][000000005.319] I/user.adxl34x_demo int1: X=-0.375 Y=1.953 Z=0.391 g
|
||||
[2026-07-21 10:26:45.491][000000005.824] I/user.adxl34x_demo 切换量程为 2g(高精度)
|
||||
[2026-07-21 10:26:45.507][000000005.827] I/user.exs_adxl34x 量程切换为 2g
|
||||
[2026-07-21 10:26:45.804][000000006.131] I/user.adxl34x_demo 2g 量程: X=0.027 Y=0.977 Z=0.078 g
|
||||
[2026-07-21 10:26:46.807][000000007.131] I/user.adxl34x_demo ---- [2/4] 完成 ----
|
||||
[2026-07-21 10:26:47.305][000000007.631] I/user.adxl34x_demo ===== [3/4] 输出速率切换 =====
|
||||
[2026-07-21 10:26:47.312][000000007.632] I/user.adxl34x_demo 设置输出速率为 25Hz
|
||||
[2026-07-21 10:26:47.316][000000007.633] I/user.exs_adxl34x 输出速率切换为 25Hz
|
||||
[2026-07-21 10:26:47.816][000000008.137] I/user.adxl34x_demo 25Hz 下: X=0.035 Y=0.969 Z=0.074 g
|
||||
[2026-07-21 10:26:48.311][000000008.637] I/user.adxl34x_demo 设置输出速率为 50Hz
|
||||
[2026-07-21 10:26:48.314][000000008.639] I/user.exs_adxl34x 输出速率切换为 50Hz
|
||||
[2026-07-21 10:26:48.811][000000009.142] I/user.adxl34x_demo 50Hz 下: X=0.031 Y=0.973 Z=0.074 g
|
||||
[2026-07-21 10:26:49.309][000000009.642] I/user.adxl34x_demo 设置输出速率为 100Hz
|
||||
[2026-07-21 10:26:49.314][000000009.644] I/user.exs_adxl34x 输出速率切换为 100Hz
|
||||
[2026-07-21 10:26:49.824][000000010.147] I/user.adxl34x_demo 100Hz 下: X=0.031 Y=0.984 Z=0.070 g
|
||||
[2026-07-21 10:26:50.320][000000010.647] I/user.adxl34x_demo 设置输出速率为 200Hz
|
||||
[2026-07-21 10:26:50.324][000000010.649] I/user.exs_adxl34x 输出速率切换为 200Hz
|
||||
[2026-07-21 10:26:50.817][000000011.152] I/user.adxl34x_demo 200Hz 下: X=0.031 Y=0.977 Z=0.074 g
|
||||
[2026-07-21 10:26:51.332][000000011.653] I/user.exs_adxl34x 输出速率切换为 100Hz
|
||||
[2026-07-21 10:26:51.345][000000011.654] I/user.adxl34x_demo ---- [3/4] 完成 ----
|
||||
[2026-07-21 10:26:51.834][000000012.154] I/user.adxl34x_demo ===== [4/4] 休眠与唤醒演示 =====
|
||||
[2026-07-21 10:26:51.842][000000012.155] I/user.adxl34x_demo 进入待机模式(低功耗)
|
||||
[2026-07-21 10:26:51.848][000000012.156] I/user.exs_adxl34x 已进入待机模式
|
||||
[2026-07-21 10:27:02.329][000000022.656] I/user.adxl34x_demo 从待机模式唤醒
|
||||
[2026-07-21 10:27:02.335][000000022.657] I/user.exs_adxl34x 已从待机模式唤醒
|
||||
[2026-07-21 10:27:02.532][000000022.860] I/user.adxl34x_demo 唤醒后数据: X=0.027 Y=0.969 Z=0.070 g
|
||||
[2026-07-21 10:27:02.536][000000022.861] I/user.adxl34x_demo ---- [4/4] 完成 ----
|
||||
[2026-07-21 10:27:03.035][000000023.361] I/user.adxl34x_demo ===== [演示完毕] =====
|
||||
[2026-07-21 10:27:03.082][000000023.363] I/user.exs_adxl34x 传感器已关闭
|
||||
[2026-07-21 10:27:03.139][000000023.363] I/user.adxl34x_demo End
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 ADXL345/ADXL346 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_adxl34x 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(SDO=GND 时地址 0x53,SDO=VCC 时地址 0x1D)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **量程切换无效果**:
|
||||
|
||||
- 确认 `set_range()` 参数为 "2g"、"4g"、"8g" 或 "16g"
|
||||
- 切换后需等待传感器稳定再读取数据
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_adxl34x 更多接口的使用可以查看 [exs_adxl34x 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_adxl34x/)
|
||||
@@ -0,0 +1,252 @@
|
||||
--[[
|
||||
@module aip650e_demo
|
||||
@summary AiP650E 驱动芯片演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 AiP650E 的逐项功能演示和综合展示。
|
||||
通过 exs_aip650e 扩展库的 API 逐一演示数码管显示、按键检测、亮度调节、
|
||||
7段/8段模式切换、睡眠唤醒等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_aip650e 扩展库
|
||||
local exs_aip650e = require "exs_aip650e"
|
||||
|
||||
-- 演示字符串显示
|
||||
local function demo_string()
|
||||
log.info("aip650e_demo", "===== [1/6] 字符串显示 =====")
|
||||
|
||||
log.info("aip650e_demo", "显示 1234")
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("1234")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("aip650e_demo", "显示 88.8")
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("88.8")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("aip650e_demo", "显示 AbCd")
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("AbCd")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("aip650e_demo", "从第 3 位开始显示 12")
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("12", 3)
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("aip650e_demo", "显示 HELO")
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("HELO")
|
||||
sys.wait(1500)
|
||||
|
||||
exs_aip650e.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示按键轮询
|
||||
local function demo_keys()
|
||||
log.info("aip650e_demo", "===== [2/6] 按键轮询 =====")
|
||||
log.info("aip650e_demo", "请在 10 秒内按下连接到 AiP650E 的按键...")
|
||||
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("KEYS")
|
||||
|
||||
local timeout = 10000
|
||||
local step = 100
|
||||
local elapsed = 0
|
||||
|
||||
while elapsed < timeout do
|
||||
local key = exs_aip650e.get_key()
|
||||
if key then
|
||||
log.info("aip650e_demo", "检测到按键, 编码:", key)
|
||||
local key_str = string.format("%02d", key)
|
||||
exs_aip650e.set_display(key_str)
|
||||
sys.wait(1000)
|
||||
return
|
||||
end
|
||||
sys.wait(step)
|
||||
elapsed = elapsed + step
|
||||
end
|
||||
|
||||
log.info("aip650e_demo", "按键检测超时,跳过")
|
||||
end
|
||||
|
||||
-- 按键回调函数
|
||||
local function on_key(key_code)
|
||||
log.info("aip650e_demo", "按键回调触发, 编码:", key_code)
|
||||
local display = string.format("%02d", key_code)
|
||||
exs_aip650e.set_display(display)
|
||||
end
|
||||
|
||||
-- 演示按键回调
|
||||
local function demo_key_callback()
|
||||
log.info("aip650e_demo", "===== [3/6] 按键回调 =====")
|
||||
log.info("aip650e_demo", "接下来 15 秒内按按键查看回调效果")
|
||||
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("CALL")
|
||||
exs_aip650e.set_key_callback(on_key)
|
||||
|
||||
sys.wait(15000)
|
||||
|
||||
exs_aip650e.set_key_callback(nil)
|
||||
log.info("aip650e_demo", "按键回调演示结束")
|
||||
end
|
||||
|
||||
-- 演示亮度调节
|
||||
local function demo_brightness()
|
||||
log.info("aip650e_demo", "===== [4/6] 亮度调节 =====")
|
||||
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("8888")
|
||||
sys.wait(500)
|
||||
|
||||
for bright = 0, 7 do
|
||||
log.info("aip650e_demo", "设置亮度:", bright)
|
||||
exs_aip650e.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
-- 恢复默认亮度
|
||||
exs_aip650e.set_brightness(4)
|
||||
exs_aip650e.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示 7段/8段 模式切换
|
||||
local function demo_segment_mode()
|
||||
log.info("aip650e_demo", "===== [5/6] 7段/8段模式切换 =====")
|
||||
|
||||
-- 8 段模式(含 DP 段),显示数字
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_mode(0)
|
||||
exs_aip650e.set_display("8SEG")
|
||||
sys.wait(2000)
|
||||
|
||||
-- 显示带小数点的内容(8 段模式特性)
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("88.8")
|
||||
sys.wait(2000)
|
||||
|
||||
-- 切换到 7 段模式
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_mode(1)
|
||||
exs_aip650e.set_display("7SEG")
|
||||
sys.wait(2000)
|
||||
|
||||
exs_aip650e.clear()
|
||||
sys.wait(500)
|
||||
|
||||
-- 切回 8 段模式
|
||||
exs_aip650e.set_mode(0)
|
||||
end
|
||||
|
||||
-- 综合演示
|
||||
local function demo_final()
|
||||
log.info("aip650e_demo", "===== [6/6] 综合演示 =====")
|
||||
|
||||
-- 倒计时
|
||||
for i = 5, 0, -1 do
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display(string.format("%04d", i))
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- HELLO 闪烁
|
||||
for i = 0, 3 do
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("HELO")
|
||||
sys.wait(500)
|
||||
exs_aip650e.clear()
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
-- 全 8 显示 + 亮度渐变
|
||||
exs_aip650e.clear()
|
||||
exs_aip650e.set_display("8888")
|
||||
for i = 0, 7 do
|
||||
exs_aip650e.set_brightness(i)
|
||||
sys.wait(200)
|
||||
end
|
||||
sys.wait(1000)
|
||||
exs_aip650e.set_brightness(4)
|
||||
exs_aip650e.clear()
|
||||
|
||||
-- 日期展示
|
||||
log.info("aip650e_demo", "日期展示: 26-07-13")
|
||||
exs_aip650e.set_display("26-07-13")
|
||||
sys.wait(3000)
|
||||
|
||||
-- 温度展示(摄氏度)
|
||||
exs_aip650e.clear()
|
||||
sys.wait(200)
|
||||
local DEGREE = "\xB0"
|
||||
for temp = 25, 32 do
|
||||
local cel = string.format("%02d", temp) .. DEGREE .. "C"
|
||||
exs_aip650e.set_display(cel)
|
||||
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
|
||||
if bright < 0 then bright = 0 end
|
||||
if bright > 7 then bright = 7 end
|
||||
exs_aip650e.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
-- 温度展示(华氏度)
|
||||
for temp = 77, 90, 2 do
|
||||
local fah = string.format("%02d", temp) .. DEGREE .. "F"
|
||||
exs_aip650e.set_display(fah)
|
||||
sys.wait(600)
|
||||
end
|
||||
|
||||
exs_aip650e.set_brightness(5)
|
||||
sys.wait(2000)
|
||||
exs_aip650e.clear()
|
||||
|
||||
-- 演示开启/关闭显示
|
||||
log.info("aip650e_demo", "显示关闭演示")
|
||||
exs_aip650e.set_display("OFF_")
|
||||
sys.wait(2000)
|
||||
exs_aip650e.display_off()
|
||||
sys.wait(2000)
|
||||
exs_aip650e.display_on()
|
||||
sys.wait(2000)
|
||||
exs_aip650e.clear()
|
||||
|
||||
log.info("aip650e_demo", "---- 综合演示结束 ----")
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function aip650e_demo_task_func()
|
||||
-- 初始化 (Air780EPM: CLK=31, DIO=30)
|
||||
local result = exs_aip650e.setup({
|
||||
clk = 31,
|
||||
dio = 30,
|
||||
bright = 5,
|
||||
})
|
||||
if not result then
|
||||
log.error("aip650e_demo", "AiP650E 初始化失败,请检查接线")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("aip650e_demo", "AiP650E 初始化成功,版本:", exs_aip650e.version())
|
||||
|
||||
-- HELLO 开始 → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
exs_aip650e.set_display("HELO")
|
||||
sys.wait(1000)
|
||||
|
||||
demo_string()
|
||||
demo_keys()
|
||||
demo_key_callback()
|
||||
demo_brightness()
|
||||
demo_segment_mode()
|
||||
demo_final()
|
||||
|
||||
exs_aip650e.set_display("End-")
|
||||
sys.wait(3000)
|
||||
log.info("aip650e_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(aip650e_demo_task_func)
|
||||
@@ -0,0 +1,71 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary AiP650E 数码管驱动芯片测试 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_aip650e 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
|
||||
1、数码管字符串显示([1/6])
|
||||
2、按键检测轮询([2/6])
|
||||
3、按键回调演示([3/6])
|
||||
4、亮度调节([4/6])
|
||||
5、7段/8段模式切换([5/6])
|
||||
6、综合演示-温度/时钟/睡眠([6/6])
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "AiP650E_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 aip650e_demo.lua 演示模块
|
||||
require "aip650e_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,180 @@
|
||||
# AiP650E 数码管驱动芯片演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **aip650e_demo.lua** - AiP650E 功能演示模块,包含数码管显示、按键检测、亮度调节、模式切换、综合展示等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_aip650e** - AiP650E 扩展库,提供数码管段码显示、按键检测、亮度调节、模式切换等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_aip650e 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/6] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示
|
||||
2. **[2/6] 按键轮询** - 通过 `get_key()` API 轮询检测按键,10 秒超时
|
||||
3. **[3/6] 亮度调节** - 展示 0~7 级亮度调节效果
|
||||
4. **[4/6] 按键回调** - 通过 `set_key_callback()` API 设置按键回调函数,15 秒演示窗口
|
||||
5. **[5/6] 模式切换** - 8 段与 7 段模式切换演示
|
||||
6. **[6/6] 综合演示** - 倒计时、HELLO 闪烁、全 8 显示、亮度渐变、日期展示、温度展示
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- AiP650E 数码管模块(4 位数码管 + 按键) × 1
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 AiP650E 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>AiP650E 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
|
||||
<tr>
|
||||
<td>31/GPIO30<br/></td><td>DIO<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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. **aip650e_demo.lua** - AiP650E 功能演示模块
|
||||
3. **exs_aip650e** - AiP650E 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 AiP650E 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 aip650e_demo.lua 演示模块
|
||||
require "aip650e_demo"
|
||||
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 字符串显示演示
|
||||
|
||||
1. 设备启动后显示 "HELLO",随后自动进入 [1/6] 字符串显示
|
||||
2. 观察数码管依次显示:`1234` → `88.8` → `AbCd` → 从第 3 位显示 `1234`
|
||||
3. 检查字符显示是否正确,带小数点功能是否正常
|
||||
|
||||
#### 5.4.2 按键检测演示
|
||||
|
||||
1. 自动进入 [2/6] 按键轮询演示,数码管显示 "KEY-"
|
||||
2. 在 10 秒内按下 AiP650E 模块上的任意按键
|
||||
3. 观察数码管显示按键编码(如 "K01"、"K02" 等)
|
||||
4. 若 10 秒内无按键按下,自动跳过
|
||||
|
||||
#### 5.4.3 亮度调节演示
|
||||
|
||||
1. 自动进入 [3/6] 亮度调节演示,数码管显示 "8888"
|
||||
2. 观察数码管亮度从 0 级到 7 级逐级变化
|
||||
3. 最终恢复到 4 级亮度
|
||||
|
||||
#### 5.4.4 按键回调演示
|
||||
|
||||
1. 自动进入 [4/6] 按键回调演示,数码管显示 "Cb-Key"
|
||||
2. 在 15 秒内按下任意按键,观察数码管显示对应按键编码
|
||||
3. 观察日志输出,确认回调函数 `on_key` 被正常触发
|
||||
4. 15 秒后自动结束回调演示
|
||||
|
||||
#### 5.4.5 模式切换演示
|
||||
|
||||
1. 自动进入 [5/6] 模式切换演示
|
||||
2. 观察数码管从 8 段模式切换到 7 段模式
|
||||
3. 再切回 8 段模式,观察显示效果变化
|
||||
4. 确认小数点(DP)在 7 段模式下不显示
|
||||
|
||||
#### 5.4.6 综合演示
|
||||
|
||||
1. 自动进入 [6/6] 综合演示
|
||||
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
|
||||
3. 观察 "HELO" 闪烁效果,重复 4 次
|
||||
4. 观察全 8 显示 + 亮度渐变
|
||||
5. 日期展示:显示格式 "YY-MM-DD"(如 "26-07-13"),停留 3 秒
|
||||
6. 温度展示:
|
||||
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
|
||||
- 华氏度:77°F → 90°F 逐度变化
|
||||
7. 演示结束后显示 "End" 并停留 3 秒
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置
|
||||
- **按键检测**:轮询模式和回调模式均能正确检测按键,编码显示正常
|
||||
- **亮度调节**:0~7 级亮度逐级变化,效果明显
|
||||
- **模式切换**:8 段和 7 段模式切换正常,小数点显示状态正确
|
||||
- **日期/温度**:格式显示正确,°C 和 °F 符号正常显示
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **数码管无显示**:
|
||||
|
||||
- 检查 AiP650E 接线是否正确(CLK、DIO、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_aip650e 扩展库已正常加载
|
||||
|
||||
2. **按键无响应**:
|
||||
|
||||
- 检查按键电路是否正常
|
||||
- 确认扩展库初始化成功
|
||||
- 查看日志确认 `setup()` 返回值为 true
|
||||
|
||||
3. **亮度无法调节**:
|
||||
|
||||
- 确认调用 `set_brightness()` 时参数为 0~7
|
||||
|
||||
4. **显示内容错乱**:
|
||||
|
||||
- 检查杜邦线是否过长导致通信不稳定
|
||||
|
||||
5. **通信不稳定**:
|
||||
|
||||
- 检查 CLK 和 DIO 接线是否牢固
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_aip650e 更多接口的使用可以查看 [exs_aip650e 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_aip650e/)
|
||||
@@ -0,0 +1,123 @@
|
||||
--[[
|
||||
@module bl0939_app
|
||||
@summary BL0939 双路免校准电能计量数据读取业务模块
|
||||
@version 1.0
|
||||
@date 2026.08.20
|
||||
@author 李明
|
||||
]]
|
||||
|
||||
local exs_bl0939 = require "exs_bl0939"
|
||||
|
||||
-- 通信模式切换:1=SPI / 2=UART
|
||||
-- 根据实际硬件接线选择
|
||||
-- SPI 模式:BL0939 SEL 接 Air780EPM GPIO28(高电平)
|
||||
-- BL0939 SCLK -> Air780EPM SPI0_SCK
|
||||
-- BL0939 RX/SDI -> Air780EPM SPI0_MOSI
|
||||
-- BL0939 TX/SDO -> Air780EPM SPI0_MISO(需外部上拉电阻)
|
||||
-- UART 模式:BL0939 SEL 接 Air780EPM GPIO28(低电平)
|
||||
-- BL0939 RX/SDI -> Air780EPM UART1_TX (GPIO18)
|
||||
-- BL0939 TX/SDO -> Air780EPM UART1_RX (GPIO17)(需外部上拉电阻)
|
||||
-- 注意:BL0939 的 SEL 引脚悬空默认为 UART 模式(内部下拉)
|
||||
local MODE = 2
|
||||
|
||||
-- UART 器件地址(仅 UART 模式生效)
|
||||
-- SOP16L 封装固定为 5;SSOP20L 封装由 A4~A1 引脚电平决定 0~15
|
||||
local UART_ADDR = 5
|
||||
|
||||
-- 外部采样电路参数,需根据实际互感器和分压电阻修改
|
||||
-- 电流有效值换算:I(A) = IA/B_RMS * Vref / 324004(规格书 2.6)
|
||||
-- 电压有效值换算:V(V) = V_RMS * Vref / 79931(规格书 2.6)
|
||||
-- 有功功率换算:P(W) = WATT * Vref^2 / 4046(规格书 2.2)
|
||||
-- Vref 为内置基准电压,典型值 1.218V
|
||||
-- 以下 ratio 为简化系数,实际需根据互感器变比和分压比标定
|
||||
local voltage_ratio = 1000 -- 电压分压比,例如 1000:1
|
||||
local current_ratio = 1000 -- 电流互感器变比,例如 1000:1
|
||||
|
||||
-- 按 MODE 组装 setup 参数
|
||||
local function build_config_func()
|
||||
if MODE == 1 then
|
||||
-- SPI 模式:BL0939 SEL 接高电平
|
||||
return {
|
||||
mode = "spi",
|
||||
spi_id = 0,
|
||||
cs = 20, -- 占位 GPIO,BL0939 SPI 无 CS,不接 BL0939
|
||||
sel_pin = 28, -- 接 BL0939 SEL,拉高选 SPI 模式
|
||||
ac_freq = 50,
|
||||
rms_update = 400,
|
||||
fast_rms_threshold = 0x7FFF,
|
||||
fast_rms_cycle = exs_bl0939.FAST_RMS_CYCLE_FULL,
|
||||
cf_func = exs_bl0939.CF_FUNC_ENERGY
|
||||
}
|
||||
else
|
||||
-- UART 模式:BL0939 SEL 接低电平
|
||||
return {
|
||||
mode = "uart",
|
||||
uart_id = 1,
|
||||
addr = UART_ADDR, -- SOP16L 固定 5
|
||||
sel_pin = 28, -- 接 BL0939 SEL,拉低选 UART 模式
|
||||
ac_freq = 50,
|
||||
rms_update = 400,
|
||||
fast_rms_threshold = 0x7FFF,
|
||||
fast_rms_cycle = exs_bl0939.FAST_RMS_CYCLE_FULL,
|
||||
cf_func = exs_bl0939.CF_FUNC_ENERGY
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- 传感器初始化函数
|
||||
-- 重要:必须返回 boolean,失败时 return false
|
||||
local function init_func()
|
||||
local result = exs_bl0939.setup(build_config_func())
|
||||
if not result then
|
||||
log.error("bl0939", "init failed")
|
||||
log.error("bl0939", "检查接线: VCC=3.3V GND, SEL=GPIO28, SPI 模式接 SCK/MOSI/MISO, UART 模式接 TX/RX")
|
||||
return false -- 返回 false,不能只 return
|
||||
end
|
||||
log.info("bl0939", "init success, version:", exs_bl0939.version())
|
||||
return true
|
||||
end
|
||||
|
||||
-- 读取并打印双路电能数据
|
||||
local function read_data_func()
|
||||
local data = exs_bl0939.get_data()
|
||||
if not data then
|
||||
log.error("bl0939", "read data failed")
|
||||
return
|
||||
end
|
||||
|
||||
-- 电压和温度
|
||||
log.info("bl0939", string.format("电压=%.2fV 温度=%.1f°C",
|
||||
data.v_rms / voltage_ratio, data.temp))
|
||||
|
||||
-- A 通道
|
||||
log.info("bl0939", string.format("A路 电流=%.3fA 有功=%.2fW 相角=%.1f°",
|
||||
data.ia_rms / current_ratio,
|
||||
data.a_watt / voltage_ratio / current_ratio,
|
||||
data.a_angle))
|
||||
|
||||
-- B 通道
|
||||
log.info("bl0939", string.format("B路 电流=%.3fA 有功=%.2fW 相角=%.1f°",
|
||||
data.ib_rms / current_ratio,
|
||||
data.b_watt / voltage_ratio / current_ratio,
|
||||
data.b_angle))
|
||||
|
||||
-- 快速有效值(用于漏电/过流监控参考)
|
||||
log.info("bl0939", string.format("快速RMS A=%d B=%d 电能脉冲A=%d B=%d",
|
||||
data.ia_fast_rms, data.ib_fast_rms, data.cfa_cnt, data.cfb_cnt))
|
||||
end
|
||||
|
||||
-- 传感器读取任务协程
|
||||
local function sensor_task_func()
|
||||
sys.wait(100) -- 等待系统稳定,100ms
|
||||
local ok = init_func()
|
||||
if not ok then return end -- 按返回值判断是否继续
|
||||
|
||||
for i = 1, 10 do
|
||||
read_data_func()
|
||||
sys.wait(1000) -- 每隔 1 秒读取一次
|
||||
end
|
||||
|
||||
exs_bl0939.close()
|
||||
log.info("bl0939", "demo finished")
|
||||
end
|
||||
sys.taskInit(sensor_task_func)
|
||||
@@ -0,0 +1,65 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary LuatOS 用户应用脚本文件入口
|
||||
@version 1.0
|
||||
@date 2026.08.20
|
||||
@author 蒋骞
|
||||
@usage
|
||||
本 demo 演示 BL0939 双路免校准电能计量芯片的数据读取功能,业务逻辑见 bl0939_app.lua
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_bl0939 扩展库的完整功能,顺序为:
|
||||
|
||||
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进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
|
||||
PROJECT = "780EPM_bl0939"
|
||||
VERSION = "001.999.000"
|
||||
|
||||
-- 在日志中打印项目名和项目版本号
|
||||
log.info("main", PROJECT, VERSION)
|
||||
|
||||
-- 设置日志输出风格为样式2(建议调试时开启)
|
||||
-- log.style(2)
|
||||
|
||||
|
||||
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
|
||||
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息
|
||||
-- if errDump then
|
||||
-- errDump.config(true, 600)
|
||||
-- end
|
||||
|
||||
|
||||
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
|
||||
-- 可以使用合宙的iot.openluat.com平台进行远程升级
|
||||
-- 也可以使用客户自己搭建的平台进行远程升级
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时/已使用/历史最高内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- local function mem_check_func()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end
|
||||
-- sys.timerLoopStart(mem_check_func, 3000)
|
||||
|
||||
-- 加载业务模块
|
||||
require "bl0939_app"
|
||||
|
||||
sys.run()
|
||||
-- sys.run() 之后不要加任何语句
|
||||
@@ -0,0 +1,194 @@
|
||||
# Air780EPM + BL0939 双路免校准电能计量 Demo
|
||||
|
||||
> <font color="red"><b>声明:
|
||||
>
|
||||
>严禁带电操作! 进行任何连接或拆卸前,务必断开电源。
|
||||
|
||||
>高压危险! 测试220V时,请确保所有接线可靠,并使用隔离变压器及漏电保护器。
|
||||
|
||||
>本介绍为技术支持页面,操作人员需具备电气安全知识,否则请勿尝试,操作风险由使用者自行承担</b></font>
|
||||
|
||||
## 项目简介
|
||||
**Air780EPM**:通过 UART1(MAIN_UART)或 SPI0 读取上海贝岭 BL0939 双路电能计量芯片,持续循环读取 + 失联自动重连,内置实机校准系数。
|
||||
|
||||
## 文件结构
|
||||
- `user/main.lua`:脚本入口
|
||||
- `user/bl0939_app.lua`:业务逻辑(循环读取/换算/断线重连;`MODE` 变量切换 uart/spi)
|
||||
- `lib/exs_bl0939.lua`:BL0939 驱动扩展库(SPI/UART 双模式)
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
[main.lua](main.lua) 为 LuatOS 脚本入口,仅负责加载业务模块并启动调度器。
|
||||
业务逻辑全部在 `bl0939_app.lua` 中实现。
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
- `exs_bl0939.lua`:BL0939 驱动扩展库,封装 SPI/UART 通信、SEL 模式切换、寄存器配置、数据读取、温度与相角换算。
|
||||
- `exs_bl0939.md`:扩展库 API 文档,含六章结构说明。
|
||||
|
||||
### 1.3 通信模式说明
|
||||
|
||||
本 Demo 支持 SPI 和 UART 两种通信模式,通过 `bl0939_app.lua` 顶部的 `MODE` 变量切换:
|
||||
|
||||
- `MODE = 1`:SPI 模式(推荐),默认使用 SPI0、SEL=GPIO28(拉高)。
|
||||
- `MODE = 2`:UART 模式,默认使用 UART1、4800bps、器件地址 5(SOP16L)。
|
||||
|
||||
BL0939 的 SEL 引脚决定通信模式:SEL=1(高电平)为 SPI,SEL=0(低电平或悬空)为 UART。
|
||||
请根据实际硬件接线选择对应模式。
|
||||
|
||||
---
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
1. 系统上电后等待 100ms 稳定。
|
||||
2. 初始化 BL0939,配置 SEL 引脚、通信接口、交流频率、RMS 刷新、快速有效值参数。
|
||||
3. 循环读取 10 次双路电能数据,每次间隔 1 秒。
|
||||
4. 打印电压、温度、A/B 双路电流、有功功率、相角、快速有效值、电能脉冲计数。
|
||||
5. 演示结束后关闭传感器。
|
||||
|
||||
注意:UART 模式下 `get_data()` 优先使用全电参数数据包(35 字节一次返回),响应更快。
|
||||
|
||||
---
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- 支持 LuatOS 的模块(如 Air780EPM)
|
||||
- BL0939 芯片或已集成模块(SOP16L 或 SSOP20L 封装)
|
||||
- 电流互感器(2 路,用于 A/B 电流通道 IP1/IN1、IP2/IN2)
|
||||
- 电压分压电路(用于 VP 电压通道)
|
||||
- 外部上拉电阻(接 TX/SDO 引脚,规格书要求)
|
||||
- 杜邦线或 PCB 转接板
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### SPI 模式(MODE = 1,SEL 接高电平)
|
||||
|
||||
```text
|
||||
Air780EPM BL0939
|
||||
SPI0_SCK ------> SCLK
|
||||
SPI0_MOSI ------> RX/SDI
|
||||
SPI0_MISO <------ TX/SDO(需外部上拉电阻)
|
||||
GPIO28 ------> SEL (高电平选 SPI 模式)
|
||||
3.3V ------> VDD
|
||||
GND ------> GND
|
||||
IP1/IN1 <------ 电流 A 通道采样
|
||||
IP2/IN2 <------ 电流 B 通道采样
|
||||
VP <------ 电压采样
|
||||
```
|
||||
|
||||
注意:BL0939 SPI 不支持片选(CS),`bl0939_app.lua` 中 `cs=20` 仅为
|
||||
`spi.deviceSetup` 所需占位 GPIO,不接 BL0939。
|
||||
|
||||
#### UART 模式(MODE = 2,SEL 接低电平或悬空)
|
||||
|
||||
```text
|
||||
Air780EPM BL0939
|
||||
UART1_TX ------> RX/SDI (GPIO18)
|
||||
UART1_RX <------ TX/SDO (GPIO17,需外部上拉电阻)
|
||||
GPIO28 ------> SEL (低电平选 UART 模式)
|
||||
3.3V ------> VDD
|
||||
GND ------> GND
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- UART 固定 4800bps,N/8/1.5,不可通过软件修改。
|
||||
- SOP16L 封装器件地址固定为 5;SSOP20L 由 A4~A1 引脚电平决定 0~15。
|
||||
- UART 模式仅需两个低速光耦即可实现隔离通信。
|
||||
|
||||
---
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- Luatools 或 LuatOS 配套 IDE
|
||||
- USB 数据线用于烧录和日志查看
|
||||
|
||||
### 4.2 内核固件
|
||||
|
||||
请使用支持 SPI/UART 扩展库模块的最新 LuatOS 固件。
|
||||
|
||||
### 4.3 脚本文件
|
||||
|
||||
- `main.lua`:脚本入口
|
||||
- `bl0939_app.lua`:业务逻辑
|
||||
- `exs_bl0939.lua`:扩展库(放到脚本同级目录)
|
||||
- `exs_bl0939.md`:API 文档
|
||||
|
||||
---
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
按 3.2 节接线,确保 BL0939 供电为 3.3V,GND 共地。
|
||||
TX/SDO 引脚需接外部上拉电阻(规格书要求)。
|
||||
电流互感器和电压分压电路参数需根据实际应用场景计算。
|
||||
|
||||

|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
1. 打开 `bl0939_app.lua`。
|
||||
2. 根据接线方式设置 `MODE = 1`(SPI)或 `MODE = 2`(UART)。
|
||||
3. UART 模式下,根据封装设置 `UART_ADDR`(SOP16L 固定 5,SSOP20L 由引脚决定)。
|
||||
4. 修改 `voltage_ratio` 和 `current_ratio` 为实际采样电路参数。
|
||||
|
||||
注意:
|
||||
|
||||
- `SEL=GPIO28` 用于切换通信模式,SPI 拉高、UART 拉低;
|
||||
- BL0939 内部下拉,SEL 悬空默认为 UART 模式;
|
||||
- UART 固定 4800bps,无法通过 `baud` 参数修改。
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
将 `main.lua`、`bl0939_app.lua`、`exs_bl0939.lua` 一起烧录到模块中,重启运行。
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
观察日志输出,确认初始化成功、数据读取正常。
|
||||
|
||||
### 5.5 预期效果(含实测日志)
|
||||
|
||||
当前测试只接了一路负载,是由一个100W 500Ω和一个200W 200Ω的功率电阻串联,测试电流为 0.318A,电压为 220V,温度为 29.2°C,部分日志如下:
|
||||
```text
|
||||
[2026-08-21 15:14:44.838][000000073.994] D/user.exs_bl0939 UART PKT RX 55 BD F6 00 A2 56 01 00 00 00 BD 36 38 82 02 00 38 C5 00 00 00 00 02 00 00 00 00 00 C7 01 00 FE 03 00 37
|
||||
[2026-08-21 15:14:44.853][000000074.016] D/user.exs_bl0939 UART RD RX 07 00 00 9C
|
||||
[2026-08-21 15:14:44.885][000000074.037] D/user.exs_bl0939 UART RD RX FF 00 00 A3
|
||||
[2026-08-21 15:14:44.893][000000074.038] I/user.bl0939 RAW V=3684029 IA=87714 IB=0 PA=50488 PB=0 W1=2 W2=0 TPS1=455
|
||||
[2026-08-21 15:14:44.909][000000074.038] I/user.bl0939 电压=222.47V 温度=29.2C
|
||||
[2026-08-21 15:14:44.924][000000074.039] I/user.bl0939 A路 电流=0.318A 有功=70.84W 相角=0.1 电能=0.0003kWh
|
||||
[2026-08-21 15:14:44.939][000000074.039] I/user.bl0939 B路 电流=0.000A 有功=0.00W 相角=4.6 电能=0.0000kWh
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
| 现象 | 排查方法 |
|
||||
|---|---|
|
||||
| 初始化失败 | 检查 VCC/GND 接线;确认 SEL 引脚电平与 MODE 一致;检查 SPI 或 UART 接线 |
|
||||
| 数据全为 0 | 检查电压/电流采样电路是否接入;确认 IP1/IN1、IP2/IN2、VP 接线正确 |
|
||||
| 温度异常 | 温度寄存器需芯片工作一段时间,上电后立即读取可能不准确 |
|
||||
| UART 读取失败 | 确认 UART 固定 4800bps;检查 TX/RX 是否交叉;确认器件地址与封装一致 |
|
||||
| SPI checksum 错误 | 检查 SPI0_SCK/MOSI/MISO 接线;确认 SPI 模式 1(CPOL=0/CPHA=1) |
|
||||
| 相角为 0 | 确认电压通道有交流信号输入;A/B_CORNER 寄存器需过零更新 |
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
- 连接 CF 引脚到 GPIO,使用 GPIO 中断统计电能脉冲。
|
||||
- 配置快速有效值阈值,用于 A/B 通道漏电/过流保护。
|
||||
- 设置 CF 为温度报警输出,配合 temp_alert_th 实现过温保护。
|
||||
- 接入校准源,写入校准系数(RMSOS/WATTOS)提高计量精度。
|
||||
- 使用 SSOP20L 封装多片级联,实现多路计量。
|
||||
- 通过 MQTT 或 OneNET 上传电能数据到云端。
|
||||
|
||||
---
|
||||
|
||||
## 六、参考文档
|
||||
|
||||
- [exs_bl0939.md](../exs_bl0939.md)
|
||||
- BL0939 规格书
|
||||
@@ -0,0 +1,315 @@
|
||||
--[[
|
||||
@module bme680_demo
|
||||
@summary BME680 四合一环境传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.1
|
||||
@date 2026.08.20
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 BME680 的逐项功能演示。
|
||||
通过 exs_bme680 扩展库的 API 逐一演示数据读取、IIR 滤波切换、过采样率切换、
|
||||
气体加热器切换、空气质量判断、海拔计算等功能。
|
||||
|
||||
通过 MODE 变量选择通信模式(改 MODE 的值即可,无需注释/取消注释代码):
|
||||
MODE = 1 软件 I2C(默认推荐,仅需 scl/sda 引脚,任意 GPIO 均可,接线最灵活)
|
||||
MODE = 2 硬件 I2C(指定 i2c_id,占用 CPU 少)
|
||||
|
||||
Air780EPM 接线(软件 I2C):
|
||||
SCL = GPIO31
|
||||
SDA = GPIO30
|
||||
]]
|
||||
|
||||
-- 加载 exs_bme680 扩展库
|
||||
-- 该库提供 BME680 的全部驱动功能: 初始化/温度/气压/湿度/气体电阻读取/过采样/滤波/加热器/海拔
|
||||
local exs_bme680 = require "exs_bme680"
|
||||
|
||||
-- ==================== 通信模式选择 ====================
|
||||
-- 改 MODE 的值选择通信模式:
|
||||
-- 1 = 软件 I2C(默认) 2 = 硬件 I2C
|
||||
-- 各模式所需引脚/参数见下方 init_config,接线说明见 readme.md
|
||||
local MODE = 1
|
||||
|
||||
local init_config
|
||||
if MODE == 1 then
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO,Air780EPM 接线示例用 GPIO31/GPIO30
|
||||
init_config = {scl = 31, sda = 30}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_id 为总线号(Air780EPM 用 1),不传 scl/sda 时无总线恢复能力
|
||||
init_config = {i2c_id = 1}
|
||||
else
|
||||
log.error("bme680_demo", "MODE 取值错误,应为 1/2")
|
||||
return
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [1/6] 初始化与数据读取
|
||||
-- - setup() 自动完成芯片 ID 校验、校准数据读取、采样/滤波/加热器参数配置
|
||||
-- - get_data() 返回温度(°C)、气压(hPa)、湿度(%RH)、气体电阻(Ω)
|
||||
--------------------------------------------------------------
|
||||
local function demo_init_and_read()
|
||||
log.info("bme680_demo", "===== [1/6] 初始化与数据读取 =====")
|
||||
|
||||
-- BME680 默认配置:温度 4X 过采样,气压 4X 过采样,湿度 2X 过采样
|
||||
-- IIR 滤波 8 次平均,气体加热器 320°C / 150ms
|
||||
local result = exs_bme680.setup(init_config)
|
||||
|
||||
if not result then
|
||||
log.error("bme680_demo", "BME680 初始化失败")
|
||||
log.error("bme680_demo", "检查接线: VCC=3.3V GND SCL SDA,I2C 地址是否正确(如 0x76/0x77)")
|
||||
return false -- 初始化失败必须返回 false
|
||||
end
|
||||
log.info("bme680_demo", "BME680 初始化成功,版本:", exs_bme680.version())
|
||||
|
||||
-- 气体预热说明:MOX 气体传感器上电后电阻会从低值缓慢爬升,
|
||||
-- 新板首次上电需预热 20~30 分钟才稳定,稳定前气体电阻读值无参考意义
|
||||
log.info("bme680_demo", "预热提示: MOX 气体传感器需预热 20~30 分钟,")
|
||||
log.info("bme680_demo", "预热期间电阻从低值爬升属正常,稳定前气体电阻读值不可信")
|
||||
|
||||
-- 等待传感器稳定,气体传感器需要预热
|
||||
-- 首次读取气体电阻可能为 0(加热器未稳定),这是正常现象
|
||||
sys.wait(500) -- 等待传感器稳定,500ms
|
||||
local data = exs_bme680.get_data()
|
||||
if data then
|
||||
local gas_kohm = data.gas_resistance / 1000
|
||||
log.info("bme680_demo", string.format("温度=%.2f°C 气压=%.2fhPa 湿度=%.1f%%RH 气体=%.1fkΩ",
|
||||
data.temperature, data.pressure, data.humidity, gas_kohm))
|
||||
else
|
||||
log.error("bme680_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(1000) -- 稳定后等待 1 秒进入连续读取
|
||||
|
||||
-- 连续读取 3 次,观察数据变化
|
||||
for i = 1, 3 do
|
||||
sys.wait(2000) -- 每次读取间隔 2 秒
|
||||
local d = exs_bme680.get_data()
|
||||
if d then
|
||||
local gas_kohm = d.gas_resistance / 1000
|
||||
log.info("bme680_demo", string.format("第%d次读取: 温度=%.2f°C 气压=%.1fhPa 湿度=%.1f%%RH 气体=%.1fkΩ",
|
||||
i, d.temperature, d.pressure, d.humidity, gas_kohm))
|
||||
end
|
||||
end
|
||||
log.info("bme680_demo", "---- [1/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [2/6] IIR 滤波器切换演示
|
||||
-- - set_filter(0~7) 设置 IIR 滤波器系数,数值越大数据越平滑
|
||||
--------------------------------------------------------------
|
||||
local function demo_filter_switch()
|
||||
log.info("bme680_demo", "===== [2/6] IIR 滤波器切换演示 =====")
|
||||
|
||||
-- 依次切换 filter=0/1/2/3/4/5/6/7,观察数据变化
|
||||
local filter_list = { 0, 1, 2, 3, 4, 5, 6, 7 }
|
||||
for _, f in ipairs(filter_list) do
|
||||
log.info("bme680_demo", string.format("设置滤波器 filter=%d", f))
|
||||
exs_bme680.set_filter(f)
|
||||
sys.wait(100) -- 等待滤波器生效,100ms
|
||||
|
||||
local data = exs_bme680.get_data()
|
||||
if data then
|
||||
log.info("bme680_demo", string.format("filter=%d: 温度=%.2f°C 气压=%.2fhPa 湿度=%.1f%%RH",
|
||||
f, data.temperature, data.pressure, data.humidity))
|
||||
end
|
||||
sys.wait(1000) -- 每档滤波器显示间隔 1 秒
|
||||
end
|
||||
log.info("bme680_demo", "---- [2/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [3/6] 过采样率切换演示
|
||||
-- - set_temp/press/hum_oversampling(0~5) 设置过采样率
|
||||
-- - 低功耗(1X)与高精度(16X)对比
|
||||
--------------------------------------------------------------
|
||||
local function demo_oversampling_switch()
|
||||
log.info("bme680_demo", "===== [3/6] 过采样率切换演示 =====")
|
||||
|
||||
-- 低功耗模式:全部 1X 过采样
|
||||
log.info("bme680_demo", "切换到低功耗模式(1X过采样)")
|
||||
exs_bme680.set_temp_oversampling(1)
|
||||
exs_bme680.set_press_oversampling(1)
|
||||
exs_bme680.set_hum_oversampling(1)
|
||||
sys.wait(100) -- 等待配置生效,100ms
|
||||
|
||||
local data = exs_bme680.get_data()
|
||||
if data then
|
||||
log.info("bme680_demo", string.format("低功耗: 温度=%.2f°C 气压=%.2fhPa 湿度=%.1f%%RH",
|
||||
data.temperature, data.pressure, data.humidity))
|
||||
end
|
||||
sys.wait(1000) -- 展示间隔 1 秒
|
||||
|
||||
-- 高精度模式:全部 16X 过采样
|
||||
log.info("bme680_demo", "切换到高精度模式(16X过采样)")
|
||||
exs_bme680.set_temp_oversampling(5)
|
||||
exs_bme680.set_press_oversampling(5)
|
||||
exs_bme680.set_hum_oversampling(5)
|
||||
sys.wait(100) -- 等待配置生效,100ms
|
||||
|
||||
data = exs_bme680.get_data()
|
||||
if data then
|
||||
log.info("bme680_demo", string.format("高精度: 温度=%.2f°C 气压=%.2fhPa 湿度=%.1f%%RH",
|
||||
data.temperature, data.pressure, data.humidity))
|
||||
end
|
||||
log.info("bme680_demo", "---- [3/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [4/6] 气体加热器切换演示
|
||||
-- - set_gas_heater(temp, time) 设置加热器温度(200~400°C)与时长(1~4032ms)
|
||||
-- - 不同温度下气体电阻值会变化
|
||||
--------------------------------------------------------------
|
||||
local function demo_gas_heater_switch()
|
||||
log.info("bme680_demo", "===== [4/6] 气体加热器切换演示 =====")
|
||||
|
||||
-- 不同加热器温度组合
|
||||
local heater_configs = {
|
||||
{ temp = 250, time = 100, desc = "低温短时(250°C/100ms)" },
|
||||
{ temp = 320, time = 150, desc = "默认配置(320°C/150ms)" },
|
||||
{ temp = 350, time = 200, desc = "高温长时(350°C/200ms)" },
|
||||
}
|
||||
|
||||
for _, cfg in ipairs(heater_configs) do
|
||||
log.info("bme680_demo", cfg.desc)
|
||||
exs_bme680.set_gas_heater(cfg.temp, cfg.time)
|
||||
sys.wait(200) -- 等待加热器参数生效,200ms
|
||||
|
||||
local data = exs_bme680.get_data()
|
||||
if data then
|
||||
local gas_kohm = data.gas_resistance / 1000
|
||||
log.info("bme680_demo", string.format("气体=%.1fkΩ 温度=%.2f°C 湿度=%.1f%%RH",
|
||||
gas_kohm, data.temperature, data.humidity))
|
||||
end
|
||||
sys.wait(1000) -- 展示间隔 1 秒
|
||||
end
|
||||
log.info("bme680_demo", "---- [4/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- 空气质量判断辅助函数
|
||||
-- 说明:不能直接看电阻绝对值判断空气好坏(不同芯片/环境基线差异大),
|
||||
-- 必须以干净空气稳定基线 R0 为基准,看实时电阻 R 的相对下降幅度:
|
||||
-- 污染度 = (1 - R/R0) * 100%,下降越多污染越高
|
||||
-- 参数:R 实时气体电阻(Ω)
|
||||
-- R0 干净空气稳定基线电阻(Ω)
|
||||
-- 返回:等级字符串, 污染度百分比
|
||||
--------------------------------------------------------------
|
||||
local function calc_air_quality(R, R0)
|
||||
if not R0 or R0 <= 0 or not R or R <= 0 then
|
||||
return "未就绪", 0
|
||||
end
|
||||
local ratio = R / R0
|
||||
local pollution = (1 - ratio) * 100
|
||||
local level
|
||||
if ratio >= 0.9 then
|
||||
level = "优"
|
||||
elseif ratio >= 0.7 then
|
||||
level = "良"
|
||||
elseif ratio >= 0.4 then
|
||||
level = "中"
|
||||
else
|
||||
level = "差"
|
||||
end
|
||||
return level, pollution
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [5/6] 空气质量判断演示
|
||||
-- - 预热说明:MOX 传感器上电后电阻从低值爬升,新板需预热 20~30 分钟才稳定
|
||||
-- - 判断方法:先记录干净空气稳定基线 R0,实时电阻相对 R0 下降越多空气越差
|
||||
--------------------------------------------------------------
|
||||
local function demo_air_quality()
|
||||
log.info("bme680_demo", "===== [5/6] 空气质量判断演示 =====")
|
||||
log.info("bme680_demo", "预热说明: 新板首次上电 MOX 气体传感器需预热 20~30 分钟")
|
||||
log.info("bme680_demo", "电阻会从低值爬升直至稳定,稳定前气体电阻读值无参考意义")
|
||||
log.info("bme680_demo", "判断方法: 以干净空气稳定电阻为基线R0,污染度=(1-R/R0)*100%")
|
||||
|
||||
local data = exs_bme680.get_data()
|
||||
if not data then
|
||||
log.error("bme680_demo", "读取数据失败,空气质量演示终止")
|
||||
return true
|
||||
end
|
||||
|
||||
-- 记录基线 R0:真实使用必须在干净空气中预热 20~30 分钟后记录稳定值,
|
||||
-- 此处为便于演示,直接以当前读数为基线(若为 0 说明加热器未稳定)
|
||||
local R0 = data.gas_resistance
|
||||
if R0 <= 0 then
|
||||
log.warn("bme680_demo", "当前气体电阻为 0(加热器未稳定),请先预热 20~30 分钟再演示")
|
||||
log.warn("bme680_demo", "本次演示基线无效,后续空气等级将显示为未就绪")
|
||||
else
|
||||
log.info("bme680_demo", string.format("记录基线 R0=%.1fkΩ(应取干净空气预热稳定后的值)", R0 / 1000))
|
||||
end
|
||||
|
||||
-- 连续读取 3 次,实时计算污染度与空气等级
|
||||
for i = 1, 3 do
|
||||
sys.wait(3000) -- 每次间隔 3 秒
|
||||
local d = exs_bme680.get_data()
|
||||
if d then
|
||||
local level, pollution = calc_air_quality(d.gas_resistance, R0)
|
||||
log.info("bme680_demo", string.format("第%d次: 气体=%.1fkΩ 污染度=%.1f%% 空气等级=%s",
|
||||
i, d.gas_resistance / 1000, pollution, level))
|
||||
end
|
||||
end
|
||||
log.info("bme680_demo", "提示: 空气等级阈值(优≥0.9R0/良≥0.7R0/中≥0.4R0/差<0.4R0)为经验值")
|
||||
log.info("bme680_demo", "---- [5/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [6/6] 海拔高度测量与关闭
|
||||
-- - get_altitude(pressure) 依据气压计算海拔高度
|
||||
-- - close() 关闭传感器并释放 I2C 资源
|
||||
--------------------------------------------------------------
|
||||
local function demo_altitude_and_close()
|
||||
log.info("bme680_demo", "===== [6/6] 海拔高度测量与关闭 =====")
|
||||
|
||||
local data = exs_bme680.get_data()
|
||||
if data then
|
||||
local alt = exs_bme680.get_altitude(data.pressure)
|
||||
local gas_kohm = data.gas_resistance / 1000
|
||||
log.info("bme680_demo", string.format("温度=%.2f°C 气压=%.1fhPa 湿度=%.1f%%RH 气体=%.1fkΩ 海拔=%.1f米",
|
||||
data.temperature, data.pressure, data.humidity, gas_kohm, alt))
|
||||
end
|
||||
|
||||
-- 关闭传感器
|
||||
exs_bme680.close()
|
||||
log.info("bme680_demo", "---- [6/6] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- 主任务:按 [1/6]~[6/6] 顺序执行全部演示
|
||||
--------------------------------------------------------------
|
||||
local function bme680_demo_task_func()
|
||||
log.info("bme680_demo", "HELLO")
|
||||
sys.wait(1000) -- 等待系统启动稳定,1 秒
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("bme680_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_filter_switch()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_oversampling_switch()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_gas_heater_switch()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_air_quality()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_altitude_and_close()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
log.info("bme680_demo", "===== [演示完毕] =====")
|
||||
log.info("bme680_demo", "End")
|
||||
end
|
||||
|
||||
-- 启动演示任务协程
|
||||
sys.taskInit(bme680_demo_task_func)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary BME680 四合一环境传感器 Demo 入口
|
||||
@version 1.1
|
||||
@date 2026.08.20
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_bme680 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
|
||||
|
||||
1、初始化和数据读取([1/6])
|
||||
2、IIR 滤波器切换演示([2/6])
|
||||
3、过采样率切换演示([3/6])
|
||||
4、气体加热器切换演示([4/6])
|
||||
5、空气质量判断演示([5/6],含气体预热说明)
|
||||
6、海拔高度测量与关闭([6/6])
|
||||
|
||||
更多说明参考本目录下的 readme.md 文件
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
|
||||
PROJECT = "BME680_Demo" -- 项目命名
|
||||
VERSION = "001.999.000" -- 项目版本号
|
||||
|
||||
-- 在日志中打印项目名和项目版本号
|
||||
log.info("main", PROJECT, VERSION)
|
||||
|
||||
-- 设置日志输出风格为样式2(建议调试时开启)
|
||||
-- log.style(2)
|
||||
|
||||
|
||||
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
|
||||
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息
|
||||
-- if errDump then
|
||||
-- errDump.config(true, 600)
|
||||
-- end
|
||||
|
||||
|
||||
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
|
||||
-- 可以使用合宙的iot.openluat.com平台进行远程升级
|
||||
-- 也可以使用客户自己搭建的平台进行远程升级
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时/已使用/历史最高内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- local function mem_check_func()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end
|
||||
-- sys.timerLoopStart(mem_check_func, 3000)
|
||||
|
||||
-- 加载 bme680_demo.lua 演示模块(完整功能演示)
|
||||
require "bme680_demo"
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run() 之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,282 @@
|
||||
# BME680 四合一环境传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口
|
||||
2. **bme680_demo.lua** - BME680 功能演示模块
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_bme680** - BME680 扩展库,提供初始化、温度/气压/湿度/气体电阻读取、过采样率配置、IIR 滤波配置、气体加热器配置、海拔高度计算等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:BME680 使用标准 I2C 接口通信,软件 I2C 模式无需指定 I2C 控制器,任意 GPIO 均可模拟 I2C 时序,灵活性更高。本 demo 默认使用软件 I2C 模式演示,也可通过 `bme680_demo.lua` 中的 `MODE` 变量切换为硬件 I2C 模式。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_bme680 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/6] 初始化与数据读取** - 初始化 BME680 传感器并读取温度(°C)、气压(hPa)、湿度(%RH)和气体电阻(Ω)数据,包含气体预热说明
|
||||
2. **[2/6] IIR 滤波器切换演示** - 依次切换 filter=0~7,观察数据平滑效果
|
||||
3. **[3/6] 过采样率切换演示** - 对比低功耗(1X)和高精度(16X)模式下的测量效果
|
||||
4. **[4/6] 气体加热器切换演示** - 依次测试三种加热器温度/时间组合(250°C、320°C、350°C)
|
||||
5. **[5/6] 空气质量判断演示** - 演示如何判断空气好坏:先记录干净空气稳定基线 R0,实时电阻相对 R0 下降越多空气越差(污染度 = (1 - R/R0) × 100%)
|
||||
6. **[6/6] 海拔高度测量与关闭** - 通过气压值计算海拔高度后关闭传感器
|
||||
|
||||
> **关于气体传感器预热与空气好坏判断**(详见下文 5.4.5):
|
||||
> - BME680 的 MOX 气体传感器上电后电阻会从低值(如几 kΩ)缓慢爬升至几十 kΩ,**新板首次上电需预热 20~30 分钟**电阻才稳定,这是正常现象(预热/烧机效应),稳定前读取的气体电阻没有参考意义
|
||||
> - **不能直接看电阻绝对值判断空气好坏**,必须以干净空气中预热稳定后的电阻为基线 R0,实时电阻 R 相对 R0 **下降越多说明 VOC 浓度越高、空气越差**
|
||||
> - 经验等级:污染度 ≤10% 优、10%~30% 良、30%~60% 中、>60% 差(阈值需结合场景标定)
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- BME680 四合一环境传感器模块 × 1
|
||||
demo所演示的 BME680 环境传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=585977696909&mi_id=00005GuQmhs21YgvmlIoT24gzgF3ZneshBSDiRStMyOfDd0&ns=1&priceTId=213e00d417839209172374576e1068&spm=a21n57.1.hoverItem.5&utparam=%7B%22aplus_abtest%22%3A%22e1d0645c1ad2540833bb794c3c13d5e1%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 BME680 模块接线
|
||||
|
||||
| Air780EPM 核心板 | BME680 模块 |
|
||||
|-----------------|------------|
|
||||
| 32/GPIO31 | SCL |
|
||||
| 31/GPIO30 | SDA |
|
||||
| VDD_EXT | VCC |
|
||||
| GND | GND |
|
||||
|
||||
> 说明:
|
||||
> 1. 接线时注意杜邦线不宜过长,以免通信不稳定
|
||||
> 2. SCL 和 SDA 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC(部分模块已自带)
|
||||
> 3. BME680 的 I2C 地址:SDO=GND 时 0x76,SDO=VCC 时 0x77
|
||||
|
||||

|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/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. **bme680_demo.lua** - BME680 功能演示模块
|
||||
3. **exs_bme680** - BME680 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 BME680 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
require "bme680_demo"
|
||||
```
|
||||
|
||||
如需切换通信模式,修改 `bme680_demo.lua` 中的 `MODE` 变量(1=软件 I2C,2=硬件 I2C)。
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/6] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功(打印校准数据、预热提示)
|
||||
3. 观察温度(°C)、气压(hPa)、湿度(%RH)和气体电阻(kΩ)的连续读取
|
||||
4. 注意:首次上电气体电阻可能为 0,MOX 气体传感器需预热 20~30 分钟才稳定(详见 5.4.5)
|
||||
|
||||
#### 5.4.2 IIR 滤波器切换演示
|
||||
|
||||
1. 自动进入 [2/6] IIR 滤波器切换演示
|
||||
2. 依次观察 filter=0(关闭)~ filter=7(128 次平均)下的数据
|
||||
3. filter 越大数据跳动越小
|
||||
|
||||
#### 5.4.3 过采样率切换演示
|
||||
|
||||
1. 自动进入 [3/6] 过采样率切换演示
|
||||
2. 先切换到低功耗模式(1X),观察数据
|
||||
3. 再切换到高精度模式(16X),对比数据精度变化
|
||||
|
||||
#### 5.4.4 气体加热器切换演示
|
||||
|
||||
1. 自动进入 [4/6] 气体加热器切换演示
|
||||
2. 依次测试 250°C/100ms、320°C/150ms、350°C/200ms 三种参数
|
||||
3. 观察不同温度下气体电阻值的变化
|
||||
|
||||
#### 5.4.5 空气质量判断演示
|
||||
|
||||
> 这是理解 BME680 气体传感器最关键的一步,演示**预热时长**和**如何判断空气好坏**。
|
||||
|
||||
1. 自动进入 [5/6] 空气质量判断演示
|
||||
2. 日志会先打印预热说明:**新板首次上电 MOX 气体传感器需预热 20~30 分钟**,电阻从低值缓慢爬升属正常,稳定前气体电阻读值无参考意义
|
||||
3. 记录当前读数作为基线 R0(真实使用时必须在干净空气中预热 20~30 分钟、电阻稳定后再记录 R0)
|
||||
4. 连续读取 3 次,每次计算污染度 `(1 - R/R0) × 100%` 并输出空气等级
|
||||
|
||||
**如何判断空气好坏(核心)**:
|
||||
|
||||
- 不能直接看电阻**绝对值**(不同芯片、不同温湿度下基线差异大)
|
||||
- 在**干净空气**中预热 20~30 分钟后,记录稳定电阻为基线 R0
|
||||
- 运行时实时电阻 R 相对 R0 **下降越多,说明 VOC 浓度越高、空气越差**
|
||||
- 判断指标:`ratio = R/R0`(越接近 1 越干净),`污染度 = (1 - R/R0) × 100%`
|
||||
- 经验等级(阈值需结合场景标定):污染度 ≤10% **优**、10%~30% **良**、30%~60% **中**、>60% **差**
|
||||
|
||||
```lua
|
||||
-- 判断空气质量等级,R 为实时气体电阻,R0 为干净空气稳定基线
|
||||
local function judge_air(R, R0)
|
||||
if R0 <= 0 or R <= 0 then return "未就绪" end
|
||||
local pollution = (1 - R / R0) * 100
|
||||
if pollution <= 10 then return "优" end
|
||||
if pollution <= 30 then return "良" end
|
||||
if pollution <= 60 then return "中" end
|
||||
return "差"
|
||||
end
|
||||
```
|
||||
|
||||
#### 5.4.6 海拔高度测量与关闭
|
||||
|
||||
1. 自动进入 [6/6] 海拔高度测量与关闭
|
||||
2. 显示温度、气压、湿度、气体电阻和海拔高度
|
||||
3. 关闭传感器后打印 "End"
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:BME680 初始化成功,四项环境数据正常输出
|
||||
- **IIR 滤波器切换**:不同滤波器下数据平滑度不同
|
||||
- **过采样率切换**:高精度模式数据更稳定
|
||||
- **气体加热器切换**:不同温度下气体电阻值有变化
|
||||
- **海拔高度测量**:根据气压计算出当前海拔高度
|
||||
|
||||
- **日志如下:**
|
||||
```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.4kΩ
|
||||
[2026-08-20 21:30:09.534][000000005.241] I/user.bme680_demo 第1次读取: 温度=24.12°C 气压=1008.4hPa 湿度=66.4%RH 气体=3.4kΩ
|
||||
[2026-08-20 21:30:11.735][000000007.434] I/user.bme680_demo 第2次读取: 温度=24.14°C 气压=1008.4hPa 湿度=66.3%RH 气体=4.6kΩ
|
||||
[2026-08-20 21:30:13.922][000000009.627] I/user.bme680_demo 第3次读取: 温度=24.16°C 气压=1008.4hPa 湿度=66.1%RH 气体=5.9kΩ
|
||||
[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.2kΩ 温度=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.6kΩ 温度=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.4kΩ 温度=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.8kΩ 海拔=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. **传感器初始化失败**:
|
||||
|
||||
- 检查 BME680 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 SCL/SDA 上拉电阻是否连接
|
||||
- 确认 exs_bme680 扩展库已正常加载
|
||||
|
||||
2. **读取数据异常**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 自动地址检测会尝试 0x76 和 0x77,确认 SDO 引脚电平
|
||||
- 检查接线无松动
|
||||
|
||||
3. **气体电阻一直为 0**:
|
||||
|
||||
- 新板首次上电需要预热 20~30 分钟,MOX 加热器稳定前 gas_resistance 返回 0,属正常现象(详见 5.4.5)
|
||||
- 预热期间电阻从低值缓慢爬升属正常,待电阻稳定后再记录基线 R0 判断空气质量
|
||||
- 确认加热器温度和时间设置合理(默认 320°C/150ms),加热器未被禁用
|
||||
- 若长时间预热后仍为 0,检查供电是否稳定、`set_gas_heater` 参数是否合法
|
||||
|
||||
4. **海拔高度显示异常**:
|
||||
|
||||
- 海拔计算基于海平面标准气压 1013.25hPa,天气变化会影响计算精度
|
||||
- 可通过 `exs_bme680.set_sea_level_pressure(pressure)` 传入实际海平面气压校正
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_bme680 更多接口的使用可以查看 [exs_bme680 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_bme680/)
|
||||
@@ -0,0 +1,253 @@
|
||||
--[[
|
||||
@module bmi270_app
|
||||
@summary BMI270 六轴惯性传感器演示模块(3 种通信模式 + 中断触发)
|
||||
@version 1.1
|
||||
@date 2026.08.05
|
||||
@author 江访
|
||||
@usage
|
||||
=== 演示流程: 初始化 → 数据读取 → 量程切换 → 姿态解算 → 中断触发 → 休眠唤醒 ===
|
||||
|
||||
通过 MODE 变量选择通信模式(改 MODE 的值即可,无需注释/取消注释代码):
|
||||
|
||||
MODE = 1 软件 I2C(默认推荐,仅需 scl/sda 引脚,任意 GPIO 均可,接线最灵活)
|
||||
MODE = 2 硬件 I2C(指定 i2c_id,占用 CPU 少,Air780EPM 用 I2C1)
|
||||
MODE = 3 SPI(高速模式,需指定 spi_id + cs,适合高速采样)
|
||||
|
||||
本文件通过 exs_bmi270 扩展库的 API 逐一演示 BMI270 的以下功能:
|
||||
|
||||
1. 初始化和基本信息查询 -- setup() 芯片 ID 校验 + 微程序自动加载 + 中断注册
|
||||
2. 加速度/角速度/温度读取 -- get_accel()/get_gyro()/get_temp(), 单位 g/°/s/°C
|
||||
3. 量程切换演示 -- set_acc_range()/set_gyro_range(), 动态调整测量范围
|
||||
4. 姿态解算 -- calibrate_gyro() 零偏标定 + get_attitude() Mahony 互补滤波
|
||||
5. 中断触发演示 -- any_motion 事件中断,topic 方式回调
|
||||
6. 休眠唤醒与资源释放 -- sleep()/wakeup()/close(), 低功耗管理
|
||||
]]
|
||||
|
||||
-- 加载 exs_bmi270 扩展库
|
||||
-- 该库提供 BMI270 的全部驱动功能: 初始化/数据读取/量程配置/姿态解算/中断/电源管理
|
||||
local exs_bmi270 = require "exs_bmi270"
|
||||
|
||||
-- ==================== 通信模式选择 ====================
|
||||
-- 改 MODE 的值选择通信模式:
|
||||
-- 1 = 软件 I2C(默认) 2 = 硬件 I2C 3 = SPI
|
||||
-- 各模式所需引脚/参数见下方 init_config,接线说明见 readme.md
|
||||
local MODE = 1
|
||||
|
||||
-- 中断 GPIO:BMI270 的 INT1 引脚接到核心板的这个 GPIO(三种模式通用,按实际接线修改)
|
||||
local INT1_GPIO = 32
|
||||
|
||||
local init_mode = "I2C"
|
||||
local init_config
|
||||
if MODE == 1 then
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO,Air780EPM 接线示例用 GPIO31/GPIO30
|
||||
-- 不传 addr:扩展库自动探测 0x68/0x69(SDO 引脚决定),chip id 校验命中即锁定
|
||||
init_config = {scl = 31, sda = 30, acc_range = "4g", gyro_range = "500", acc_odr = 200, gyro_odr = 200}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_id 为总线号(Air780EPM 用 1:Pin66=SDA, Pin67=SCL)
|
||||
init_config = {i2c_id = 1, acc_range = "4g", gyro_range = "500", acc_odr = 200, gyro_odr = 200}
|
||||
elseif MODE == 3 then
|
||||
-- SPI:需接线 SPI0_CS=GPIO8, SPI0_CLK=GPIO11, SPI0_MOSI=GPIO9, SPI0_MISO=GPIO10
|
||||
-- 注意:BMI270 最高支持 10MHz,杜邦线长时建议 1MHz 起步,稳定后再提速
|
||||
init_mode = "SPI"
|
||||
init_config = {spi_id = 0, cs = 8, speed = 1000000, acc_range = "4g", gyro_range = "500", acc_odr = 200, gyro_odr = 200}
|
||||
else
|
||||
log.error("TEST", "MODE 取值错误,应为 1/2/3")
|
||||
return
|
||||
end
|
||||
|
||||
-- 中断消息 topic:GPIO 中断回调发布,主任务等待后读取
|
||||
local INT_TOPIC = "BMI270_INT"
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [1/6] 初始化
|
||||
-- - 自动完成芯片 ID 校验(期望 0x24)
|
||||
-- - 自动加载 8192 字节 Bosch 出厂微程序(首次使用必须,否则无法测量)
|
||||
-- - 自动配置量程、采样率,并注册 INT1 中断(data_ready + any_motion)
|
||||
--------------------------------------------------------------
|
||||
local function init_func()
|
||||
log.info("TEST", "=== [1/6] 初始化 ===")
|
||||
log.info("TEST", string.format("通信模式: %s (MODE=%d)", MODE == 3 and "SPI" or (MODE == 2 and "硬件I2C" or "软件I2C"), MODE))
|
||||
local result = exs_bmi270.setup(init_mode, {
|
||||
scl = init_config.scl, sda = init_config.sda,
|
||||
i2c_id = init_config.i2c_id,
|
||||
spi_id = init_config.spi_id, cs = init_config.cs, speed = init_config.speed,
|
||||
acc_range = init_config.acc_range, gyro_range = init_config.gyro_range,
|
||||
acc_odr = init_config.acc_odr, gyro_odr = init_config.gyro_odr,
|
||||
int1 = {
|
||||
int_gpio = INT1_GPIO, -- BMI270 INT1 引脚接的 GPIO
|
||||
-- data_ready = true, -- 数据就绪中断:每个采样周期触发一次
|
||||
any_motion = true, -- 任意运动中断:检测到晃动触发
|
||||
any_motion_thresh_mg = 100, -- 阈值 100mg(默认 83mg,越小越灵敏)
|
||||
topic = INT_TOPIC, -- 中断回调发布该 topic,主任务等待
|
||||
},
|
||||
})
|
||||
if not result then
|
||||
log.error("TEST", "初始化失败! 检查接线: VCC=3.3V GND SCL SDA")
|
||||
return false -- 初始化失败必须返回 false
|
||||
end
|
||||
log.info("TEST", "初始化成功,扩展库版本:", exs_bmi270.version())
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [2/6] 加速度/角速度/温度读取
|
||||
-- - get_accel() 单位 g,水平静止时 Z≈1.0g,X/Y≈0
|
||||
-- - get_gyro() 单位 °/s,静止时应接近 0
|
||||
-- - get_temp() 单位 °C,芯片温度会高于环境温度
|
||||
--------------------------------------------------------------
|
||||
local function read_data_func()
|
||||
log.info("TEST", "=== [2/6] 数据读取 (单位 g / °/s / °C) ===")
|
||||
local acc = exs_bmi270.get_accel()
|
||||
local gyro = exs_bmi270.get_gyro()
|
||||
local temp = exs_bmi270.get_temp()
|
||||
if not acc or not gyro or not temp then
|
||||
log.error("TEST", "读取数据失败!")
|
||||
return
|
||||
end
|
||||
log.info("TEST", string.format("accel x=%.3f y=%.3f z=%.3f", acc.x, acc.y, acc.z))
|
||||
log.info("TEST", string.format("gyro x=%.1f y=%.1f z=%.1f", gyro.x, gyro.y, gyro.z))
|
||||
log.info("TEST", string.format("temp %.1f°C", temp))
|
||||
-- 静止水平时 Z 轴应接近 1g;若设备竖直/倾斜安装,重力会分布到 X/Y/Z 上,
|
||||
-- 属正常现象(此时姿态解算会自动以真实安装方向为基准)。
|
||||
local acc_mag = math.sqrt(acc.x * acc.x + acc.y * acc.y + acc.z * acc.z)
|
||||
if math.abs(acc_mag - 1.0) > 0.15 then
|
||||
log.warn("TEST", "加速度合矢量偏差较大(期望≈1.0g),检查传感器是否受振动或供电异常")
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [3/6] 量程切换演示
|
||||
-- - set_acc_range("8g") 将加速度量程从 ±4g 切换到 ±8g(分辨率下降但可测更大加速度)
|
||||
-- - set_gyro_range("1000") 将陀螺仪量程从 ±500°/s 切换到 ±1000°/s
|
||||
-- - 切换后 get_accel()/get_gyro() 自动按新量程换算
|
||||
--------------------------------------------------------------
|
||||
local function range_switch_func()
|
||||
log.info("TEST", "=== [3/6] 量程切换演示 ===")
|
||||
if not exs_bmi270.set_acc_range("8g") then
|
||||
log.error("TEST", "加速度量程切换失败!")
|
||||
return
|
||||
end
|
||||
log.info("TEST", "加速度量程已切换为 ±8g")
|
||||
local acc = exs_bmi270.get_accel()
|
||||
if acc then
|
||||
log.info("TEST", string.format("accel x=%.3f y=%.3f z=%.3f", acc.x, acc.y, acc.z))
|
||||
end
|
||||
|
||||
if not exs_bmi270.set_gyro_range("1000") then
|
||||
log.error("TEST", "陀螺仪量程切换失败!")
|
||||
return
|
||||
end
|
||||
log.info("TEST", "陀螺仪量程已切换为 ±1000°/s")
|
||||
local gyro = exs_bmi270.get_gyro()
|
||||
if gyro then
|
||||
log.info("TEST", string.format("gyro x=%.1f y=%.1f z=%.1f", gyro.x, gyro.y, gyro.z))
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [4/6] 姿态解算(Mahony 互补滤波)
|
||||
-- - get_attitude() 融合陀螺仪积分与加速度计修正,输出 roll/pitch/yaw
|
||||
-- - yaw 角连续叠加,无 ±180° 跳变;无磁力计会随时间缓慢漂移
|
||||
-- - 必须在固定间隔循环中持续调用,保持陀螺积分连续
|
||||
-- - 首次使用建议先调用 calibrate_gyro() 做陀螺零偏标定(设备保持静止),
|
||||
-- 可显著抑制静止时 roll/pitch/yaw 的缓慢漂移
|
||||
--------------------------------------------------------------
|
||||
local function attitude_func()
|
||||
log.info("TEST", "=== [4/6] 姿态解算 (5秒) ===")
|
||||
|
||||
-- 陀螺零偏标定:设备必须保持静止,采集 50 次陀螺读数求平均
|
||||
-- 标定结果在库内部自动生效,后续 get_attitude() 积分前会扣除零偏
|
||||
log.info("TEST", "请保持设备静止,正在进行陀螺零偏标定...")
|
||||
local bias = exs_bmi270.calibrate_gyro(50)
|
||||
if bias then
|
||||
log.info("TEST", string.format("零偏标定完成: (%.3f, %.3f, %.3f)°/s", bias.x, bias.y, bias.z))
|
||||
else
|
||||
log.warn("TEST", "零偏标定失败,姿态解算将不带零偏补偿")
|
||||
end
|
||||
|
||||
local start = os.clock()
|
||||
while os.clock() - start < 5 do
|
||||
local roll, pitch, yaw = exs_bmi270.get_attitude()
|
||||
if roll then
|
||||
log.info("TEST", string.format("roll=%.1f° pitch=%.1f° yaw=%.1f°", roll, pitch, yaw))
|
||||
end
|
||||
sys.wait(20) -- 20ms 调用一次(50Hz),间隔过大会影响姿态平滑度
|
||||
end
|
||||
log.info("TEST", "姿态解算演示结束")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [5/6] 中断触发演示
|
||||
-- - 已通过 setup 注册 any_motion 事件中断(未启用 data_ready,避免高频触发)
|
||||
-- - GPIO 中断回调只发布消息(不读 I2C),主任务 sys.waitUntil 等待
|
||||
-- - 收到中断后 get_int_status() 查询具体事件,get_data() 读取数据
|
||||
-- 测试方法:晃动设备 → any_motion 触发
|
||||
--------------------------------------------------------------
|
||||
local function int_func()
|
||||
log.info("TEST", "=== [5/6] 中断触发演示 (10秒) ===")
|
||||
log.info("TEST", "测试方法:晃动设备触发 any_motion 中断")
|
||||
local start = os.clock()
|
||||
while os.clock() - start < 10 do
|
||||
sys.waitUntil(INT_TOPIC, 2000) -- 等待中断消息,超时 2 秒
|
||||
-- 读取并清除中断状态(区分具体是哪个事件触发)
|
||||
local events = exs_bmi270.get_int_status()
|
||||
if events and #events > 0 then
|
||||
log.info("TEST", "中断事件:", table.concat(events, ","))
|
||||
end
|
||||
-- 读取一次数据验证(在主任务协程中,I2C 时序完整)
|
||||
local data = exs_bmi270.get_data()
|
||||
if data then
|
||||
log.info("TEST", string.format("acc(%.2f,%.2f,%.2f)g gyr(%.1f,%.1f,%.1f)°/s",
|
||||
data.x, data.y, data.z, data.gx, data.gy, data.gz))
|
||||
end
|
||||
end
|
||||
log.info("TEST", "中断触发演示结束")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [6/6] 休眠唤醒与资源释放
|
||||
-- - sleep() 进入休眠,功耗最低;wakeup() 快速恢复,无需重新 setup()
|
||||
-- - close() 关闭传感器并释放通信资源,之后需重新 setup() 才能使用
|
||||
--------------------------------------------------------------
|
||||
local function sleep_wakeup_func()
|
||||
log.info("TEST", "=== [6/6] 休眠唤醒演示 ===")
|
||||
exs_bmi270.sleep()
|
||||
log.info("TEST", "已进入休眠,3 秒后唤醒")
|
||||
sys.wait(3000) -- 休眠演示 3 秒
|
||||
exs_bmi270.wakeup()
|
||||
log.info("TEST", "已唤醒,读取一次数据验证")
|
||||
local acc = exs_bmi270.get_accel()
|
||||
if acc then
|
||||
log.info("TEST", string.format("accel x=%.3f y=%.3f z=%.3f", acc.x, acc.y, acc.z))
|
||||
end
|
||||
|
||||
-- 释放资源(演示用,实际项目按需调用)
|
||||
exs_bmi270.close()
|
||||
log.info("TEST", "传感器已关闭")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- 主任务:按 [1/6]~[6/6] 顺序执行全部演示
|
||||
--------------------------------------------------------------
|
||||
local function bmi270_task()
|
||||
sys.wait(300) -- 等待系统启动稳定,300ms
|
||||
if not init_func() then return end -- 初始化失败则结束,按返回值判断
|
||||
|
||||
read_data_func()
|
||||
sys.wait(500) -- 两个演示之间留 500ms,便于观察日志
|
||||
|
||||
range_switch_func()
|
||||
sys.wait(500) -- 量程切换后等待配置生效,500ms
|
||||
|
||||
attitude_func()
|
||||
sys.wait(500) -- 姿态解算演示后间隔 500ms
|
||||
|
||||
int_func()
|
||||
|
||||
sleep_wakeup_func()
|
||||
|
||||
log.info("TEST", "========== 所有演示完成 ==========")
|
||||
end
|
||||
|
||||
-- 启动演示任务协程
|
||||
sys.taskInit(bmi270_task)
|
||||
@@ -0,0 +1,76 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary BMI270 六轴惯性传感器 Demo 入口
|
||||
@version 1.1
|
||||
@date 2026.08.05
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_bmi270 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
|
||||
1、初始化和基本信息查询([1/6])- 芯片识别/版本/中断注册
|
||||
2、加速度/角速度/温度读取([2/6])- 三轴物理量数据
|
||||
3、量程切换演示([3/6])- 加速度/陀螺仪量程动态切换
|
||||
4、姿态解算([4/6])- Mahony 互补滤波,roll/pitch/yaw
|
||||
5、中断触发演示([5/6])- data_ready + any_motion 特征中断
|
||||
6、休眠唤醒与资源释放([6/6])- 低功耗演示
|
||||
|
||||
通信模式通过 bmi270_app.lua 中的 MODE 变量选择:
|
||||
1 = 软件 I2C 2 = 硬件 I2C 3 = SPI
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "BMI270_Demo" -- 项目命名
|
||||
VERSION = "001.000.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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 bmi270_app.lua 演示模块
|
||||
-- 通信模式通过 bmi270_app.lua 中的 MODE 变量选择(1=软件I2C / 2=硬件I2C / 3=SPI)
|
||||
require "bmi270_app"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,235 @@
|
||||
# BMI270 六轴惯性传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **bmi270_app.lua** - BMI270 功能演示模块,包含初始化、数据读取、量程切换、姿态解算、中断触发、休眠唤醒共 6 项功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_bmi270** - BMI270 扩展库,提供 I2C/SPI 双接口初始化、三轴加速度/角速度/温度读取、量程与采样率配置、Mahony 姿态解算、中断功能、计步功能、休眠唤醒等 API(8192 字节微程序已内嵌于扩展库,无需单独加载)
|
||||
|
||||
### 1.3 通信模式选择(MODE 变量)
|
||||
|
||||
`bmi270_app.lua` 顶部通过 **MODE 变量**选择通信模式,改一个变量即可切换,无需注释/取消注释代码:
|
||||
|
||||
| MODE 值 | 通信模式 | 所需参数 | 适用场景 |
|
||||
|---------|---------|---------|---------|
|
||||
| 1 | 软件 I2C(默认) | `scl`/`sda`(任意 GPIO) | 接线最灵活,Air780EPM 接线示例用 GPIO31/GPIO30 |
|
||||
| 2 | 硬件 I2C | `i2c_id`(Air780EPM 用 1,Pin66=SDA、Pin67=SCL) | 占用 CPU 少,实时性要求高 |
|
||||
| 3 | SPI | `spi_id`/`cs`/`speed`(Air780EPM 用 SPI0) | 高速采样场景 |
|
||||
|
||||
### 1.4 中断功能说明
|
||||
|
||||
BMI270 支持硬件中断输出(INT1/INT2 引脚),扩展库提供:
|
||||
- **data_ready 数据就绪中断**:开箱即用,每个采样周期触发一次,适合低功耗事件驱动
|
||||
- **特征中断**(any_motion 任意运动 / no_motion 无运动 / sig_motion 显著运动 / step 步进检测):开箱即用,`setup()`/`int_config()` 配置后自动使能并映射到 INT 引脚;支持阈值与持续时间参数调节(`any_motion_thresh_mg`/`any_motion_duration_ms`、`no_motion_thresh_mg`/`no_motion_duration_ms`、`sig_motion_block_ms`、`step_counter`、`step_watermark_steps`)
|
||||
|
||||
- **计步说明**:`step` 中断每检测到一步触发一次;`get_step_count()` 读取累计步数(32 位,0~4294967295),步数按 `step_watermark_steps` 的间隔刷新(默认每 20 步);`reset_step_count()` 可清零重新计步
|
||||
|
||||
中断使用示例见 `bmi270_app.lua` 的 `[5/6] 中断触发演示`,演示 data_ready + any_motion 的配置与触发;接线需将 BMI270 的 INT1 引脚接到一个空闲 GPIO(默认低有效,GPIO 用 FALLING 触发)。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_bmi270 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/6] 初始化和基本信息查询** - 初始化 BMI270 传感器,自动完成芯片 ID 校验(期望 0x24)与 8192 字节微程序加载,注册 INT1 中断,打印扩展库版本号
|
||||
2. **[2/6] 加速度/角速度/温度读取** - 读取三轴加速度(单位 g)、三轴角速度(单位 °/s)、芯片温度(单位 °C)
|
||||
3. **[3/6] 量程切换演示** - 动态切换加速度量程(±4g→±8g)和陀螺仪量程(±500→±1000 °/s),验证切换后数据自动换算
|
||||
4. **[4/6] 姿态解算** - 通过 Mahony 互补滤波输出 roll/pitch/yaw 姿态角,持续演示 5 秒
|
||||
5. **[5/6] 中断触发演示** - data_ready + any_motion 特征中断,topic 方式回调,持续 10 秒
|
||||
6. **[6/6] 休眠唤醒与资源释放** - 进入休眠、3 秒后唤醒验证数据,最后关闭传感器释放资源
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
|
||||
- BMI270 六轴惯性传感器模块 × 1
|
||||
demo所演示的BMI270 惯性传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=1041004170261&mi_id=00004EzeZNi57_QjBNIlFbQ5VJZffnITA6qTwK2xBTP-baw&ns=1&skuId=6062545293708&spm=a21n57.1.hoverItem.2&utparam=%7B%22aplus_abtest%22%3A%227b34fb2d453729db70345acf83f5f9e2%22%7D&xxc=taobaoSearch)
|
||||
|
||||
- 母对母杜邦线 × 4
|
||||
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 BMI270 模块接线(软件 I2C,MODE=1,默认推荐)
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>BMI270 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>GPIO31(PIN32)<br/></td><td>SCL<br/></td></tr>
|
||||
<tr>
|
||||
<td>GPIO30(PIN31)<br/></td><td>SDA<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
<tr>
|
||||
<td>GPIO32(PIN33)<br/></td><td>INT1(中断输出,可选)<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。BMI270 模块需 3.3V 供电,SCL/SDA 需上拉电阻(常见模块已内置)。SDO 引脚接 GND 时 I2C 地址为 0x68,接 VCC 时为 0x69,如读取不到数据可切换试试。
|
||||

|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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 脚本文件
|
||||
|
||||
- **main.lua** - 程序入口
|
||||
- **bmi270_app.lua** - 演示模块
|
||||
- **exs_bmi270** - 扩展库(含 8192 字节微程序)
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 BMI270 模块连接到核心板(选择 MODE 对应的接线)
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 首次上电请将设备水平静止放置,便于观察加速度数据
|
||||
4. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
1. 打开 `bmi270_app.lua`,根据实际接线设置 **MODE 变量**(1=软件I2C / 2=硬件I2C / 3=SPI)
|
||||
2. 确认 INT1_GPIO 与你的中断接线一致
|
||||
3. `main.lua` 保持 `require "bmi270_app"` 即可
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件(含 exs_bmi270 扩展库)
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化和基本信息查询演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/6] 初始化
|
||||
2. 观察日志输出,确认初始化成功、芯片 ID 校验通过、中断注册
|
||||
3. 初始化失败时检查接线:VCC=3.3V、GND、SCL、SDA
|
||||
|
||||
#### 5.4.2 数据读取演示
|
||||
|
||||
1. 自动进入 [2/6] 数据读取
|
||||
2. 观察三轴加速度(单位 g)、角速度(单位 °/s)、温度(单位 °C)输出
|
||||
3. 静止水平放置时,加速度 Z 轴应接近 1.0g,X/Y 接近 0;角速度三轴接近 0
|
||||
|
||||
#### 5.4.3 量程切换演示
|
||||
|
||||
1. 自动进入 [3/6] 量程切换
|
||||
2. 观察加速度量程从 ±4g 切换为 ±8g、陀螺仪量程从 ±500°/s 切换为 ±1000°/s
|
||||
3. 切换后数据自动按新量程换算
|
||||
|
||||
> 说明:
|
||||
> 扩展库的量程切换会自动执行软复位 + 完整重新初始化(约 150ms),
|
||||
> 日志中会再次出现"微程序已分块写入",属正常现象。
|
||||
|
||||
#### 5.4.4 姿态解算演示
|
||||
|
||||
1. 自动进入 [4/6] 姿态解算
|
||||
2. 演示会先自动执行陀螺零偏标定(约 50 次采样,需保持设备静止)
|
||||
3. 标定完成后,观察 roll/pitch 反映设备当前真实静态姿态(水平放置约 0°,竖直/倾斜安装则显示对应角度)
|
||||
4. 缓慢转动设备,观察三个姿态角实时跟踪变化
|
||||
5. yaw 角连续叠加无 ±180° 跳变;无磁力计会随时间缓慢漂移
|
||||
|
||||
#### 5.4.5 中断触发演示
|
||||
|
||||
1. 自动进入 [5/6] 中断触发演示(持续 10 秒)
|
||||
2. 晃动设备 → 触发 `any_motion` 事件;静置 → `data_ready` 周期性触发
|
||||
3. 观察日志打印触发事件名和三轴数据
|
||||
4. 若无中断触发,检查 INT1 接线与 INT1_GPIO 配置
|
||||
|
||||
#### 5.4.6 休眠唤醒演示
|
||||
|
||||
1. 自动进入 [6/6] 休眠唤醒
|
||||
2. 观察 "已进入休眠" 日志,3 秒后自动唤醒
|
||||
3. 唤醒后数据恢复读取,最后打印 "传感器已关闭"
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化**:BMI270 初始化成功,微程序加载完成,打印扩展库版本号
|
||||
- **数据读取**:静止水平时 Z 轴加速度接近 1.0g,角速度接近 0,温度 30~45°C
|
||||
- **量程切换**:量程切换成功(自动软复位重初始化),切换后数据正常输出
|
||||
- **姿态解算**:先零偏标定,后姿态角平滑跟踪,Mahony 互补滤波有效抑制噪声
|
||||
- **中断触发**:晃动触发 any_motion,静置时 data_ready 周期性触发,事件名打印正常
|
||||
- **休眠唤醒**:休眠日志正常,唤醒后数据恢复
|
||||
- **日志如下:**
|
||||
|
||||
```lua
|
||||
[2026-08-05 12:15:08.669][000000000.200] I/user.main BMI270_Demo 001.000.000
|
||||
[2026-08-05 12:15:08.728][000000000.522] I/user.TEST === [1/6] 初始化 ===
|
||||
[2026-08-05 12:15:08.790][000000000.525] I/user.exs_bmi270 BMI270 @ I2C 模式,芯片 ID=0x24
|
||||
[2026-08-05 12:15:10.464][000000002.784] I/user.exs_bmi270 微程序已分块写入(8192 字节,每块 128)
|
||||
[2026-08-05 12:15:10.635][000000002.953] I/user.exs_bmi270 init verify: PWR_CTRL=0x0E STATUS=0xD0 ACC_RANGE=0x01 GYR_RANGE=0x02
|
||||
[2026-08-05 12:15:10.654][000000002.957] I/user.exs_bmi270 初始化完成:acc_range=4g gyro_range=500 acc_odr=200Hz gyro_odr=200Hz
|
||||
[2026-08-05 12:15:10.673][000000002.967] I/user.exs_bmi270 any_motion 特征已使能(含自定义阈值)
|
||||
[2026-08-05 12:15:10.689][000000002.974] I/user.exs_bmi270 INT1 已注册, int_gpio=32
|
||||
[2026-08-05 12:15:10.706][000000002.975] I/user.TEST 初始化成功,扩展库版本: 202608051200
|
||||
[2026-08-05 12:15:10.727][000000002.975] I/user.TEST === [2/6] 数据读取 (单位 g / °/s / °C) ===
|
||||
[2026-08-05 12:15:10.743][000000002.981] I/user.exs_bmi270 ACC_RAW: 01 F1 BB 00 64 F3
|
||||
[2026-08-05 12:15:10.761][000000002.981] I/user.exs_bmi270 GYR_RAW: 00 1E 03 18 C2 FE
|
||||
[2026-08-05 12:15:10.778][000000002.982] I/user.exs_bmi270 TMP_RAW: 97 0C
|
||||
[2026-08-05 12:15:10.795][000000002.993] I/user.TEST accel x=-0.469 y=0.023 z=-0.394
|
||||
[2026-08-05 12:15:10.811][000000002.994] I/user.TEST gyro x=126.0 y=81.2 z=-11.3
|
||||
[2026-08-05 12:15:10.829][000000002.994] I/user.TEST temp 29.3°C
|
||||
[2026-08-05 12:15:11.178][000000003.495] I/user.TEST === [3/6] 量程切换演示 ===
|
||||
[2026-08-05 12:15:13.439][000000005.755] I/user.exs_bmi270 微程序已分块写入(8192 字节,每块 128)
|
||||
[2026-08-05 12:15:13.662][000000005.946] I/user.TEST 加速度量程已切换为 ±8g
|
||||
[2026-08-05 12:15:16.114][000000008.403] I/user.TEST 陀螺仪量程已切换为 ±1000°/s
|
||||
[2026-08-05 12:15:16.596][000000008.909] I/user.TEST === [4/6] 姿态解算 (5秒) ===
|
||||
[2026-08-05 12:15:16.845][000000009.165] I/user.exs_bmi270 陀螺零偏标定完成: (1.976, -7.871, -10.207)°/s
|
||||
[2026-08-05 12:15:16.877][000000009.172] I/user.TEST roll=168.6° pitch=41.8° yaw=150.8°
|
||||
[2026-08-05 12:15:16.892][000000009.198] I/user.TEST roll=168.9° pitch=41.7° yaw=150.9°
|
||||
[2026-08-05 12:15:16.908][000000009.224] I/user.TEST roll=169.2° pitch=41.5° yaw=151.0°
|
||||
(姿态角每 20ms 打印一次,此处省略中间大量日志)
|
||||
[2026-08-05 12:15:21.690][000000014.011] I/user.TEST 姿态解算演示结束
|
||||
[2026-08-05 12:15:22.201][000000014.511] I/user.TEST === [5/6] 中断触发演示 (10秒) ===
|
||||
[2026-08-05 12:15:22.435][000000014.754] I/user.TEST 中断事件: any_motion
|
||||
[2026-08-05 12:15:22.453][000000014.759] I/user.TEST acc(-0.17,-0.03,1.02)g gyr(-89.8,70.2,-5.8)°/s
|
||||
[2026-08-05 12:15:33.119][000000025.408] I/user.TEST 中断触发演示结束
|
||||
[2026-08-05 12:15:33.135][000000025.408] I/user.TEST === [6/6] 休眠唤醒演示 ===
|
||||
[2026-08-05 12:15:33.156][000000025.409] I/user.exs_bmi270 已进入休眠模式
|
||||
[2026-08-05 12:15:36.139][000000028.432] I/user.TEST 已唤醒,读取一次数据验证
|
||||
[2026-08-05 12:15:36.157][000000028.437] I/user.TEST accel x=-0.678 y=0.011 z=-0.725
|
||||
[2026-08-05 12:15:36.174][000000028.439] I/user.exs_bmi270 传感器已关闭
|
||||
[2026-08-05 12:15:36.213][000000028.439] I/user.TEST ========== 所有演示完成 ==========
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
| 现象 | 可能原因 | 解决方法 |
|
||||
| ---- | ---- | ---- |
|
||||
| 初始化失败,日志提示芯片识别失败 | 接线错误或供电不足 | 检查 VCC/GND/SCL/SDA 接线,确保 3.3V 供电 |
|
||||
| 初始化失败,日志提示配置加载失败 | 传感器损坏 | 更换传感器模块 |
|
||||
| 读取不到数据 | 接线错误或地址探测无命中 | 扩展库已自动探测 0x68/0x69(SDO 决定),仍失败检查 SDO 接线、供电与总线冲突 |
|
||||
| 加速度 Z 轴偏差大 | 传感器未水平放置 | 水平静止放置后重新观察;竖直/倾斜安装属正常 |
|
||||
| 数据不稳定 | 杜邦线过长/干扰 | 缩短杜邦线,降低 SPI 速率或改软件 I2C |
|
||||
| 中断不触发 | INT1 接线错误或 INT1_GPIO 配置不对 | 检查 INT1 引脚接线,确认 bmi270_app.lua 中 INT1_GPIO 与实际一致 |
|
||||
| SPI 模式芯片 ID 读回 0xFF | ① SDO/MISO 未接 ② 上电时 CSB 非低电平 ③ 模块 I2C 地址电阻钳住 SDO ④ SPI 引脚复用被占用 | ① 检查 4 根信号线 ② 确认 CS 上电为低 ③ 移除/确认 SDO 电阻 ④ 通过 LuatIO 检查 SPI0 复用是否被其他外设占用 |
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
1. **多圈偏航累计**:get_attitude() 的 yaw 角为连续叠加值,可用于旋转圈数计数场景
|
||||
2. **跌倒检测**:将加速度量程设为 "16g" 并监测合加速度阈值,可识别剧烈冲击
|
||||
3. **SPI 高速采样**:对采样率要求高的场景可改用 SPI 模式(MODE=3,接线见 3.2.3,速率最高 1MHz 以上)
|
||||
4. **低功耗应用**:间歇采样场景可读取一次后调用 sleep(),需要时再 wakeup() 降低功耗
|
||||
5. **零偏标定**:产品首次上电静止 1~2 秒调用 calibrate_gyro(),可显著降低静止姿态漂移
|
||||
6. **计步功能**:配置 `step = true` + `step_counter = true` + `step_watermark_steps`,配合 `get_step_count()`/`reset_step_count()` 实现计步器
|
||||
7. exs_bmi270 更多接口的使用可以查看 [exs_bmi270 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_bmi270/)
|
||||
@@ -0,0 +1,111 @@
|
||||
--[[
|
||||
@module bmp180_demo
|
||||
@summary BMP180 数字气压传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.23
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 BMP180 的逐项功能演示。
|
||||
通过 exs_bmp180 扩展库的 API 逐一演示数据读取、过采样率切换、海拔高度计算、关闭传感器等功能。
|
||||
]]
|
||||
|
||||
local exs_bmp180 = require "exs_bmp180"
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("bmp180_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_bmp180.setup({
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
})
|
||||
|
||||
if not result then
|
||||
log.error("bmp180_demo", "BMP180 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
log.info("bmp180_demo", "BMP180 初始化成功,版本:", exs_bmp180.version())
|
||||
|
||||
-- 等待传感器稳定,数据手册推荐值
|
||||
sys.wait(200)
|
||||
local data = exs_bmp180.get_data()
|
||||
if data then
|
||||
log.info("bmp180_demo", string.format("温度=%.1f°C 气压=%.2fhPa", data.temperature, data.pressure / 100))
|
||||
else
|
||||
log.error("bmp180_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(1000) -- 稳定后等待 1 秒进入连续读取
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(2000) -- 每次读取间隔 2 秒
|
||||
local d = exs_bmp180.get_data()
|
||||
if d then
|
||||
log.info("bmp180_demo", string.format("第%d次读取: 温度=%.1f°C 气压=%.1fPa", i, d.temperature, d.pressure))
|
||||
end
|
||||
end
|
||||
log.info("bmp180_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] 过采样率切换演示
|
||||
local function demo_oss_switch()
|
||||
log.info("bmp180_demo", "===== [2/4] 过采样率切换演示 =====")
|
||||
|
||||
local oss_list = { 0, 1, 2, 3 }
|
||||
for _, oss in ipairs(oss_list) do
|
||||
log.info("bmp180_demo", string.format("设置过采样率为 oss=%d", oss))
|
||||
exs_bmp180.set_oss(oss)
|
||||
sys.wait(100) -- 等待 OSS 切换生效
|
||||
|
||||
local data = exs_bmp180.get_data()
|
||||
if data then
|
||||
log.info("bmp180_demo", string.format("oss=%d: 温度=%.1f°C 气压=%.2fhPa", oss, data.temperature, data.pressure / 100))
|
||||
end
|
||||
sys.wait(1000) -- 每档 OSS 显示间隔 1 秒
|
||||
end
|
||||
log.info("bmp180_demo", "---- [2/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/4] 海拔高度测量
|
||||
local function demo_altitude()
|
||||
log.info("bmp180_demo", "===== [3/4] 海拔高度测量 =====")
|
||||
|
||||
local data = exs_bmp180.get_data()
|
||||
if data then
|
||||
local alt = exs_bmp180.get_altitude(data.pressure)
|
||||
log.info("bmp180_demo", string.format("温度=%.1f°C 气压=%.1fPa 海拔=%.1f米", data.temperature, data.pressure, alt))
|
||||
end
|
||||
log.info("bmp180_demo", "---- [3/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/4] 关闭传感器
|
||||
local function demo_close()
|
||||
log.info("bmp180_demo", "===== [4/4] 演示完毕 =====")
|
||||
log.info("bmp180_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function bmp180_demo_task_func()
|
||||
log.info("bmp180_demo", "HELLO")
|
||||
sys.wait(1000) -- 启动后等待 1 秒再开始演示
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("bmp180_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_oss_switch()
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_altitude()
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_close()
|
||||
sys.wait(500) -- 关闭后等待 500ms 再结束
|
||||
|
||||
log.info("bmp180_demo", "===== [演示完毕] =====")
|
||||
log.info("bmp180_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(bmp180_demo_task_func)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary BMP180 数字气压传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.23
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_bmp180 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化和数据读取([1/4])
|
||||
2、过采样率切换演示([2/4])
|
||||
3、海拔高度测量([3/4])
|
||||
4、关闭传感器([4/4])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "BMP180_Demo" -- 项目命名
|
||||
VERSION = "001.000.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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 bmp180_demo.lua 演示模块
|
||||
require "bmp180_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,194 @@
|
||||
# BMP180 数字气压传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **bmp180_demo.lua** - BMP180 功能演示模块,包含数据读取、过采样率切换、海拔高度计算等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_bmp180** - BMP180 扩展库,提供初始化、气压/温度读取、过采样率切换、海拔高度计算、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:BMP180 使用标准 I2C 接口通信,软件 I2C 模式无需指定 I2C 控制器,任意 GPIO 均可模拟 I2C 时序,灵活性更高。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_bmp180 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 BMP180 传感器并读取温度(°C)和气压(Pa/hPa)数据
|
||||
2. **[2/4] 过采样率切换演示** - 依次切换 OSS=0/1/2/3,观察不同精度下的温度与气压数据
|
||||
3. **[3/4] 海拔高度测量** - 通过气压值计算当前海拔高度(米)
|
||||
4. **[4/4] 关闭传感器** - 演示正确的传感器关闭流程
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- BMP180 数字气压传感器模块 × 1
|
||||
demo所演示的BMP180 气压传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=944404504388&mi_id=0000ZuOrQ4eZ6pWb2BYc1iPpBMJ6TrMasd1C9m_mvfsV1tk&ns=1&priceTId=213e00d417839207947873080e1068&skuId=5844683444104&spm=a21n57.1.hoverItem.2&utparam=%7B%22aplus_abtest%22%3A%224cad96d9d94a499da42340cb4d160b98%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 BMP180 模块接线
|
||||
|
||||

|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>BMP180 模块<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>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:
|
||||
> 1. 接线时注意杜邦线不宜过长,以免通信不稳定
|
||||
> 2. SCL 和 SDA 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC(部分模块已自带)
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/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. **bmp180_demo.lua** - BMP180 功能演示模块
|
||||
3. **exs_bmp180** - BMP180 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 BMP180 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 bmp180_demo.lua 演示模块
|
||||
require "bmp180_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察温度(°C)和气压(Pa/hPa)的连续读取
|
||||
|
||||
#### 5.4.2 过采样率切换演示
|
||||
|
||||
1. 自动进入 [2/4] 过采样率切换演示
|
||||
2. 依次观察 OSS=0(最快)、OSS=1、OSS=2、OSS=3(最高精度)下的数据
|
||||
3. 注意 OSS 越高,数据跳动越小,但转换时间越长
|
||||
|
||||
#### 5.4.3 海拔高度测量
|
||||
|
||||
1. 自动进入 [3/4] 海拔高度测量
|
||||
2. 观察基于当前气压值和海平面标准气压(101325Pa)计算的海拔高度
|
||||
|
||||
#### 5.4.4 关闭传感器
|
||||
|
||||
1. 自动进入 [4/4] 关闭传感器
|
||||
2. 演示完毕后打印 "End"
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:BMP180 初始化成功,温度与气压数据正常输出
|
||||
- **过采样率切换**:不同 OSS 下精度不同,OSS 越高数据越稳定
|
||||
- **海拔高度测量**:根据气压计算出当前海拔高度
|
||||
- **关闭传感器**:传感器正常关闭
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-23 15:30:32.854][000000000.247] I/user.main BMP180_Demo 001.000.000
|
||||
[2026-07-23 15:30:32.868][000000000.259] D/user.exs_bmp180 version -> 202607220900
|
||||
[2026-07-23 15:30:32.882][000000000.260] I/user.bmp180_demo HELLO
|
||||
[2026-07-23 15:30:33.032][000000001.261] I/user.bmp180_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-07-23 15:30:33.042][000000001.269] I/user.exs_bmp180 BMP180 @ I2C 0x77, CHIP_ID=0x55
|
||||
[2026-07-23 15:30:33.055][000000001.286] I/user.exs_bmp180 校准数据: AC1=6464 AC2=-1308 AC3=-14829 AC4=33096 AC5=24574 AC6=21778
|
||||
[2026-07-23 15:30:33.069][000000001.286] I/user.exs_bmp180 初始化完成, oss=0
|
||||
[2026-07-23 15:30:33.081][000000001.286] I/user.bmp180_demo BMP180 初始化成功,版本: 202607220900
|
||||
[2026-07-23 15:30:33.092][000000001.502] I/user.bmp180_demo 温度=24.1°C 气压=1004.56hPa
|
||||
[2026-07-23 15:30:35.560][000000004.517] I/user.bmp180_demo 第1次读取: 温度=24.1°C 气压=100450.0Pa
|
||||
[2026-07-23 15:30:37.582][000000006.533] I/user.bmp180_demo 第2次读取: 温度=24.1°C 气压=100450.0Pa
|
||||
[2026-07-23 15:30:39.588][000000008.548] I/user.bmp180_demo 第3次读取: 温度=24.1°C 气压=100453.0Pa
|
||||
[2026-07-23 15:30:39.605][000000008.548] I/user.bmp180_demo ---- [1/4] 完成 ----
|
||||
[2026-07-23 15:30:40.099][000000009.049] I/user.bmp180_demo ===== [2/4] 过采样率切换演示 =====
|
||||
[2026-07-23 15:30:40.121][000000009.049] I/user.bmp180_demo 设置过采样率为 oss=0
|
||||
[2026-07-23 15:30:40.136][000000009.050] I/user.exs_bmp180 过采样率切换为 oss=0
|
||||
[2026-07-23 15:30:40.208][000000009.165] I/user.bmp180_demo oss=0: 温度=24.1°C 气压=1004.59hPa
|
||||
[2026-07-23 15:30:41.203][000000010.165] I/user.bmp180_demo 设置过采样率为 oss=1
|
||||
[2026-07-23 15:30:41.216][000000010.165] I/user.exs_bmp180 过采样率切换为 oss=1
|
||||
[2026-07-23 15:30:41.328][000000010.284] I/user.bmp180_demo oss=1: 温度=24.1°C 气压=1004.57hPa
|
||||
[2026-07-23 15:30:42.320][000000011.284] I/user.bmp180_demo 设置过采样率为 oss=2
|
||||
[2026-07-23 15:30:42.336][000000011.284] I/user.exs_bmp180 过采样率切换为 oss=2
|
||||
[2026-07-23 15:30:42.444][000000011.409] I/user.bmp180_demo oss=2: 温度=24.1°C 气压=1004.56hPa
|
||||
[2026-07-23 15:30:43.456][000000012.409] I/user.bmp180_demo 设置过采样率为 oss=3
|
||||
[2026-07-23 15:30:43.469][000000012.409] I/user.exs_bmp180 过采样率切换为 oss=3
|
||||
[2026-07-23 15:30:43.595][000000012.546] I/user.bmp180_demo oss=3: 温度=24.1°C 气压=1004.60hPa
|
||||
[2026-07-23 15:30:44.589][000000013.546] I/user.bmp180_demo ---- [2/4] 完成 ----
|
||||
[2026-07-23 15:30:45.086][000000014.046] I/user.bmp180_demo ===== [3/4] 海拔高度测量 =====
|
||||
[2026-07-23 15:30:45.118][000000014.082] I/user.bmp180_demo 温度=24.1°C 气压=100457.0Pa 海拔=72.5米
|
||||
[2026-07-23 15:30:45.135][000000014.082] I/user.bmp180_demo ---- [3/4] 完成 ----
|
||||
[2026-07-23 15:30:45.631][000000014.583] I/user.bmp180_demo ===== [4/4] 演示完毕 =====
|
||||
[2026-07-23 15:30:45.646][000000014.583] I/user.bmp180_demo ---- [4/4] 完成 ----
|
||||
[2026-07-23 15:30:46.126][000000015.083] I/user.bmp180_demo ===== [演示完毕] =====
|
||||
[2026-07-23 15:30:46.139][000000015.083] I/user.bmp180_demo End
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 BMP180 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 SCL/SDA 上拉电阻是否连接
|
||||
- 确认 exs_bmp180 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零或异常**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(BMP180 固定地址 0x77)
|
||||
- 确认接线无松动
|
||||
- 检查 SCL/SDA 上拉电阻
|
||||
|
||||
3. **海拔高度显示异常**:
|
||||
|
||||
- 海拔计算基于海平面标准气压 101325Pa,天气变化会影响计算精度
|
||||
- 可通过 `get_altitude(pressure, sea_level_pressure)` 传入实际海平面气压校正
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_bmp180 更多接口的使用可以查看 [exs_bmp180 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_bmp180/)
|
||||
@@ -0,0 +1,121 @@
|
||||
--[[
|
||||
@module bmp280_demo
|
||||
@summary BMP280 数字气压传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.24
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 BMP280 的逐项功能演示。
|
||||
通过 exs_bmx280 扩展库的 API 逐一演示数据读取、IIR 滤波切换、海拔计算等功能。
|
||||
|
||||
Air780EPM 接线(软件 I2C):
|
||||
SCL = GPIO31
|
||||
SDA = GPIO30
|
||||
]]
|
||||
|
||||
local exs_bmx280 = require "exs_bmx280"
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("bmp280_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
-- BMP280 使用软件 I2C 模式初始化,开启 IIR 滤波
|
||||
-- 注意:BMP180 返回气压单位为 Pa,BMP280 返回气压单位为 hPa,使用时不需换算
|
||||
local result = exs_bmx280.setup("I2C", {
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
filter = 4, -- 16 次采样平均,数据更平滑
|
||||
})
|
||||
|
||||
if not result then
|
||||
log.error("bmp280_demo", "BMP280 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
log.info("bmp280_demo", "BMP280 初始化成功,版本:", exs_bmx280.version())
|
||||
|
||||
-- 等待传感器稳定,数据手册推荐 200ms
|
||||
sys.wait(200)
|
||||
local data = exs_bmx280.get_data()
|
||||
if data then
|
||||
log.info("bmp280_demo", string.format("温度=%.2f°C 气压=%.2fhPa", data.temperature, data.pressure))
|
||||
else
|
||||
log.error("bmp280_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(1000) -- 稳定后等待 1 秒进入连续读取
|
||||
|
||||
-- 连续读取 3 次,观察数据变化
|
||||
for i = 1, 3 do
|
||||
sys.wait(2000) -- 每次读取间隔 2 秒
|
||||
local d = exs_bmx280.get_data()
|
||||
if d then
|
||||
log.info("bmp280_demo", string.format("第%d次读取: 温度=%.2f°C 气压=%.1fhPa", i, d.temperature, d.pressure))
|
||||
end
|
||||
end
|
||||
log.info("bmp280_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] IIR 滤波器切换演示
|
||||
local function demo_filter_switch()
|
||||
log.info("bmp280_demo", "===== [2/4] IIR 滤波器切换演示 =====")
|
||||
|
||||
-- 依次切换 filter=0/1/2/3/4,观察数据变化
|
||||
local filter_list = { 0, 1, 2, 3, 4 }
|
||||
for _, f in ipairs(filter_list) do
|
||||
log.info("bmp280_demo", string.format("设置滤波器 filter=%d", f))
|
||||
exs_bmx280.set_filter(f)
|
||||
sys.wait(100) -- 等待滤波器生效
|
||||
|
||||
local data = exs_bmx280.get_data()
|
||||
if data then
|
||||
log.info("bmp280_demo", string.format("filter=%d: 温度=%.2f°C 气压=%.2fhPa", f, data.temperature, data.pressure))
|
||||
end
|
||||
sys.wait(1000) -- 每档滤波器显示间隔 1 秒
|
||||
end
|
||||
log.info("bmp280_demo", "---- [2/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/4] 海拔高度测量
|
||||
local function demo_altitude()
|
||||
log.info("bmp280_demo", "===== [3/4] 海拔高度测量 =====")
|
||||
|
||||
local data = exs_bmx280.get_data()
|
||||
if data then
|
||||
local alt = exs_bmx280.get_altitude(data.pressure)
|
||||
log.info("bmp280_demo", string.format("温度=%.2f°C 气压=%.1fhPa 海拔=%.1f米", data.temperature, data.pressure, alt))
|
||||
end
|
||||
log.info("bmp280_demo", "---- [3/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/4] 关闭传感器
|
||||
local function demo_close()
|
||||
log.info("bmp280_demo", "===== [4/4] 关闭传感器 =====")
|
||||
exs_bmx280.close()
|
||||
log.info("bmp280_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function bmp280_demo_task_func()
|
||||
log.info("bmp280_demo", "HELLO")
|
||||
sys.wait(1000) -- 启动后等待 1 秒再开始演示
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("bmp280_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_filter_switch()
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_altitude()
|
||||
sys.wait(500) -- 每项演示间隔 500ms
|
||||
|
||||
demo_close()
|
||||
sys.wait(500) -- 关闭后等待 500ms 再结束
|
||||
|
||||
log.info("bmp280_demo", "===== [演示完毕] =====")
|
||||
log.info("bmp280_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(bmp280_demo_task_func)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary BMP280 数字气压传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.24
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_bmx280 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化和数据读取([1/4])
|
||||
2、IIR 滤波器切换演示([2/4])
|
||||
3、海拔高度测量([3/4])
|
||||
4、关闭传感器([4/4])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "BMP280_Demo" -- 项目命名
|
||||
VERSION = "001.000.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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 bmx280_demo.lua 演示模块
|
||||
require "bmx280_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,208 @@
|
||||
# BMP280 数字气压传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口
|
||||
2. **bmp280_demo.lua** - BMP280 功能演示模块
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_bmx280** - BMP280/BME280 扩展库,提供初始化、气压/温度/湿度读取、IIR 滤波配置、海拔高度计算等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:BMP280 使用标准 I2C 接口通信,软件 I2C 模式无需指定 I2C 控制器,任意 GPIO 均可模拟 I2C 时序,灵活性更高。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_bmx280 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 BMP280 传感器并读取温度(°C)和气压(hPa)数据
|
||||
2. **[2/4] IIR 滤波器切换演示** - 依次切换 filter=0/1/2/3/4,观察数据平滑效果
|
||||
3. **[3/4] 海拔高度测量** - 通过气压值计算当前海拔高度(米)
|
||||
4. **[4/4] 关闭传感器** - 关闭传感器,结束演示
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- BMP280 数字气压传感器模块 × 1
|
||||
demo所演示的BMP280 气压传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=536588151627&mi_id=0000rIYIyPLv_DpmZ6ZcJUWP9s0vMMalxqy2nPnWDpHQZ48&ns=1&spm=a21n57.1.hoverItem.3&utparam=%7B%22aplus_abtest%22%3A%2296002c296ee298a12225edacf84fa11b%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 BMP280 模块接线
|
||||
|
||||

|
||||
|
||||
| Air780EPM 核心板 | BMP280 模块 |
|
||||
|-----------------|------------|
|
||||
| 32/GPIO31 | SCL |
|
||||
| 31/GPIO30 | SDA |
|
||||
| VDD_EXT | VCC |
|
||||
| GND | GND |
|
||||
|
||||
> 说明:
|
||||
> 1. 接线时注意杜邦线不宜过长,以免通信不稳定
|
||||
> 2. SCL 和 SDA 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC(部分模块已自带)
|
||||
> 3. BMP280 的 I2C 地址:SDO=GND 时 0x76,SDO=VCC 时 0x77
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/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. **bmp280_demo.lua** - BMP280 功能演示模块
|
||||
3. **exs_bmx280** - BMP280/BME280 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 BMP280 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
require "bmp280_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察温度(°C)和气压(hPa)的连续读取
|
||||
|
||||
#### 5.4.2 IIR 滤波器切换演示
|
||||
|
||||
1. 自动进入 [2/4] IIR 滤波器切换演示
|
||||
2. 依次观察 filter=0(关闭)~ filter=4(16 次平均)下的数据
|
||||
3. filter 越大数据跳动越小
|
||||
|
||||
#### 5.4.3 海拔高度测量
|
||||
|
||||
1. 自动进入 [3/4] 海拔高度测量
|
||||
2. 观察基于当前气压值和海平面标准气压(101325Pa)计算的海拔高度
|
||||
|
||||
#### 5.4.4 关闭传感器
|
||||
|
||||
1. 自动进入 [4/4] 关闭传感器
|
||||
2. 演示完毕后打印 "End"
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:BMP280 初始化成功,温度与气压数据正常输出
|
||||
- **IIR 滤波器切换**:不同滤波器下数据平滑度不同
|
||||
- **海拔高度测量**:根据气压计算出当前海拔高度
|
||||
- **关闭传感器**:传感器正常关闭
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-24 19:59:39.006][000000000.213] D/user.exs_bmx280 version -> 202607240000
|
||||
[2026-07-24 19:59:39.028][000000000.214] I/user.bmp280_demo HELLO
|
||||
[2026-07-24 19:59:39.586][000000001.214] I/user.bmp280_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-07-24 19:59:39.605][000000001.224] I/user.exs_bmx280 BMP280 @ I2C 0x76
|
||||
[2026-07-24 19:59:39.613][000000001.262] I/user.exs_bmx280 校准数据: T1=27251 T2=25882 T3=50 P1=39170 P2=-10689
|
||||
[2026-07-24 19:59:39.622][000000001.264] I/user.exs_bmx280 BMP280 初始化完成, filter=4
|
||||
[2026-07-24 19:59:39.630][000000001.265] I/user.bmp280_demo BMP280 初始化成功,版本: 202607240000
|
||||
[2026-07-24 19:59:39.640][000000001.469] I/user.bmp280_demo 温度=25.55°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:42.440][000000004.473] I/user.bmp280_demo 第1次读取: 温度=26.02°C 气压=1008.0hPa
|
||||
[2026-07-24 19:59:43.789][000000005.748] I/mobile sim0 sms ready
|
||||
[2026-07-24 19:59:43.809][000000005.749] D/mobile cid1, state0
|
||||
[2026-07-24 19:59:43.822][000000005.749] D/mobile bearer act 0, result 0
|
||||
[2026-07-24 19:59:43.837][000000005.750] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-24 19:59:43.852][000000005.786] D/mobile TIME_SYNC 0 tm 1784894382
|
||||
[2026-07-24 19:59:44.448][000000006.477] I/user.bmp280_demo 第2次读取: 温度=26.06°C 气压=1008.0hPa
|
||||
[2026-07-24 19:59:46.450][000000008.481] I/user.bmp280_demo 第3次读取: 温度=26.08°C 气压=1008.0hPa
|
||||
[2026-07-24 19:59:46.476][000000008.481] I/user.bmp280_demo ---- [1/4] 完成 ----
|
||||
[2026-07-24 19:59:46.949][000000008.982] I/user.bmp280_demo ===== [2/4] IIR 滤波器切换演示 =====
|
||||
[2026-07-24 19:59:46.967][000000008.983] I/user.bmp280_demo 设置滤波器 filter=0
|
||||
[2026-07-24 19:59:46.983][000000008.986] I/user.exs_bmx280 IIR 滤波器系数设为 0
|
||||
[2026-07-24 19:59:47.059][000000009.090] I/user.bmp280_demo filter=0: 温度=26.09°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:48.071][000000010.090] I/user.bmp280_demo 设置滤波器 filter=1
|
||||
[2026-07-24 19:59:48.091][000000010.093] I/user.exs_bmx280 IIR 滤波器系数设为 1
|
||||
[2026-07-24 19:59:48.164][000000010.197] I/user.bmp280_demo filter=1: 温度=26.10°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:49.175][000000011.197] I/user.bmp280_demo 设置滤波器 filter=2
|
||||
[2026-07-24 19:59:49.196][000000011.200] I/user.exs_bmx280 IIR 滤波器系数设为 2
|
||||
[2026-07-24 19:59:49.284][000000011.305] I/user.bmp280_demo filter=2: 温度=26.11°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:50.281][000000012.305] I/user.bmp280_demo 设置滤波器 filter=3
|
||||
[2026-07-24 19:59:50.301][000000012.308] I/user.exs_bmx280 IIR 滤波器系数设为 3
|
||||
[2026-07-24 19:59:50.390][000000012.412] I/user.bmp280_demo filter=3: 温度=26.12°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:51.387][000000013.412] I/user.bmp280_demo 设置滤波器 filter=4
|
||||
[2026-07-24 19:59:51.409][000000013.415] I/user.exs_bmx280 IIR 滤波器系数设为 4
|
||||
[2026-07-24 19:59:51.497][000000013.520] I/user.bmp280_demo filter=4: 温度=26.13°C 气压=1008.00hPa
|
||||
[2026-07-24 19:59:52.493][000000014.520] I/user.bmp280_demo ---- [2/4] 完成 ----
|
||||
[2026-07-24 19:59:52.992][000000015.020] I/user.bmp280_demo ===== [3/4] 海拔高度测量 =====
|
||||
[2026-07-24 19:59:53.011][000000015.024] I/user.bmp280_demo 温度=26.14°C 气压=1008.0hPa 海拔=43.8米
|
||||
[2026-07-24 19:59:53.025][000000015.025] I/user.bmp280_demo ---- [3/4] 完成 ----
|
||||
[2026-07-24 19:59:53.492][000000015.525] I/user.bmp280_demo ===== [4/4] 关闭传感器 =====
|
||||
[2026-07-24 19:59:53.511][000000015.527] I/user.exs_bmx280 传感器已关闭
|
||||
[2026-07-24 19:59:53.528][000000015.527] I/user.bmp280_demo ---- [4/4] 完成 ----
|
||||
[2026-07-24 19:59:54.003][000000016.027] I/user.bmp280_demo ===== [演示完毕] =====
|
||||
[2026-07-24 19:59:54.025][000000016.027] I/user.bmp280_demo End
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 BMP280 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 SCL/SDA 上拉电阻是否连接
|
||||
- 确认 exs_bmx280 扩展库已正常加载
|
||||
|
||||
2. **读取数据异常**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 自动地址检测会尝试 0x76 和 0x77,确认 SDO 引脚电平
|
||||
- 检查接线无松动
|
||||
|
||||
3. **海拔高度显示异常**:
|
||||
|
||||
- 海拔计算基于海平面标准气压 101325Pa,天气变化会影响计算精度
|
||||
- 可通过 `exs_bmx280.set_sea_level_pressure(pressure)` 传入实际海平面气压校正
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_bmx280 更多接口的使用可以查看 [exs_bmx280 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_bmx280/)
|
||||
|
||||
## 六、BMP180 与 BMP280 对比
|
||||
|
||||
| 特性 | BMP180 | BMP280 |
|
||||
|------|--------|--------|
|
||||
| 扩展库 | exs_bmp180 | exs_bmx280 |
|
||||
| 初始化方式 | `exs_bmp180.setup({scl, sda})` | `exs_bmx280.setup("I2C", {scl, sda, ...})` |
|
||||
| 气压单位 | Pa(帕斯卡) | hPa(百帕斯卡) |
|
||||
| 温度精度 | 0.1°C | 0.01°C |
|
||||
| IIR 滤波 | 不支持(过采样 OSS 方式) | 支持 filter=0~4 |
|
||||
| 工作电压 | 1.8V~3.6V | 1.71V~3.6V |
|
||||
| 气压范围 | 300~1100hPa | 300~1100hPa |
|
||||
| 湿度测量 | 不支持 | BME280 型号支持 |
|
||||
@@ -0,0 +1,152 @@
|
||||
--[[
|
||||
@module lis2dh12_demo
|
||||
@summary LIS2DH12 三轴加速度传感器演示模块,包含所有功能的演示用例
|
||||
@version 2.0
|
||||
@date 2026.07.17
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 LIS2DH12 的逐项功能演示。
|
||||
通过 exs_lis2dh12 扩展库的 API 逐一演示数据读取、量程切换、输出速率切换、温度读取、休眠唤醒等功能。
|
||||
]]
|
||||
|
||||
local exs_lis2dh12 = require "exs_lis2dh12"
|
||||
|
||||
local function lis2dh12_int1_cb(data)
|
||||
if data.dir then
|
||||
log.info("lis2dh12_demo", string.format("int1: 朝向=%s X=%.3f Y=%.3f Z=%.3f g", data.dir, data.x, data.y, data.z))
|
||||
else
|
||||
log.info("lis2dh12_demo", string.format("int1: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
end
|
||||
|
||||
-- [1/5] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("lis2dh12_demo", "===== [1/5] 初始化与数据读取 =====")
|
||||
local result = exs_lis2dh12.setup("I2C", {
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
powermode = "highres",
|
||||
enable_direction = "6d",
|
||||
int1 = { int_gpio = 29, tap = true, direction = true, cb = lis2dh12_int1_cb },
|
||||
})
|
||||
|
||||
if not result then
|
||||
log.error("lis2dh12_demo", "LIS2DH12 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
log.info("lis2dh12_demo", "LIS2DH12 初始化成功,版本:", exs_lis2dh12.version())
|
||||
exs_lis2dh12.dump_regs()
|
||||
|
||||
sys.wait(200)
|
||||
local data = exs_lis2dh12.get_data()
|
||||
if data then
|
||||
log.info("lis2dh12_demo", string.format("X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
else
|
||||
log.error("lis2dh12_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500)
|
||||
local d = exs_lis2dh12.get_data()
|
||||
if d then
|
||||
log.info("lis2dh12_demo", string.format("第%d次读取: X=%.3f Y=%.3f Z=%.3f g", i, d.x, d.y, d.z))
|
||||
end
|
||||
end
|
||||
log.info("lis2dh12_demo", "---- [1/5] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/5] 量程切换演示
|
||||
local function demo_range_switch()
|
||||
log.info("lis2dh12_demo", "===== [2/5] 量程切换演示 =====")
|
||||
log.info("lis2dh12_demo", "切换量程为 4g")
|
||||
exs_lis2dh12.set_range("4g")
|
||||
sys.wait(300)
|
||||
local data = exs_lis2dh12.get_data()
|
||||
if data then
|
||||
log.info("lis2dh12_demo", string.format("4g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("lis2dh12_demo", "切换量程为 2g(高精度)")
|
||||
exs_lis2dh12.set_range("2g")
|
||||
sys.wait(300)
|
||||
data = exs_lis2dh12.get_data()
|
||||
if data then
|
||||
log.info("lis2dh12_demo", string.format("2g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
log.info("lis2dh12_demo", "---- [2/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/5] 输出速率切换
|
||||
local function demo_odr_switch()
|
||||
log.info("lis2dh12_demo", "===== [3/5] 输出速率切换 =====")
|
||||
local odr_list = { 25, 50, 100, 200 }
|
||||
for _, odr in ipairs(odr_list) do
|
||||
log.info("lis2dh12_demo", string.format("设置输出速率为 %dHz", odr))
|
||||
exs_lis2dh12.set_odr(odr)
|
||||
sys.wait(500)
|
||||
local data = exs_lis2dh12.get_data()
|
||||
if data then
|
||||
log.info("lis2dh12_demo", string.format("%dHz 下: X=%.3f Y=%.3f Z=%.3f g", odr, data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
exs_lis2dh12.set_odr(100)
|
||||
log.info("lis2dh12_demo", "---- [3/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/5] 温度读取演示
|
||||
local function demo_temp_read()
|
||||
log.info("lis2dh12_demo", "===== [4/5] 温度读取演示 =====")
|
||||
log.info("lis2dh12_demo", "使能温度传感器")
|
||||
exs_lis2dh12.enable_temp(true)
|
||||
sys.wait(200)
|
||||
local temp = exs_lis2dh12.get_temp()
|
||||
if temp then
|
||||
log.info("lis2dh12_demo", string.format("芯片温度: %.1f °C", temp))
|
||||
else
|
||||
log.error("lis2dh12_demo", "读取温度失败")
|
||||
end
|
||||
exs_lis2dh12.enable_temp(false)
|
||||
log.info("lis2dh12_demo", "---- [4/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- [5/5] 休眠与唤醒演示
|
||||
local function demo_sleep_wakeup()
|
||||
log.info("lis2dh12_demo", "===== [5/5] 休眠与唤醒演示 =====")
|
||||
log.info("lis2dh12_demo", "进入 power-down 模式(低功耗)")
|
||||
exs_lis2dh12.sleep(); sys.wait(10000)
|
||||
sys.wait(500)
|
||||
log.info("lis2dh12_demo", "从 power-down 模式唤醒")
|
||||
exs_lis2dh12.wakeup()
|
||||
sys.wait(200)
|
||||
local data = exs_lis2dh12.get_data()
|
||||
if data then
|
||||
log.info("lis2dh12_demo", string.format("唤醒后数据: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
log.info("lis2dh12_demo", "---- [5/5] 完成 ----")
|
||||
end
|
||||
|
||||
local function lis2dh12_demo_task_func()
|
||||
log.info("lis2dh12_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then return end
|
||||
sys.wait(500)
|
||||
demo_range_switch()
|
||||
sys.wait(500)
|
||||
demo_odr_switch()
|
||||
sys.wait(500)
|
||||
demo_temp_read()
|
||||
sys.wait(500)
|
||||
demo_sleep_wakeup()
|
||||
sys.wait(500)
|
||||
log.info("lis2dh12_demo", "===== [演示完毕] =====")
|
||||
exs_lis2dh12.close()
|
||||
log.info("lis2dh12_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(lis2dh12_demo_task_func)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary LIS2DH12 三轴加速度传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.16
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_lis2dh12 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化和数据读取([1/4])
|
||||
2、量程切换演示([2/4])
|
||||
3、输出速率切换([3/4])
|
||||
4、温度读取演示([4/4])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "LIS2DH12_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 lis2dh12_demo.lua 演示模块
|
||||
require "lis2dh12_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,243 @@
|
||||
# LIS2DH12 三轴加速度传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **lis2dh12_demo.lua** - LIS2DH12 功能演示模块,包含数据读取、量程切换、输出速率切换、温度读取等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_lis2dh12** - LIS2DH12 扩展库,提供初始化、三轴加速度数据读取、量程切换、输出速率切换、功耗模式切换、温度读取、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:LIS2DH12 在异常 I2C 通信后可能锁死 SDA 总线。本库已内置 I2C 总线卡死自动检测与恢复功能。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_lis2dh12 扩展库的 5 项功能:HELLO → [1/5] → [2/5] → [3/5] → [4/5] → [5/5] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/5] 初始化与数据读取** - 初始化 LIS2DH12 传感器并读取三轴加速度数据(X/Y/Z,单位 g),附带 data_ready 中断示例
|
||||
2. **[2/5] 量程切换演示** - 在 ±2g(高精度)和 ±4g(宽范围)量程之间切换,观察数据变化
|
||||
3. **[3/5] 输出速率切换** - 依次切换 25Hz / 50Hz / 100Hz / 200Hz 输出速率
|
||||
4. **[4/5] 温度读取演示** - 使能温度传感器并读取芯片温度
|
||||
5. **[5/5] 休眠与唤醒演示** - 演示 sleep()/wakeup() 待机与唤醒
|
||||
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- CJMCU-LIS2DH12 三轴加速度传感器模块 × 1
|
||||
demo所演示的LIS2DH12 三轴加速度传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=558250923931&mi_id=0000CnnCsR0FV7f0P7irmdBj13iLAdQybnwMchjjsbtxS9Q&ns=1&priceTId=215045e417839190178541937e1198&skuId=4867682785456&spm=a21n57.1.hoverItem.2&utparam=%7B%22aplus_abtest%22%3A%2259cc019145c3f9fde211bc6c0f71f883%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 6
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 I2C 模式接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>CJMCU-LIS2DH12 模块<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>30/GPIO29<br/></td><td>INT1<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||

|
||||
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/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. **lis2dh12_demo.lua** - LIS2DH12 功能演示模块
|
||||
3. **exs_lis2dh12** - LIS2DH12 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 CJMCU-LIS2DH12 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 lis2dh12_demo.lua 演示模块
|
||||
require "lis2dh12_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/5] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴加速度数据(X/Y/Z,单位 g)的连续读取
|
||||
|
||||
#### 5.4.2 量程切换演示
|
||||
|
||||
1. 自动进入 [2/5] 量程切换演示
|
||||
2. 观察 ±4g 宽范围量程下的数据
|
||||
3. 观察 ±2g 高精度量程下的数据
|
||||
|
||||
#### 5.4.3 输出速率切换演示
|
||||
|
||||
1. 自动进入 [3/5] 输出速率切换演示
|
||||
2. 依次观察 25Hz / 50Hz / 100Hz / 200Hz 下的数据读取
|
||||
3. 最终恢复为 100Hz
|
||||
|
||||
#### 5.4.4 温度读取演示
|
||||
|
||||
1. 自动进入 [4/5] 温度读取演示
|
||||
2. 使能温度传感器并等待稳定
|
||||
3. 读取并显示芯片温度(单位 °C)
|
||||
|
||||
#### 5.4.5 休眠与唤醒演示
|
||||
|
||||
1. 自动进入 [5/5] 休眠与唤醒演示
|
||||
2. 观察 sleep() 进入待机模式
|
||||
3. 观察 wakeup() 唤醒后数据恢复
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:LIS2DH12 初始化成功,三轴加速度数据正常输出
|
||||
- **量程切换**:量程切换后数据范围随之变化,灵敏度不同
|
||||
- **输出速率切换**:不同速率下均能正常读取数据
|
||||
- **温度读取**:正常读取芯片温度(约 20-40°C)
|
||||
- **休眠与唤醒**:sleep 后进入低功耗,wakeup 后数据读取正常
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:30:03.304][000000000.179] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:30:03.305][000000000.179] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:30:03.307][000000000.181] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:30:03.310][000000000.183] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:30:03.312][000000000.184] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:30:03.315][000000000.184] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:30:03.317][000000000.201] I/user.main LIS2DH12_Demo 001.999.000
|
||||
[2026-07-21 10:30:03.319][000000000.217] D/user.exs_lis2dh12 version -> 202607170900
|
||||
[2026-07-21 10:30:03.320][000000000.218] I/user.lis2dh12_demo HELLO
|
||||
[2026-07-21 10:30:03.512][000000001.218] I/user.lis2dh12_demo ===== [1/5] 初始化与数据读取 =====
|
||||
[2026-07-21 10:30:03.515][000000001.233] I/user.exs_lis2dh12 LIS2DH12 @ I2C 0x19
|
||||
[2026-07-21 10:30:03.517][000000001.243] I/user.exs_lis2dh12 REG读回 CTRL1=0x57 CTRL4=0x88 STATUS=0x0F INT1_CFG=0x00
|
||||
[2026-07-21 10:30:03.518][000000001.252] I/user.exs_lis2dh12 INT1 已注册, gpio=29
|
||||
[2026-07-21 10:30:03.520][000000001.252] I/user.exs_lis2dh12 初始化完成 mode=I2C range=2g odr=100Hz mode=highres
|
||||
[2026-07-21 10:30:03.533][000000001.253] I/user.lis2dh12_demo LIS2DH12 初始化成功,版本: 202607170900
|
||||
[2026-07-21 10:30:03.539][000000001.269] I/user.exs_lis2dh12 CTRL1=0x57 CTRL2=0x00 CTRL3=0xC0 CTRL4=0x88 CTRL5=0x0C CTRL6=0x00 STATUS=0xFF INT1_SRC=0x00 INT2_SRC=0x00 FIFO_SRC=0x20
|
||||
[2026-07-21 10:30:03.544][000000001.478] I/user.lis2dh12_demo X=-0.965 Y=-0.008 Z=-0.029 g
|
||||
[2026-07-21 10:30:04.086][000000002.295] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:30:04.091][000000002.296] D/mobile cid1, state0
|
||||
[2026-07-21 10:30:04.096][000000002.296] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:30:04.100][000000002.297] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:30:04.104][000000002.353] D/mobile TIME_SYNC 0 tm 1784601007
|
||||
[2026-07-21 10:30:04.724][000000002.986] I/user.lis2dh12_demo 第1次读取: X=-0.368 Y=-0.170 Z=-0.713 g
|
||||
[2026-07-21 10:30:05.223][000000003.494] I/user.lis2dh12_demo 第2次读取: X=-0.083 Y=0.008 Z=-1.023 g
|
||||
[2026-07-21 10:30:05.732][000000004.004] I/user.lis2dh12_demo 第3次读取: X=-0.119 Y=0.108 Z=0.237 g
|
||||
[2026-07-21 10:30:05.735][000000004.004] I/user.lis2dh12_demo ---- [1/5] 完成 ----
|
||||
[2026-07-21 10:30:06.013][000000004.271] I/user.lis2dh12_demo int1: 朝向=front X=-0.670 Y=-0.097 Z=-0.194 g
|
||||
[2026-07-21 10:30:06.243][000000004.504] I/user.lis2dh12_demo ===== [2/5] 量程切换演示 =====
|
||||
[2026-07-21 10:30:06.247][000000004.505] I/user.lis2dh12_demo 切换量程为 4g
|
||||
[2026-07-21 10:30:06.252][000000004.508] I/user.exs_lis2dh12 量程切换为 4g
|
||||
[2026-07-21 10:30:06.555][000000004.816] I/user.lis2dh12_demo 4g 量程: X=0.102 Y=0.350 Z=-0.872 g
|
||||
[2026-07-21 10:30:07.549][000000005.816] I/user.lis2dh12_demo 切换量程为 2g(高精度)
|
||||
[2026-07-21 10:30:07.553][000000005.819] I/user.exs_lis2dh12 量程切换为 2g
|
||||
[2026-07-21 10:30:07.861][000000006.127] I/user.lis2dh12_demo 2g 量程: X=-0.063 Y=0.379 Z=0.801 g
|
||||
[2026-07-21 10:30:08.856][000000007.127] I/user.lis2dh12_demo ---- [2/5] 完成 ----
|
||||
[2026-07-21 10:30:09.369][000000007.627] I/user.lis2dh12_demo ===== [3/5] 输出速率切换 =====
|
||||
[2026-07-21 10:30:09.374][000000007.628] I/user.lis2dh12_demo 设置输出速率为 25Hz
|
||||
[2026-07-21 10:30:09.378][000000007.631] I/user.exs_lis2dh12 输出速率切换为 25Hz
|
||||
[2026-07-21 10:30:09.881][000000008.139] I/user.lis2dh12_demo 25Hz 下: X=0.033 Y=0.084 Z=0.999 g
|
||||
[2026-07-21 10:30:10.377][000000008.639] I/user.lis2dh12_demo 设置输出速率为 50Hz
|
||||
[2026-07-21 10:30:10.382][000000008.643] I/user.exs_lis2dh12 输出速率切换为 50Hz
|
||||
[2026-07-21 10:30:10.890][000000009.151] I/user.lis2dh12_demo 50Hz 下: X=0.145 Y=0.163 Z=0.982 g
|
||||
[2026-07-21 10:30:11.385][000000009.651] I/user.lis2dh12_demo 设置输出速率为 100Hz
|
||||
[2026-07-21 10:30:11.388][000000009.654] I/user.exs_lis2dh12 输出速率切换为 100Hz
|
||||
[2026-07-21 10:30:11.898][000000010.162] I/user.lis2dh12_demo 100Hz 下: X=0.754 Y=0.033 Z=0.060 g
|
||||
[2026-07-21 10:30:12.395][000000010.662] I/user.lis2dh12_demo 设置输出速率为 200Hz
|
||||
[2026-07-21 10:30:12.398][000000010.665] I/user.exs_lis2dh12 输出速率切换为 200Hz
|
||||
[2026-07-21 10:30:12.905][000000011.173] I/user.lis2dh12_demo 200Hz 下: X=-0.589 Y=-0.397 Z=0.942 g
|
||||
[2026-07-21 10:30:13.215][000000011.481] I/user.lis2dh12_demo int1: 朝向=down X=-0.341 Y=-0.250 Z=0.819 g
|
||||
[2026-07-21 10:30:13.419][000000011.676] I/user.exs_lis2dh12 输出速率切换为 100Hz
|
||||
[2026-07-21 10:30:13.423][000000011.676] I/user.lis2dh12_demo ---- [3/5] 完成 ----
|
||||
[2026-07-21 10:30:13.915][000000012.176] I/user.lis2dh12_demo ===== [4/5] 温度读取演示 =====
|
||||
[2026-07-21 10:30:13.919][000000012.177] I/user.lis2dh12_demo 使能温度传感器
|
||||
[2026-07-21 10:30:13.923][000000012.178] I/user.exs_lis2dh12 温度传感器 已使能
|
||||
[2026-07-21 10:30:14.087][000000012.353] I/user.lis2dh12_demo int1: 朝向=front X=-0.906 Y=0.708 Z=-0.263 g
|
||||
[2026-07-21 10:30:14.118][000000012.381] I/user.lis2dh12_demo 芯片温度: 39.0 °C
|
||||
[2026-07-21 10:30:14.122][000000012.382] I/user.exs_lis2dh12 温度传感器 已禁用
|
||||
[2026-07-21 10:30:14.125][000000012.382] I/user.lis2dh12_demo ---- [4/5] 完成 ----
|
||||
[2026-07-21 10:30:14.616][000000012.883] I/user.lis2dh12_demo ===== [5/5] 休眠与唤醒演示 =====
|
||||
[2026-07-21 10:30:14.619][000000012.884] I/user.lis2dh12_demo 进入 power-down 模式(低功耗)
|
||||
[2026-07-21 10:30:14.623][000000012.886] I/user.exs_lis2dh12 已进入 power-down 模式
|
||||
[2026-07-21 10:30:25.117][000000023.386] I/user.lis2dh12_demo 从 power-down 模式唤醒
|
||||
[2026-07-21 10:30:25.120][000000023.389] I/user.exs_lis2dh12 已从 power-down 模式唤醒,ODR=100Hz
|
||||
[2026-07-21 10:30:25.336][000000023.597] I/user.lis2dh12_demo 唤醒后数据: X=-0.933 Y=0.196 Z=-0.178 g
|
||||
[2026-07-21 10:30:25.340][000000023.597] I/user.lis2dh12_demo ---- [5/5] 完成 ----
|
||||
[2026-07-21 10:30:25.833][000000024.098] I/user.lis2dh12_demo ===== [演示完毕] =====
|
||||
[2026-07-21 10:30:25.837][000000024.104] I/user.exs_lis2dh12 传感器已关闭
|
||||
[2026-07-21 10:30:25.842][000000024.104] I/user.lis2dh12_demo End
|
||||
```
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 LIS2DH12 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_lis2dh12 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(SA0=GND 时地址 0x18,SA0=VCC 时地址 0x19)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **量程切换无效果**:
|
||||
|
||||
- 确认 `set_range()` 参数为 "2g"、"4g"、"8g" 或 "16g"
|
||||
- 切换后需等待传感器稳定再读取数据
|
||||
|
||||
4. **温度读取失败**:
|
||||
|
||||
- 确认已在 setup 时设置 `enable_temp = true` 或调用 `enable_temp(true)`
|
||||
- 使能后需等待约 200ms 让 ADC 稳定
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_lis2dh12 更多接口的使用可以查看 [exs_lis2dh12 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_lis2dh12/)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary MPU6050 六轴姿态传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.23
|
||||
@author 王城钧
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_mpu6050 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化和数据读取([1/4])- 加速度/角速度/温度
|
||||
2、静态倾角测量([2/4])- 加速度计推算俯仰/横滚
|
||||
3、动态姿态解算,互补滤波([3/4])- 陀螺+加速度融合
|
||||
4、碰撞检测与自由落体([4/4])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "MPU6050_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 mpu6050_demo.lua 演示模块
|
||||
require "mpu6050_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,212 @@
|
||||
--[[
|
||||
@module mpu6050_demo
|
||||
@summary MPU6050 六轴姿态传感器演示模块
|
||||
@version 2.0
|
||||
@date 2026.07.23
|
||||
@author 王城钧
|
||||
@usage
|
||||
=== 演示流程: 基础测试(10项) → 持续读取(10秒) → DMP测试(可选) ===
|
||||
|
||||
本文件通过 exs_mpu6050 扩展库的 API 逐一演示 MPU6050 的以下功能:
|
||||
|
||||
1. I2C 初始化与芯片自检 -- i2c.setup + mpu.setup, 自动检测地址 0x68/0x69, 自动加载校准
|
||||
2. 芯片温度读取 -- mpu.get_data().temp, 单位 ℃
|
||||
3. 三轴加速度读取 -- mpu.get_data().accel, 单位 g, 静止水平时 Z≈1.0g
|
||||
4. 三轴角速度读取 -- mpu.get_data().gyro, 单位 °/s, 静止时应接近 0
|
||||
5. 静态倾角测量 -- mpu.get_tilt(), 通过加速度计直接推算俯仰/横滚角
|
||||
6. 碰撞/敲击检测 -- mpu.detect_tap(阈值, 去抖时间), 检测瞬时加速度冲击
|
||||
7. 自由落体/失重检测 -- mpu.detect_freefall(阈值), 三轴合加速度低于阈值时触发
|
||||
8. 校准状态查询 -- mpu.is_calibrated(), 检查加速度/陀螺零偏是否已校准
|
||||
9. 手动重新校准(注释) -- mpu.calibrate(), 设备需水平静止, 200次采样取平均
|
||||
10. 持续读取(加速度+互补滤波+碰撞) -- 循环 10 秒, 演示 get_attitude() 动态姿态融合
|
||||
|
||||
附加: DMP 数字运动处理器 -- mpu.dmp_init() + mpu.dmp_get_euler(), 固件已内置
|
||||
]]
|
||||
|
||||
-- 加载 exs_mpu6050 扩展库
|
||||
-- 该库提供 MPU6050 的全部驱动功能: 初始化/校准/数据读取/姿态解算/DMP
|
||||
local mpu = require "exs_mpu6050"
|
||||
|
||||
-- 硬件 I2C 总线 ID
|
||||
-- Air780EGH: 使用 I2C1 (Pin66=SDA, Pin67=SCL) → hwid=1
|
||||
-- Air8000: 使用 I2C0 (GPIO2=SDA, GPIO1=SCL) → hwid=0
|
||||
local i2c_hwid = 1
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- 基础功能测试 (10 项, 顺序执行)
|
||||
-- 覆盖: 初始化 → 温度 → 加速度 → 陀螺仪 → 倾角 → 碰撞 → 失重 → 校准 → 持续读取
|
||||
----------------------------------------------------------------
|
||||
local function mpu6050_task()
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [1/10] 初始化 I2C + MPU6050
|
||||
-- - i2c.setup 配置 I2C 总线为快速模式(400kHz)
|
||||
-- - mpu.setup 自动检测芯片地址(先试0x68, 再试0x69), 验证 WHO_AM_I 寄存器(应为0x68)
|
||||
-- - 无校准数据时建议调用 calibrate(): 设备需水平静止, 采样200次, 需要50次以上有效静止采样
|
||||
-- - 校准数据会保存到文件 /mpu6050_calib.txt, 后续启动自动加载
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [1/10] 初始化 ===")
|
||||
i2c.setup(i2c_hwid, i2c.FAST)
|
||||
|
||||
if not mpu.setup({ i2c_id = i2c_hwid }) then
|
||||
log.error("TEST", "初始化失败! 检查接线: VCC=3.3V GND SCL SDA")
|
||||
while true do sys.wait(1000) end
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [2/10] 芯片温度读取
|
||||
-- - MPU6050 内置温度传感器, 用于内部补偿陀螺零漂
|
||||
-- - 正常工作时芯片温度约 30~45℃, 随运行时间缓慢上升
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [2/10] 温度 ===")
|
||||
local temp = mpu.get_data().temp
|
||||
log.info("TEST", string.format("芯片温度: %.1f°C", temp))
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [3/10] 三轴加速度读取 (已校准)
|
||||
-- - 返回 x, y, z 分量, 单位 g (1g ≈ 9.8m/s² 重力加速度)
|
||||
-- - 静止水平放置时: Z≈+1.0g, X≈0g, Y≈0g
|
||||
-- - Z 轴正向为芯片顶面朝上, X/Y 向由芯片丝印方向决定
|
||||
-- - 量程默认 ±2g, 分辨率 16384 LSB/g
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [3/10] 加速度 (单位g) ===")
|
||||
local a = mpu.get_data().accel
|
||||
log.info("TEST", string.format("accel x=%.3f y=%.3f z=%.3f", a.x, a.y, a.z))
|
||||
-- 如果 Z 轴偏差超过 0.15g, 提示检查放置或校准
|
||||
if math.abs(a.z - 1.0) > 0.15 then
|
||||
log.warn("TEST", "Z轴偏差较大(期望≈1.0g), 检查传感器是否水平")
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [4/10] 三轴角速度读取 (已校准)
|
||||
-- - 返回 x, y, z 分量, 单位 °/s (度每秒)
|
||||
-- - 静止时应全部接近 0, 超过 ±5°/s 说明零偏校准不佳
|
||||
-- - 量程默认 ±250°/s, 分辨率 131 LSB/(°/s)
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [4/10] 陀螺仪 (单位°/s) ===")
|
||||
local g = mpu.get_data().gyro
|
||||
log.info("TEST", string.format("gyro x=%.1f y=%.1f z=%.1f", g.x, g.y, g.z))
|
||||
if math.abs(g.x) > 5 or math.abs(g.y) > 5 or math.abs(g.z) > 5 then
|
||||
log.warn("TEST", "陀螺零偏较大(期望≈0), 重新校准试试")
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [5/10] 静态倾角读取 (加速度计直接推算)
|
||||
-- - pitch(俯仰): 设备前后倾斜角度, 前倾为正
|
||||
-- - roll(横滚): 设备左右倾斜角度, 右倾为正
|
||||
-- - 纯加速度推算, 静态精度高(受重力矢量影响)
|
||||
-- - 动态时受运动加速度干扰, 噪声大, 不宜用于运动中的姿态估计
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [5/10] 倾角 (单位°) ===")
|
||||
local pitch, roll = mpu.get_tilt()
|
||||
log.info("TEST", string.format("tilt pitch=%.1f° roll=%.1f°", pitch, roll))
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [6/10] 碰撞/敲击检测
|
||||
-- - detect_tap(threshold, debounce_ms)
|
||||
-- threshold: 加速度合矢量阈值(g), 默认 2.0g, 轻敲可设 1.5g
|
||||
-- debounce_ms: 去抖时间(ms), 默认 500ms, 防止单次敲击被多次触发
|
||||
-- - 原理: 三轴加速度模长 sqrt(x²+y²+z²) 超过阈值则触发
|
||||
-- - 静止时模长约 1.0g, 敲击瞬间可达 3~5g
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [6/10] 碰撞检测 ===")
|
||||
if mpu.detect_tap(2.0) then
|
||||
log.info("TEST", "碰撞检测: YES")
|
||||
else
|
||||
log.info("TEST", "碰撞检测: NO (正常, 静止时不应触发)")
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [7/10] 自由落体/失重检测
|
||||
-- - detect_freefall(threshold)
|
||||
-- threshold: 加速度合矢量阈值(g), 默认 0.3g
|
||||
-- - 原理: 三轴合加速度 < 阈值时判定为失重/自由落体
|
||||
-- - 自由落体时加速度趋近于 0, 正常静止时为 1.0g
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [7/10] 自由落体检测 ===")
|
||||
if mpu.detect_freefall() then
|
||||
log.info("TEST", "自由落体: YES (你在自由落体?)")
|
||||
else
|
||||
log.info("TEST", "自由落体: NO (正常)")
|
||||
end
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [8/10] 校准状态查询
|
||||
-- - is_calibrated() 返回校准数据是否就绪
|
||||
-- - 校准数据来自: 首次自动校准 或 手动 calibrate() 调用
|
||||
-- - 数据保存在 /mpu6050_calib.txt (6个值: gx,gy,gz,ax,ay,az)
|
||||
-- - 无校准时 get_data() 返回原始值, 精度降低
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [8/10] 校准状态 ===")
|
||||
log.info("TEST", "已校准:", mpu.is_calibrated())
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [9/10] 手动重新校准 (默认注释)
|
||||
-- - 在运行过程中需要重新校准时取消注释
|
||||
-- - 调用前确保设备水平静止, 否则校准结果不准确
|
||||
-- - 校准完成会自动覆盖 /mpu6050_calib.txt
|
||||
------------------------------------------------------------
|
||||
-- log.info("TEST", "=== [9/10] 手动校准 ===")
|
||||
-- local ok = mpu.calibrate()
|
||||
-- log.info("TEST", "校准结果:", ok)
|
||||
|
||||
------------------------------------------------------------
|
||||
-- [10/10] 持续读取 (10秒循环)
|
||||
-- - 每 200ms 读取一次: 加速度 + 互补滤波姿态 + 碰撞检测
|
||||
-- - get_attitude() 使用互补滤波: alpha=0.96
|
||||
-- 陀螺积分权重 96% + 加速度推算权重 4%
|
||||
-- 陀螺积分提供高频动态响应, 加速度修正低频漂移
|
||||
-- - 必须持续循环调用以保持积分连续性, 中断后积分重置
|
||||
-- - 在循环中同时监控碰撞事件并累计次数
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "=== [10/10] 持续读取 (10秒) ===")
|
||||
local start = os.clock()
|
||||
local tap_count = 0
|
||||
while os.clock() - start < 10 do
|
||||
local a = mpu.get_data().accel
|
||||
local p, r = mpu.get_attitude()
|
||||
if mpu.detect_tap(2.0, 500) then
|
||||
tap_count = tap_count + 1
|
||||
log.info("TEST", string.format("碰撞! 第%d次", tap_count))
|
||||
end
|
||||
log.info("TEST", string.format(
|
||||
"a:(%5.2f,%5.2f,%5.2f)g p=%.1f° r=%.1f°",
|
||||
a.x, a.y, a.z, p, r))
|
||||
sys.wait(200)
|
||||
end
|
||||
log.info("TEST", string.format("持续读取完成, 碰撞%d次", tap_count))
|
||||
|
||||
------------------------------------------------------------
|
||||
-- 基础测试完毕
|
||||
------------------------------------------------------------
|
||||
log.info("TEST", "========== 所有测试完成 ==========")
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- DMP 数字运动处理器测试 (可选)
|
||||
-- - DMP 是 MPU6050 内置的运动处理引擎, 直接输出融合后的四元数/欧拉角
|
||||
-- - 相比互补滤波, DMP 精度更高、CPU 负载更低
|
||||
-- - DMP 固件已内置在 exs_mpu6050.lua 中 (MotionApps v20), 无需额外文件
|
||||
-- 固件来源: GitHub i2cdevlib → Arduino/MPU6050/MPU6050_6Axis_MotionApps20.h
|
||||
-- - DMP 输出: Roll(横滚), Pitch(俯仰), Yaw(偏航, 无磁力计会漂移)
|
||||
----------------------------------------------------------------
|
||||
local function mpu6050_dmp()
|
||||
sys.wait(3000) -- 等待基础测试开始后再启动 DMP
|
||||
if mpu.dmp_init() then
|
||||
log.info("DMP_TEST", "DMP 就绪")
|
||||
while true do
|
||||
local r, p, y = mpu.dmp_get_euler()
|
||||
if r then
|
||||
log.info("DMP", string.format("R:%.1f P:%.1f Y:%.1f", r, p, y))
|
||||
end
|
||||
sys.wait(3000)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 启动基础测试任务 (协程运行, 通过命名函数指定)
|
||||
sys.taskInit(mpu6050_task)
|
||||
|
||||
-- 启动 DMP 测试任务 (可选)
|
||||
sys.taskInit(mpu6050_dmp)
|
||||
@@ -0,0 +1,216 @@
|
||||
# MPU6050 六轴姿态传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **mpu6050_demo.lua** - MPU6050 功能演示模块,包含数据读取、静态倾角、动态姿态解算、碰撞检测等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_mpu6050** - MPU6050 扩展库,提供 I2C 初始化、三轴加速度/角速度数据读取、温度、倾角、姿态解算(互补滤波)、碰撞/敲击检测、自由落体检测、自动校准等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_mpu6050 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 MPU6050 传感器并读取三轴加速度(X/Y/Z,单位 g)、三轴角速度(X/Y/Z,单位 °/s)、芯片温度
|
||||
2. **[2/4] 静态倾角测量** - 通过加速度计推算俯仰角(Pitch)和横滚角(Roll),适用于静态姿态测量
|
||||
3. **[3/4] 动态姿态解算(互补滤波)** - 融合陀螺仪积分与加速度计数据,通过互补滤波输出动态姿态角
|
||||
4. **[4/4] 碰撞检测与自由落体** - 演示敲击检测(detect_tap)和失重/自由落体检测(detect_freefall)
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板
|
||||
|
||||
- MPU6050 六轴姿态传感器模块 × 1
|
||||
|
||||
- 母对母杜邦线 × 4
|
||||
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||

|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 MPU6050 模块接线(硬件 I2C)
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>MPU6050 模块(GY-521)<br/></td></tr>
|
||||
<tr>
|
||||
<td>67 / I2C1_SCL<br/></td><td>SCL<br/></td></tr>
|
||||
<tr>
|
||||
<td>66 / I2C1_SDA<br/></td><td>SDA<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。MPU6050 模块(GY-521)通常包含 3.3V 稳压器,可直接使用 VDD_EXT 供电。
|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 4.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/)
|
||||
|
||||
### 4.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/version/),demo 使用 LuatOS-SoC_V2050_Air780EPM 1号固件
|
||||
|
||||
### 4.3 脚本文件
|
||||
|
||||
- **main.lua** - 程序入口
|
||||
- **mpu6050_demo.lua** - 演示模块
|
||||
- **exs_mpu6050** - 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 MPU6050 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 首次上电请将设备水平放置,以便自动校准
|
||||
4. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 mpu6050_demo.lua 演示模块
|
||||
require "mpu6050_demo"
|
||||
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴加速度数据(X/Y/Z,单位 g)、角速度(°/s)、温度(℃)输出
|
||||
4. 静止水平放置时,加速度 Z 轴应接近 1.0g,X/Y 接近 0
|
||||
|
||||
#### 5.4.2 静态倾角测量演示
|
||||
|
||||
1. 自动进入 [2/4] 静态倾角测量
|
||||
2. 保持设备静止,观察俯仰角和横滚角
|
||||
3. 水平放置时倾角应接近 0°
|
||||
4. 可倾斜设备观察角度变化
|
||||
|
||||
#### 5.4.3 动态姿态解算演示
|
||||
|
||||
1. 自动进入 [3/4] 动态姿态解算(互补滤波)
|
||||
2. 缓慢转动设备,观察俯仰角和横滚角的变化
|
||||
3. 互补滤波融合了陀螺仪和加速度计数据,动态响应更好
|
||||
|
||||
#### 5.4.4 碰撞检测演示
|
||||
|
||||
1. 自动进入 [4/4] 碰撞检测与自由落体
|
||||
2. 5 秒检测窗口内,用手指轻轻敲击传感器
|
||||
3. 观察日志是否输出"检测到敲击!"
|
||||
4. 快速抛接设备可触发"失重/自由落体"检测
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:MPU6050 初始化成功,自动校准完成,三轴加速度/角速度/温度数据正常输出
|
||||
- **静态倾角**:水平放置时俯仰/横滚接近 0°,倾斜设备时角度准确响应
|
||||
- **动态姿态解算**:转动设备时姿态角平滑跟踪,互补滤波有效抑制噪声
|
||||
- **碰撞检测**:敲击传感器可被 detect_tap 捕获,自由落体可被 detect_freefall 捕获
|
||||
- **日志如下:**
|
||||
|
||||
```lua
|
||||
[2026-07-23 18:22:49.845][000000000.253] I/user.TEST === 1. 初始化 ===
|
||||
[2026-07-23 18:22:49.846][000000000.253] I2C_MasterSetup 426:I2C1, Total 65 HCNT 22 LCNT 40
|
||||
[2026-07-23 18:22:49.848][000000000.305] I/user.mpu6050 WHO_AM_I 0x68 addr 0x68
|
||||
[2026-07-23 18:22:49.850][000000000.560] I/user.mpu6050 已加载校准 g:(-283,-72,239) a:(-1851,2252,-28738)
|
||||
[2026-07-23 18:22:49.851][000000000.561] I/user.mpu6050 init 完成
|
||||
[2026-07-23 18:22:49.858][000000000.561] I/user.TEST === 2. 温度 ===
|
||||
[2026-07-23 18:22:49.860][000000000.562] I/user.TEST 芯片温度: 29.6°C
|
||||
[2026-07-23 18:22:49.863][000000000.562] I/user.TEST === 3. 加速度 (单位g) ===
|
||||
[2026-07-23 18:22:49.867][000000000.564] I/user.TEST accel x=0.127 y=-0.077 z=1.112
|
||||
[2026-07-23 18:22:49.870][000000000.564] I/user.TEST === 4. 陀螺仪 (单位°/s) ===
|
||||
[2026-07-23 18:22:49.873][000000000.566] I/user.TEST gyro x=1.9 y=9.1 z=3.6
|
||||
[2026-07-23 18:22:49.876][000000000.566] W/user.TEST 陀螺零偏较大(期望≈0), 重新校准试试
|
||||
[2026-07-23 18:22:49.879][000000000.566] I/user.TEST === 5. 倾角 (单位°) ===
|
||||
[2026-07-23 18:22:49.883][000000000.568] I/user.TEST tilt pitch=-3.7° roll=6.4°
|
||||
[2026-07-23 18:22:49.885][000000000.568] I/user.TEST === 6. 碰撞检测 ===
|
||||
[2026-07-23 18:22:49.888][000000000.570] I/user.TEST 碰撞检测: NO (正常, 静止时不应触发)
|
||||
[2026-07-23 18:22:49.891][000000000.570] I/user.TEST === 7. 自由落体检测 ===
|
||||
[2026-07-23 18:22:49.894][000000000.572] I/user.TEST 自由落体: NO (正常)
|
||||
[2026-07-23 18:22:49.897][000000000.572] I/user.TEST === 8. 校准状态 ===
|
||||
[2026-07-23 18:22:49.900][000000000.572] I/user.TEST 已校准: true
|
||||
[2026-07-23 18:22:49.903][000000000.572] I/user.TEST === 10. 持续读取 (10秒) ===
|
||||
[2026-07-23 18:22:49.906][000000000.578] I/user.TEST a:( 0.12,-0.07, 1.09)g p=-0.1° r=0.3°
|
||||
[2026-07-23 18:22:49.945][000000000.783] I/user.TEST a:( 0.14,-0.09, 0.98)g p=-0.3° r=0.7°
|
||||
[2026-07-23 18:22:49.948][000000000.990] I/user.TEST a:( 0.14,-0.07, 0.98)g p=-0.6° r=0.9°
|
||||
[2026-07-23 18:22:49.950][000000001.195] I/user.TEST a:( 0.13,-0.05, 0.97)g p=-1.9° r=2.7°
|
||||
[2026-07-23 18:22:49.953][000000001.401] I/user.TEST a:( 0.13,-0.06, 0.97)g p=-2.0° r=2.9°
|
||||
[2026-07-23 18:22:49.990][000000001.607] I/user.TEST a:( 0.14,-0.06, 0.97)g p=-2.0° r=3.1°
|
||||
[2026-07-23 18:22:50.135][000000001.813] I/user.TEST a:( 0.13,-0.06, 0.98)g p=-2.1° r=3.3°
|
||||
[2026-07-23 18:22:50.341][000000002.019] I/user.TEST a:( 0.14,-0.06, 0.97)g p=-3.4° r=1.9°
|
||||
[2026-07-23 18:22:50.545][000000002.225] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-3.4° r=2.1°
|
||||
[2026-07-23 18:22:50.752][000000002.431] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-3.4° r=2.3°
|
||||
[2026-07-23 18:22:50.958][000000002.637] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-3.4° r=2.5°
|
||||
[2026-07-23 18:22:51.162][000000002.843] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-3.3° r=2.7°
|
||||
[2026-07-23 18:22:51.369][000000003.049] I/user.TEST a:( 0.13,-0.05, 0.97)g p=-2.3° r=1.0°
|
||||
[2026-07-23 18:22:51.575][000000003.255] I/user.TEST a:( 0.13,-0.06, 0.98)g p=-2.4° r=1.3°
|
||||
[2026-07-23 18:22:51.591][000000003.271] I/user.mpu6050 DMP固件加载中, 1929字节
|
||||
[2026-07-23 18:22:51.783][000000003.461] I/user.TEST a:( 0.13,-0.05, 0.97)g p=-2.4° r=1.6°
|
||||
[2026-07-23 18:22:51.909][000000003.589] I/user.mpu6050 固件写入完成
|
||||
[2026-07-23 18:22:51.989][000000003.667] I/user.TEST a:( 0.13,-0.06, 0.97)g p=-2.4° r=1.8°
|
||||
[2026-07-23 18:22:52.115][000000003.791] I/user.mpu6050 DMP 就绪
|
||||
[2026-07-23 18:22:52.119][000000003.791] I/user.DMP_TEST DMP 就绪
|
||||
[2026-07-23 18:22:52.121][000000003.800] I/user.DMP R:-173.1 P:0.2 Y:0.3
|
||||
[2026-07-23 18:22:52.196][000000003.873] I/user.TEST a:( 0.13,-0.06, 0.98)g p=-2.4° r=2.0°
|
||||
[2026-07-23 18:22:52.400][000000004.079] I/user.TEST a:( 0.14,-0.05, 0.96)g p=-0.8° r=2.4°
|
||||
[2026-07-23 18:22:52.606][000000004.285] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-0.8° r=2.6°
|
||||
[2026-07-23 18:22:52.813][000000004.491] I/user.TEST a:( 0.13,-0.05, 0.97)g p=-0.9° r=2.8°
|
||||
[2026-07-23 18:22:53.018][000000004.697] I/user.TEST a:( 0.13,-0.06, 0.98)g p=-1.0° r=3.0°
|
||||
[2026-07-23 18:22:53.220][000000004.903] I/user.TEST a:( 0.13,-0.05, 0.98)g p=-1.0° r=3.2°
|
||||
[2026-07-23 18:22:53.425][000000005.109] I/user.TEST a:( 0.13,-0.05, 0.98)g p=0.5° r=3.8°
|
||||
[2026-07-23 18:22:53.644][000000005.315] I/user.TEST a:( 0.13,-0.05, 0.97)g p=0.4° r=3.9°
|
||||
[2026-07-23 18:22:53.836][000000005.521] I/user.TEST a:( 0.13,-0.04, 0.98)g p=0.3° r=4.1°
|
||||
[2026-07-23 18:22:54.042][000000005.727] I/user.TEST a:( 0.12,-0.06, 0.99)g p=0.2° r=4.2°
|
||||
[2026-07-23 18:22:54.263][000000005.933] I/user.TEST a:( 0.13,-0.05, 0.98)g p=0.1° r=4.4°
|
||||
[2026-07-23 18:22:54.454][000000006.139] I/user.TEST a:( 0.13,-0.05, 0.97)g p=1.6° r=5.0°
|
||||
[2026-07-23 18:22:54.660][000000006.345] I/user.TEST a:( 0.13,-0.04, 0.98)g p=1.5° r=5.1°
|
||||
[2026-07-23 18:22:54.865][000000006.551] I/user.TEST a:( 0.13,-0.04, 0.99)g p=1.3° r=5.2°
|
||||
[2026-07-23 18:22:55.074][000000006.758] I/user.TEST a:( 0.13,-0.05, 0.98)g p=1.2° r=5.3°
|
||||
[2026-07-23 18:22:55.152][000000006.828] I/user.DMP R:0.0 P:-0.1 Y:-1.4
|
||||
[2026-07-23 18:22:55.280][000000006.965] I/user.TEST a:( 0.13,-0.06, 0.99)g p=1.0° r=5.4°
|
||||
[2026-07-23 18:22:55.487][000000007.170] I/user.TEST a:( 0.13,-0.05, 0.98)g p=2.4° r=6.0°
|
||||
[2026-07-23 18:22:55.695][000000007.376] I/user.TEST a:( 0.14,-0.04, 0.97)g p=2.3° r=6.1°
|
||||
[2026-07-23 18:22:55.899][000000007.582] I/user.TEST a:( 0.14,-0.05, 0.99)g p=2.1° r=6.2°
|
||||
[2026-07-23 18:22:56.104][000000007.788] I/user.TEST a:( 0.14,-0.04, 0.97)g p=1.9° r=6.2°
|
||||
[2026-07-23 18:22:56.324][000000007.994] I/user.TEST a:( 0.13,-0.04, 0.98)g p=1.7° r=6.3°
|
||||
[2026-07-23 18:22:56.516][000000008.200] I/user.TEST a:( 0.13,-0.04, 0.98)g p=3.5° r=6.7°
|
||||
[2026-07-23 18:22:56.722][000000008.406] I/user.TEST a:( 0.13,-0.05, 0.97)g p=3.2° r=6.8°
|
||||
[2026-07-23 18:22:56.928][000000008.612] I/user.TEST a:( 0.14,-0.05, 0.97)g p=3.0° r=6.8°
|
||||
[2026-07-23 18:22:57.136][000000008.818] I/user.TEST a:( 0.14,-0.04, 0.97)g p=2.8° r=6.9°
|
||||
[2026-07-23 18:22:57.341][000000009.024] I/user.TEST a:( 0.13,-0.04, 0.98)g p=4.7° r=7.4°
|
||||
[2026-07-23 18:22:57.547][000000009.230] I/user.TEST a:( 0.14,-0.04, 0.96)g p=4.4° r=7.4°
|
||||
[2026-07-23 18:22:57.751][000000009.436] I/user.TEST a:( 0.14,-0.05, 0.98)g p=4.2° r=7.4°
|
||||
[2026-07-23 18:22:57.957][000000009.643] I/user.TEST a:( 0.14,-0.04, 0.97)g p=3.9° r=7.5°
|
||||
[2026-07-23 18:22:58.179][000000009.855] I/user.DMP R:0.0 P:-0.0 Y:-1.5
|
||||
[2026-07-23 18:22:58.182][000000009.862] I/user.TEST a:( 0.14,-0.05, 0.97)g p=3.7° r=7.5°
|
||||
[2026-07-23 18:22:58.383][000000010.063] I/user.TEST 持续读取完成, 碰撞0次
|
||||
[2026-07-23 18:22:58.385][000000010.063] I/user.TEST ========== 所有测试完成 ==========
|
||||
|
||||
```
|
||||
@@ -0,0 +1,68 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary QMC5883L 三轴地磁传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.14
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_qmc5883l 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/3]→[2/3]→[3/3]→End
|
||||
1、初始化和数据读取([1/3])
|
||||
2、量程切换演示([2/3])
|
||||
3、输出速率切换([3/3])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "QMC5883L_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 qmc5883l_demo.lua 演示模块
|
||||
require "qmc5883l_demo"
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!
|
||||
@@ -0,0 +1,144 @@
|
||||
--[[
|
||||
@module qmc5883l_demo
|
||||
@summary QMC5883L 三轴地磁传感器演示模块,包含所有功能的演示用例
|
||||
@version 2.0
|
||||
@date 2026.07.17
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 QMC5883L 的逐项功能演示。
|
||||
通过 exs_qmc5883l 扩展库的 API 逐一演示数据读取、量程切换、输出速率切换、休眠唤醒等功能。
|
||||
]]
|
||||
|
||||
local exs_qmc5883l = require "exs_qmc5883l"
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("qmc5883l_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_qmc5883l.setup({
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
})
|
||||
if not result then
|
||||
log.error("qmc5883l_demo", "QMC5883L 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
|
||||
log.info("qmc5883l_demo", "QMC5883L 初始化成功,版本:", exs_qmc5883l.version())
|
||||
|
||||
sys.wait(200)
|
||||
local data = exs_qmc5883l.get_data()
|
||||
if data then
|
||||
log.info("qmc5883l_demo", string.format("X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
else
|
||||
log.error("qmc5883l_demo", "读取数据失败")
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500)
|
||||
local d = exs_qmc5883l.get_data()
|
||||
if d then
|
||||
log.info("qmc5883l_demo", string.format("第%d次读取: X=%.2f Y=%.2f Z=%.2f uT", i, d.x, d.y, d.z))
|
||||
end
|
||||
end
|
||||
|
||||
log.info("qmc5883l_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] 量程切换演示
|
||||
local function demo_range_switch()
|
||||
log.info("qmc5883l_demo", "===== [2/4] 量程切换演示 =====")
|
||||
|
||||
log.info("qmc5883l_demo", "切换量程为 2G(高精度)")
|
||||
exs_qmc5883l.set_range("2G")
|
||||
sys.wait(300)
|
||||
|
||||
local data = exs_qmc5883l.get_data()
|
||||
if data then
|
||||
log.info("qmc5883l_demo", string.format("2G 量程: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("qmc5883l_demo", "切换量程为 8G(宽范围)")
|
||||
exs_qmc5883l.set_range("8G")
|
||||
sys.wait(300)
|
||||
|
||||
data = exs_qmc5883l.get_data()
|
||||
if data then
|
||||
log.info("qmc5883l_demo", string.format("8G 量程: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("qmc5883l_demo", "---- [2/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/4] 输出速率切换
|
||||
local function demo_odr_switch()
|
||||
log.info("qmc5883l_demo", "===== [3/4] 输出速率切换 =====")
|
||||
|
||||
local odr_list = {10, 50, 100, 200}
|
||||
for _, odr in ipairs(odr_list) do
|
||||
log.info("qmc5883l_demo", string.format("设置输出速率为 %dHz", odr))
|
||||
exs_qmc5883l.set_odr(odr)
|
||||
sys.wait(500)
|
||||
|
||||
local data = exs_qmc5883l.get_data()
|
||||
if data then
|
||||
log.info("qmc5883l_demo", string.format("%dHz 下: X=%.2f Y=%.2f Z=%.2f uT", odr, data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
exs_qmc5883l.set_odr(10)
|
||||
log.info("qmc5883l_demo", "---- [3/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/4] 休眠与唤醒演示
|
||||
local function demo_sleep_wakeup()
|
||||
log.info("qmc5883l_demo", "===== [4/4] 休眠与唤醒演示 =====")
|
||||
|
||||
log.info("qmc5883l_demo", "进入待机模式(低功耗)")
|
||||
exs_qmc5883l.sleep(); sys.wait(10000)
|
||||
sys.wait(500)
|
||||
|
||||
log.info("qmc5883l_demo", "从待机模式唤醒")
|
||||
exs_qmc5883l.wakeup()
|
||||
sys.wait(200)
|
||||
|
||||
local data = exs_qmc5883l.get_data()
|
||||
if data then
|
||||
log.info("qmc5883l_demo", string.format("唤醒后数据: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
log.info("qmc5883l_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function qmc5883l_demo_task_func()
|
||||
log.info("qmc5883l_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("qmc5883l_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500)
|
||||
|
||||
demo_range_switch()
|
||||
sys.wait(500)
|
||||
|
||||
demo_odr_switch()
|
||||
sys.wait(500)
|
||||
|
||||
demo_sleep_wakeup()
|
||||
sys.wait(500)
|
||||
|
||||
log.info("qmc5883l_demo", "===== [演示完毕] =====")
|
||||
exs_qmc5883l.close()
|
||||
log.info("qmc5883l_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(qmc5883l_demo_task_func)
|
||||
@@ -0,0 +1,217 @@
|
||||
# QMC5883L 三轴地磁传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **qmc5883l_demo.lua** - QMC5883L 功能演示模块,包含数据读取、量程切换、输出速率切换等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_qmc5883l** - QMC5883L 扩展库,提供初始化、三轴磁场数据读取、量程切换、输出速率切换、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:QMC5883L 在异常 I2C 通信后可能锁死 SDA 总线。本库已内置 I2C 总线卡死自动检测与恢复功能。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_qmc5883l 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 QMC5883L 传感器并读取三轴磁场数据(X/Y/Z,单位 μT)
|
||||
2. **[2/4] 量程切换演示** - 在 ±2G(高精度)和 ±8G(宽范围)量程之间切换,观察数据变化
|
||||
3. **[3/4] 输出速率切换** - 依次切换 10Hz / 50Hz / 100Hz / 200Hz 输出速率
|
||||
4. **[4/4] 休眠与唤醒演示** - 演示 sleep()/wakeup() 待机与唤醒
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- QMC5883L 三轴地磁传感器模块 × 1
|
||||
demo所演示的QMC5883L 三轴地磁传感器模块[购买链接](https://detail.tmall.com/item.htm?abbucket=12&id=41286452886&mi_id=0000mL_358u9JOlcX4nXEexqz-sHmWlRSDzJVprt2nO-dBw&ns=1&priceTId=215045e417839191910527013e1198&skuId=5886090880527&spm=a21n57.1.hoverItem.10&utparam=%7B%22aplus_abtest%22%3A%22dc3bc40800adf636989efd96ef16c269%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 5
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 QMC5883L 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>QMC5883L 模块<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>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 程序入口
|
||||
2. **qmc5883l_demo.lua** - QMC5883L 功能演示模块
|
||||
3. **exs_qmc5883l** - QMC5883L 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 QMC5883L 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 qmc5883l_demo.lua 演示模块
|
||||
require "qmc5883l_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴磁场数据(X/Y/Z,单位 μT)的连续读取
|
||||
|
||||
#### 6.4.2 量程切换演示
|
||||
|
||||
1. 自动进入 [2/4] 量程切换演示
|
||||
2. 观察 ±2G 高精度量程下的数据
|
||||
3. 观察 ±8G 宽范围量程下的数据
|
||||
|
||||
#### 6.4.3 输出速率切换演示
|
||||
|
||||
1. 自动进入 [3/4] 输出速率切换演示
|
||||
2. 依次观察 10Hz / 50Hz / 100Hz / 200Hz 下的数据读取
|
||||
3. 最终恢复为 10Hz
|
||||
|
||||
#### 6.4.4 休眠与唤醒演示
|
||||
|
||||
1. 自动进入 [4/4] 休眠与唤醒演示
|
||||
2. 观察 sleep() 进入待机模式
|
||||
3. 观察 wakeup() 唤醒后数据恢复
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:QMC5883L 初始化成功,三轴磁场数据正常输出
|
||||
- **量程切换**:量程切换后数据范围随之变化,灵敏度不同
|
||||
- **输出速率切换**:不同速率下均能正常读取数据
|
||||
- **休眠与唤醒**:sleep 后进入低功耗,wakeup 后数据读取正常
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:31:33.902][000000000.180] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:31:33.908][000000000.180] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:31:33.914][000000000.182] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:31:33.921][000000000.184] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:31:33.930][000000000.184] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:31:33.940][000000000.185] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:31:33.945][000000000.202] I/user.main QMC5883L_Demo 001.999.000
|
||||
[2026-07-21 10:31:33.953][000000000.215] D/user.exs_qmc5883l version -> 202607200639
|
||||
[2026-07-21 10:31:33.958][000000000.216] I/user.qmc5883l_demo HELLO
|
||||
[2026-07-21 10:31:34.544][000000001.216] I/user.qmc5883l_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-07-21 10:31:34.551][000000001.224] I/user.exs_qmc5883l I2C总线恢复完成
|
||||
[2026-07-21 10:31:34.561][000000001.230] I/user.exs_qmc5883l 初始化完成, range=8G odr=10Hz osr=512
|
||||
[2026-07-21 10:31:34.571][000000001.231] I/user.qmc5883l_demo QMC5883L 初始化成功,版本: 202607200639
|
||||
[2026-07-21 10:31:34.586][000000001.434] I/user.qmc5883l_demo X=-25.90 Y=13.70 Z=13.33 uT
|
||||
[2026-07-21 10:31:36.087][000000002.863] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:31:36.099][000000002.863] D/mobile cid1, state0
|
||||
[2026-07-21 10:31:36.113][000000002.864] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:31:36.125][000000002.864] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:31:36.133][000000002.906] D/mobile TIME_SYNC 0 tm 1784601099
|
||||
[2026-07-21 10:31:36.144][000000002.937] I/user.qmc5883l_demo 第1次读取: X=-30.07 Y=14.53 Z=7.33 uT
|
||||
[2026-07-21 10:31:36.579][000000003.440] I/user.qmc5883l_demo 第2次读取: X=-29.90 Y=15.93 Z=3.53 uT
|
||||
[2026-07-21 10:31:37.075][000000003.943] I/user.qmc5883l_demo 第3次读取: X=-19.70 Y=21.90 Z=-12.53 uT
|
||||
[2026-07-21 10:31:37.088][000000003.943] I/user.qmc5883l_demo ---- [1/4] 完成 ----
|
||||
[2026-07-21 10:31:37.572][000000004.443] I/user.qmc5883l_demo ===== [2/4] 量程切换演示 =====
|
||||
[2026-07-21 10:31:37.587][000000004.444] I/user.qmc5883l_demo 切换量程为 2G(高精度)
|
||||
[2026-07-21 10:31:37.599][000000004.446] I/user.exs_qmc5883l 量程切换为 2G
|
||||
[2026-07-21 10:31:37.884][000000004.749] I/user.qmc5883l_demo 2G 量程: X=8.56 Y=16.00 Z=-10.85 uT
|
||||
[2026-07-21 10:31:38.892][000000005.749] I/user.qmc5883l_demo 切换量程为 8G(宽范围)
|
||||
[2026-07-21 10:31:38.906][000000005.752] I/user.exs_qmc5883l 量程切换为 8G
|
||||
[2026-07-21 10:31:39.186][000000006.055] I/user.qmc5883l_demo 8G 量程: X=-37.03 Y=10.07 Z=-3.60 uT
|
||||
[2026-07-21 10:31:40.192][000000007.055] I/user.qmc5883l_demo ---- [2/4] 完成 ----
|
||||
[2026-07-21 10:31:40.690][000000007.555] I/user.qmc5883l_demo ===== [3/4] 输出速率切换 =====
|
||||
[2026-07-21 10:31:40.701][000000007.556] I/user.qmc5883l_demo 设置输出速率为 10Hz
|
||||
[2026-07-21 10:31:40.711][000000007.558] I/user.exs_qmc5883l 输出速率切换为 10Hz
|
||||
[2026-07-21 10:31:41.203][000000008.061] I/user.qmc5883l_demo 10Hz 下: X=-16.93 Y=-30.57 Z=-4.20 uT
|
||||
[2026-07-21 10:31:41.696][000000008.561] I/user.qmc5883l_demo 设置输出速率为 50Hz
|
||||
[2026-07-21 10:31:41.709][000000008.564] I/user.exs_qmc5883l 输出速率切换为 50Hz
|
||||
[2026-07-21 10:31:42.208][000000009.067] I/user.qmc5883l_demo 50Hz 下: X=-32.77 Y=-15.93 Z=7.07 uT
|
||||
[2026-07-21 10:31:42.704][000000009.567] I/user.qmc5883l_demo 设置输出速率为 100Hz
|
||||
[2026-07-21 10:31:42.717][000000009.570] I/user.exs_qmc5883l 输出速率切换为 100Hz
|
||||
[2026-07-21 10:31:43.201][000000010.073] I/user.qmc5883l_demo 100Hz 下: X=-33.20 Y=-13.87 Z=8.43 uT
|
||||
[2026-07-21 10:31:43.715][000000010.573] I/user.qmc5883l_demo 设置输出速率为 200Hz
|
||||
[2026-07-21 10:31:43.725][000000010.576] I/user.exs_qmc5883l 输出速率切换为 200Hz
|
||||
[2026-07-21 10:31:44.213][000000011.079] I/user.qmc5883l_demo 200Hz 下: X=-32.93 Y=-13.70 Z=8.43 uT
|
||||
[2026-07-21 10:31:44.711][000000011.581] I/user.exs_qmc5883l 输出速率切换为 10Hz
|
||||
[2026-07-21 10:31:44.722][000000011.582] I/user.qmc5883l_demo ---- [3/4] 完成 ----
|
||||
[2026-07-21 10:31:45.211][000000012.082] I/user.qmc5883l_demo ===== [4/4] 休眠与唤醒演示 =====
|
||||
[2026-07-21 10:31:45.222][000000012.083] I/user.qmc5883l_demo 进入待机模式(低功耗)
|
||||
[2026-07-21 10:31:45.233][000000012.084] I/user.exs_qmc5883l 已进入待机模式
|
||||
[2026-07-21 10:31:55.716][000000022.584] I/user.qmc5883l_demo 从待机模式唤醒
|
||||
[2026-07-21 10:31:55.727][000000022.585] I/user.exs_qmc5883l 已从待机模式唤醒
|
||||
[2026-07-21 10:31:55.918][000000022.788] I/user.qmc5883l_demo 唤醒后数据: X=-32.70 Y=-13.93 Z=8.53 uT
|
||||
[2026-07-21 10:31:55.930][000000022.788] I/user.qmc5883l_demo ---- [4/4] 完成 ----
|
||||
[2026-07-21 10:31:56.431][000000023.289] I/user.qmc5883l_demo ===== [演示完毕] =====
|
||||
[2026-07-21 10:31:56.445][000000023.290] I/user.exs_qmc5883l 传感器已关闭
|
||||
[2026-07-21 10:31:56.461][000000023.291] I/user.qmc5883l_demo End
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 QMC5883L 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_qmc5883l 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(QMC5883L 7 位地址为 0x0D,写操作地址 0x1A)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **量程切换无效果**:
|
||||
|
||||
- 确认 `set_range()` 参数为 "2G" 或 "8G"
|
||||
- 切换后需等待传感器稳定再读取数据
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_qmc5883l 更多接口的使用可以查看 [exs_qmc5883l 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_qmc5883l/)
|
||||
@@ -0,0 +1,73 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary QMC5883P 三轴地磁传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.08.05
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_qmc5883p 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/7]→[2/7]→[3/7]→[4/7]→[5/7]→[6/7]→[7/7]→End
|
||||
|
||||
1、初始化和数据读取([1/7])
|
||||
2、量程切换演示([2/7])
|
||||
3、输出速率切换([3/7])
|
||||
4、过采样/降采样配置([4/7])
|
||||
5、软复位演示([5/7])
|
||||
6、芯片自检演示([6/7])
|
||||
7、休眠唤醒与关闭([7/7])
|
||||
|
||||
更多说明参考本目录下的 readme.md 文件
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
|
||||
PROJECT = "QMC5883P_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 qmc5883p_app.lua 演示模块
|
||||
require "qmc5883p_app"
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!
|
||||
@@ -0,0 +1,289 @@
|
||||
--[[
|
||||
@module qmc5883p_app
|
||||
@summary QMC5883P 三轴地磁传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.08.05
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 QMC5883P 的逐项功能演示。
|
||||
通过 exs_qmc5883p 扩展库的 API 逐一演示数据读取、量程切换、输出速率切换、
|
||||
过采样/降采样配置、软复位、芯片自检、休眠唤醒等功能。
|
||||
|
||||
通过 MODE 变量选择通信模式(改 MODE 的值即可,无需注释/取消注释代码):
|
||||
MODE = 1 软件 I2C(默认推荐,仅需 scl/sda 引脚,任意 GPIO 均可,接线最灵活)
|
||||
MODE = 2 硬件 I2C(指定 i2c_id,占用 CPU 少,Air780EPM 用 I2C1)
|
||||
]]
|
||||
|
||||
-- 加载 exs_qmc5883p 扩展库
|
||||
-- 该库提供 QMC5883P 的全部驱动功能: 初始化/数据读取/量程配置/速率配置/自检/电源管理
|
||||
local exs_qmc5883p = require "exs_qmc5883p"
|
||||
|
||||
-- ==================== 通信模式选择 ====================
|
||||
-- 改 MODE 的值选择通信模式:
|
||||
-- 1 = 软件 I2C(默认) 2 = 硬件 I2C
|
||||
-- 各模式所需引脚/参数见下方 init_config,接线说明见 readme.md
|
||||
local MODE = 1
|
||||
|
||||
local init_config
|
||||
if MODE == 1 then
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO,Air780EPM 接线示例用 GPIO31/GPIO30
|
||||
init_config = {scl = 31, sda = 30}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_id 为总线号(Air780EPM 用 1),不传 scl/sda 时无总线恢复能力
|
||||
init_config = {i2c_id = 1}
|
||||
else
|
||||
log.error("qmc5883p_demo", "MODE 取值错误,应为 1/2")
|
||||
return
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [1/7] 初始化与数据读取
|
||||
-- - setup() 自动完成芯片 ID 校验、I2C 总线恢复、采样参数配置
|
||||
-- - get_data() 返回三轴磁场强度,单位 μT,并带溢出标志 overflow
|
||||
--------------------------------------------------------------
|
||||
local function demo_init_and_read()
|
||||
log.info("qmc5883p_demo", "===== [1/7] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_qmc5883p.setup(init_config)
|
||||
if not result then
|
||||
log.error("qmc5883p_demo", "QMC5883P 初始化失败")
|
||||
log.error("qmc5883p_demo", "检查接线: VCC=3.3V GND SCL SDA")
|
||||
return false -- 初始化失败必须返回 false
|
||||
end
|
||||
|
||||
log.info("qmc5883p_demo", "QMC5883P 初始化成功,版本:", exs_qmc5883p.version())
|
||||
|
||||
sys.wait(200) -- 等待首次测量数据就绪,200ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
else
|
||||
log.error("qmc5883p_demo", "读取数据失败")
|
||||
end
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500) -- 每 500ms 读取一次
|
||||
local d = exs_qmc5883p.get_data()
|
||||
if d then
|
||||
log.info("qmc5883p_demo", string.format("第%d次读取: X=%.2f Y=%.2f Z=%.2f uT", i, d.x, d.y, d.z))
|
||||
end
|
||||
end
|
||||
|
||||
log.info("qmc5883p_demo", "---- [1/7] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [2/7] 量程切换演示
|
||||
-- - set_range() 支持 "2G"/"8G"/"12G"/"30G" 四种量程
|
||||
-- - 切换后 get_data() 自动按新灵敏度换算 μT 值,无需重新 setup()
|
||||
--------------------------------------------------------------
|
||||
local function demo_range_switch()
|
||||
log.info("qmc5883p_demo", "===== [2/7] 量程切换演示 =====")
|
||||
|
||||
log.info("qmc5883p_demo", "切换量程为 2G(高精度,灵敏度 15000 LSB/G)")
|
||||
exs_qmc5883p.set_range("2G")
|
||||
sys.wait(300) -- 等待量程切换生效,300ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("2G 量程: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000) -- 展示间隔,1 秒
|
||||
|
||||
log.info("qmc5883p_demo", "切换量程为 8G(宽范围,灵敏度 3750 LSB/G)")
|
||||
exs_qmc5883p.set_range("8G")
|
||||
sys.wait(300) -- 等待量程切换生效,300ms
|
||||
|
||||
data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("8G 量程: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000) -- 展示间隔,1 秒
|
||||
|
||||
log.info("qmc5883p_demo", "切换量程为 30G(最宽量程,抗干扰最强)")
|
||||
exs_qmc5883p.set_range("30G")
|
||||
sys.wait(300) -- 等待量程切换生效,300ms
|
||||
|
||||
data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("30G 量程: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
-- 恢复默认量程
|
||||
exs_qmc5883p.set_range("8G")
|
||||
log.info("qmc5883p_demo", "---- [2/7] 完成 ----")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [3/7] 输出速率切换演示
|
||||
-- - set_odr() 支持 10Hz / 50Hz / 100Hz / 200Hz
|
||||
-- - ODR 越低功耗越低,越高响应越快
|
||||
--------------------------------------------------------------
|
||||
local function demo_odr_switch()
|
||||
log.info("qmc5883p_demo", "===== [3/7] 输出速率切换 =====")
|
||||
|
||||
local odr_list = {10, 50, 100, 200}
|
||||
for _, odr in ipairs(odr_list) do
|
||||
log.info("qmc5883p_demo", string.format("设置输出速率为 %dHz", odr))
|
||||
exs_qmc5883p.set_odr(odr)
|
||||
sys.wait(500) -- 等待速率配置生效,500ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("%dHz 下: X=%.2f Y=%.2f Z=%.2f uT", odr, data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(500) -- 展示间隔,500ms
|
||||
end
|
||||
|
||||
exs_qmc5883p.set_odr(10) -- 恢复默认 10Hz
|
||||
log.info("qmc5883p_demo", "---- [3/7] 完成 ----")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [4/7] 过采样/降采样配置演示
|
||||
-- - set_osr(osr, osr2):osr 为过采样率(8/4/2/1),osr2 为降采样率(1/2/4/8)
|
||||
-- - 两者乘积最大 64,值越大噪声越低、功耗越高
|
||||
--------------------------------------------------------------
|
||||
local function demo_osr_config()
|
||||
log.info("qmc5883p_demo", "===== [4/7] 过采样/降采样配置 =====")
|
||||
|
||||
log.info("qmc5883p_demo", "配置为最高滤波:OSR1=8(过采样 8 次)+ OSR2=8(降采样 8 次)")
|
||||
exs_qmc5883p.set_osr(8, 8)
|
||||
sys.wait(300) -- 等待配置生效,300ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("最高滤波: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000) -- 展示间隔,1 秒
|
||||
|
||||
log.info("qmc5883p_demo", "配置为最低功耗:OSR1=1 + OSR2=1")
|
||||
exs_qmc5883p.set_osr(1, 1)
|
||||
sys.wait(300) -- 等待配置生效,300ms
|
||||
|
||||
data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("最低功耗: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
-- 恢复默认配置
|
||||
exs_qmc5883p.set_osr(8, 8)
|
||||
log.info("qmc5883p_demo", "---- [4/7] 完成 ----")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [5/7] 软复位演示
|
||||
-- - soft_reset() 复位芯片后自动重新应用当前配置,无需重新 setup()
|
||||
--------------------------------------------------------------
|
||||
local function demo_soft_reset()
|
||||
log.info("qmc5883p_demo", "===== [5/7] 软复位演示 =====")
|
||||
|
||||
local result = exs_qmc5883p.soft_reset()
|
||||
if not result then
|
||||
log.error("qmc5883p_demo", "软复位失败")
|
||||
return false
|
||||
end
|
||||
log.info("qmc5883p_demo", "软复位完成,配置已恢复")
|
||||
sys.wait(300) -- 等待复位后数据稳定,300ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("复位后数据: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
log.info("qmc5883p_demo", "---- [5/7] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [6/7] 芯片自检演示
|
||||
-- - self_test() 利用芯片内置自检激励信号验证信号链路是否正常
|
||||
-- - 返回自检前后三轴增量(单位 LSB),增量明显大于正常噪声
|
||||
-- 表示信号链路正常
|
||||
--------------------------------------------------------------
|
||||
local function demo_self_test()
|
||||
log.info("qmc5883p_demo", "===== [6/7] 芯片自检演示 =====")
|
||||
|
||||
local delta = exs_qmc5883p.self_test()
|
||||
if not delta then
|
||||
log.error("qmc5883p_demo", "芯片自检失败")
|
||||
return false
|
||||
end
|
||||
log.info("qmc5883p_demo", string.format("自检增量 dx=%d dy=%d dz=%d", delta.dx, delta.dy, delta.dz))
|
||||
log.info("qmc5883p_demo", "自检增量明显大于正常噪声表示信号链路正常")
|
||||
log.info("qmc5883p_demo", "---- [6/7] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [7/7] 休眠唤醒与关闭
|
||||
-- - sleep() 进入挂起模式(功耗约 22 μA),wakeup() 快速恢复,无需重新 setup()
|
||||
-- - close() 关闭传感器,之后需重新 setup() 才能使用
|
||||
--------------------------------------------------------------
|
||||
local function demo_sleep_wakeup_close()
|
||||
log.info("qmc5883p_demo", "===== [7/7] 休眠唤醒与关闭 =====")
|
||||
|
||||
log.info("qmc5883p_demo", "进入挂起模式(低功耗约 22 μA)")
|
||||
exs_qmc5883p.sleep()
|
||||
sys.wait(3000) -- 挂起演示 3 秒
|
||||
|
||||
log.info("qmc5883p_demo", "从挂起模式唤醒")
|
||||
exs_qmc5883p.wakeup()
|
||||
sys.wait(200) -- 等待唤醒后数据稳定,200ms
|
||||
|
||||
local data = exs_qmc5883p.get_data()
|
||||
if data then
|
||||
log.info("qmc5883p_demo", string.format("唤醒后数据: X=%.2f Y=%.2f Z=%.2f uT", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
exs_qmc5883p.close()
|
||||
log.info("qmc5883p_demo", "---- [7/7] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- 主任务:按 [1/7]~[7/7] 顺序执行全部演示
|
||||
--------------------------------------------------------------
|
||||
local function qmc5883p_demo_task_func()
|
||||
log.info("qmc5883p_demo", "HELLO")
|
||||
sys.wait(1000) -- 等待系统启动稳定,1 秒
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("qmc5883p_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_range_switch()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_odr_switch()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_osr_config()
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
ok = demo_soft_reset()
|
||||
if not ok then
|
||||
log.error("qmc5883p_demo", "软复位失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
ok = demo_self_test()
|
||||
if not ok then
|
||||
log.error("qmc5883p_demo", "自检失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 演示间隔,500ms
|
||||
|
||||
demo_sleep_wakeup_close()
|
||||
|
||||
log.info("qmc5883p_demo", "===== [演示完毕] =====")
|
||||
log.info("qmc5883p_demo", "End")
|
||||
end
|
||||
|
||||
-- 启动演示任务协程
|
||||
sys.taskInit(qmc5883p_demo_task_func)
|
||||
@@ -0,0 +1,265 @@
|
||||
# QMC5883P 三轴地磁传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **qmc5883p_app.lua** - QMC5883P 功能演示模块,包含数据读取、量程切换、输出速率切换、过采样/降采样配置、软复位、自检、休眠唤醒等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_qmc5883p** - QMC5883P 扩展库,提供初始化、三轴磁场数据读取、量程切换、输出速率切换、过采样/降采样配置、软复位、芯片自检、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:QMC5883P 在异常 I2C 通信后可能锁死 SDA 总线。本库已内置 I2C 总线卡死自动检测与恢复功能。本 demo 默认使用软件 I2C 模式演示,也可通过 `qmc5883p_app.lua` 中的 `MODE` 变量切换为硬件 I2C 模式。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_qmc5883p 扩展库的 7 项功能:HELLO → [1/7] → [2/7] → [3/7] → [4/7] → [5/7] → [6/7] → [7/7] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/7] 初始化与数据读取** - 初始化 QMC5883P 传感器并读取三轴磁场数据(X/Y/Z,单位 μT)
|
||||
2. **[2/7] 量程切换演示** - 在 ±2G(高精度)、±8G(宽范围)和 ±30G(最宽量程)之间切换,观察数据变化
|
||||
3. **[3/7] 输出速率切换** - 依次切换 10Hz / 50Hz / 100Hz / 200Hz 输出速率
|
||||
4. **[4/7] 过采样/降采样配置** - 演示过采样率(OSR1)与降采样率(OSR2)的组合配置
|
||||
5. **[5/7] 软复位演示** - 软复位芯片并自动恢复当前配置
|
||||
6. **[6/7] 芯片自检演示** - 利用芯片内置自检激励信号验证信号链路是否正常
|
||||
7. **[7/7] 休眠唤醒与关闭** - 演示 sleep()/wakeup() 挂起与唤醒,以及 close() 关闭
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 4.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- QMC5883P 三轴地磁传感器模块 × 1
|
||||
demo所演示的QMC5883P[购买链接](https://item.taobao.com/item.htm?id=40554139118&mi_id=000052zSrRJbsW6EV_ocgwEuuox1wD1Jox20itdXNm9CiTc&skuId=4534297737305&spm=tbpc.boughtlist.suborder_itemtitle.1.67002e8dIVsk7g)
|
||||
- 母对母杜邦线 × 5
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 4.2 接线配置
|
||||
|
||||
#### 4.2.1 QMC5883P 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>QMC5883P 模块<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>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 程序入口
|
||||
2. **qmc5883p_app.lua** - QMC5883P 功能演示模块
|
||||
3. **exs_qmc5883p** - QMC5883P 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 QMC5883P 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 qmc5883p_app.lua 演示模块
|
||||
require "qmc5883p_app"
|
||||
```
|
||||
|
||||
如需切换通信模式,修改 `qmc5883p_app.lua` 中的 `MODE` 变量(1=软件 I2C,2=硬件 I2C)。
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/7] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴磁场数据(X/Y/Z,单位 μT)的连续读取
|
||||
|
||||
#### 6.4.2 量程切换演示
|
||||
|
||||
1. 自动进入 [2/7] 量程切换演示
|
||||
2. 观察 ±2G 高精度量程下的数据
|
||||
3. 观察 ±8G 宽范围量程下的数据
|
||||
4. 观察 ±30G 最宽量程下的数据
|
||||
|
||||
#### 6.4.3 输出速率切换演示
|
||||
|
||||
1. 自动进入 [3/7] 输出速率切换演示
|
||||
2. 依次观察 10Hz / 50Hz / 100Hz / 200Hz 下的数据读取
|
||||
3. 最终恢复为 10Hz
|
||||
|
||||
#### 6.4.4 过采样/降采样配置演示
|
||||
|
||||
1. 自动进入 [4/7] 过采样/降采样配置演示
|
||||
2. 观察最高滤波配置(OSR1=8 + OSR2=8)下的数据
|
||||
3. 观察最低功耗配置(OSR1=1 + OSR2=1)下的数据
|
||||
|
||||
#### 6.4.5 软复位演示
|
||||
|
||||
1. 自动进入 [5/7] 软复位演示
|
||||
2. 观察软复位完成后配置自动恢复
|
||||
3. 观察复位后的数据读取
|
||||
|
||||
#### 6.4.6 芯片自检演示
|
||||
|
||||
1. 自动进入 [6/7] 芯片自检演示
|
||||
2. 观察自检增量 dx/dy/dz 输出
|
||||
3. 增量明显大于正常噪声表示信号链路正常
|
||||
|
||||
#### 6.4.7 休眠唤醒与关闭演示
|
||||
|
||||
1. 自动进入 [7/7] 休眠唤醒与关闭演示
|
||||
2. 观察 sleep() 进入挂起模式
|
||||
3. 观察 wakeup() 唤醒后数据恢复
|
||||
4. 观察 close() 关闭传感器
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:QMC5883P 初始化成功,三轴磁场数据正常输出
|
||||
- **量程切换**:量程切换后数据范围随之变化,灵敏度不同
|
||||
- **输出速率切换**:不同速率下均能正常读取数据
|
||||
- **过采样/降采样配置**:配置切换后均能正常读取数据
|
||||
- **软复位**:复位后配置自动恢复,数据读取正常
|
||||
- **芯片自检**:自检增量明显大于噪声,信号链路正常
|
||||
- **休眠唤醒与关闭**:sleep 后进入低功耗,wakeup 后数据读取正常
|
||||
|
||||
**日志如下:**
|
||||
|
||||
```lua
|
||||
[2026-08-07 14:44:44.084][000000000.200] I/user.main QMC5883P_Demo 001.999.000
|
||||
[2026-08-07 14:44:44.090][000000000.215] D/user.exs_qmc5883p version -> 202608050000
|
||||
[2026-08-07 14:44:44.099][000000000.216] I/user.qmc5883p_demo HELLO
|
||||
[2026-08-07 14:44:44.219][000000001.216] I/user.qmc5883p_demo ===== [1/7] 初始化与数据读取 =====
|
||||
[2026-08-07 14:44:44.224][000000001.222] I/user.exs_qmc5883p I2C总线恢复完成
|
||||
[2026-08-07 14:44:44.229][000000001.229] I/user.exs_qmc5883p 初始化完成, range=8G odr=10Hz osr=8 osr2=8 set_reset=on
|
||||
[2026-08-07 14:44:44.237][000000001.229] I/user.qmc5883p_demo QMC5883P 初始化成功,版本: 202608050000
|
||||
[2026-08-07 14:44:44.242][000000001.431] I/user.exs_qmc5883p 首次读取原始字节: F4 FC 23 FB 31 FF
|
||||
[2026-08-07 14:44:44.251][000000001.433] I/user.qmc5883p_demo X=-20.80 Y=-33.20 Z=-5.52 uT
|
||||
[2026-08-07 14:44:44.418][000000001.937] I/user.qmc5883p_demo 第1次读取: X=-20.83 Y=-33.39 Z=-5.71 uT
|
||||
[2026-08-07 14:44:44.929][000000002.441] I/user.qmc5883p_demo 第2次读取: X=-20.80 Y=-33.36 Z=-5.81 uT
|
||||
[2026-08-07 14:44:45.426][000000002.945] I/user.qmc5883p_demo 第3次读取: X=-22.00 Y=-29.60 Z=-6.40 uT
|
||||
[2026-08-07 14:44:45.433][000000002.945] I/user.qmc5883p_demo ---- [1/7] 完成 ----
|
||||
[2026-08-07 14:44:45.922][000000003.445] I/user.qmc5883p_demo ===== [2/7] 量程切换演示 =====
|
||||
[2026-08-07 14:44:45.926][000000003.445] I/user.qmc5883p_demo 切换量程为 2G(高精度,灵敏度 15000 LSB/G)
|
||||
[2026-08-07 14:44:45.938][000000003.450] I/user.exs_qmc5883p 量程切换为 2G
|
||||
[2026-08-07 14:44:46.234][000000003.754] I/user.qmc5883p_demo 2G 量程: X=-16.60 Y=-6.70 Z=-29.81 uT
|
||||
[2026-08-07 14:44:47.229][000000004.754] I/user.qmc5883p_demo 切换量程为 8G(宽范围,灵敏度 3750 LSB/G)
|
||||
[2026-08-07 14:44:47.244][000000004.758] I/user.exs_qmc5883p 量程切换为 8G
|
||||
[2026-08-07 14:44:47.541][000000005.062] I/user.qmc5883p_demo 8G 量程: X=31.09 Y=5.89 Z=-17.23 uT
|
||||
[2026-08-07 14:44:48.551][000000006.062] I/user.qmc5883p_demo 切换量程为 30G(最宽量程,抗干扰最强)
|
||||
[2026-08-07 14:44:48.558][000000006.066] I/user.exs_qmc5883p 量程切换为 30G
|
||||
[2026-08-07 14:44:48.847][000000006.370] I/user.qmc5883p_demo 30G 量程: X=-16.50 Y=5.40 Z=-19.00 uT
|
||||
[2026-08-07 14:44:48.862][000000006.374] I/user.exs_qmc5883p 量程切换为 8G
|
||||
[2026-08-07 14:44:48.868][000000006.374] I/user.qmc5883p_demo ---- [2/7] 完成 ----
|
||||
[2026-08-07 14:44:49.361][000000006.874] I/user.qmc5883p_demo ===== [3/7] 输出速率切换 =====
|
||||
[2026-08-07 14:44:49.368][000000006.875] I/user.qmc5883p_demo 设置输出速率为 10Hz
|
||||
[2026-08-07 14:44:49.373][000000006.879] I/user.exs_qmc5883p 输出速率切换为 10Hz
|
||||
[2026-08-07 14:44:49.859][000000007.383] I/user.qmc5883p_demo 10Hz 下: X=-23.39 Y=-9.60 Z=-20.96 uT
|
||||
[2026-08-07 14:44:50.367][000000007.883] I/user.qmc5883p_demo 设置输出速率为 50Hz
|
||||
[2026-08-07 14:44:50.371][000000007.887] I/user.exs_qmc5883p 输出速率切换为 50Hz
|
||||
[2026-08-07 14:44:50.866][000000008.391] I/user.qmc5883p_demo 50Hz 下: X=11.52 Y=-20.48 Z=19.33 uT
|
||||
[2026-08-07 14:44:51.366][000000008.891] I/user.qmc5883p_demo 设置输出速率为 100Hz
|
||||
[2026-08-07 14:44:51.382][000000008.895] I/user.exs_qmc5883p 输出速率切换为 100Hz
|
||||
[2026-08-07 14:44:51.881][000000009.399] I/user.qmc5883p_demo 100Hz 下: X=-14.75 Y=-15.76 Z=12.11 uT
|
||||
[2026-08-07 14:44:52.378][000000009.899] I/user.qmc5883p_demo 设置输出速率为 200Hz
|
||||
[2026-08-07 14:44:52.383][000000009.903] I/user.exs_qmc5883p 输出速率切换为 200Hz
|
||||
[2026-08-07 14:44:52.891][000000010.407] I/user.qmc5883p_demo 200Hz 下: X=-19.97 Y=-13.39 Z=-27.09 uT
|
||||
[2026-08-07 14:44:53.389][000000010.911] I/user.exs_qmc5883p 输出速率切换为 10Hz
|
||||
[2026-08-07 14:44:53.400][000000010.911] I/user.qmc5883p_demo ---- [3/7] 完成 ----
|
||||
[2026-08-07 14:44:53.889][000000011.411] I/user.qmc5883p_demo ===== [4/7] 过采样/降采样配置 =====
|
||||
[2026-08-07 14:44:53.893][000000011.411] I/user.qmc5883p_demo 配置为最高滤波:OSR1=8(过采样 8 次)+ OSR2=8(降采样 8 次)
|
||||
[2026-08-07 14:44:53.907][000000011.416] I/user.exs_qmc5883p 过采样/降采样配置为 osr=8 osr2=8
|
||||
[2026-08-07 14:44:54.199][000000011.720] I/user.qmc5883p_demo 最高滤波: X=-19.60 Y=-11.20 Z=-25.89 uT
|
||||
[2026-08-07 14:44:55.206][000000012.720] I/user.qmc5883p_demo 配置为最低功耗:OSR1=1 + OSR2=1
|
||||
[2026-08-07 14:44:55.212][000000012.724] I/user.exs_qmc5883p 过采样/降采样配置为 osr=1 osr2=1
|
||||
[2026-08-07 14:44:55.504][000000013.028] I/user.qmc5883p_demo 最低功耗: X=-25.89 Y=-8.88 Z=-5.39 uT
|
||||
[2026-08-07 14:44:55.519][000000013.032] I/user.exs_qmc5883p 过采样/降采样配置为 osr=8 osr2=8
|
||||
[2026-08-07 14:44:55.526][000000013.032] I/user.qmc5883p_demo ---- [4/7] 完成 ----
|
||||
[2026-08-07 14:44:56.015][000000013.532] I/user.qmc5883p_demo ===== [5/7] 软复位演示 =====
|
||||
[2026-08-07 14:44:56.030][000000013.544] I/user.exs_qmc5883p 软复位完成,配置已恢复
|
||||
[2026-08-07 14:44:56.033][000000013.544] I/user.qmc5883p_demo 软复位完成,配置已恢复
|
||||
[2026-08-07 14:44:56.327][000000013.848] I/user.qmc5883p_demo 复位后数据: X=3.01 Y=5.31 Z=-5.41 uT
|
||||
[2026-08-07 14:44:56.334][000000013.848] I/user.qmc5883p_demo ---- [5/7] 完成 ----
|
||||
[2026-08-07 14:44:56.823][000000014.348] I/user.qmc5883p_demo ===== [6/7] 芯片自检演示 =====
|
||||
[2026-08-07 14:44:57.043][000000014.559] I/user.exs_qmc5883p 自检完成, 增量 dx=-154 dy=-130 dz=-84
|
||||
[2026-08-07 14:44:57.049][000000014.559] I/user.qmc5883p_demo 自检增量 dx=-154 dy=-130 dz=-84
|
||||
[2026-08-07 14:44:57.053][000000014.560] I/user.qmc5883p_demo 增量明显大于正常噪声(通常 >1000 LSB)表示信号链路正常
|
||||
[2026-08-07 14:44:57.058][000000014.560] I/user.qmc5883p_demo ---- [6/7] 完成 ----
|
||||
[2026-08-07 14:44:57.540][000000015.060] I/user.qmc5883p_demo ===== [7/7] 休眠唤醒与关闭 =====
|
||||
[2026-08-07 14:44:57.546][000000015.060] I/user.qmc5883p_demo 进入挂起模式(低功耗约 22 μA)
|
||||
[2026-08-07 14:44:57.551][000000015.062] I/user.exs_qmc5883p 已进入挂起模式
|
||||
[2026-08-07 14:45:00.545][000000018.062] I/user.qmc5883p_demo 从挂起模式唤醒
|
||||
[2026-08-07 14:45:00.551][000000018.064] I/user.exs_qmc5883p 已从挂起模式唤醒
|
||||
[2026-08-07 14:45:00.747][000000018.267] I/user.qmc5883p_demo 唤醒后数据: X=-4.85 Y=-0.27 Z=3.81 uT
|
||||
[2026-08-07 14:45:00.752][000000018.268] I/user.exs_qmc5883p 传感器已关闭
|
||||
[2026-08-07 14:45:00.754][000000018.268] I/user.qmc5883p_demo ---- [7/7] 完成 ----
|
||||
[2026-08-07 14:45:00.757][000000018.269] I/user.qmc5883p_demo ===== [演示完毕] =====
|
||||
[2026-08-07 14:45:00.761][000000018.269] I/user.qmc5883p_demo End
|
||||
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 QMC5883P 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_qmc5883p 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(QMC5883P 7 位地址为 0x2C,写操作地址 0x58,读操作地址 0x59)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **量程切换无效果**:
|
||||
|
||||
- 确认 `set_range()` 参数为 "2G"/"8G"/"12G"/"30G"
|
||||
- 切换后需等待传感器稳定再读取数据
|
||||
|
||||
4. **自检增量过小**:
|
||||
|
||||
- 确认传感器工作正常,供电稳定
|
||||
- 自检增量明显大于正常噪声表示信号链路正常
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_qmc5883p 更多接口的使用可以查看 [exs_qmc5883p 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_qmc5883p/)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary SC7A20H 三轴加速度传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.23
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_sc7a20h 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、初始化和数据读取([1/4])
|
||||
2、量程切换演示([2/4])
|
||||
3、输出速率切换([3/4])
|
||||
4、休眠与唤醒演示([4/4])
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "SC7A20H_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 sc7a20h_demo.lua 演示模块
|
||||
require "sc7a20h_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,216 @@
|
||||
# SC7A20H 三轴加速度传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **sc7a20h_demo.lua** - SC7A20H 功能演示模块,包含数据读取、量程切换、输出速率切换、休眠唤醒等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_sc7a20h** - SC7A20H 扩展库,提供初始化、三轴加速度数据读取、量程切换、输出速率切换、功耗模式切换、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:SC7A20H 在异常 I2C 通信后可能锁死 SDA 总线。本库已内置 I2C 总线卡死自动检测与恢复功能。本 demo 使用软件 I2C 模式演示。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_sc7a20h 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 初始化与数据读取** - 初始化 SC7A20H 传感器并读取三轴加速度数据(X/Y/Z,单位 g)
|
||||
2. **[2/4] 量程切换演示** - 在 ±2g(高精度)和 ±4g(宽范围)量程之间切换,观察数据变化
|
||||
3. **[3/4] 输出速率切换** - 依次切换 25Hz / 50Hz / 100Hz / 200Hz 输出速率
|
||||
4. **[4/4] 休眠与唤醒演示** - 演示 sleep()/wakeup() 待机与唤醒
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 4.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- SC7A20H 三轴加速度传感器模块 × 1
|
||||
demo所演示的SC7A20H 三轴加速度传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=952174888778&mi_id=0000k9PlrHnaylHxzFwS6fLcPWcOuAeIBtBNy8ctxSmKAXs&ns=1&priceTId=215045e417839190910407222e1198&spm=a21n57.1.hoverItem.3&utparam=%7B%22aplus_abtest%22%3A%22c1f47c9c4ac843532d170075a796f4a9%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 6
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 4.2 接线配置
|
||||
|
||||
#### 4.2.1 SC7A20H 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>SC7A20H 模块<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>30/GPIO29<br/></td><td>INT1<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 程序入口
|
||||
2. **sc7a20h_demo.lua** - SC7A20H 功能演示模块
|
||||
3. **exs_sc7a20h** - SC7A20H 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 SC7A20H 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 sc7a20h_demo.lua 演示模块
|
||||
require "sc7a20h_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 初始化与数据读取演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/4] 初始化与数据读取
|
||||
2. 观察日志输出,确认初始化成功
|
||||
3. 观察三轴加速度数据(X/Y/Z,单位 g)的连续读取
|
||||
|
||||
#### 6.4.2 量程切换演示
|
||||
|
||||
1. 自动进入 [2/4] 量程切换演示
|
||||
2. 观察 ±4g 宽范围量程下的数据
|
||||
3. 观察 ±2g 高精度量程下的数据
|
||||
|
||||
#### 6.4.3 输出速率切换演示
|
||||
|
||||
1. 自动进入 [3/4] 输出速率切换演示
|
||||
2. 依次观察 25Hz / 50Hz / 100Hz / 200Hz 下的数据读取
|
||||
3. 最终恢复为 100Hz
|
||||
|
||||
#### 6.4.4 休眠与唤醒演示
|
||||
|
||||
1. 自动进入 [4/4] 休眠与唤醒演示
|
||||
2. 观察 sleep() 进入待机模式
|
||||
3. 观察 wakeup() 唤醒后数据恢复
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **初始化与数据读取**:SC7A20H 初始化成功,三轴加速度数据正常输出
|
||||
- **量程切换**:量程切换后数据范围随之变化,灵敏度不同
|
||||
- **输出速率切换**:不同速率下均能正常读取数据
|
||||
- **休眠与唤醒**:sleep 后进入低功耗,wakeup 后数据读取正常
|
||||
- **打印日志**:
|
||||
```lua
|
||||
[2026-07-23 14:13:19.999][000000000.246] I/user.main SC7A20H_Demo 001.999.000
|
||||
[2026-07-23 14:13:20.005][000000000.262] D/user.exs_sc7a20h version -> 202607180900
|
||||
[2026-07-23 14:13:20.014][000000000.264] I/user.sc7a20h_demo HELLO
|
||||
[2026-07-23 14:13:20.506][000000001.265] I/user.sc7a20h_demo ===== [1/4] 初始化与数据读取 =====
|
||||
[2026-07-23 14:13:20.521][000000001.274] I/user.exs_sc7a20h SC7A20H @ I2C 0x18
|
||||
[2026-07-23 14:13:20.537][000000001.295] I/user.exs_sc7a20h REG读回 CTRL1=0x57 CTRL4=0x88 STATUS=0xFF INT1_CFG=0x00
|
||||
[2026-07-23 14:13:20.548][000000001.302] I/user.exs_sc7a20h INT1 已注册, gpio=29
|
||||
[2026-07-23 14:13:20.555][000000001.303] I/user.exs_sc7a20h 初始化完成 mode=I2C range=2g odr=100Hz mode=highres
|
||||
[2026-07-23 14:13:20.564][000000001.303] I/user.sc7a20h_demo SC7A20H 初始化成功,版本: 202607180900
|
||||
[2026-07-23 14:13:20.570][000000001.318] I/user.exs_sc7a20h CTRL1=0x57 CTRL2=0x01 CTRL3=0x40 CTRL4=0x88 CTRL5=0x08 CTRL6=0x00 STATUS=0xFF INT1_SRC=0x15 INT2_SRC=0x00 FIFO_SRC=0x20
|
||||
[2026-07-23 14:13:20.757][000000001.521] I/user.sc7a20h_demo X=-0.660 Y=0.545 Z=0.551 g
|
||||
[2026-07-23 14:13:22.264][000000003.024] I/user.sc7a20h_demo 第1次读取: X=-0.660 Y=0.549 Z=0.555 g
|
||||
[2026-07-23 14:13:22.774][000000003.527] I/user.sc7a20h_demo 第2次读取: X=-0.666 Y=0.552 Z=0.552 g
|
||||
[2026-07-23 14:13:23.269][000000004.030] I/user.sc7a20h_demo 第3次读取: X=-0.661 Y=0.545 Z=0.551 g
|
||||
[2026-07-23 14:13:23.273][000000004.030] I/user.sc7a20h_demo ---- [1/4] 完成 ----
|
||||
[2026-07-23 14:13:23.769][000000004.531] I/user.sc7a20h_demo ===== [2/4] 量程切换演示 =====
|
||||
[2026-07-23 14:13:23.773][000000004.531] I/user.sc7a20h_demo 切换量程为 4g
|
||||
[2026-07-23 14:13:23.776][000000004.534] I/user.exs_sc7a20h 量程切换为 4g
|
||||
[2026-07-23 14:13:24.080][000000004.836] I/user.sc7a20h_demo 4g 量程: X=-0.662 Y=0.545 Z=0.551 g
|
||||
[2026-07-23 14:13:25.076][000000005.837] I/user.sc7a20h_demo 切换量程为 2g(高精度)
|
||||
[2026-07-23 14:13:25.081][000000005.839] I/user.exs_sc7a20h 量程切换为 2g
|
||||
[2026-07-23 14:13:25.387][000000006.142] I/user.sc7a20h_demo 2g 量程: X=-0.663 Y=0.546 Z=0.556 g
|
||||
[2026-07-23 14:13:26.385][000000007.143] I/user.sc7a20h_demo ---- [2/4] 完成 ----
|
||||
[2026-07-23 14:13:26.882][000000007.643] I/user.sc7a20h_demo ===== [3/4] 输出速率切换 =====
|
||||
[2026-07-23 14:13:26.898][000000007.643] I/user.sc7a20h_demo 设置输出速率为 25Hz
|
||||
[2026-07-23 14:13:26.913][000000007.646] I/user.exs_sc7a20h 输出速率切换为 25Hz
|
||||
[2026-07-23 14:13:27.395][000000008.149] I/user.sc7a20h_demo 25Hz 下: X=-0.670 Y=0.551 Z=0.559 g
|
||||
[2026-07-23 14:13:27.891][000000008.650] I/user.sc7a20h_demo 设置输出速率为 50Hz
|
||||
[2026-07-23 14:13:27.903][000000008.653] I/user.exs_sc7a20h 输出速率切换为 50Hz
|
||||
[2026-07-23 14:13:28.092][000000008.856] I/user.sc7a20h_demo int1: 朝向=down X=0.125 Y=0.323 Z=0.513 g
|
||||
[2026-07-23 14:13:28.373][000000009.133] I/user.sc7a20h_demo int1: 朝向=back X=0.475 Y=0.291 Z=0.404 g
|
||||
[2026-07-23 14:13:28.389][000000009.155] I/user.sc7a20h_demo 50Hz 下: X=0.208 Y=0.180 Z=0.390 g
|
||||
[2026-07-23 14:13:28.656][000000009.410] I/user.sc7a20h_demo int1: 朝向=down X=0.075 Y=1.164 Z=1.317 g
|
||||
[2026-07-23 14:13:28.876][000000009.628] I/user.sc7a20h_demo int1: 朝向=down X=0.281 Y=0.115 Z=0.308 g
|
||||
[2026-07-23 14:13:28.891][000000009.656] I/user.sc7a20h_demo 设置输出速率为 100Hz
|
||||
[2026-07-23 14:13:28.903][000000009.659] I/user.exs_sc7a20h 输出速率切换为 100Hz
|
||||
[2026-07-23 14:13:28.937][000000009.693] I/user.sc7a20h_demo int1: 朝向=down X=-0.659 Y=1.035 Z=1.466 g
|
||||
[2026-07-23 14:13:29.404][000000010.161] I/user.sc7a20h_demo 100Hz 下: X=-0.659 Y=0.357 Z=0.859 g
|
||||
[2026-07-23 14:13:29.905][000000010.662] I/user.sc7a20h_demo 设置输出速率为 200Hz
|
||||
[2026-07-23 14:13:29.921][000000010.665] I/user.exs_sc7a20h 输出速率切换为 200Hz
|
||||
[2026-07-23 14:13:30.404][000000011.167] I/user.sc7a20h_demo 200Hz 下: X=-0.440 Y=0.722 Z=0.582 g
|
||||
[2026-07-23 14:13:30.918][000000011.670] I/user.exs_sc7a20h 输出速率切换为 100Hz
|
||||
[2026-07-23 14:13:30.933][000000011.670] I/user.sc7a20h_demo ---- [3/4] 完成 ----
|
||||
[2026-07-23 14:13:31.416][000000012.171] I/user.sc7a20h_demo ===== [4/4] 休眠与唤醒演示 =====
|
||||
[2026-07-23 14:13:31.432][000000012.171] I/user.sc7a20h_demo 进入 power-down 模式(低功耗)
|
||||
[2026-07-23 14:13:31.444][000000012.174] I/user.exs_sc7a20h 已进入 power-down 模式
|
||||
[2026-07-23 14:13:41.913][000000022.674] I/user.sc7a20h_demo 从 power-down 模式唤醒
|
||||
[2026-07-23 14:13:41.932][000000022.676] I/user.exs_sc7a20h 已从 power-down 模式唤醒,ODR=100Hz
|
||||
[2026-07-23 14:13:42.116][000000022.879] I/user.sc7a20h_demo 唤醒后数据: X=-0.614 Y=0.165 Z=0.852 g
|
||||
[2026-07-23 14:13:42.132][000000022.879] I/user.sc7a20h_demo ---- [4/4] 完成 ----
|
||||
[2026-07-23 14:13:42.613][000000023.380] I/user.sc7a20h_demo ===== [演示完毕] =====
|
||||
[2026-07-23 14:13:42.628][000000023.386] I/user.exs_sc7a20h 传感器已关闭
|
||||
[2026-07-23 14:13:42.640][000000023.386] I/user.sc7a20h_demo End
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 SC7A20H 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_sc7a20h 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为零**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 检查 I2C 地址是否正确(SA0=GND 时地址 0x18,SA0=VCC 时地址 0x19)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **量程切换无效果**:
|
||||
|
||||
- 确认 `set_range()` 参数为 "2g"、"4g"、"8g" 或 "16g"
|
||||
- 切换后需等待传感器稳定再读取数据
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_sc7a20h 更多接口的使用可以查看 [exs_sc7a20h 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_sc7a20h/)
|
||||
@@ -0,0 +1,154 @@
|
||||
--[[
|
||||
@module sc7a20h_demo
|
||||
@summary SC7A20H 三轴加速度传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.1
|
||||
@date 2026.07.23
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 SC7A20H 的逐项功能演示。
|
||||
通过 exs_sc7a20h 扩展库的 API 逐一演示数据读取、量程切换、输出速率切换、休眠唤醒等功能。
|
||||
]]
|
||||
|
||||
local exs_sc7a20h = require "exs_sc7a20h"
|
||||
|
||||
local function sc7a20h_int1_cb(data)
|
||||
if data.dir then
|
||||
log.info("sc7a20h_demo", string.format("int1: 朝向=%s X=%.3f Y=%.3f Z=%.3f g", data.dir, data.x, data.y, data.z))
|
||||
else
|
||||
log.info("sc7a20h_demo", string.format("int1: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
end
|
||||
|
||||
-- [1/4] 初始化与数据读取
|
||||
local function demo_init_and_read()
|
||||
log.info("sc7a20h_demo", "===== [1/4] 初始化与数据读取 =====")
|
||||
|
||||
local result = exs_sc7a20h.setup("I2C", {
|
||||
scl = 31,
|
||||
sda = 30,
|
||||
powermode = "highres",
|
||||
enable_direction = "6d",
|
||||
int1 = { int_gpio = 29, activity = true, threshold_mg = 500, cb = sc7a20h_int1_cb },
|
||||
})
|
||||
|
||||
if not result then
|
||||
log.error("sc7a20h_demo", "SC7A20H 初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
log.info("sc7a20h_demo", "SC7A20H 初始化成功,版本:", exs_sc7a20h.version())
|
||||
exs_sc7a20h.dump_regs()
|
||||
|
||||
sys.wait(200)
|
||||
local data = exs_sc7a20h.get_data()
|
||||
if data then
|
||||
log.info("sc7a20h_demo", string.format("X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
else
|
||||
log.error("sc7a20h_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
for i = 1, 3 do
|
||||
sys.wait(500)
|
||||
local d = exs_sc7a20h.get_data()
|
||||
if d then
|
||||
log.info("sc7a20h_demo", string.format("第%d次读取: X=%.3f Y=%.3f Z=%.3f g", i, d.x, d.y, d.z))
|
||||
end
|
||||
end
|
||||
log.info("sc7a20h_demo", "---- [1/4] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/4] 量程切换演示
|
||||
local function demo_range_switch()
|
||||
log.info("sc7a20h_demo", "===== [2/4] 量程切换演示 =====")
|
||||
|
||||
log.info("sc7a20h_demo", "切换量程为 4g")
|
||||
exs_sc7a20h.set_range("4g")
|
||||
sys.wait(300)
|
||||
|
||||
local data = exs_sc7a20h.get_data()
|
||||
if data then
|
||||
log.info("sc7a20h_demo", string.format("4g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("sc7a20h_demo", "切换量程为 2g(高精度)")
|
||||
exs_sc7a20h.set_range("2g")
|
||||
sys.wait(300)
|
||||
|
||||
data = exs_sc7a20h.get_data()
|
||||
if data then
|
||||
log.info("sc7a20h_demo", string.format("2g 量程: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("sc7a20h_demo", "---- [2/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/4] 输出速率切换
|
||||
local function demo_odr_switch()
|
||||
log.info("sc7a20h_demo", "===== [3/4] 输出速率切换 =====")
|
||||
|
||||
local odr_list = { 25, 50, 100, 200 }
|
||||
for _, odr in ipairs(odr_list) do
|
||||
log.info("sc7a20h_demo", string.format("设置输出速率为 %dHz", odr))
|
||||
exs_sc7a20h.set_odr(odr)
|
||||
sys.wait(500)
|
||||
|
||||
local data = exs_sc7a20h.get_data()
|
||||
if data then
|
||||
log.info("sc7a20h_demo", string.format("%dHz 下: X=%.3f Y=%.3f Z=%.3f g", odr, data.x, data.y, data.z))
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
exs_sc7a20h.set_odr(100)
|
||||
log.info("sc7a20h_demo", "---- [3/4] 完成 ----")
|
||||
end
|
||||
|
||||
-- [4/4] 休眠与唤醒演示
|
||||
local function demo_sleep_wakeup()
|
||||
log.info("sc7a20h_demo", "===== [4/4] 休眠与唤醒演示 =====")
|
||||
|
||||
log.info("sc7a20h_demo", "进入 power-down 模式(低功耗)")
|
||||
exs_sc7a20h.sleep(); sys.wait(10000)
|
||||
sys.wait(500)
|
||||
|
||||
log.info("sc7a20h_demo", "从 power-down 模式唤醒")
|
||||
exs_sc7a20h.wakeup()
|
||||
sys.wait(200)
|
||||
|
||||
local data = exs_sc7a20h.get_data()
|
||||
if data then
|
||||
log.info("sc7a20h_demo", string.format("唤醒后数据: X=%.3f Y=%.3f Z=%.3f g", data.x, data.y, data.z))
|
||||
end
|
||||
|
||||
log.info("sc7a20h_demo", "---- [4/4] 完成 ----")
|
||||
end
|
||||
|
||||
local function sc7a20h_demo_task_func()
|
||||
log.info("sc7a20h_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
local ok = demo_init_and_read()
|
||||
if not ok then
|
||||
log.error("sc7a20h_demo", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500)
|
||||
|
||||
demo_range_switch()
|
||||
sys.wait(500)
|
||||
|
||||
demo_odr_switch()
|
||||
sys.wait(500)
|
||||
|
||||
demo_sleep_wakeup()
|
||||
sys.wait(500)
|
||||
|
||||
log.info("sc7a20h_demo", "===== [演示完毕] =====")
|
||||
exs_sc7a20h.close()
|
||||
log.info("sc7a20h_demo", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(sc7a20h_demo_task_func)
|
||||
@@ -0,0 +1,70 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary SPL06-001 数字气压传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.08.21
|
||||
@author 江访
|
||||
@usage
|
||||
本 demo 演示 exs_spl06 扩展库的完整功能,业务逻辑见 spl06_app.lua
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_spl06 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/5]→[2/5]→[3/5]→[4/5]→[5/5]→End
|
||||
1、初始化([1/5])
|
||||
2、数据读取([2/5])
|
||||
3、海拔高度计算([3/5])
|
||||
4、过采样率切换([4/5])
|
||||
5、测量模式切换与休眠唤醒([5/5])
|
||||
|
||||
更多说明参考本目录下的 readme.md 文件
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
|
||||
PROJECT = "sensor_spl06" -- 项目命名
|
||||
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进行使用
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- local function mem_check_func()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end
|
||||
-- sys.timerLoopStart(mem_check_func, 3000)
|
||||
|
||||
-- 加载 spl06_app.lua 演示模块
|
||||
require "spl06_app"
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,232 @@
|
||||
# SPL06-001 数字气压传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **spl06_app.lua** - SPL06-001 功能演示模块,包含初始化、数据读取、海拔计算、过采样切换、模式切换与休眠唤醒等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_spl06** - SPL06-001 扩展库,提供初始化(I2C 地址自动探测、芯片 ID 校验、校准系数读取)、气压/温度读取、过采样率切换、海拔高度计算、测量模式切换、休眠唤醒、关闭等 API
|
||||
|
||||
### 1.3 I2C 模式说明
|
||||
|
||||
**推荐使用软件 I2C 模式**:SPL06-001 使用标准 I2C 接口通信,软件 I2C 模式无需指定 I2C 控制器,任意 GPIO 均可模拟 I2C 时序,灵活性更高。本 demo 默认使用软件 I2C 模式(SCL=GPIO31, SDA=GPIO30)演示,也可通过 `spl06_app.lua` 中的 `MODE` 变量切换为硬件 I2C 模式。
|
||||
|
||||
> SPL06-001 是**双地址芯片**:SDO 引脚悬空或接高电平时地址为 0x77,SDO 接 GND 时地址为 0x76。`setup()` 不传 `addr` 时扩展库会自动探测两个地址并校验芯片 ID,无需手动配置。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_spl06 扩展库的 5 项功能:HELLO → [1/5] → [2/5] → [3/5] → [4/5] → [5/5] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/5] 初始化** - 初始化传感器(I2C 地址自动探测、芯片 ID 校验、校准系数读取、过采样率配置、缩放基准建立)
|
||||
2. **[2/5] 数据读取** - 连续读取 5 次气压(hPa)和温度(℃),并演示单次读取接口
|
||||
3. **[3/5] 海拔高度计算** - 按国际气压测高公式计算海拔高度,支持自定义海平面气压
|
||||
4. **[4/5] 过采样率切换** - 依次切换气压过采样率 1x/16x/64x(含缩放因子动态自校准),观察不同精度下的数据
|
||||
5. **[5/5] 模式切换与休眠唤醒** - 切换待机/单次/连续测量模式,演示休眠唤醒与资源释放
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- SPL06-001 数字气压传感器模块 × 1
|
||||
demo所演示的SPL06-001 数字气压传感器模块[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=754082120547&mi_id=00002cEFf0br1iAbdFxAZR2wZA_t7gtaASLPpQM39JfcWTs&ns=1&priceTId=214783cd17873034704783015e0fdd&skuId=5372558067929&spm=a21n57.1.hoverItem.2&utparam=%7B%22aplus_abtest%22%3A%222783bdd13dde62ac2d7099c56862328f%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 I2C 模式接线
|
||||
|
||||
| Air780EPM 核心板 | SPL06-001 模块 |
|
||||
|------------------|--------------|
|
||||
| 32/GPIO31 | SCL |
|
||||
| 31/GPIO30 | SDA |
|
||||
| VDD_EXT | VCC(3.3V) |
|
||||
| GND | GND |
|
||||
|
||||
> 说明:
|
||||
> 1. 接线时注意杜邦线不宜过长,以免通信不稳定
|
||||
> 2. SCL 和 SDA 需外接 4.7kΩ~10kΩ 上拉电阻到 VCC(部分模块已自带)
|
||||
> 3. 模块 SDO 引脚悬空(或接高电平)时 I2C 地址为 0x77,接 GND 时地址为 0x76;扩展库会自动探测,无需关心
|
||||
|
||||

|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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. **spl06_app.lua** - SPL06-001 功能演示模块
|
||||
3. **exs_spl06** - SPL06-001 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 SPL06-001 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 spl06_app.lua 演示模块
|
||||
require "spl06_app"
|
||||
```
|
||||
|
||||
如需切换通信模式,修改 `spl06_app.lua` 中的 `MODE` 变量(1=软件 I2C,2=硬件 I2C)。
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 初始化演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/5] 初始化
|
||||
2. 观察日志输出,确认初始化成功(应看到 `芯片地址自适应:0x76/0x77` 和 `初始化完成`)
|
||||
|
||||
#### 5.4.2 数据读取演示
|
||||
|
||||
1. 自动进入 [2/5] 数据读取
|
||||
2. 观察气压(hPa)和温度(℃)的连续读取,共 5 次,再观察单次读取接口结果
|
||||
|
||||
#### 5.4.3 海拔计算演示
|
||||
|
||||
1. 自动进入 [3/5] 海拔高度计算
|
||||
2. 观察气压值与两种海平面气压基准(默认 1013.25hPa / 自定义 1005hPa)下的海拔高度
|
||||
|
||||
#### 5.4.4 过采样率切换演示
|
||||
|
||||
1. 自动进入 [4/5] 过采样率切换演示
|
||||
2. 依次观察气压 OSR=0(1x 最快)、OSR=4(16x 默认)、OSR=6(64x 高精度)下的数据
|
||||
3. 切换高过采样时观察缩放因子动态自校准日志(`缩放因子动态校准: kP ... kT ...`)
|
||||
4. 注意 OSR 越高,数据跳动越小,但单次测量耗时越长
|
||||
|
||||
#### 5.4.5 模式切换与休眠唤醒演示
|
||||
|
||||
1. 自动进入 [5/5] 模式切换与休眠唤醒
|
||||
2. 依次观察待机(standby)/单次气压(pressure)/连续(both)模式的切换日志
|
||||
3. 观察睡眠 3 秒后唤醒、唤醒后数据恢复输出、最后关闭传感器
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **初始化**:SPL06-001 初始化成功,芯片地址自动探测锁定、校准系数读取正常
|
||||
- **数据读取**:气压与温度数据正常输出(气压约 1002.87hPa,温度约 23.6℃)
|
||||
- **海拔计算**:基于实测气压输出海拔高度(默认/自定义海平面气压两种)
|
||||
- **过采样率切换**:不同 OSR 下精度不同,OSR 越高数据越稳定;切换高过采样时自动动态校准
|
||||
- **模式切换与休眠唤醒**:待机/单次/连续模式切换正常,睡眠后唤醒数据恢复输出
|
||||
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-08-21 17:28:45.888][000000000.200] I/user.main sensor_spl06 001.999.000
|
||||
[2026-08-21 17:28:45.899][000000000.216] D/user.exs_spl06 version -> 202608211700
|
||||
[2026-08-21 17:28:45.942][000000000.217] I/user.spl06_app HELLO
|
||||
[2026-08-21 17:28:47.219][000000001.217] I/user.spl06_app ===== [1/5] 初始化 =====
|
||||
[2026-08-21 17:28:47.638][000000001.225] I/user.exs_spl06 芯片地址自适应:0x76
|
||||
[2026-08-21 17:28:47.681][000000001.294] I/user.exs_spl06 缩放基准原始值: P -112660 T 2295708
|
||||
[2026-08-21 17:28:47.761][000000001.294] I/user.exs_spl06 初始化完成, prs_osr=4 tmp_osr=3
|
||||
[2026-08-21 17:28:47.833][000000001.295] I/user.spl06_app SPL06-001 初始化成功,版本: 202608211700
|
||||
[2026-08-21 17:28:47.882][000000001.795] I/user.spl06_app ===== [2/5] 数据读取 =====
|
||||
[2026-08-21 17:28:47.899][000000001.795] I/user.spl06_app 连续读取 5 次气压/温度(单位 hPa / ℃)
|
||||
[2026-08-21 17:28:48.336][000000001.802] I/user.spl06_app 第1次: 气压=1002.86hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:48.366][000000002.808] I/user.spl06_app 第2次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:48.408][000000003.814] I/user.spl06_app 第3次: 气压=1002.86hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:48.588][000000004.820] I/user.spl06_app 第4次: 气压=1002.86hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:49.571][000000005.826] I/user.spl06_app 第5次: 气压=1002.86hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:50.691][000000006.928] I/user.spl06_app 单次气压=1002.86hPa 单次温度=23.8℃
|
||||
[2026-08-21 17:28:51.194][000000007.428] I/user.spl06_app ===== [3/5] 海拔高度计算 =====
|
||||
[2026-08-21 17:28:51.240][000000007.440] I/user.spl06_app 气压=1002.87hPa,默认海平面气压海拔=86.8米,自定义1005hPa海拔=17.9米
|
||||
[2026-08-21 17:28:51.687][000000007.940] I/user.spl06_app ===== [4/5] 过采样率切换 =====
|
||||
[2026-08-21 17:28:51.709][000000007.940] I/user.spl06_app 依次切换气压过采样率 1x/16x/64x(温度保持 8x),观察数据精度
|
||||
[2026-08-21 17:28:51.749][000000007.985] I/user.exs_spl06 缩放因子动态校准: kP 524310 kT 7864779
|
||||
[2026-08-21 17:28:51.765][000000007.986] I/user.exs_spl06 过采样切换成功, prs_osr=0 tmp_osr=3
|
||||
[2026-08-21 17:28:51.802][000000007.986] I/user.spl06_app 气压OSR=0(1x),开始采集
|
||||
[2026-08-21 17:28:52.186][000000008.442] I/user.spl06_app OSR=0 第1次: 气压=1002.83hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:53.202][000000009.448] I/user.spl06_app OSR=0 第2次: 气压=1002.88hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:54.196][000000010.454] I/user.spl06_app OSR=0 第3次: 气压=1002.87hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:55.210][000000011.460] I/user.spl06_app OSR=0 第4次: 气压=1002.84hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:56.213][000000012.466] I/user.spl06_app OSR=0 第5次: 气压=1002.84hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:57.208][000000013.466] I/user.spl06_app OSR=0 平均气压=1002.85hPa
|
||||
[2026-08-21 17:28:57.286][000000013.536] I/user.exs_spl06 缩放因子动态校准: kP 253984 kT 7868382
|
||||
[2026-08-21 17:28:57.294][000000013.537] I/user.exs_spl06 过采样切换成功, prs_osr=4 tmp_osr=3
|
||||
[2026-08-21 17:28:57.304][000000013.537] I/user.spl06_app 气压OSR=4(16x),开始采集
|
||||
[2026-08-21 17:28:57.800][000000014.047] I/user.spl06_app OSR=4 第1次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:58.805][000000015.053] I/user.spl06_app OSR=4 第2次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:28:59.823][000000016.059] I/user.spl06_app OSR=4 第3次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:00.819][000000017.065] I/user.spl06_app OSR=4 第4次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:01.814][000000018.071] I/user.spl06_app OSR=4 第5次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:02.822][000000019.071] I/user.spl06_app OSR=4 平均气压=1002.85hPa
|
||||
[2026-08-21 17:29:02.963][000000019.219] I/user.exs_spl06 缩放因子动态校准: kP 1040493 kT 7864292
|
||||
[2026-08-21 17:29:02.970][000000019.220] I/user.exs_spl06 过采样切换成功, prs_osr=6 tmp_osr=3
|
||||
[2026-08-21 17:29:02.976][000000019.220] I/user.spl06_app 气压OSR=6(64x),开始采集
|
||||
[2026-08-21 17:29:03.476][000000019.730] I/user.spl06_app OSR=6 第1次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:04.489][000000020.736] I/user.spl06_app OSR=6 第2次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:05.495][000000021.742] I/user.spl06_app OSR=6 第3次: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:06.493][000000022.748] I/user.spl06_app OSR=6 第4次: 气压=1002.84hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:07.495][000000023.754] I/user.spl06_app OSR=6 第5次: 气压=1002.84hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:08.504][000000024.754] I/user.spl06_app OSR=6 平均气压=1002.85hPa
|
||||
[2026-08-21 17:29:09.033][000000025.292] I/user.exs_spl06 缩放因子动态校准: kP 253960 kT 7869000
|
||||
[2026-08-21 17:29:09.044][000000025.293] I/user.exs_spl06 过采样切换成功, prs_osr=4 tmp_osr=3
|
||||
[2026-08-21 17:29:09.548][000000025.793] I/user.spl06_app ===== [5/5] 模式切换与休眠唤醒 =====
|
||||
[2026-08-21 17:29:09.557][000000025.795] I/user.spl06_app 已切换待机模式(standby)
|
||||
[2026-08-21 17:29:09.565][000000025.796] I/user.spl06_app 已切换单次气压测量模式(pressure)
|
||||
[2026-08-21 17:29:09.573][000000025.797] I/user.spl06_app 已切换连续气压+温度测量模式(both)
|
||||
[2026-08-21 17:29:10.046][000000026.303] I/user.spl06_app 连续模式数据: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:10.056][000000026.304] I/user.exs_spl06 已进入待机(睡眠)
|
||||
[2026-08-21 17:29:10.066][000000026.305] I/user.spl06_app 已进入睡眠(待机),3 秒后唤醒
|
||||
[2026-08-21 17:29:13.063][000000029.306] I/user.exs_spl06 已唤醒,恢复连续测量
|
||||
[2026-08-21 17:29:13.073][000000029.306] I/user.spl06_app 已唤醒,恢复连续测量
|
||||
[2026-08-21 17:29:13.561][000000029.812] I/user.spl06_app 唤醒后数据: 气压=1002.85hPa 温度=23.8℃
|
||||
[2026-08-21 17:29:13.573][000000029.813] I/user.exs_spl06 传感器已关闭
|
||||
[2026-08-21 17:29:13.590][000000029.813] I/user.spl06_app 已关闭传感器
|
||||
[2026-08-21 17:29:13.619][000000029.814] I/user.spl06_app ===== [演示完毕] =====
|
||||
[2026-08-21 17:29:13.631][000000029.814] I/user.spl06_app End
|
||||
```
|
||||
|
||||
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 SPL06-001 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 SCL/SDA 上拉电阻是否连接
|
||||
- 确认 exs_spl06 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为 0 或异常**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 确认 I2C 地址是否正确(SPL06-001 支持 0x76/0x77,由 SDO 引脚决定,扩展库会自动探测)
|
||||
- 确认接线无松动
|
||||
- 检查 SCL/SDA 上拉电阻
|
||||
|
||||
3. **气压数据跳动过大**:
|
||||
|
||||
- 提高过采样率(如 `set_osr(6, 4)` 对应 64x),数据更稳定但耗时更长
|
||||
- 传感器附近避免风吹、空调等气压扰动源
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_spl06 更多接口的使用可以查看 [exs_spl06 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_spl06/)
|
||||
@@ -0,0 +1,221 @@
|
||||
--[[
|
||||
@module spl06_app
|
||||
@summary SPL06-001 数字气压传感器演示模块,包含初始化、数据读取、海拔计算、过采样切换、模式切换与休眠唤醒演示用例
|
||||
@version 1.0
|
||||
@date 2026.08.21
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 SPL06-001 的逐项功能演示。
|
||||
通过 exs_spl06 扩展库的 API 逐一演示初始化、数据读取、海拔计算、
|
||||
过采样率切换、测量模式切换与休眠唤醒等功能。
|
||||
|
||||
通过 MODE 变量选择通信模式(改 MODE 的值即可,无需注释/取消注释代码):
|
||||
MODE = 1 软件 I2C(默认推荐,仅需 scl/sda 引脚,任意 GPIO 均可,接线最灵活)
|
||||
MODE = 2 硬件 I2C(指定 i2c_id,占用 CPU 少)
|
||||
|
||||
Air780EPM 接线(软件 I2C):
|
||||
SCL = GPIO31
|
||||
SDA = GPIO30
|
||||
]]
|
||||
|
||||
-- 加载 exs_spl06 扩展库
|
||||
local exs_spl06 = require "exs_spl06"
|
||||
|
||||
-- ==================== 通信模式选择 ====================
|
||||
-- 改 MODE 的值选择通信模式:
|
||||
-- 1 = 软件 I2C(默认) 2 = 硬件 I2C
|
||||
-- 各模式所需引脚/参数见下方 init_config,接线说明见 readme.md
|
||||
local MODE = 1
|
||||
|
||||
local init_config
|
||||
if MODE == 1 then
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO,Air780EPM 接线示例用 GPIO31/GPIO30
|
||||
-- SPL06-001 支持双地址 0x76/0x77(由 SDO 引脚决定),不传 addr 时扩展库自动探测
|
||||
init_config = {scl = 31, sda = 30}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_id 为总线号(Air780EPM 用 1),不传 scl/sda 时无总线恢复能力
|
||||
init_config = {i2c_id = 1}
|
||||
else
|
||||
log.error("spl06_app", "MODE 取值错误,应为 1/2")
|
||||
return
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [1/5] 初始化
|
||||
-- - setup() 自动完成 I2C 地址自动探测、芯片 ID 校验、校准系数读取、
|
||||
-- 过采样率配置、缩放基准建立(16x 气压/8x 温度)
|
||||
--------------------------------------------------------------
|
||||
local function demo_init()
|
||||
log.info("spl06_app", "===== [1/5] 初始化 =====")
|
||||
|
||||
local result = exs_spl06.setup(init_config)
|
||||
if not result then
|
||||
log.error("spl06_app", "初始化失败")
|
||||
log.error("spl06_app", "检查接线: VCC=3.3V GND SCL SDA,I2C 地址是否正确(如 0x76/0x77)")
|
||||
return false -- 初始化失败必须返回 false
|
||||
end
|
||||
log.info("spl06_app", "SPL06-001 初始化成功,版本:", exs_spl06.version())
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [2/5] 数据读取
|
||||
-- - get_data() 返回气压(hPa)与温度(℃),get_pressure()/get_temperature() 单次读取
|
||||
--------------------------------------------------------------
|
||||
local function demo_read_data()
|
||||
log.info("spl06_app", "===== [2/5] 数据读取 =====")
|
||||
log.info("spl06_app", "连续读取 5 次气压/温度(单位 hPa / ℃)")
|
||||
|
||||
-- 连续读取 5 次气压/温度
|
||||
for i = 1, 5 do
|
||||
local data = exs_spl06.get_data()
|
||||
if data then
|
||||
log.info("spl06_app", string.format("第%d次: 气压=%.2fhPa 温度=%.1f℃",
|
||||
i, data.pressure, data.temperature))
|
||||
else
|
||||
log.error("spl06_app", string.format("第%d次读取失败", i))
|
||||
end
|
||||
sys.wait(1000) -- 每隔 1 秒读取一次,1000ms
|
||||
end
|
||||
|
||||
-- 演示单次读取接口
|
||||
local pressure = exs_spl06.get_pressure()
|
||||
local temperature = exs_spl06.get_temperature()
|
||||
log.info("spl06_app", string.format("单次气压=%.2fhPa 单次温度=%.1f℃",
|
||||
pressure or 0, temperature or 0))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [3/5] 海拔高度计算
|
||||
-- - get_altitude() 按国际气压测高公式计算海拔(纯计算接口,不耗时)
|
||||
-- - 默认海平面气压 1013.25hPa,也可传当地海平面气压提高精度
|
||||
--------------------------------------------------------------
|
||||
local function demo_altitude()
|
||||
log.info("spl06_app", "===== [3/5] 海拔高度计算 =====")
|
||||
|
||||
local pressure = exs_spl06.get_pressure()
|
||||
if not pressure then
|
||||
log.error("spl06_app", "气压读取失败,跳过海拔计算")
|
||||
return
|
||||
end
|
||||
local h_default = exs_spl06.get_altitude(pressure) -- 默认 1013.25hPa
|
||||
local h_custom = exs_spl06.get_altitude(pressure, 1005) -- 自定义 1005hPa
|
||||
log.info("spl06_app", string.format("气压=%.2fhPa,默认海平面气压海拔=%.1f米,自定义1005hPa海拔=%.1f米",
|
||||
pressure, h_default, h_custom))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [4/5] 过采样率切换
|
||||
-- - set_osr() 在线切换气压过采样率,切换后扩展库自动完成缩放因子动态自校准
|
||||
-- - OSR 越高数据越稳定,但单次测量耗时越长;校准失败自动回退默认 16x/8x
|
||||
--------------------------------------------------------------
|
||||
local function demo_switch_osr()
|
||||
log.info("spl06_app", "===== [4/5] 过采样率切换 =====")
|
||||
log.info("spl06_app", "依次切换气压过采样率 1x/16x/64x(温度保持 8x),观察数据精度")
|
||||
|
||||
-- 依次切换 3 档气压过采样率(1x/16x/64x)
|
||||
local osr_list = {0, 4, 6}
|
||||
local osr_names = {"1x", "16x", "64x"}
|
||||
for i = 1, #osr_list do
|
||||
local ok = exs_spl06.set_osr(osr_list[i], 3)
|
||||
if not ok then
|
||||
log.error("spl06_app", string.format("气压OSR切换为%d(%s)失败,已回退默认16x/8x", osr_list[i], osr_names[i]))
|
||||
end
|
||||
log.info("spl06_app", string.format("气压OSR=%d(%s),开始采集", osr_list[i], osr_names[i]))
|
||||
local sum = 0
|
||||
local cnt = 0
|
||||
for j = 1, 5 do
|
||||
local data = exs_spl06.get_data()
|
||||
if data then
|
||||
sum = sum + data.pressure
|
||||
cnt = cnt + 1
|
||||
log.info("spl06_app", string.format("OSR=%d 第%d次: 气压=%.2fhPa 温度=%.1f℃",
|
||||
osr_list[i], j, data.pressure, data.temperature))
|
||||
else
|
||||
log.error("spl06_app", "读取失败")
|
||||
end
|
||||
sys.wait(1000) -- 每隔 1 秒读取一次,1000ms
|
||||
end
|
||||
if cnt > 0 then
|
||||
log.info("spl06_app", string.format("OSR=%d 平均气压=%.2fhPa", osr_list[i], sum / cnt))
|
||||
end
|
||||
end
|
||||
|
||||
-- 恢复默认过采样(16x/8x)
|
||||
exs_spl06.set_osr(4, 3)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- [5/5] 测量模式切换与休眠唤醒
|
||||
-- - set_mode() 切换待机/单次气压/连续气压+温度测量模式
|
||||
-- - sleep() 进入低功耗待机(电流<1µA),wakeup() 唤醒恢复连续测量
|
||||
-- - 最后 close() 释放资源
|
||||
--------------------------------------------------------------
|
||||
local function demo_mode_and_sleep()
|
||||
log.info("spl06_app", "===== [5/5] 模式切换与休眠唤醒 =====")
|
||||
|
||||
-- 待机模式(电流 < 1µA)
|
||||
exs_spl06.set_mode("standby")
|
||||
log.info("spl06_app", "已切换待机模式(standby)")
|
||||
|
||||
-- 单次气压测量模式(测完自动回待机)
|
||||
exs_spl06.set_mode("pressure")
|
||||
log.info("spl06_app", "已切换单次气压测量模式(pressure)")
|
||||
|
||||
-- 连续气压+温度测量模式(后台模式)
|
||||
exs_spl06.set_mode("both")
|
||||
log.info("spl06_app", "已切换连续气压+温度测量模式(both)")
|
||||
sys.wait(500) -- 等待后台连续测量稳定,500ms
|
||||
local data = exs_spl06.get_data()
|
||||
if data then
|
||||
log.info("spl06_app", string.format("连续模式数据: 气压=%.2fhPa 温度=%.1f℃", data.pressure, data.temperature))
|
||||
end
|
||||
|
||||
-- 休眠唤醒(睡眠 3 秒后唤醒)
|
||||
exs_spl06.sleep()
|
||||
log.info("spl06_app", "已进入睡眠(待机),3 秒后唤醒")
|
||||
sys.wait(3000) -- 睡眠 3 秒,3000ms
|
||||
exs_spl06.wakeup()
|
||||
log.info("spl06_app", "已唤醒,恢复连续测量")
|
||||
sys.wait(500) -- 等待连续测量恢复,500ms
|
||||
data = exs_spl06.get_data()
|
||||
if data then
|
||||
log.info("spl06_app", string.format("唤醒后数据: 气压=%.2fhPa 温度=%.1f℃", data.pressure, data.temperature))
|
||||
end
|
||||
|
||||
-- 关闭传感器(进入待机并释放 I2C 资源)
|
||||
exs_spl06.close()
|
||||
log.info("spl06_app", "已关闭传感器")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- 主任务:按 [1/5]~[5/5] 顺序执行全部演示
|
||||
--------------------------------------------------------------
|
||||
local function spl06_demo_task_func()
|
||||
log.info("spl06_app", "HELLO")
|
||||
sys.wait(1000) -- 等待系统稳定,1000ms
|
||||
|
||||
-- HELLO 开始 → [1/5] → [2/5] → [3/5] → [4/5] → [5/5] → End
|
||||
local ok = demo_init()
|
||||
if not ok then
|
||||
log.error("spl06_app", "初始化失败,演示终止")
|
||||
return
|
||||
end
|
||||
sys.wait(500) -- 步骤间隔,500ms
|
||||
|
||||
demo_read_data()
|
||||
sys.wait(500) -- 步骤间隔,500ms
|
||||
|
||||
demo_altitude()
|
||||
sys.wait(500) -- 步骤间隔,500ms
|
||||
|
||||
demo_switch_osr()
|
||||
sys.wait(500) -- 步骤间隔,500ms
|
||||
|
||||
demo_mode_and_sleep()
|
||||
|
||||
log.info("spl06_app", "===== [演示完毕] =====")
|
||||
log.info("spl06_app", "End")
|
||||
end
|
||||
|
||||
sys.taskInit(spl06_demo_task_func)
|
||||
@@ -0,0 +1,73 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary TM1637 数码管驱动芯片测试 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_tm1637 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
|
||||
1、数码管字符串显示([1/6])
|
||||
2、按键轮询检测([2/6])
|
||||
3、亮度调节([3/6])
|
||||
4、按键回调([4/6])
|
||||
5、综合演示([5/6])
|
||||
6、日期/时钟/温度([6/6])
|
||||
|
||||
]]
|
||||
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "TM1637_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 tm1637_demo.lua 演示模块
|
||||
require "tm1637_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,240 @@
|
||||
# TM1637 数码管驱动芯片演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **tm1637_demo.lua** - TM1637 功能演示模块,包含数码管显示、按键检测、亮度调节、综合展示等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_tm1637** - TM1637 扩展库,提供数码管段码显示、按键检测、亮度调节等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_tm1637 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/6] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示
|
||||
2. **[2/6] 按键轮询** - 通过 `get_key()` API 轮询检测按键,10 秒超时
|
||||
3. **[3/6] 按键回调** - 通过 `set_key_callback()` API 设置按键回调函数,12 秒演示窗口
|
||||
4. **[4/6] 亮度调节** - 展示 0~7 级亮度调节效果
|
||||
5. **[5/6] 综合演示** - 倒计时、HELLO 闪烁、全 8 显示、亮度渐变
|
||||
6. **[6/6] 日期/时钟/温度** - 日期展示(YY-MM-DD 格式)、时钟模拟走时(HH-MM-SS)、温度展示(摄氏度°C 和华氏度°F)
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- TM1637 数码管模块(6 位数码管 + 16 个按键) × 1
|
||||
demo所演示的TM1637数码管[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=1007027539110&mi_id=0000QVgQh2GhxEs_zMNZK6bhYAbQv0eR95YG6IfO11pxPlY&ns=1&priceTId=213e00d417839212452374999e1068&skuId=6005284956850&spm=a21n57.1.hoverItem.5&utparam=%7B%22aplus_abtest%22%3A%22d1bf89b9b16b6e795e9cbd76e360f1b3%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 TM1637 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>TM1637 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
|
||||
<tr>
|
||||
<td>31/GPIO30<br/></td><td>DIO<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 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. **tm1637_demo.lua** - TM1637 功能演示模块
|
||||
3. **exs_tm1637** - TM1637 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 TM1637 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 tm1637_demo.lua 演示模块
|
||||
require "tm1637_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 字符串显示演示
|
||||
|
||||
1. 设备启动后显示 "HELLO",随后自动进入 [1/6] 字符串显示
|
||||
2. 观察数码管依次显示:`123456` → `88.88` → `AbCd` → 从第 3 位显示 `1234`
|
||||
3. 检查字符显示是否正确,带小数点功能是否正常
|
||||
|
||||
#### 6.4.2 按键检测演示
|
||||
|
||||
1. 自动进入 [2/6] 按键轮询演示,数码管显示 "KEY---"
|
||||
2. 在 10 秒内按下 TM1637 模块上的任意按键
|
||||
3. 观察数码管显示按键编码(如 "K01"、"K02" 等)
|
||||
4. 若 10 秒内无按键按下,自动跳过
|
||||
|
||||
#### 6.4.3 按键回调演示
|
||||
|
||||
1. 自动进入 [3/6] 按键回调演示,数码管显示 "Cb-Key"
|
||||
2. 在 12 秒内按下任意按键,观察数码管显示对应按键编码
|
||||
3. 观察日志输出,确认回调函数 `on_key` 被正常触发
|
||||
4. 12 秒后自动结束回调演示
|
||||
|
||||
#### 6.4.4 亮度调节演示
|
||||
|
||||
1. 自动进入 [4/6] 亮度调节演示,数码管显示 "888888"
|
||||
2. 观察数码管亮度从 0 级到 7 级逐级变化
|
||||
3. 最终恢复到 4 级亮度
|
||||
|
||||
#### 6.4.5 综合演示
|
||||
|
||||
1. 自动进入 [5/6] 综合演示
|
||||
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
|
||||
3. 观察 "-HELLO" 闪烁效果,重复 4 次
|
||||
4. 观察全 8 显示 + 亮度渐变
|
||||
5. 数码管全灭
|
||||
|
||||
#### 6.4.6 日期/时钟/温度演示
|
||||
|
||||
1. 自动进入 [6/6] 日期/时钟/温度演示
|
||||
2. 日期展示:6 位数码管显示 "YYMMDD"(如 "260713"),停留 3 秒
|
||||
3. 时钟展示:模拟走时 "083000" → "083001" → ... → "083009"
|
||||
4. 温度展示:
|
||||
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
|
||||
- 华氏度:77°F → 90°F 逐度变化
|
||||
5. 演示结束后显示 "End" 并停留 3 秒
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置
|
||||
- **按键检测**:轮询模式和回调模式均能正确检测按键,编码显示正常
|
||||
- **亮度调节**:0~7 级亮度逐级变化,效果明显
|
||||
- **日期/时钟/温度**:格式显示正确,°C 和 °F 符号正常显示
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:33:01.174][000000000.180] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:33:01.177][000000000.180] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:33:01.179][000000000.182] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:33:01.180][000000000.185] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:33:01.182][000000000.185] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:33:01.184][000000000.185] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:33:01.186][000000000.203] I/user.main TM1637_Demo 001.999.000
|
||||
[2026-07-21 10:33:01.188][000000000.217] D/user.exs_tm1637 version -> 202607161200
|
||||
[2026-07-21 10:33:01.190][000000000.226] I/user.exs_tm1637 初始化完成, clk=31 dio=30 亮度=5
|
||||
[2026-07-21 10:33:01.193][000000000.227] I/user.tm1637_demo TM1637 初始化成功,版本: 202607161200
|
||||
[2026-07-21 10:33:01.396][000000001.233] I/user.tm1637_demo ===== [1/6] 字符串显示 =====
|
||||
[2026-07-21 10:33:01.397][000000001.234] I/user.tm1637_demo 显示 123456
|
||||
[2026-07-21 10:33:02.359][000000002.745] I/user.tm1637_demo 显示 88.88
|
||||
[2026-07-21 10:33:03.870][000000004.258] I/user.tm1637_demo 显示 AbCd
|
||||
[2026-07-21 10:33:05.377][000000005.770] I/user.tm1637_demo 从第 3 位开始显示 1234
|
||||
[2026-07-21 10:33:05.497][000000005.829] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:33:05.506][000000005.830] D/mobile cid1, state0
|
||||
[2026-07-21 10:33:05.512][000000005.831] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:33:05.516][000000005.831] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:33:05.521][000000005.886] D/mobile TIME_SYNC 0 tm 1784601188
|
||||
[2026-07-21 10:33:07.395][000000007.790] I/user.tm1637_demo ===== [2/6] 按键轮询 =====
|
||||
[2026-07-21 10:33:07.399][000000007.791] I/user.tm1637_demo 按下任意按键测试,10 秒无操作后自动结束
|
||||
[2026-07-21 10:33:08.328][000000008.724] I/user.tm1637_demo 检测到按键, 编码: 1
|
||||
[2026-07-21 10:33:09.461][000000009.851] I/user.tm1637_demo 检测到按键, 编码: 2
|
||||
[2026-07-21 10:33:11.605][000000011.999] I/user.tm1637_demo 检测到按键, 编码: 3
|
||||
[2026-07-21 10:33:12.428][000000012.822] I/user.tm1637_demo 检测到按键, 编码: 4
|
||||
[2026-07-21 10:33:13.452][000000013.846] I/user.tm1637_demo 检测到按键, 编码: 5
|
||||
[2026-07-21 10:33:14.382][000000014.771] I/user.tm1637_demo 检测到按键, 编码: 6
|
||||
[2026-07-21 10:33:15.203][000000015.592] I/user.tm1637_demo 检测到按键, 编码: 7
|
||||
[2026-07-21 10:33:16.431][000000016.822] I/user.tm1637_demo 检测到按键, 编码: 8
|
||||
[2026-07-21 10:33:17.350][000000017.744] I/user.tm1637_demo 检测到按键, 编码: 9
|
||||
[2026-07-21 10:33:18.280][000000018.668] I/user.tm1637_demo 检测到按键, 编码: 10
|
||||
[2026-07-21 10:33:19.103][000000019.488] I/user.tm1637_demo 检测到按键, 编码: 11
|
||||
[2026-07-21 10:33:20.018][000000020.412] I/user.tm1637_demo 检测到按键, 编码: 12
|
||||
[2026-07-21 10:33:20.843][000000021.233] I/user.tm1637_demo 检测到按键, 编码: 13
|
||||
[2026-07-21 10:33:21.668][000000022.055] I/user.tm1637_demo 检测到按键, 编码: 14
|
||||
[2026-07-21 10:33:22.490][000000022.875] I/user.tm1637_demo 检测到按键, 编码: 15
|
||||
[2026-07-21 10:33:23.811][000000024.206] I/user.tm1637_demo 检测到按键, 编码: 16
|
||||
[2026-07-21 10:33:30.758][000000031.145] I/user.tm1637_demo 按键检测结束
|
||||
[2026-07-21 10:33:30.761][000000031.145] I/user.tm1637_demo ===== [4/6] 按键回调 =====
|
||||
[2026-07-21 10:33:30.766][000000031.146] I/user.tm1637_demo 接下来 12 秒内按按键查看回调效果
|
||||
[2026-07-21 10:33:32.123][000000032.512] I/user.tm1637_demo 按键回调触发, 编码: 16
|
||||
[2026-07-21 10:33:42.771][000000043.160] I/user.tm1637_demo 按键回调演示结束
|
||||
[2026-07-21 10:33:42.774][000000043.160] I/user.tm1637_demo ===== [3/6] 亮度调节 =====
|
||||
[2026-07-21 10:33:43.282][000000043.673] I/user.tm1637_demo 设置亮度: 0
|
||||
[2026-07-21 10:33:44.090][000000044.475] I/user.tm1637_demo 设置亮度: 1
|
||||
[2026-07-21 10:33:44.880][000000045.277] I/user.tm1637_demo 设置亮度: 2
|
||||
[2026-07-21 10:33:45.688][000000046.078] I/user.tm1637_demo 设置亮度: 3
|
||||
[2026-07-21 10:33:46.494][000000046.880] I/user.tm1637_demo 设置亮度: 4
|
||||
[2026-07-21 10:33:47.285][000000047.681] I/user.tm1637_demo 设置亮度: 5
|
||||
[2026-07-21 10:33:48.092][000000048.483] I/user.tm1637_demo 设置亮度: 6
|
||||
[2026-07-21 10:33:48.895][000000049.285] I/user.tm1637_demo 设置亮度: 7
|
||||
[2026-07-21 10:33:50.199][000000050.594] I/user.tm1637_demo ===== [5/6] 综合演示 =====
|
||||
[2026-07-21 10:33:59.171][000000059.565] I/user.tm1637_demo ---- 综合演示结束 ----
|
||||
[2026-07-21 10:33:59.175][000000059.566] I/user.tm1637_demo ===== [6/6] 日期/时钟/温度 =====
|
||||
[2026-07-21 10:33:59.179][000000059.566] I/user.tm1637_demo 日期展示: 260713
|
||||
[2026-07-21 10:34:02.692][000000063.084] I/user.tm1637_demo 时钟展示: 083000 ~ 083009
|
||||
[2026-07-21 10:34:22.982][000000083.365] I/user.tm1637_demo ===== [演示完毕] =====
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **数码管无显示**:
|
||||
|
||||
- 检查 TM1637 接线是否正确(CLK、DIO、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_tm1637 扩展库已正常加载
|
||||
|
||||
2. **按键无响应**:
|
||||
|
||||
- 检查按键接线和 TM1637 模块是否正常
|
||||
- 确认扩展库初始化成功
|
||||
- 查看日志确认 `setup()` 返回值为 true
|
||||
|
||||
3. **亮度无法调节**:
|
||||
|
||||
- 确认调用 `set_brightness()` 时参数为 0~7
|
||||
|
||||
4. **显示内容错乱**:
|
||||
|
||||
- 检查杜邦线是否过长导致通信不稳定
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_tm1637 更多接口的使用可以查看 [exs_tm1637 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_tm1637/)
|
||||
@@ -0,0 +1,232 @@
|
||||
--[[
|
||||
@module tm1637_demo
|
||||
@summary TM1637 驱动芯片演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 TM1637 的逐项功能演示和综合展示。
|
||||
通过 exs_tm1637 扩展库的 API 逐一演示数码管显示、按键检测等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_tm1637 扩展库
|
||||
local exs_tm1637 = require "exs_tm1637"
|
||||
|
||||
-- 演示字符串显示
|
||||
local function demo_string()
|
||||
log.info("tm1637_demo", "===== [1/6] 字符串显示 =====")
|
||||
|
||||
log.info("tm1637_demo", "显示 123456")
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("123456")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1637_demo", "显示 88.88")
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("88.88")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1637_demo", "显示 AbCd")
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("AbCd")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1637_demo", "从第 3 位开始显示 1234")
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("1234", 3)
|
||||
sys.wait(1500)
|
||||
|
||||
exs_tm1637.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示按键轮询
|
||||
local function demo_keys()
|
||||
log.info("tm1637_demo", "===== [2/6] 按键轮询 =====")
|
||||
log.info("tm1637_demo", "按下任意按键测试,10 秒无操作后自动结束")
|
||||
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("KEY---")
|
||||
|
||||
local timeout = 10000
|
||||
local step = 100
|
||||
local elapsed = 0
|
||||
|
||||
while elapsed < timeout do
|
||||
local key = exs_tm1637.get_key()
|
||||
if key then
|
||||
log.info("tm1637_demo", "检测到按键, 编码:", key)
|
||||
local key_str = string.format("K%02d", key)
|
||||
exs_tm1637.set_display(key_str)
|
||||
sys.wait(800)
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("KEY---")
|
||||
else
|
||||
sys.wait(step)
|
||||
elapsed = elapsed + step
|
||||
end
|
||||
end
|
||||
|
||||
log.info("tm1637_demo", "按键检测结束")
|
||||
end
|
||||
|
||||
-- 演示亮度调节
|
||||
local function demo_brightness()
|
||||
log.info("tm1637_demo", "===== [3/6] 亮度调节 =====")
|
||||
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("888888")
|
||||
sys.wait(500)
|
||||
|
||||
for brightness = 0, 7 do
|
||||
log.info("tm1637_demo", "设置亮度:", brightness)
|
||||
exs_tm1637.set_brightness(brightness)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
exs_tm1637.set_brightness(4)
|
||||
exs_tm1637.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 按键回调函数
|
||||
local function on_key(key_code)
|
||||
log.info("tm1637_demo", "按键回调触发, 编码:", key_code)
|
||||
local display = string.format("K%02d", key_code)
|
||||
exs_tm1637.set_display(display)
|
||||
end
|
||||
|
||||
-- 演示按键回调
|
||||
local function demo_key_callback()
|
||||
log.info("tm1637_demo", "===== [4/6] 按键回调 =====")
|
||||
log.info("tm1637_demo", "接下来 12 秒内按按键查看回调效果")
|
||||
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("Cb-Key")
|
||||
exs_tm1637.set_key_callback(on_key)
|
||||
|
||||
sys.wait(12000)
|
||||
|
||||
exs_tm1637.set_key_callback(nil)
|
||||
log.info("tm1637_demo", "按键回调演示结束")
|
||||
end
|
||||
|
||||
-- 综合演示
|
||||
local function demo_final_show()
|
||||
log.info("tm1637_demo", "===== [5/6] 综合演示 =====")
|
||||
|
||||
for i = 5, 0, -1 do
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display(string.format("%d", i))
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
for i = 0, 3 do
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("-HELLO")
|
||||
sys.wait(500)
|
||||
exs_tm1637.clear()
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
exs_tm1637.clear()
|
||||
exs_tm1637.set_display("888888")
|
||||
|
||||
for i = 0, 7 do
|
||||
exs_tm1637.set_brightness(i)
|
||||
sys.wait(200)
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
exs_tm1637.clear()
|
||||
|
||||
log.info("tm1637_demo", "---- 综合演示结束 ----")
|
||||
end
|
||||
|
||||
-- 展示日期:6 位数码管,格式 "260713"
|
||||
local function show_date()
|
||||
log.info("tm1637_demo", "日期展示: 260713")
|
||||
exs_tm1637.set_display("260713")
|
||||
sys.wait(3000)
|
||||
exs_tm1637.clear()
|
||||
end
|
||||
|
||||
-- 展示时间:模拟走时 "083000" ~ "083009"
|
||||
local function show_clock()
|
||||
exs_tm1637.clear()
|
||||
sys.wait(200)
|
||||
log.info("tm1637_demo", "时钟展示: 083000 ~ 083009")
|
||||
for sec = 0, 9 do
|
||||
exs_tm1637.set_display(string.format("0830%02d", sec))
|
||||
sys.wait(500)
|
||||
end
|
||||
end
|
||||
|
||||
-- 展示温度:摄氏度用 "°C",华氏度用 "°F"
|
||||
local function show_temperature()
|
||||
exs_tm1637.clear()
|
||||
sys.wait(200)
|
||||
local DEGREE = "°"
|
||||
for temp = 25, 32 do
|
||||
local cel = string.format("%02d", temp) .. DEGREE .. "C"
|
||||
exs_tm1637.set_display(cel)
|
||||
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
|
||||
if bright < 0 then bright = 0 end
|
||||
if bright > 7 then bright = 7 end
|
||||
exs_tm1637.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
for temp = 77, 90, 2 do
|
||||
local fah = string.format("%02d", temp) .. DEGREE .. "F"
|
||||
exs_tm1637.set_display(fah)
|
||||
sys.wait(600)
|
||||
end
|
||||
|
||||
exs_tm1637.set_brightness(5)
|
||||
sys.wait(1000)
|
||||
exs_tm1637.clear()
|
||||
end
|
||||
|
||||
local function run_main()
|
||||
log.info("tm1637_demo", "===== [6/6] 日期/时钟/温度 =====")
|
||||
|
||||
show_date()
|
||||
sys.wait(300)
|
||||
show_clock()
|
||||
sys.wait(300)
|
||||
show_temperature()
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function tm1637_demo_task_func()
|
||||
-- 初始化
|
||||
local result = exs_tm1637.setup({
|
||||
clk = 31,
|
||||
dio = 30,
|
||||
bright = 5,
|
||||
})
|
||||
if not result then
|
||||
log.error("tm1637_demo", "TM1637 初始化失败,请检查接线")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("tm1637_demo", "TM1637 初始化成功,版本:", exs_tm1637.version())
|
||||
|
||||
-- HELLO 开始 → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
exs_tm1637.set_display("HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
demo_string()
|
||||
demo_keys()
|
||||
demo_key_callback()
|
||||
demo_brightness()
|
||||
demo_final_show()
|
||||
run_main()
|
||||
|
||||
exs_tm1637.set_display("End")
|
||||
sys.wait(3000)
|
||||
log.info("tm1637_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(tm1637_demo_task_func)
|
||||
@@ -0,0 +1,74 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary TM1638 数码管驱动芯片测试 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.07
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_tm1638 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/7]→[2/7]→[3/7]→[4/7]→[5/7]→[6/7]→[7/7]→End
|
||||
1、数码管字符串显示([1/7])
|
||||
2、LED 指示灯控制([2/7])
|
||||
3、按键轮询检测([3/7])
|
||||
4、亮度调节([4/7])
|
||||
5、按键回调([5/7])
|
||||
6、综合演示([6/7])
|
||||
7、日期/时钟/温度([7/7])
|
||||
|
||||
]]
|
||||
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "TM1638_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 tm1638_demo.lua 演示模块
|
||||
require "tm1638_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,249 @@
|
||||
# TM1638 数码管驱动芯片演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **tm1638_demo.lua** - TM1638 功能演示模块,包含数码管显示、LED 控制、按键检测、亮度调节、综合展示等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_tm1638** - TM1638 扩展库,提供数码管段码显示、LED 指示灯控制、按键检测、亮度调节等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_tm1638 扩展库的 7 项功能:HELLO → [1/7] → [2/7] → [3/7] → [4/7] → [5/7] → [6/7] → [7/7] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/7] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示
|
||||
2. **[2/7] LED 控制** - 逐个点亮/熄灭 LED 指示灯、LED 跑马灯效果
|
||||
3. **[3/7] 按键轮询** - 通过 `get_key()` API 轮询检测按键,10 秒超时
|
||||
4. **[4/7] 亮度调节** - 展示 0~7 级亮度调节效果
|
||||
5. **[5/7] 按键回调** - 通过 `set_key_callback()` API 设置按键回调函数,15 秒演示窗口
|
||||
6. **[6/7] 综合演示** - 倒计时、HELLO 闪烁、全亮全灭、亮度渐变
|
||||
7. **[7/7] 日期/时钟/温度** - 日期展示(YY-MM-DD 格式)、时钟模拟走时(HH-MM-SS)、温度展示(摄氏度°C 和华氏度°F)
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 4.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- TM1638 数码管模块(8 位数码管 + 8 个 LED 指示灯 + 8 个按键) × 1
|
||||
demo所演示的TM1638数码管[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=862890736053&mi_id=0000hQbdi599Ci7xSkwlh3JRFNce012vqjQLR8ZnTZt0bG8&ns=1&spm=a21n57.1.hoverItem.7&utparam=%7B%22aplus_abtest%22%3A%22224c84d139b925f8f3d8268f9e91b200%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 5
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 4.2 接线配置
|
||||
|
||||
#### 4.2.1 TM1638 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>TM1638 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
|
||||
<tr>
|
||||
<td>31/GPIO30<br/></td><td>DIO<br/></td></tr>
|
||||
<tr>
|
||||
<td>33/GPIO32<br/></td><td>STB<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:TM1638 模块通常还带有 VCC 和 GND 引脚,直接连接核心板的 VDD_EXT(3.3V)和 GND 即可。接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780egh/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 主程序入口
|
||||
2. **tm1638_demo.lua** - TM1638 功能演示模块
|
||||
3. **exs_tm1638** - TM1638 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 TM1638 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 tm1638_demo.lua 演示模块
|
||||
require "tm1638_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 字符串显示演示
|
||||
|
||||
1. 设备启动后显示 "HELLO",随后自动进入 [1/7] 字符串显示
|
||||
2. 观察数码管依次显示:`87654321` → `88.88` → `AbCd` → 从第 3 位显示 `1234`
|
||||
3. 检查字符显示是否正确,带小数点功能是否正常
|
||||
|
||||
#### 6.4.2 LED 控制演示
|
||||
|
||||
1. 自动进入 [2/7] LED 控制演示
|
||||
2. 观察 LED 指示灯从 1 到 8 逐个点亮,再逐个熄灭
|
||||
3. 观察 LED 跑马灯效果,共循环 3 轮
|
||||
4. 数码管同步显示当前位置数字
|
||||
|
||||
#### 6.4.3 按键检测演示
|
||||
|
||||
1. 自动进入 [3/7] 按键轮询演示,数码管显示 "KEY----"
|
||||
2. 在 10 秒内按下 TM1638 模块上的任意按键
|
||||
3. 观察数码管显示按键编码(如 "K01"、"K02" 等)
|
||||
4. 若 10 秒内无按键按下,自动跳过
|
||||
|
||||
#### 6.4.4 亮度调节演示
|
||||
|
||||
1. 自动进入 [4/7] 亮度调节演示,数码管显示 "88888888"
|
||||
2. 观察数码管亮度从 0 级到 7 级逐级变化
|
||||
3. 最终恢复到 4 级亮度
|
||||
|
||||
#### 6.4.5 按键回调演示
|
||||
|
||||
1. 自动进入 [5/7] 按键回调演示,数码管显示 "Cb-Key"
|
||||
2. 在 15 秒内按下任意按键,观察数码管显示对应按键编码
|
||||
3. 观察日志输出,确认回调函数 `on_key` 被正常触发
|
||||
4. 15 秒后自动结束回调演示
|
||||
|
||||
#### 6.4.6 综合演示
|
||||
|
||||
1. 自动进入 [6/7] 综合演示
|
||||
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
|
||||
3. 观察 "-HELLO-" 闪烁效果,重复 4 次
|
||||
4. 观察全 8 显示 + 全部 LED 点亮 + 亮度渐变
|
||||
5. 数字和 LED 指示灯全灭
|
||||
|
||||
#### 6.4.7 日期/时钟/温度演示
|
||||
|
||||
1. 自动进入 [7/7] 日期/时钟/温度演示
|
||||
2. 日期展示:显示格式 "YY-MM-DD"(如 "26-07-08"),停留 3 秒
|
||||
3. 时钟展示:模拟走时 "08-30-00" → "08-30-01" → ... → "08-30-09"
|
||||
4. 温度展示:
|
||||
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
|
||||
- 华氏度:77°F → 90°F 逐度变化
|
||||
5. 演示结束后显示 "End" 并停留 3 秒
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置
|
||||
- **LED 控制**:8 颗 LED 指示灯均可独立控制,跑马灯效果流畅
|
||||
- **按键检测**:轮询模式和回调模式均能正确检测按键,编码显示正常
|
||||
- **亮度调节**:0~7 级亮度逐级变化,效果明显
|
||||
- **日期/时钟/温度**:格式显示正确,°C 和 °F 符号正常显示
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:36:28.010][000000000.184] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:36:28.014][000000000.184] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:36:28.017][000000000.186] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:36:28.020][000000000.188] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:36:28.044][000000000.188] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:36:28.046][000000000.189] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:36:28.048][000000000.207] I/user.main TM1638_Demo 001.999.000
|
||||
[2026-07-21 10:36:28.051][000000000.223] D/user.exs_tm1638 version -> 202607131200
|
||||
[2026-07-21 10:36:28.055][000000000.239] I/user.exs_tm1638 初始化完成, clk=31 dio=30 stb=32 亮度=5
|
||||
[2026-07-21 10:36:28.058][000000000.239] I/user.tm1638_demo TM1638 初始化成功,版本: 202607131200
|
||||
[2026-07-21 10:36:28.689][000000001.251] I/user.tm1638_demo ===== [1/7] 字符串显示 =====
|
||||
[2026-07-21 10:36:28.692][000000001.252] I/user.tm1638_demo 显示 87654321
|
||||
[2026-07-21 10:36:29.798][000000002.300] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:36:29.800][000000002.300] D/mobile cid1, state0
|
||||
[2026-07-21 10:36:29.801][000000002.301] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:36:29.810][000000002.301] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:36:29.818][000000002.356] D/mobile TIME_SYNC 0 tm 1784601393
|
||||
[2026-07-21 10:36:30.210][000000002.776] I/user.tm1638_demo 显示 88.88
|
||||
[2026-07-21 10:36:31.730][000000004.300] I/user.tm1638_demo 显示 AbCd
|
||||
[2026-07-21 10:36:33.254][000000005.824] I/user.tm1638_demo 从第 3 位开始显示 1234
|
||||
[2026-07-21 10:36:35.285][000000007.859] I/user.tm1638_demo ===== [2/7] LED =====
|
||||
[2026-07-21 10:36:38.805][000000011.371] I/user.tm1638_demo 逐个熄灭
|
||||
[2026-07-21 10:36:40.422][000000012.987] I/user.tm1638_demo LED 跑马灯
|
||||
[2026-07-21 10:36:44.912][000000017.474] I/user.tm1638_demo ===== [3/7] 亮度调节 =====
|
||||
[2026-07-21 10:36:45.426][000000017.998] I/user.tm1638_demo 设置亮度: 0
|
||||
[2026-07-21 10:36:46.229][000000018.799] I/user.tm1638_demo 设置亮度: 1
|
||||
[2026-07-21 10:36:47.036][000000019.600] I/user.tm1638_demo 设置亮度: 2
|
||||
[2026-07-21 10:36:47.826][000000020.401] I/user.tm1638_demo 设置亮度: 3
|
||||
[2026-07-21 10:36:48.631][000000021.202] I/user.tm1638_demo 设置亮度: 4
|
||||
[2026-07-21 10:36:49.437][000000022.003] I/user.tm1638_demo 设置亮度: 5
|
||||
[2026-07-21 10:36:50.242][000000022.804] I/user.tm1638_demo 设置亮度: 6
|
||||
[2026-07-21 10:36:51.033][000000023.605] I/user.tm1638_demo 设置亮度: 7
|
||||
[2026-07-21 10:36:52.356][000000024.919] I/user.tm1638_demo ===== [4/7] 按键轮询 =====
|
||||
[2026-07-21 10:36:52.366][000000024.919] I/user.tm1638_demo 请在 10 秒内按下连接到 TM1638 的按键...
|
||||
[2026-07-21 10:36:53.831][000000026.399] I/user.tm1638_demo 检测到按键, 编码: 17
|
||||
[2026-07-21 10:36:54.842][000000027.412] I/user.tm1638_demo [5/7] 按键回调(15 秒内按按键演示)
|
||||
[2026-07-21 10:36:55.774][000000028.342] I/user.tm1638_demo 按键回调触发, 编码: 19
|
||||
[2026-07-21 10:36:56.721][000000029.292] I/user.tm1638_demo 按键回调触发, 编码: 21
|
||||
[2026-07-21 10:36:57.468][000000030.042] I/user.tm1638_demo 按键回调触发, 编码: 23
|
||||
[2026-07-21 10:36:58.227][000000030.792] I/user.tm1638_demo 按键回调触发, 编码: 18
|
||||
[2026-07-21 10:36:58.929][000000031.492] I/user.tm1638_demo 按键回调触发, 编码: 20
|
||||
[2026-07-21 10:36:59.581][000000032.142] I/user.tm1638_demo 按键回调触发, 编码: 22
|
||||
[2026-07-21 10:37:00.218][000000032.792] I/user.tm1638_demo 按键回调触发, 编码: 24
|
||||
[2026-07-21 10:37:09.864][000000042.439] I/user.tm1638_demo 按键回调演示结束
|
||||
[2026-07-21 10:37:09.876][000000042.439] I/user.tm1638_demo ===== [6/7] 综合演示 =====
|
||||
[2026-07-21 10:37:19.103][000000051.675] I/user.tm1638_demo ---- 综合演示结束 ----
|
||||
[2026-07-21 10:37:19.116][000000051.675] I/user.tm1638_demo ===== [7/7] 日期/时钟/温度 =====
|
||||
[2026-07-21 10:37:19.128][000000051.675] I/user.tm1638_demo 日期展示: 26-07-08
|
||||
[2026-07-21 10:37:22.644][000000055.209] I/user.tm1638_demo 时钟展示: 08-30-00 ~ 08-30-09
|
||||
[2026-07-21 10:37:43.095][000000075.654] I/user.tm1638_demo ===== [演示完毕] =====
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **数码管无显示**:
|
||||
|
||||
- 检查 TM1638 接线是否正确(CLK、DIO、STB、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_tm1638 扩展库已正常加载
|
||||
|
||||
2. **LED 指示灯不亮**:
|
||||
|
||||
- 检查 TM1638 模块供电是否正常
|
||||
- 确认模块是否支持 LED 功能(部分精简模块可能没有 LED)
|
||||
|
||||
3. **按键无响应**:
|
||||
|
||||
- 检查按键接线和 TM1638 模块是否正常
|
||||
- 确认扩展库初始化成功
|
||||
- 查看日志确认 `init()` 返回值为 true
|
||||
|
||||
4. **亮度无法调节**:
|
||||
|
||||
- 确认调用 `set_brightness()` 时参数为 0~7
|
||||
|
||||
5. **显示内容错乱**:
|
||||
|
||||
- 检查杜邦线是否过长导致通信不稳定
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_tm1638 更多接口的使用可以查看 [exs_tm1638 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_tm1638/)
|
||||
@@ -0,0 +1,280 @@
|
||||
--[[
|
||||
@module tm1638_demo
|
||||
@summary TM1638 驱动芯片演示模块,包含所有功能的演示用例
|
||||
@version 2.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 TM1638 的逐项功能演示和综合展示。
|
||||
通过 exs_tm1638 扩展库的 API 逐一演示数码管显示、LED 控制、按键检测等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_tm1638 扩展库
|
||||
local exs_tm1638 = require "exs_tm1638"
|
||||
|
||||
-- 演示字符串显示
|
||||
local function demo_string()
|
||||
log.info("tm1638_demo", "===== [1/7] 字符串显示 =====")
|
||||
|
||||
log.info("tm1638_demo", "显示 87654321")
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("87654321")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1638_demo", "显示 88.88")
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("88.88")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1638_demo", "显示 AbCd")
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("AbCd")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1638_demo", "从第 3 位开始显示 1234")
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("1234", 3)
|
||||
sys.wait(1500)
|
||||
|
||||
exs_tm1638.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示 LED 指示灯
|
||||
local function demo_leds()
|
||||
log.info("tm1638_demo", "===== [2/7] LED =====")
|
||||
|
||||
for i = 1, 8 do
|
||||
exs_tm1638.set_display(string.format("%d", i))
|
||||
exs_tm1638.set_led(true, i)
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
|
||||
log.info("tm1638_demo", "逐个熄灭")
|
||||
for i = 1, 8 do
|
||||
exs_tm1638.set_led(false, i)
|
||||
sys.wait(200)
|
||||
end
|
||||
|
||||
log.info("tm1638_demo", "LED 跑马灯")
|
||||
exs_tm1638.clear()
|
||||
for round = 1, 3 do
|
||||
for i = 1, 8 do
|
||||
if i > 1 then
|
||||
exs_tm1638.set_led(false, i - 1)
|
||||
else
|
||||
exs_tm1638.set_led(false, 8)
|
||||
end
|
||||
exs_tm1638.set_led(true, i)
|
||||
exs_tm1638.set_display(string.format("%d", i))
|
||||
sys.wait(150)
|
||||
end
|
||||
end
|
||||
|
||||
exs_tm1638.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示亮度调节
|
||||
local function demo_brightness()
|
||||
log.info("tm1638_demo", "===== [3/7] 亮度调节 =====")
|
||||
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("88888888")
|
||||
sys.wait(500)
|
||||
|
||||
for brightness = 0, 7 do
|
||||
log.info("tm1638_demo", "设置亮度:", brightness)
|
||||
exs_tm1638.set_brightness(brightness)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
exs_tm1638.set_brightness(4)
|
||||
exs_tm1638.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示按键轮询
|
||||
local function demo_keys()
|
||||
log.info("tm1638_demo", "===== [4/7] 按键轮询 =====")
|
||||
log.info("tm1638_demo", "请在 10 秒内按下连接到 TM1638 的按键...")
|
||||
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("KEY----")
|
||||
|
||||
local timeout = 10000
|
||||
local step = 100
|
||||
local elapsed = 0
|
||||
|
||||
while elapsed < timeout do
|
||||
local key = exs_tm1638.get_key()
|
||||
if key then
|
||||
exs_tm1638.clear()
|
||||
log.info("tm1638_demo", "检测到按键, 编码:", key)
|
||||
local key_str = string.format("K%02d", key)
|
||||
exs_tm1638.set_display(key_str)
|
||||
sys.wait(1000)
|
||||
return
|
||||
end
|
||||
sys.wait(step)
|
||||
elapsed = elapsed + step
|
||||
end
|
||||
|
||||
log.info("tm1638_demo", "按键检测超时,跳过")
|
||||
end
|
||||
|
||||
-- 按键回调函数
|
||||
local function on_key(key_code)
|
||||
log.info("tm1638_demo", "按键回调触发, 编码:", key_code)
|
||||
local display = string.format("K%02d", key_code)
|
||||
exs_tm1638.set_display(display)
|
||||
end
|
||||
|
||||
-- 演示按键回调
|
||||
local function demo_key_callback()
|
||||
log.info("tm1638_demo", "[5/7] 按键回调(15 秒内按按键演示)")
|
||||
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("Cb-Key")
|
||||
exs_tm1638.set_key_callback(on_key)
|
||||
|
||||
sys.wait(15000)
|
||||
|
||||
exs_tm1638.set_key_callback(nil)
|
||||
log.info("tm1638_demo", "按键回调演示结束")
|
||||
end
|
||||
|
||||
-- 综合演示
|
||||
local function demo_final_show()
|
||||
log.info("tm1638_demo", "===== [6/7] 综合演示 =====")
|
||||
|
||||
for i = 5, 0, -1 do
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display(string.format("%d", i))
|
||||
for j = 1, 8 do
|
||||
exs_tm1638.set_led(false, j)
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
for i = 0, 3 do
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("-HELLO-")
|
||||
sys.wait(500)
|
||||
exs_tm1638.clear()
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
exs_tm1638.clear()
|
||||
exs_tm1638.set_display("88888888")
|
||||
for i = 1, 8 do
|
||||
exs_tm1638.set_led(true, i)
|
||||
end
|
||||
|
||||
for i = 0, 7 do
|
||||
exs_tm1638.set_brightness(i)
|
||||
sys.wait(200)
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
exs_tm1638.clear()
|
||||
|
||||
for i = 1, 8 do
|
||||
exs_tm1638.set_led(false, i)
|
||||
end
|
||||
|
||||
log.info("tm1638_demo", "---- 综合演示结束 ----")
|
||||
end
|
||||
|
||||
-- 展示日期:格式 "26-07-08"
|
||||
local function show_date()
|
||||
log.info("tm1638_demo", "日期展示: 26-07-08")
|
||||
exs_tm1638.set_display("26-07-08")
|
||||
sys.wait(3000)
|
||||
exs_tm1638.clear()
|
||||
end
|
||||
|
||||
-- 展示时间:模拟走时 "08-30-00" ~ "08-30-09"
|
||||
local function show_clock()
|
||||
exs_tm1638.clear()
|
||||
sys.wait(200)
|
||||
log.info("tm1638_demo", "时钟展示: 08-30-00 ~ 08-30-09")
|
||||
for sec = 0, 9 do
|
||||
exs_tm1638.set_display(string.format("08-30-%02d", sec))
|
||||
sys.wait(500)
|
||||
end
|
||||
end
|
||||
|
||||
-- 展示温度:摄氏度用 "°C",华氏度用 "°F"
|
||||
local function show_temperature()
|
||||
exs_tm1638.clear()
|
||||
sys.wait(200)
|
||||
local DEGREE = "°"
|
||||
for temp = 25, 32 do
|
||||
local cel = string.format("%02d", temp) .. DEGREE .. "C"
|
||||
exs_tm1638.set_display(cel)
|
||||
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
|
||||
if bright < 0 then bright = 0 end
|
||||
if bright > 7 then bright = 7 end
|
||||
exs_tm1638.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
for temp = 77, 90, 2 do
|
||||
local fah = string.format("%02d", temp) .. DEGREE .. "F"
|
||||
exs_tm1638.set_display(fah)
|
||||
sys.wait(600)
|
||||
end
|
||||
|
||||
exs_tm1638.set_brightness(5)
|
||||
sys.wait(1000)
|
||||
exs_tm1638.clear()
|
||||
end
|
||||
|
||||
local function run_main()
|
||||
log.info("tm1638_demo", "===== [7/7] 日期/时钟/温度 =====")
|
||||
|
||||
show_date()
|
||||
sys.wait(300)
|
||||
show_clock()
|
||||
sys.wait(300)
|
||||
show_temperature()
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function tm1638_demo_task_func()
|
||||
-- 初始化
|
||||
local result = exs_tm1638.setup({
|
||||
clk = 31,
|
||||
dio = 30,
|
||||
stb = 32,
|
||||
bright = 5,
|
||||
write_mode = "auto",
|
||||
})
|
||||
if not result then
|
||||
log.error("tm1638_demo", "TM1638 初始化失败,请检查接线")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("tm1638_demo", "TM1638 初始化成功,版本:", exs_tm1638.version())
|
||||
|
||||
-- HELLO 开始 → [1/7] → [2/7] → [3/7] → [4/7] → [5/7] → [6/7] → [7/7] → End
|
||||
exs_tm1638.set_display("HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
demo_string()
|
||||
demo_leds()
|
||||
demo_brightness()
|
||||
demo_keys()
|
||||
demo_key_callback()
|
||||
demo_final_show()
|
||||
run_main()
|
||||
|
||||
exs_tm1638.set_display("End")
|
||||
sys.wait(3000)
|
||||
log.info("tm1638_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(tm1638_demo_task_func)
|
||||
@@ -0,0 +1,71 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary TM1640 数码管驱动芯片测试 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_tm1640 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/4]→[2/4]→[3/4]→[4/4]→End
|
||||
1、数码管字符串显示([1/4])
|
||||
2、亮度调节([2/4])
|
||||
3、综合演示([3/4])
|
||||
4、日期/时钟/温度([4/4])
|
||||
|
||||
]]
|
||||
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "TM1640_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 tm1640_demo.lua 演示模块
|
||||
require "tm1640_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,195 @@
|
||||
# TM1640 数码管驱动芯片演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **tm1640_demo.lua** - TM1640 功能演示模块,包含数码管显示、亮度调节、综合展示等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_tm1640** - TM1640 扩展库,提供数码管段码显示、亮度调节等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_tm1640 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/4] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示(利用 16 位显示能力)
|
||||
2. **[2/4] 亮度调节** - 展示 0~7 级亮度调节效果
|
||||
3. **[3/4] 综合演示** - 倒计时、HELLO 闪烁、全亮全灭、亮度渐变
|
||||
4. **[4/4] 日期/时钟/温度** - 日期展示(YY-MM-DD HH:MM 格式)、时钟模拟走时(HH-MM-SS)、温度展示(摄氏度°C 和华氏度°F)
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 4.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- TM1640 数码管模块(16 位数码管) × 1
|
||||
demo所演示的TM1640数码管[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=993241354836&mi_id=0000snMzr-QYn9Az44HHVAD7gjY_XJWQal2Z8EbIpIZRa-k&ns=1&priceTId=213e00d417839211007372882e1068&skuId=5970246265328&spm=a21n57.1.hoverItem.4&utparam=%7B%22aplus_abtest%22%3A%22dc10f02e922922befeb0841a2cbe561e%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 4.2 接线配置
|
||||
|
||||
#### 4.2.1 TM1640 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>TM1640 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
|
||||
<tr>
|
||||
<td>31/GPIO30<br/></td><td>DIN<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 主程序入口
|
||||
2. **tm1640_demo.lua** - TM1640 功能演示模块
|
||||
3. **exs_tm1640** - TM1640 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 TM1640 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 tm1640_demo.lua 演示模块
|
||||
require "tm1640_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 字符串显示演示
|
||||
|
||||
1. 设备启动后显示 "HELLO",随后自动进入 [1/4] 字符串显示
|
||||
2. 观察数码管依次显示:`0123456789ABCDEF` → `88.88` → 从第 3 位显示 `AbCd` → 从第 8 位显示 `1234` → 从第 12 位显示 `5678`
|
||||
3. 检查字符显示是否正确,带小数点功能是否正常
|
||||
|
||||
#### 6.4.2 亮度调节演示
|
||||
|
||||
1. 自动进入 [2/4] 亮度调节演示,数码管显示 16 个 8
|
||||
2. 观察数码管亮度从 0 级到 7 级逐级变化
|
||||
3. 最终恢复到 4 级亮度
|
||||
|
||||
#### 6.4.3 综合演示
|
||||
|
||||
1. 自动进入 [3/4] 综合演示
|
||||
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
|
||||
3. 观察 "HELLO" 闪烁效果,重复 4 次
|
||||
4. 观察 16 位全 8 显示 + 亮度渐变
|
||||
5. 数码管全灭
|
||||
|
||||
#### 6.4.4 日期/时钟/温度演示
|
||||
|
||||
1. 自动进入 [4/4] 日期/时钟/温度演示
|
||||
2. 日期时钟展示:显示格式 "YY-MM-DD HH:MM"(如 "26-07-13 08:30"),停留 4 秒
|
||||
3. 时钟展示:模拟走时 "08-30-00" → "08-30-01" → ... → "08-30-09"
|
||||
4. 温度展示:
|
||||
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
|
||||
- 华氏度:77°F → 90°F 逐度变化
|
||||
5. 演示结束后显示 "End" 并停留 3 秒
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置,16 位完整显示
|
||||
- **亮度调节**:0~7 级亮度逐级变化,效果明显
|
||||
- **日期/时钟/温度**:格式显示正确,°C 和 °F 符号正常显示
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:40:01.164][000000000.185] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:40:01.175][000000000.185] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:40:01.185][000000000.187] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:40:01.193][000000000.190] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:40:01.201][000000000.190] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:40:01.210][000000000.190] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:40:01.221][000000000.209] I/user.main TM1640_Demo 001.999.000
|
||||
[2026-07-21 10:40:01.229][000000000.223] D/user.exs_tm1640 version -> 202607131200
|
||||
[2026-07-21 10:40:01.237][000000000.250] I/user.exs_tm1640 初始化完成, clk=31 din=30 亮度=5
|
||||
[2026-07-21 10:40:01.245][000000000.250] I/user.tm1640_demo TM1640 初始化成功,版本: 202607131200
|
||||
[2026-07-21 10:40:01.745][000000001.273] I/user.tm1640_demo ===== [1/4] 字符串显示 =====
|
||||
[2026-07-21 10:40:01.752][000000001.274] I/user.tm1640_demo 显示 0123456789ABCDEF
|
||||
[2026-07-21 10:40:02.854][000000002.318] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:40:02.859][000000002.319] D/mobile cid1, state0
|
||||
[2026-07-21 10:40:02.865][000000002.320] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:40:02.889][000000002.320] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:40:02.905][000000002.374] D/mobile TIME_SYNC 0 tm 1784601606
|
||||
[2026-07-21 10:40:03.797][000000003.323] I/user.tm1640_demo 显示 88.88
|
||||
[2026-07-21 10:40:05.337][000000004.870] I/user.tm1640_demo 从第 3 位开始显示 AbCd
|
||||
[2026-07-21 10:40:06.878][000000006.416] I/user.tm1640_demo 偏移显示 1234 在第 8 位
|
||||
[2026-07-21 10:40:08.430][000000007.962] I/user.tm1640_demo 从第 12 位显示 5678
|
||||
[2026-07-21 10:40:10.496][000000010.032] I/user.tm1640_demo ===== [2/4] 亮度调节 =====
|
||||
[2026-07-21 10:40:11.041][000000010.579] I/user.tm1640_demo 设置亮度: 0
|
||||
[2026-07-21 10:40:11.851][000000011.380] I/user.tm1640_demo 设置亮度: 1
|
||||
[2026-07-21 10:40:12.644][000000012.181] I/user.tm1640_demo 设置亮度: 2
|
||||
[2026-07-21 10:40:13.454][000000012.982] I/user.tm1640_demo 设置亮度: 3
|
||||
[2026-07-21 10:40:14.252][000000013.783] I/user.tm1640_demo 设置亮度: 4
|
||||
[2026-07-21 10:40:15.060][000000014.584] I/user.tm1640_demo 设置亮度: 5
|
||||
[2026-07-21 10:40:15.854][000000015.385] I/user.tm1640_demo 设置亮度: 6
|
||||
[2026-07-21 10:40:16.646][000000016.186] I/user.tm1640_demo 设置亮度: 7
|
||||
[2026-07-21 10:40:17.983][000000017.510] I/user.tm1640_demo ===== [3/4] 综合演示 =====
|
||||
[2026-07-21 10:40:27.394][000000026.923] I/user.tm1640_demo ---- 综合演示结束 ----
|
||||
[2026-07-21 10:40:27.410][000000026.924] I/user.tm1640_demo ===== [4/4] 日期/时钟/温度 =====
|
||||
[2026-07-21 10:40:27.421][000000026.924] I/user.tm1640_demo 日期时钟展示: 26-07-13 08:30
|
||||
[2026-07-21 10:40:31.964][000000031.492] I/user.tm1640_demo 时钟展示: 08-30-00 ~ 08-30-09
|
||||
[2026-07-21 10:40:52.715][000000052.244] I/user.tm1640_demo ===== [演示完毕] =====
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **数码管无显示**:
|
||||
|
||||
- 检查 TM1640 接线是否正确(CLK、DIN、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_tm1640 扩展库已正常加载
|
||||
|
||||
2. **亮度无法调节**:
|
||||
|
||||
- 确认调用 `set_brightness()` 时参数为 0~7
|
||||
|
||||
3. **显示内容错乱**:
|
||||
|
||||
- 检查杜邦线是否过长导致通信不稳定
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_tm1640 更多接口的使用可以查看 [exs_tm1640 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_tm1640/)
|
||||
@@ -0,0 +1,186 @@
|
||||
--[[
|
||||
@module tm1640_demo
|
||||
@summary TM1640 驱动芯片演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 TM1640 的逐项功能演示和综合展示。
|
||||
通过 exs_tm1640 扩展库的 API 逐一演示数码管显示、亮度调节等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_tm1640 扩展库
|
||||
local exs_tm1640 = require "exs_tm1640"
|
||||
|
||||
-- 演示字符串显示(利用 16 位数码管)
|
||||
local function demo_string()
|
||||
log.info("tm1640_demo", "===== [1/4] 字符串显示 =====")
|
||||
|
||||
log.info("tm1640_demo", "显示 0123456789ABCDEF")
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("0123456789ABCDEF")
|
||||
sys.wait(2000)
|
||||
|
||||
log.info("tm1640_demo", "显示 88.88")
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("88.88")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1640_demo", "从第 3 位开始显示 AbCd")
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("AbCd", 3)
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1640_demo", "偏移显示 1234 在第 8 位")
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("1234", 8)
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1640_demo", "从第 12 位显示 5678")
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("5678", 12)
|
||||
sys.wait(1500)
|
||||
|
||||
exs_tm1640.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示亮度调节
|
||||
local function demo_brightness()
|
||||
log.info("tm1640_demo", "===== [2/4] 亮度调节 =====")
|
||||
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("8888888888888888")
|
||||
sys.wait(500)
|
||||
|
||||
for brightness = 0, 7 do
|
||||
log.info("tm1640_demo", "设置亮度:", brightness)
|
||||
exs_tm1640.set_brightness(brightness)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
exs_tm1640.set_brightness(4)
|
||||
exs_tm1640.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 综合演示
|
||||
local function demo_final_show()
|
||||
log.info("tm1640_demo", "===== [3/4] 综合演示 =====")
|
||||
|
||||
-- 倒计时
|
||||
for i = 5, 0, -1 do
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display(string.format("%d", i))
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- HELLO 闪烁
|
||||
for i = 0, 3 do
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("HELLO")
|
||||
sys.wait(500)
|
||||
exs_tm1640.clear()
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
-- 全 8 显示加亮度渐变
|
||||
exs_tm1640.clear()
|
||||
exs_tm1640.set_display("8888888888888888")
|
||||
|
||||
for i = 0, 7 do
|
||||
exs_tm1640.set_brightness(i)
|
||||
sys.wait(200)
|
||||
end
|
||||
|
||||
sys.wait(1000)
|
||||
exs_tm1640.clear()
|
||||
|
||||
log.info("tm1640_demo", "---- 综合演示结束 ----")
|
||||
end
|
||||
|
||||
-- 展示日期:16 位显示 "26-07-13 08:30"
|
||||
local function show_datetime()
|
||||
log.info("tm1640_demo", "日期时钟展示: 26-07-13 08:30")
|
||||
exs_tm1640.set_display("26-07-13 08:30")
|
||||
sys.wait(4000)
|
||||
exs_tm1640.clear()
|
||||
end
|
||||
|
||||
-- 展示时间:模拟走时 "08-30-00" ~ "08-30-09"
|
||||
local function show_clock()
|
||||
exs_tm1640.clear()
|
||||
sys.wait(200)
|
||||
log.info("tm1640_demo", "时钟展示: 08-30-00 ~ 08-30-09")
|
||||
for sec = 0, 9 do
|
||||
exs_tm1640.set_display(string.format("08-30-%02d", sec))
|
||||
sys.wait(500)
|
||||
end
|
||||
end
|
||||
|
||||
-- 展示温度:摄氏度用 "°C",华氏度用 "°F"
|
||||
local function show_temperature()
|
||||
exs_tm1640.clear()
|
||||
sys.wait(200)
|
||||
local DEGREE = "°"
|
||||
for temp = 25, 32 do
|
||||
local cel = string.format("%02d", temp) .. DEGREE .. "C"
|
||||
exs_tm1640.set_display(cel)
|
||||
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
|
||||
if bright < 0 then bright = 0 end
|
||||
if bright > 7 then bright = 7 end
|
||||
exs_tm1640.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
for temp = 77, 90, 2 do
|
||||
local fah = string.format("%02d", temp) .. DEGREE .. "F"
|
||||
exs_tm1640.set_display(fah)
|
||||
sys.wait(600)
|
||||
end
|
||||
|
||||
exs_tm1640.set_brightness(5)
|
||||
sys.wait(1000)
|
||||
exs_tm1640.clear()
|
||||
end
|
||||
|
||||
local function run_main()
|
||||
log.info("tm1640_demo", "===== [4/4] 日期/时钟/温度 =====")
|
||||
|
||||
show_datetime()
|
||||
sys.wait(300)
|
||||
show_clock()
|
||||
sys.wait(300)
|
||||
show_temperature()
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function tm1640_demo_task_func()
|
||||
-- 初始化(2-wire:CLK + DIN,无 STB)
|
||||
local result = exs_tm1640.setup({
|
||||
clk = 31,
|
||||
din = 30,
|
||||
bright = 5,
|
||||
})
|
||||
if not result then
|
||||
log.error("tm1640_demo", "TM1640 初始化失败,请检查接线")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("tm1640_demo", "TM1640 初始化成功,版本:", exs_tm1640.version())
|
||||
|
||||
-- HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
exs_tm1640.set_display("HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
demo_string()
|
||||
demo_brightness()
|
||||
demo_final_show()
|
||||
run_main()
|
||||
|
||||
exs_tm1640.set_display("End")
|
||||
sys.wait(3000)
|
||||
log.info("tm1640_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(tm1640_demo_task_func)
|
||||
@@ -0,0 +1,71 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary TM1650 数码管驱动芯片测试 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_tm1650 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/6]→[2/6]→[3/6]→[4/6]→[5/6]→[6/6]→End
|
||||
1、数码管字符串显示([1/6])
|
||||
2、按键检测轮询([2/6])
|
||||
3、按键回调演示([3/6])
|
||||
4、亮度调节([4/6])
|
||||
5、7段/8段模式切换([5/6])
|
||||
6、综合演示-日期/温度([6/6])
|
||||
]]
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "TM1650_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 tm1650_demo.lua 演示模块
|
||||
require "tm1650_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,256 @@
|
||||
# TM1650 数码管驱动芯片演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **tm1650_demo.lua** - TM1650 功能演示模块,包含数码管显示、按键检测、亮度调节、模式切换、综合展示等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_tm1650** - TM1650 扩展库,提供数码管段码显示、按键检测、亮度调节、模式切换等 API
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_tm1650 扩展库的 6 项功能:HELLO → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/6] 字符串显示** - 数码管逐项显示数字、带小数点数字、字母组合、指定位置显示
|
||||
2. **[2/6] 按键轮询** - 通过 `get_key()` API 轮询检测按键,10 秒超时
|
||||
3. **[3/6] 亮度调节** - 展示 0~7 级亮度调节效果
|
||||
4. **[4/6] 按键回调** - 通过 `set_key_callback()` API 设置按键回调函数,15 秒演示窗口
|
||||
5. **[5/6] 模式切换** - 8 段与 7 段模式切换演示
|
||||
6. **[6/6] 综合演示** - 倒计时、HELLO 闪烁、全 8 显示、亮度渐变、日期展示、温度展示
|
||||
|
||||
## 三、显示效果
|
||||
|
||||

|
||||
|
||||
## 四、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- TM1650 数码管模块(4 位数码管 + 28 个按键) × 1
|
||||
demo所演示的TM1650数码管[购买链接](https://item.taobao.com/item.htm?abbucket=12&id=894744356431&mi_id=0000-4_DHCxKAB3Xj0nlwc0YnvYkgo5-xS43MtZ8NtPojx4&ns=1&priceTId=213e00d417839211691737686e1068&skuId=5910411206496&spm=a21n57.1.hoverItem.3&utparam=%7B%22aplus_abtest%22%3A%22e04de8195726cbf718476351001570dd%22%7D&xxc=taobaoSearch)
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 TM1650 模块接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>TM1650 模块<br/></td></tr>
|
||||
<tr>
|
||||
<td>32/GPIO31<br/></td><td>CLK<br/></td></tr>
|
||||
<tr>
|
||||
<td>31/GPIO30<br/></td><td>DIO<br/></td></tr>
|
||||
<tr>
|
||||
<td>VDD_EXT<br/></td><td>VCC<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。
|
||||
|
||||
## 五、演示软件环境
|
||||
|
||||
### 5.1 开发工具
|
||||
|
||||
- [Luatools下载调试工具](https://docs.openluat.com/air780epm/luatos/common/download/) - 固件烧录和代码调试
|
||||
|
||||
### 5.2 内核固件
|
||||
|
||||
- [点击下载Air780EPM系列最新版本内核固件](https://docs.openluat.com/air780epm/luatos/firmware/780epm_version/),demo所使用的是 LuatOS-SoC_V2046_Air780EPM 1号固件
|
||||
|
||||
### 5.3 脚本文件
|
||||
|
||||
1. **main.lua** - 主程序入口
|
||||
2. **tm1650_demo.lua** - TM1650 功能演示模块
|
||||
3. **exs_tm1650** - TM1650 扩展库
|
||||
|
||||
## 六、演示核心步骤
|
||||
|
||||
### 6.1 硬件准备
|
||||
|
||||
1. 按照接线表将 TM1650 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 6.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 tm1650_demo.lua 演示模块
|
||||
require "tm1650_demo"
|
||||
|
||||
```
|
||||
|
||||
### 6.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 6.4 功能测试
|
||||
|
||||
#### 6.4.1 字符串显示演示
|
||||
|
||||
1. 设备启动后显示 "HELLO",随后自动进入 [1/6] 字符串显示
|
||||
2. 观察数码管依次显示:`1234` → `88.8` → `AbCd` → 从第 3 位显示 `1234`
|
||||
3. 检查字符显示是否正确,带小数点功能是否正常
|
||||
|
||||
#### 6.4.2 按键检测演示
|
||||
|
||||
1. 自动进入 [2/6] 按键轮询演示,数码管显示 "KEY-"
|
||||
2. 在 10 秒内按下 TM1650 模块上的任意按键
|
||||
3. 观察数码管显示按键编码(如 "K01"、"K02" 等)
|
||||
4. 若 10 秒内无按键按下,自动跳过
|
||||
|
||||
#### 6.4.3 亮度调节演示
|
||||
|
||||
1. 自动进入 [3/6] 亮度调节演示,数码管显示 "8888"
|
||||
2. 观察数码管亮度从 0 级到 7 级逐级变化
|
||||
3. 最终恢复到 4 级亮度
|
||||
|
||||
#### 6.4.4 按键回调演示
|
||||
|
||||
1. 自动进入 [4/6] 按键回调演示,数码管显示 "Cb-Key"
|
||||
2. 在 15 秒内按下任意按键,观察数码管显示对应按键编码
|
||||
3. 观察日志输出,确认回调函数 `on_key` 被正常触发
|
||||
4. 15 秒后自动结束回调演示
|
||||
|
||||
#### 6.4.5 模式切换演示
|
||||
|
||||
1. 自动进入 [5/6] 模式切换演示
|
||||
2. 观察数码管从 8 段模式切换到 7 段模式
|
||||
3. 再切回 8 段模式,观察显示效果变化
|
||||
4. 确认小数点(DP)在 7 段模式下不显示
|
||||
|
||||
#### 6.4.6 综合演示
|
||||
|
||||
1. 自动进入 [6/6] 综合演示
|
||||
2. 观察倒计时效果:5 → 4 → 3 → 2 → 1 → 0
|
||||
3. 观察 "HELO" 闪烁效果,重复 4 次
|
||||
4. 观察全 8 显示 + 亮度渐变
|
||||
5. 日期展示:显示格式 "YY-MM-DD"(如 "26-07-13"),停留 3 秒
|
||||
6. 温度展示:
|
||||
- 摄氏度:25°C → 32°C 逐度变化,亮度随温度升高而增加
|
||||
- 华氏度:77°F → 90°F 逐度变化
|
||||
7. 演示结束后显示 "End" 并停留 3 秒
|
||||
|
||||
### 6.5 预期效果
|
||||
|
||||
- **字符串显示**:数字、字母、小数点均能正确显示,支持指定起始位置
|
||||
- **按键检测**:轮询模式和回调模式均能正确检测按键,编码显示正常
|
||||
- **亮度调节**:0~7 级亮度逐级变化,效果明显
|
||||
- **模式切换**:8 段和 7 段模式切换正常,小数点显示状态正确
|
||||
- **日期/温度**:格式显示正确,°C 和 °F 符号正常显示
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 10:42:14.862][000000000.178] I/main LuatOS@Air780EPM base 26.04 bsp V2046 32bit
|
||||
[2026-07-21 10:42:14.863][000000000.178] I/main ROM Build: Jul 7 2026 20:39:17
|
||||
[2026-07-21 10:42:14.865][000000000.180] W/pins /luadb/pins_air780epm.json not exist!!
|
||||
[2026-07-21 10:42:14.867][000000000.182] D/main loadlibs luavm 1048568 14784 14784
|
||||
[2026-07-21 10:42:14.870][000000000.182] D/main loadlibs sys 2366664 82756 89356
|
||||
[2026-07-21 10:42:14.872][000000000.182] D/main loadlibs psram 2366664 82756 89356
|
||||
[2026-07-21 10:42:14.874][000000000.200] I/user.main TM1650_Demo 001.000.001
|
||||
[2026-07-21 10:42:14.876][000000000.213] D/user.exs_tm1650 version -> 202607161200
|
||||
[2026-07-21 10:42:14.878][000000000.224] I/user.exs_tm1650 初始化完成, clk=31 dio=30 亮度=5
|
||||
[2026-07-21 10:42:14.880][000000000.224] I/user.tm1650_demo TM1650 初始化成功,版本: 202607161200
|
||||
[2026-07-21 10:42:15.073][000000001.230] I/user.tm1650_demo ===== [1/6] 字符串显示 =====
|
||||
[2026-07-21 10:42:15.075][000000001.231] I/user.tm1650_demo 显示 1234
|
||||
[2026-07-21 10:42:15.958][000000002.611] I/mobile sim0 sms ready
|
||||
[2026-07-21 10:42:15.960][000000002.611] D/mobile cid1, state0
|
||||
[2026-07-21 10:42:15.973][000000002.612] D/mobile bearer act 0, result 0
|
||||
[2026-07-21 10:42:15.977][000000002.613] D/mobile NETIF_LINK_ON -> IP_READY
|
||||
[2026-07-21 10:42:15.982][000000002.654] D/mobile TIME_SYNC 0 tm 1784601739
|
||||
[2026-07-21 10:42:16.024][000000002.744] I/user.tm1650_demo 显示 88.8
|
||||
[2026-07-21 10:42:17.529][000000004.256] I/user.tm1650_demo 显示 AbCd
|
||||
[2026-07-21 10:42:19.038][000000005.768] I/user.tm1650_demo 从第 3 位开始显示 12
|
||||
[2026-07-21 10:42:20.562][000000007.280] I/user.tm1650_demo 显示 HELO
|
||||
[2026-07-21 10:42:22.567][000000009.297] I/user.tm1650_demo ===== [2/6] 按键轮询 =====
|
||||
[2026-07-21 10:42:22.571][000000009.298] I/user.tm1650_demo 请在 10 秒内按下连接到 TM1650 的按键...
|
||||
[2026-07-21 10:42:24.405][000000011.130] I/user.tm1650_demo 检测到按键, 编码: 1
|
||||
[2026-07-21 10:42:24.515][000000011.238] I/user.tm1650_demo 检测到按键, 编码: 1
|
||||
[2026-07-21 10:42:25.431][000000012.155] I/user.tm1650_demo 检测到按键, 编码: 2
|
||||
[2026-07-21 10:42:25.540][000000012.262] I/user.tm1650_demo 检测到按键, 编码: 2
|
||||
[2026-07-21 10:42:26.053][000000012.774] I/user.tm1650_demo 检测到按键, 编码: 3
|
||||
[2026-07-21 10:42:26.161][000000012.881] I/user.tm1650_demo 检测到按键, 编码: 3
|
||||
[2026-07-21 10:42:26.674][000000013.394] I/user.tm1650_demo 检测到按键, 编码: 4
|
||||
[2026-07-21 10:42:27.389][000000014.107] I/user.tm1650_demo 检测到按键, 编码: 5
|
||||
[2026-07-21 10:42:27.903][000000014.620] I/user.tm1650_demo 检测到按键, 编码: 6
|
||||
[2026-07-21 10:42:28.308][000000015.030] I/user.tm1650_demo 检测到按键, 编码: 7
|
||||
[2026-07-21 10:42:28.711][000000015.440] I/user.tm1650_demo 检测到按键, 编码: 8
|
||||
[2026-07-21 10:42:29.333][000000016.054] I/user.tm1650_demo 检测到按键, 编码: 9
|
||||
[2026-07-21 10:42:29.738][000000016.465] I/user.tm1650_demo 检测到按键, 编码: 10
|
||||
[2026-07-21 10:42:30.250][000000016.977] I/user.tm1650_demo 检测到按键, 编码: 11
|
||||
[2026-07-21 10:42:30.670][000000017.387] I/user.tm1650_demo 检测到按键, 编码: 12
|
||||
[2026-07-21 10:42:31.278][000000018.000] I/user.tm1650_demo 检测到按键, 编码: 13
|
||||
[2026-07-21 10:42:31.682][000000018.413] I/user.tm1650_demo 检测到按键, 编码: 14
|
||||
[2026-07-21 10:42:32.103][000000018.823] I/user.tm1650_demo 检测到按键, 编码: 15
|
||||
[2026-07-21 10:42:32.507][000000019.233] I/user.tm1650_demo 检测到按键, 编码: 16
|
||||
[2026-07-21 10:42:32.817][000000019.541] I/user.tm1650_demo 按键检测超时,跳过
|
||||
[2026-07-21 10:42:32.822][000000019.541] I/user.tm1650_demo ===== [3/6] 按键回调 =====
|
||||
[2026-07-21 10:42:32.827][000000019.542] I/user.tm1650_demo 接下来 15 秒内按按键查看回调效果
|
||||
[2026-07-21 10:42:33.035][000000019.755] I/user.tm1650_demo 按键回调触发, 编码: 17
|
||||
[2026-07-21 10:42:33.581][000000020.306] I/user.tm1650_demo 按键回调触发, 编码: 18
|
||||
[2026-07-21 10:42:34.125][000000020.855] I/user.tm1650_demo 按键回调触发, 编码: 19
|
||||
[2026-07-21 10:42:34.529][000000021.255] I/user.tm1650_demo 按键回调触发, 编码: 20
|
||||
[2026-07-21 10:42:35.024][000000021.755] I/user.tm1650_demo 按键回调触发, 编码: 21
|
||||
[2026-07-21 10:42:35.428][000000022.155] I/user.tm1650_demo 按键回调触发, 编码: 22
|
||||
[2026-07-21 10:42:35.833][000000022.556] I/user.tm1650_demo 按键回调触发, 编码: 23
|
||||
[2026-07-21 10:42:36.175][000000022.905] I/user.tm1650_demo 按键回调触发, 编码: 24
|
||||
[2026-07-21 10:42:36.577][000000023.305] I/user.tm1650_demo 按键回调触发, 编码: 25
|
||||
[2026-07-21 10:42:36.981][000000023.705] I/user.tm1650_demo 按键回调触发, 编码: 26
|
||||
[2026-07-21 10:42:37.323][000000024.055] I/user.tm1650_demo 按键回调触发, 编码: 27
|
||||
[2026-07-21 10:42:37.730][000000024.455] I/user.tm1650_demo 按键回调触发, 编码: 28
|
||||
[2026-07-21 10:42:47.837][000000034.556] I/user.tm1650_demo 按键回调演示结束
|
||||
[2026-07-21 10:42:47.841][000000034.556] I/user.tm1650_demo ===== [4/6] 亮度调节 =====
|
||||
[2026-07-21 10:42:48.350][000000035.068] I/user.tm1650_demo 设置亮度: 0
|
||||
[2026-07-21 10:42:49.141][000000035.870] I/user.tm1650_demo 设置亮度: 1
|
||||
[2026-07-21 10:42:49.950][000000036.672] I/user.tm1650_demo 设置亮度: 2
|
||||
[2026-07-21 10:42:50.742][000000037.474] I/user.tm1650_demo 设置亮度: 3
|
||||
[2026-07-21 10:42:51.550][000000038.276] I/user.tm1650_demo 设置亮度: 4
|
||||
[2026-07-21 10:42:52.360][000000039.078] I/user.tm1650_demo 设置亮度: 5
|
||||
[2026-07-21 10:42:53.154][000000039.880] I/user.tm1650_demo 设置亮度: 6
|
||||
[2026-07-21 10:42:53.963][000000040.682] I/user.tm1650_demo 设置亮度: 7
|
||||
[2026-07-21 10:42:55.268][000000041.991] I/user.tm1650_demo ===== [5/6] 7段/8段模式切换 =====
|
||||
[2026-07-21 10:43:01.812][000000048.536] I/user.tm1650_demo ===== [6/6] 综合演示 =====
|
||||
[2026-07-21 10:43:10.772][000000057.497] I/user.tm1650_demo 日期展示: 0713
|
||||
[2026-07-21 10:43:26.692][000000073.417] I/user.tm1650_demo ---- 综合演示结束 ----
|
||||
[2026-07-21 10:43:29.693][000000076.423] I/user.tm1650_demo ===== [演示完毕] =====
|
||||
```
|
||||
|
||||
### 6.6 故障排除
|
||||
|
||||
1. **数码管无显示**:
|
||||
|
||||
- 检查 TM1650 接线是否正确(CLK、DIO、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_tm1650 扩展库已正常加载
|
||||
|
||||
2. **按键无响应**:
|
||||
|
||||
- 检查按键接线和 TM1650 模块是否正常
|
||||
- 确认扩展库初始化成功
|
||||
- 查看日志确认 `setup()` 返回值为 true
|
||||
|
||||
3. **亮度无法调节**:
|
||||
|
||||
- 确认调用 `set_brightness()` 时参数为 0~7
|
||||
|
||||
4. **显示内容错乱**:
|
||||
|
||||
- 检查杜邦线是否过长导致通信不稳定
|
||||
|
||||
### 6.7 扩展功能建议
|
||||
|
||||
exs_tm1650 更多接口的使用可以查看 [exs_tm1650 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_tm1650/)
|
||||
@@ -0,0 +1,243 @@
|
||||
--[[
|
||||
@module tm1650_demo
|
||||
@summary TM1650 驱动芯片演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.13
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 TM1650 的逐项功能演示和综合展示。
|
||||
通过 exs_tm1650 扩展库的 API 逐一演示数码管显示、按键检测、亮度调节、
|
||||
7段/8段模式切换等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_tm1650 扩展库
|
||||
local exs_tm1650 = require "exs_tm1650"
|
||||
|
||||
-- 演示字符串显示
|
||||
local function demo_string()
|
||||
log.info("tm1650_demo", "===== [1/6] 字符串显示 =====")
|
||||
|
||||
log.info("tm1650_demo", "显示 1234")
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("1234")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1650_demo", "显示 88.8")
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("88.8")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1650_demo", "显示 AbCd")
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("AbCd")
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1650_demo", "从第 3 位开始显示 12")
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("12", 3)
|
||||
sys.wait(1500)
|
||||
|
||||
log.info("tm1650_demo", "显示 HELO")
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("HELO")
|
||||
sys.wait(1500)
|
||||
|
||||
exs_tm1650.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示按键轮询
|
||||
local function demo_keys()
|
||||
log.info("tm1650_demo", "===== [2/6] 按键轮询 =====")
|
||||
log.info("tm1650_demo", "请在 10 秒内按下连接到 TM1650 的按键...")
|
||||
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("KEYS")
|
||||
|
||||
local timeout = 10000
|
||||
local step = 100
|
||||
local elapsed = 0
|
||||
|
||||
while elapsed < timeout do
|
||||
local key = exs_tm1650.get_key()
|
||||
if key then
|
||||
log.info("tm1650_demo", "检测到按键, 编码:", key)
|
||||
local key_str = string.format("%02d", key)
|
||||
exs_tm1650.set_display(key_str)
|
||||
sys.wait(100)
|
||||
elapsed = elapsed + 100
|
||||
else
|
||||
sys.wait(step)
|
||||
elapsed = elapsed + step
|
||||
end
|
||||
end
|
||||
|
||||
log.info("tm1650_demo", "按键检测超时,跳过")
|
||||
end
|
||||
|
||||
-- 按键回调函数
|
||||
local function on_key(key_code)
|
||||
log.info("tm1650_demo", "按键回调触发, 编码:", key_code)
|
||||
local display = string.format("%02d", key_code)
|
||||
exs_tm1650.set_display(display)
|
||||
end
|
||||
|
||||
-- 演示按键回调
|
||||
local function demo_key_callback()
|
||||
log.info("tm1650_demo", "===== [3/6] 按键回调 =====")
|
||||
log.info("tm1650_demo", "接下来 15 秒内按按键查看回调效果")
|
||||
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("CALL")
|
||||
exs_tm1650.set_key_callback(on_key)
|
||||
|
||||
sys.wait(15000)
|
||||
|
||||
exs_tm1650.set_key_callback(nil)
|
||||
log.info("tm1650_demo", "按键回调演示结束")
|
||||
end
|
||||
|
||||
-- 演示亮度调节
|
||||
local function demo_brightness()
|
||||
log.info("tm1650_demo", "===== [4/6] 亮度调节 =====")
|
||||
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("8888")
|
||||
sys.wait(500)
|
||||
|
||||
for bright = 0, 7 do
|
||||
log.info("tm1650_demo", "设置亮度:", bright)
|
||||
exs_tm1650.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
-- 恢复默认亮度
|
||||
exs_tm1650.set_brightness(4)
|
||||
exs_tm1650.clear()
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- 演示 7段/8段 模式切换
|
||||
local function demo_segment_mode()
|
||||
log.info("tm1650_demo", "===== [5/6] 7段/8段模式切换 =====")
|
||||
|
||||
-- 8 段模式(含 DP 段),显示数字
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_mode(0)
|
||||
exs_tm1650.set_display("8SEG")
|
||||
sys.wait(2000)
|
||||
|
||||
-- 显示带小数点的内容(8 段模式特性)
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("88.8")
|
||||
sys.wait(2000)
|
||||
|
||||
-- 切换到 7 段模式
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_mode(1)
|
||||
exs_tm1650.set_display("7SEG")
|
||||
sys.wait(2000)
|
||||
|
||||
exs_tm1650.clear()
|
||||
sys.wait(500)
|
||||
|
||||
-- 切回 8 段模式
|
||||
exs_tm1650.set_mode(0)
|
||||
end
|
||||
|
||||
-- 综合演示
|
||||
local function demo_final()
|
||||
log.info("tm1650_demo", "===== [6/6] 综合演示 =====")
|
||||
|
||||
-- 倒计时
|
||||
for i = 5, 0, -1 do
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display(string.format("%04d", i))
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
-- HELO 闪烁
|
||||
for i = 0, 3 do
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("HELO")
|
||||
sys.wait(500)
|
||||
exs_tm1650.clear()
|
||||
sys.wait(300)
|
||||
end
|
||||
|
||||
-- 全 8 显示 + 亮度渐变
|
||||
exs_tm1650.clear()
|
||||
exs_tm1650.set_display("8888")
|
||||
for i = 0, 7 do
|
||||
exs_tm1650.set_brightness(i)
|
||||
sys.wait(200)
|
||||
end
|
||||
sys.wait(1000)
|
||||
exs_tm1650.set_brightness(4)
|
||||
exs_tm1650.clear()
|
||||
|
||||
-- 日期展示(4 位数码管,显示月日)
|
||||
log.info("tm1650_demo", "日期展示: 0713")
|
||||
exs_tm1650.set_display("0713")
|
||||
sys.wait(3000)
|
||||
|
||||
-- 温度展示(摄氏度)
|
||||
exs_tm1650.clear()
|
||||
sys.wait(200)
|
||||
local DEGREE = "\xB0"
|
||||
for temp = 25, 32 do
|
||||
local cel = string.format("%02d", temp) .. DEGREE .. "C"
|
||||
exs_tm1650.set_display(cel)
|
||||
local bright = math.floor((temp - 25) / 7 * 7 + 0.5)
|
||||
if bright < 0 then bright = 0 end
|
||||
if bright > 7 then bright = 7 end
|
||||
exs_tm1650.set_brightness(bright)
|
||||
sys.wait(800)
|
||||
end
|
||||
|
||||
-- 温度展示(华氏度)
|
||||
for temp = 77, 90, 2 do
|
||||
local fah = string.format("%02d", temp) .. DEGREE .. "F"
|
||||
exs_tm1650.set_display(fah)
|
||||
sys.wait(600)
|
||||
end
|
||||
|
||||
exs_tm1650.set_brightness(5)
|
||||
sys.wait(2000)
|
||||
exs_tm1650.clear()
|
||||
|
||||
log.info("tm1650_demo", "---- 综合演示结束 ----")
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function tm1650_demo_task_func()
|
||||
-- 初始化
|
||||
local result = exs_tm1650.setup({
|
||||
clk = 31,
|
||||
dio = 30,
|
||||
bright = 5,
|
||||
})
|
||||
if not result then
|
||||
log.error("tm1650_demo", "TM1650 初始化失败,请检查接线")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("tm1650_demo", "TM1650 初始化成功,版本:", exs_tm1650.version())
|
||||
|
||||
-- HELLO 开始 → [1/6] → [2/6] → [3/6] → [4/6] → [5/6] → [6/6] → End
|
||||
exs_tm1650.set_display("HELO")
|
||||
sys.wait(1000)
|
||||
|
||||
demo_string()
|
||||
demo_keys()
|
||||
demo_key_callback()
|
||||
demo_brightness()
|
||||
demo_segment_mode()
|
||||
demo_final()
|
||||
|
||||
exs_tm1650.set_display("End-")
|
||||
sys.wait(3000)
|
||||
log.info("tm1650_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(tm1650_demo_task_func)
|
||||
@@ -0,0 +1,72 @@
|
||||
--[[
|
||||
@module main
|
||||
@summary VL53L1X 飞行时间测距传感器 Demo 入口
|
||||
@version 1.0
|
||||
@date 2026.07.20
|
||||
@author 江访
|
||||
]]
|
||||
|
||||
--[[
|
||||
=== 演示内容 ===
|
||||
|
||||
本 demo 演示 exs_vl53l1x 扩展库的完整功能,顺序为:
|
||||
HELLO→[1/5]→[2/5]→[3/5]→[4/5]→[5/5]→End
|
||||
1、标准测距演示([1/5])
|
||||
2、测距模式切换([2/5])
|
||||
3、中断读取演示([3/5])
|
||||
4、休眠与唤醒([4/5])
|
||||
5、持续测距演示([5/5])
|
||||
|
||||
]]
|
||||
|
||||
|
||||
--[[
|
||||
VERSION:项目版本号,ascii string类型
|
||||
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
|
||||
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
|
||||
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
|
||||
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
|
||||
]]
|
||||
-- main.lua - 程序入口文件
|
||||
|
||||
PROJECT = "VL53L1X_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进行使用
|
||||
|
||||
|
||||
-- 启动一个循环定时器
|
||||
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
|
||||
-- 方便分析内存使用是否有异常
|
||||
-- sys.timerLoopStart(function()
|
||||
-- log.info("mem.lua", rtos.meminfo())
|
||||
-- log.info("mem.sys", rtos.meminfo("sys"))
|
||||
-- end, 3000)
|
||||
|
||||
-- 加载 vl53l1x_demo.lua 演示模块
|
||||
require "vl53l1x_demo"
|
||||
|
||||
|
||||
-- 用户代码已结束
|
||||
-- 结尾总是这一句
|
||||
sys.run()
|
||||
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
|
||||
@@ -0,0 +1,224 @@
|
||||
# VL53L1X 激光红外测距传感器演示
|
||||
|
||||
## 一、功能模块介绍
|
||||
|
||||
### 1.1 核心主程序模块
|
||||
|
||||
1. **main.lua** - 主程序入口,负责项目初始化、版本定义和任务调度
|
||||
2. **vl53l1x_demo.lua** - VL53L1X 功能演示模块,包含标准测距、模式切换、休眠唤醒、持续测距等所有功能的演示用例
|
||||
|
||||
### 1.2 扩展库模块
|
||||
|
||||
1. **exs_vl53l1x** - VL53L1X 扩展库,提供初始化、测距数据读取、模式切换、睡眠/唤醒、关闭等 API
|
||||
|
||||
### 1.3 诊断工具模块(按需使用)
|
||||
|
||||
1. **vl53l1x_scan.lua** - 基础扫描:I2C 地址检测、软件复位、固件状态、Model ID 读取
|
||||
2. **vl53l1x_deep_scan.lua** - 深度扫描:扫描全寄存器,判断芯片响应是否正常
|
||||
3. **vl53l1x_xshut_test.lua** - XSHUT 硬件复位测试
|
||||
|
||||
> 注:诊断工具模块需要在 main.lua 中通过 `require` 切换加载,不参与演示流程。
|
||||
|
||||
## 二、演示流程介绍
|
||||
|
||||
本 demo 按顺序演示 exs_vl53l1x 扩展库的 4 项功能:HELLO → [1/4] → [2/4] → [3/4] → [4/4] → End
|
||||
|
||||
### 2.1 功能演示项说明
|
||||
|
||||
1. **[1/5] 标准测距** - 初始化传感器,连续读取 5 次距离数据(默认 standard 模式)
|
||||
2. **[2/4] 测距模式切换** - 演示 short(抗强光)和 long(远距离)两种模式切换
|
||||
3. **[3/4] 休眠与唤醒** - 演示 sleep() 进入软件待机、wakeup() 唤醒恢复测距
|
||||
4. **[4/4] 持续测距** - 演示 sleep() 进入软件待机、wakeup() 唤醒恢复测距
|
||||
** - 每隔 1 秒读取一次距离数据,共 5 次
|
||||
|
||||
## 三、演示硬件环境
|
||||
|
||||
### 3.1 硬件清单
|
||||
|
||||
- Air780EPM 核心板 × 1
|
||||
- VL53L1X 激光红外测距传感器模块(如 GY-VL53L1X 等) × 1
|
||||
demo所演示的VL53L1X 激光红外测距传感器模块[购买链接](https://item.taobao.com/item.htm?app=chrome&bxsign=scd0Y1aCFssu5WNBf4zgfL9PHTC771hSBaYQhJANVSUUTh2awzexyQyuQSg4mN6Pbloj55y5X5F66iW6hytMgKrQauVMZK_2eg_EVTNPrAckp1M2aoTVhEBdqhZFkPdhK0r&cpp=1&h5_spm=a-tb-item.b-tb-item&id=597981154375&share_crt_v=1&shareurl=true&short_name=h.8XEIWwnTbGSsdlI&sp_tk=MGdwOGd0NWtvME0%3D&spm=a2159r.13376460.0.0&tbSocialPopKey=shareItem&tk=0gp8gt5ko0M&un=33e3e4902f14a2acade3a8129ff9a52d&un_site=0&ut_sk=1.aHcpu1x%2F2XQDACU%2ByKbrGPzO_21646297_1784598506860.TaoPassword-WeiXin.1&wxsign=tbwRNA5Uhd58zJzNm2egOHG_-dy1Cgfx7h_MWqBNsxfXGOARu2O3Fc6t-RivRx0dfSe2M0HcrjjRwaVMelu4sxeZQ-Sg6ckAT9CCpBMe0GKHQ-1vgswN6QAK7KQCMvOfph_&x-ssr=true)
|
||||
|
||||
- 母对母杜邦线 × 4
|
||||
- TYPE-C 数据线 × 1
|
||||
|
||||
### 3.2 接线配置
|
||||
|
||||
#### 3.2.1 I2C 模式接线
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Air780EPM 核心板<br/></td><td>VL53L1X 模块<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>VCC(3.3V)<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。VL53L1X 模块上的 SCL/SDA 通常已集成上拉电阻,无需额外配置。XSHUT 引脚不接时传感器会自动启动。
|
||||
|
||||

|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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. **vl53l1x_demo.lua** - VL53L1X 功能演示模块
|
||||
3. **exs_vl53l1x** - VL53L1X 扩展库
|
||||
|
||||
## 五、演示核心步骤
|
||||
|
||||
### 5.1 硬件准备
|
||||
|
||||
1. 按照接线表将 VL53L1X 模块连接到核心板
|
||||
2. 确保电源连接正确,通过 TYPE-C USB 口供电
|
||||
3. 检查所有接线无误,避免短路
|
||||
|
||||
### 5.2 软件配置
|
||||
|
||||
在 `main.lua` 中加载对应的演示模块:
|
||||
|
||||
```lua
|
||||
-- 加载 vl53l1x_demo.lua 演示模块
|
||||
require "vl53l1x_demo"
|
||||
```
|
||||
|
||||
### 5.3 软件烧录
|
||||
|
||||
1. 使用 Luatools 选择最新内核固件
|
||||
2. 下载本项目所有脚本文件
|
||||
3. 将固件和脚本一起烧录到设备
|
||||
4. 烧录成功后设备自动重启后开始运行
|
||||
|
||||
### 5.4 功能测试
|
||||
|
||||
#### 5.4.1 标准测距演示
|
||||
|
||||
1. 设备启动后打印 "HELLO",随后自动进入 [1/5] 标准测距
|
||||
2. 观察日志输出,确认初始化成功(应看到 `MID=0xEA MT=0xCC`)
|
||||
3. 观察距离数据(单位 mm)的连续读取,共 5 次
|
||||
|
||||
#### 5.4.2 测距模式切换演示
|
||||
|
||||
1. 自动进入 [2/4] 测距模式切换
|
||||
2. short 模式:抗环境光干扰最强,适合窗口附近等强光环境
|
||||
3. long 模式:最远可测约 3.6m,适合室内暗光远距离场景
|
||||
|
||||
#### 5.4.3 休眠与唤醒演示
|
||||
|
||||
1. 自动进入 [3/4] 休眠与唤醒演示
|
||||
2. 读一次当前距离作为参考
|
||||
3. sleep() 进入软件待机(约 6μA),3 秒后 wakeup() 唤醒恢复测距
|
||||
4. 观察唤醒后测距是否正常恢复
|
||||
|
||||
#### 5.4.4 持续测距演示
|
||||
|
||||
1. 自动进入 [4/4] 持续测距演示
|
||||
2. 每隔 1 秒读取一次距离数据,共 5 次
|
||||
3. 观察数据稳定性与状态码
|
||||
|
||||
### 5.5 预期效果
|
||||
|
||||
- **标准测距**:初始化成功,距离数据正常输出
|
||||
- **模式切换**:short/long 模式均能正常读取距离
|
||||
- **休眠唤醒**:sleep 后停止测距,wakeup 后测距恢复正常
|
||||
- **持续测距**:每秒一帧数据,状态码 0(测距成功)
|
||||
- **日志如下:**
|
||||
```lua
|
||||
[2026-07-21 20:17:13.093][000000000.246] I/user.main VL53L1X_Demo 001.999.000
|
||||
[2026-07-21 20:17:13.099][000000000.263] I/user.vl53l1x_demo HELLO
|
||||
[2026-07-21 20:17:13.228][000000001.264] I/user.vl53l1x_demo ===== [1/5] 标准测距 =====
|
||||
[2026-07-21 20:17:13.232][000000001.275] I/user.exs_vl53l1x 固件就绪 0x00E5=0x03
|
||||
[2026-07-21 20:17:13.238][000000001.385] I/user.exs_vl53l1x 预设模式配置写入完成 (mode=standard)
|
||||
[2026-07-21 20:17:13.243][000000001.388] I/user.exs_vl53l1x 芯片 MID=0xEA MT=0xCC
|
||||
[2026-07-21 20:17:13.377][000000001.591] I/user.exs_vl53l1x 初始化完成,Standard Ranging 测距已启动
|
||||
[2026-07-21 20:17:13.382][000000001.591] I/user.vl53l1x_demo VL53L1X 初始化成功,版本: 202607201200
|
||||
[2026-07-21 20:17:13.400][000000001.845] I/user.vl53l1x_demo 第1次: 距离=201mm 状态=测距成功 stream=1
|
||||
[2026-07-21 20:17:13.820][000000002.354] I/user.vl53l1x_demo 第2次: 距离=200mm 状态=测距成功 stream=2
|
||||
[2026-07-21 20:17:14.325][000000002.863] I/user.vl53l1x_demo 第3次: 距离=200mm 状态=测距成功 stream=3
|
||||
[2026-07-21 20:17:14.827][000000003.372] I/user.vl53l1x_demo 第4次: 距离=196mm 状态=测距成功 stream=4
|
||||
[2026-07-21 20:17:15.339][000000003.881] I/user.vl53l1x_demo 第5次: 距离=197mm 状态=测距成功 stream=5
|
||||
[2026-07-21 20:17:15.837][000000004.385] I/user.exs_vl53l1x 传感器已关闭
|
||||
[2026-07-21 20:17:15.845][000000004.385] I/user.vl53l1x_demo ---- [1/5] 完成 ----
|
||||
[2026-07-21 20:17:16.343][000000004.886] I/user.vl53l1x_demo ===== [2/5] 测距模式切换 =====
|
||||
[2026-07-21 20:17:16.348][000000004.886] I/user.vl53l1x_demo 切换 short 模式(抗强光)
|
||||
[2026-07-21 20:17:16.358][000000004.898] I/user.exs_vl53l1x 固件就绪 0x00E5=0x03
|
||||
[2026-07-21 20:17:16.466][000000005.008] I/user.exs_vl53l1x 预设模式配置写入完成 (mode=short)
|
||||
[2026-07-21 20:17:16.471][000000005.011] I/user.exs_vl53l1x 芯片 MID=0xEA MT=0xCC
|
||||
[2026-07-21 20:17:16.668][000000005.215] I/user.exs_vl53l1x 初始化完成,Standard Ranging 测距已启动
|
||||
[2026-07-21 20:17:16.916][000000005.461] I/user.vl53l1x_demo short 模式: 距离=24mm 状态=串扰信号
|
||||
[2026-07-21 20:17:16.923][000000005.465] I/user.exs_vl53l1x 传感器已关闭
|
||||
[2026-07-21 20:17:16.928][000000005.465] I/user.vl53l1x_demo 切换 long 模式(远距离)
|
||||
[2026-07-21 20:17:16.934][000000005.477] I/user.exs_vl53l1x 固件就绪 0x00E5=0x03
|
||||
[2026-07-21 20:17:17.040][000000005.587] I/user.exs_vl53l1x 预设模式配置写入完成 (mode=long)
|
||||
[2026-07-21 20:17:17.056][000000005.590] I/user.exs_vl53l1x 芯片 MID=0xEA MT=0xCC
|
||||
[2026-07-21 20:17:17.258][000000005.794] I/user.exs_vl53l1x 初始化完成,Standard Ranging 测距已启动
|
||||
[2026-07-21 20:17:17.524][000000006.058] I/user.vl53l1x_demo long 模式: 距离=199mm 状态=测距成功
|
||||
[2026-07-21 20:17:17.530][000000006.062] I/user.exs_vl53l1x 传感器已关闭
|
||||
[2026-07-21 20:17:17.534][000000006.062] I/user.vl53l1x_demo ---- [2/5] 完成 ----
|
||||
[2026-07-21 20:17:18.021][000000006.563] I/user.vl53l1x_demo ===== [4/5] 休眠与唤醒演示 =====
|
||||
[2026-07-21 20:17:18.036][000000006.574] I/user.exs_vl53l1x 固件就绪 0x00E5=0x03
|
||||
[2026-07-21 20:17:18.144][000000006.684] I/user.exs_vl53l1x 预设模式配置写入完成 (mode=standard)
|
||||
[2026-07-21 20:17:18.151][000000006.688] I/user.exs_vl53l1x 芯片 MID=0xEA MT=0xCC
|
||||
[2026-07-21 20:17:18.345][000000006.891] I/user.exs_vl53l1x 初始化完成,Standard Ranging 测距已启动
|
||||
[2026-07-21 20:17:18.609][000000007.144] I/user.vl53l1x_demo 休眠前: 距离=201mm 状态=测距成功
|
||||
[2026-07-21 20:17:18.614][000000007.144] I/user.vl53l1x_demo 进入软件待机模式
|
||||
[2026-07-21 20:17:18.620][000000007.149] I/user.exs_vl53l1x 已进入软件待机
|
||||
[2026-07-21 20:17:21.610][000000010.149] I/user.vl53l1x_demo 从软件待机模式唤醒
|
||||
[2026-07-21 20:17:21.626][000000010.162] I/user.exs_vl53l1x 已从软件待机唤醒,测距已恢复
|
||||
[2026-07-21 20:17:21.875][000000010.415] I/user.vl53l1x_demo 唤醒后: 距离=199mm 状态=测距成功
|
||||
[2026-07-21 20:17:21.882][000000010.419] I/user.exs_vl53l1x 传感器已关闭
|
||||
[2026-07-21 20:17:21.887][000000010.419] I/user.vl53l1x_demo ---- [4/5] 完成 ----
|
||||
[2026-07-21 20:17:22.385][000000010.920] I/user.vl53l1x_demo ===== [5/5] 持续测距演示 =====
|
||||
[2026-07-21 20:17:22.391][000000010.931] I/user.exs_vl53l1x 固件就绪 0x00E5=0x03
|
||||
[2026-07-21 20:17:22.508][000000011.041] I/user.exs_vl53l1x 预设模式配置写入完成 (mode=standard)
|
||||
[2026-07-21 20:17:22.514][000000011.044] I/user.exs_vl53l1x 芯片 MID=0xEA MT=0xCC
|
||||
[2026-07-21 20:17:22.711][000000011.248] I/user.exs_vl53l1x 初始化完成,Standard Ranging 测距已启动
|
||||
[2026-07-21 20:17:22.721][000000011.248] I/user.vl53l1x_demo 每隔 1 秒读取一次距离数据,共 5 次
|
||||
[2026-07-21 20:17:23.764][000000012.302] I/user.vl53l1x_demo 持续测距[1]: 距离=201mm 状态=测距成功
|
||||
[2026-07-21 20:17:24.771][000000013.311] I/user.vl53l1x_demo 持续测距[2]: 距离=199mm 状态=测距成功
|
||||
[2026-07-21 20:17:25.779][000000014.320] I/user.vl53l1x_demo 持续测距[3]: 距离=197mm 状态=测距成功
|
||||
[2026-07-21 20:17:26.788][000000015.329] I/user.vl53l1x_demo 持续测距[4]: 距离=198mm 状态=测距成功
|
||||
[2026-07-21 20:17:27.803][000000016.338] I/user.vl53l1x_demo 持续测距[5]: 距离=197mm 状态=测距成功
|
||||
[2026-07-21 20:17:27.808][000000016.342] I/user.exs_vl53l1x 传感器已关闭
|
||||
[2026-07-21 20:17:27.813][000000016.342] I/user.vl53l1x_demo ---- [5/5] 完成 ----
|
||||
[2026-07-21 20:17:28.299][000000016.843] I/user.vl53l1x_demo ===== [演示完毕] =====
|
||||
```
|
||||
### 5.6 故障排除
|
||||
|
||||
1. **传感器初始化失败**:
|
||||
|
||||
- 检查 VL53L1X 接线是否正确(SCL、SDA、VCC、GND)
|
||||
- 确认 GPIO 引脚配置与接线一致
|
||||
- 检查电源电压是否稳定(3.3V)
|
||||
- 确认 exs_vl53l1x 扩展库已正常加载
|
||||
|
||||
2. **读取数据始终为 0 或异常**:
|
||||
|
||||
- 检查传感器供电是否正常
|
||||
- 确认 I2C 地址是否正确(默认 0x29)
|
||||
- 确认接线无松动
|
||||
|
||||
3. **测距状态码异常**:
|
||||
|
||||
- 状态码 1(Sigma 失效):测量波动太大,目标反射率过低
|
||||
- 状态码 2(信号失效):信号太弱,目标距离过远或反射率低
|
||||
- 状态码 9(串扰信号):有保护玻璃串扰,可运行串扰校准
|
||||
- 状态码 14(范围无效):通常对应第一帧无效数据,会自动跳过
|
||||
|
||||
### 5.7 扩展功能建议
|
||||
|
||||
exs_vl53l1x 更多接口的使用可以查看 [exs_vl53l1x 扩展库说明](https://docs.openluat.com/osapi/ext/sensor/exs_vl53l1x/)
|
||||
@@ -0,0 +1,151 @@
|
||||
--[[
|
||||
@module vl53l1x_demo
|
||||
@summary VL53L1X 飞行时间测距传感器演示模块,包含所有功能的演示用例
|
||||
@version 1.0
|
||||
@date 2026.07.20
|
||||
@author 江访
|
||||
@usage
|
||||
本文件包含 VL53L1X 的逐项功能演示。
|
||||
通过 exs_vl53l1x 扩展库的 API 逐一演示标准测距、模式切换、中断读取、休眠唤醒、持续测距等功能。
|
||||
]]
|
||||
|
||||
-- 加载 exs_vl53l1x 扩展库
|
||||
local exs_vl53l1x = require "exs_vl53l1x"
|
||||
|
||||
-- [1/5] 标准测距演示
|
||||
local function demo_standard_ranging()
|
||||
log.info("vl53l1x_demo", "===== [1/5] 标准测距 =====")
|
||||
|
||||
-- 软件 I2C 模式:SCL=GPIO31, SDA=GPIO30(Air780EPM 接线)
|
||||
local result = exs_vl53l1x.setup({scl = 31, sda = 30})
|
||||
if not result then
|
||||
log.error("vl53l1x_demo", "初始化失败,请检查接线")
|
||||
return false
|
||||
end
|
||||
log.info("vl53l1x_demo", "VL53L1X 初始化成功,版本:", exs_vl53l1x.version())
|
||||
|
||||
sys.wait(200)
|
||||
for i = 1, 5 do
|
||||
local data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("第%d次: 距离=%dmm 状态=%s stream=%d",
|
||||
i, data.distance, data.status_str, data.stream_count or 0))
|
||||
else
|
||||
log.error("vl53l1x_demo", "读取数据失败")
|
||||
end
|
||||
sys.wait(500)
|
||||
end
|
||||
|
||||
exs_vl53l1x.close()
|
||||
log.info("vl53l1x_demo", "---- [1/5] 完成 ----")
|
||||
return true
|
||||
end
|
||||
|
||||
-- [2/5] 测距模式切换
|
||||
local function demo_range_mode()
|
||||
log.info("vl53l1x_demo", "===== [2/5] 测距模式切换 =====")
|
||||
|
||||
-- short 模式(抗强光,约 1.36m)
|
||||
log.info("vl53l1x_demo", "切换 short 模式(抗强光)")
|
||||
local ok = exs_vl53l1x.setup({scl = 31, sda = 30, range_mode = "short"})
|
||||
if not ok then return end
|
||||
sys.wait(200)
|
||||
local data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("short 模式: 距离=%dmm 状态=%s", data.distance, data.status_str))
|
||||
end
|
||||
exs_vl53l1x.close()
|
||||
|
||||
-- long 模式(远距离,约 3.6m)
|
||||
log.info("vl53l1x_demo", "切换 long 模式(远距离)")
|
||||
ok = exs_vl53l1x.setup({scl = 31, sda = 30, range_mode = "long"})
|
||||
if not ok then return end
|
||||
sys.wait(200)
|
||||
data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("long 模式: 距离=%dmm 状态=%s", data.distance, data.status_str))
|
||||
end
|
||||
exs_vl53l1x.close()
|
||||
|
||||
log.info("vl53l1x_demo", "---- [2/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- [3/5] 休眠与唤醒
|
||||
local function demo_sleep_wakeup()
|
||||
log.info("vl53l1x_demo", "===== [4/5] 休眠与唤醒演示 =====")
|
||||
|
||||
local result = exs_vl53l1x.setup({scl = 31, sda = 30})
|
||||
if not result then return end
|
||||
sys.wait(200)
|
||||
|
||||
-- 读一次数据作为参考
|
||||
local data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("休眠前: 距离=%dmm 状态=%s", data.distance, data.status_str))
|
||||
end
|
||||
|
||||
-- 进入软件待机(约 6μA)
|
||||
log.info("vl53l1x_demo", "进入软件待机模式")
|
||||
exs_vl53l1x.sleep()
|
||||
sys.wait(3000)
|
||||
|
||||
-- 唤醒(自动恢复测距)
|
||||
log.info("vl53l1x_demo", "从软件待机模式唤醒")
|
||||
exs_vl53l1x.wakeup()
|
||||
sys.wait(200)
|
||||
|
||||
data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("唤醒后: 距离=%dmm 状态=%s", data.distance, data.status_str))
|
||||
end
|
||||
|
||||
exs_vl53l1x.close()
|
||||
log.info("vl53l1x_demo", "---- [4/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- [5/5] 持续测距演示
|
||||
local function demo_continuous_ranging()
|
||||
log.info("vl53l1x_demo", "===== [5/5] 持续测距演示 =====")
|
||||
|
||||
local result = exs_vl53l1x.setup({scl = 31, sda = 30})
|
||||
if not result then return end
|
||||
|
||||
log.info("vl53l1x_demo", "每隔 1 秒读取一次距离数据,共 5 次")
|
||||
for i = 1, 5 do
|
||||
sys.wait(1000)
|
||||
local data = exs_vl53l1x.get_data()
|
||||
if data then
|
||||
log.info("vl53l1x_demo", string.format("持续测距[%d]: 距离=%dmm 状态=%s",
|
||||
i, data.distance, data.status_str))
|
||||
else
|
||||
log.warn("vl53l1x_demo", string.format("持续测距[%d] 读取失败", i))
|
||||
end
|
||||
end
|
||||
|
||||
exs_vl53l1x.close()
|
||||
log.info("vl53l1x_demo", "---- [5/5] 完成 ----")
|
||||
end
|
||||
|
||||
-- 演示主函数(运行在协程中)
|
||||
local function vl53l1x_demo_task_func()
|
||||
log.info("vl53l1x_demo", "HELLO")
|
||||
sys.wait(1000)
|
||||
|
||||
-- HELLO 开始 → [1/5] → [2/5] → [3/5] → [4/5] → End
|
||||
local ok = demo_standard_ranging()
|
||||
if not ok then return end
|
||||
sys.wait(500)
|
||||
|
||||
demo_range_mode()
|
||||
sys.wait(500)
|
||||
|
||||
demo_sleep_wakeup()
|
||||
sys.wait(500)
|
||||
|
||||
demo_continuous_ranging()
|
||||
sys.wait(500)
|
||||
|
||||
log.info("vl53l1x_demo", "===== [演示完毕] =====")
|
||||
end
|
||||
|
||||
sys.taskInit(vl53l1x_demo_task_func)
|
||||
@@ -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>VCC(3.3V)<br/></td></tr>
|
||||
<tr>
|
||||
<td>GND<br/></td><td>GND<br/></td></tr>
|
||||
</table>
|
||||
|
||||
> 说明:接线时注意杜邦线不宜过长,以免通信不稳定。VL6180X 模块上的 SCL/SDA 通常已集成上拉电阻,无需额外配置。
|
||||
|
||||

|
||||
|
||||
## 四、演示软件环境
|
||||
|
||||
### 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=软件 I2C,2=硬件 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.4kΩ
|
||||
[2026-08-20 21:30:09.534][000000005.241] I/user.bme680_demo 第1次读取: 温度=24.12°C 气压=1008.4hPa 湿度=66.4%RH 气体=3.4kΩ
|
||||
[2026-08-20 21:30:11.735][000000007.434] I/user.bme680_demo 第2次读取: 温度=24.14°C 气压=1008.4hPa 湿度=66.3%RH 气体=4.6kΩ
|
||||
[2026-08-20 21:30:13.922][000000009.627] I/user.bme680_demo 第3次读取: 温度=24.16°C 气压=1008.4hPa 湿度=66.1%RH 气体=5.9kΩ
|
||||
[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.2kΩ 温度=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.6kΩ 温度=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.4kΩ 温度=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.8kΩ 海拔=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
|
||||
-- 软件 I2C:SCL/SDA 用任意 GPIO,Air780EPM 接线示例用 GPIO31/GPIO30
|
||||
init_config = {scl = 31, sda = 30}
|
||||
elseif MODE == 2 then
|
||||
-- 硬件 I2C:i2c_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 SDA,I2C 地址是否正确(如 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 SDA,I2C 地址是否正确(如 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)
|
||||
Reference in New Issue
Block a user