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

- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码
- 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等)
- 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
wangfq
2026-08-31 08:53:49 +08:00
commit 173dd6874f
813 changed files with 125484 additions and 0 deletions
@@ -0,0 +1,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
-- 软件 I2CSCL/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
-- 硬件 I2Ci2c_id 为总线号(Air780EPM 用 1PIN66=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 VALERT=%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 使用 I2C1PIN66=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
![](https://docs.openluat.com/cdn/image/Air780EPM/780EPM_ads1115.jpg)
### 3.2 接线配置
#### 3.2.1 ADS1115 模块接线
<table>
<tr>
<td>Air780EPM 核心板<br/></td><td>ADS1115 模块<br/></td></tr>
<tr>
<td>3.3VVDD_EXT<br/></td><td>VCC<br/></td></tr>
<tr>
<td>GND<br/></td><td>GND<br/></td></tr>
<tr>
<td>PIN67I2C1_SCL<br/></td><td>SCL<br/></td></tr>
<tr>
<td>PIN66I2C1_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 VALERT=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/)