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,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 封装固定为 5SSOP20L 封装由 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, -- 占位 GPIOBL0939 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**:通过 UART1MAIN_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、器件地址 5SOP16L)。
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 = 1SEL 接高电平)
```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 = 2SEL 接低电平或悬空)
```text
Air780EPM BL0939
UART1_TX ------> RX/SDI GPIO18
UART1_RX <------ TX/SDO GPIO17,需外部上拉电阻)
GPIO28 ------> SEL (低电平选 UART 模式)
3.3V ------> VDD
GND ------> GND
```
注意:
- UART 固定 4800bpsN/8/1.5,不可通过软件修改。
- SOP16L 封装器件地址固定为 5SSOP20L 由 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.3VGND 共地。
TX/SDO 引脚需接外部上拉电阻(规格书要求)。
电流互感器和电压分压电路参数需根据实际应用场景计算。
![](https://docs.openluat.com/cdn/image/780EPM_BL0939.jpg)
### 5.2 软件配置
1. 打开 `bl0939_app.lua`
2. 根据接线方式设置 `MODE = 1`SPI)或 `MODE = 2`UART)。
3. UART 模式下,根据封装设置 `UART_ADDR`SOP16L 固定 5SSOP20L 由引脚决定)。
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 模式 1CPOL=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 规格书