Air201-LuatOS-如何使用超低功耗
一、超低功耗模式概述
当 Air201 进入超低功耗模式后,CPU 会暂停工作,同时 RAM 掉电,即便是在尝试保留 RAM 数据的情形下也会如此。普通 GPIO 在与外设驱动相连时,同样会随掉电而失效。然而,AON_GPIO 能够保持其在进入休眠前的电平状态。此外,DTIMER 定时器具备唤醒设备的功能,而 wakeup 引脚同样可以作为唤醒设备的一种方式。一旦设备被唤醒,程序将会从头开始执行,休眠前所有的运行时数据都将丢失。
二、演示功能概述
Air201 进入超低功耗模式时会进入飞行模式、普通 GPIO 会掉电,定时唤醒(退出超低功耗模式),上报一个数据,然后再进入超低功耗模式。
三、准备硬件环境
3.1 Air201 模组
使用 Air201 开发套件,如下图所示:
淘宝购买链接:Air201 开发套件淘宝购买链接 ;
此开发套件的详细使用说明参考:Air201 产品手册 中的 Air201 硬件手册 和 Air201 的 LuatOS 快速入门。
3.2 直流稳压电源
在需要直流稳压电源的场景(例如 adc 测量外部输入的模拟电压),使用合宙功耗分析仪 Air9000P,如下图所示:
淘宝购买链接:Air9000P 淘宝购买链接 。
3.3 SIM 卡
请准备一张可正常上网的 SIM 卡,该卡可以是物联网卡或您的个人手机卡。
特别提醒:请确保 SIM 卡未欠费且网络功能正常,以便顺利进行后续操作。
3.4 PC 电脑
WINDOWS 系统,其他暂无特别要求;
3.5 数据通信线
USB 数据线(其一端为 Type-C 接口,用于连接 Air201)。
四、准备软件环境
4.1 下载调试工具
使用说明参考:Luatools 下载和详细使用
4.2 功耗分析仪 PC 端软件
下载链接:功耗分析仪 PC 端软件
4.3 TCP/UDP测试网站
使用链接:TCP/UDP 测试网站
4.4 源码及固件
- Air201 模组使用固件:core/LuatOS-SoC_V1004_Air201.soc,本 demo 使用的固件版本是:LuatOS-SoC_V1004_Air201.soc
- 本教程使用的 demo:合宙 Luat/LuatOS-Air201/psm
源码和固件已打包,如下所示:
注:缩包中 core 文件夹存放固件,code 文件夹存放 demo
五、Air201 软硬件资料
5.1 API 接口介绍
本教程使用 api 接口为:低功耗 api 接口,socket-api 接口
5.2 Air201 烧录说明
将 Air201 通过 usb-boot 小板连接电脑,如下图所示:
注意:boot 小板和 Air201 连接时,要确保 RESET 按键,BOOT 按键,电源开关机键 三个按键在同一侧,否则无法进入 boot 下载模式。
如何判断有没有进入下载模式:可以通过 PC 端的设备管理器中虚拟出来的 USB 断开数量来判断,
正常开机模式:
下载模式:
六、代码示例介绍
6.1 Air201 超低功耗定时上报
6.1.1 代码介绍
1.关闭一些可能影响功耗,误唤醒的引脚。
gpio.close(22)
gpio.close(23)
gpio.close(24)
gpio.close(39) --wakeup 0
gpio.close(41) -- simcd脚
2.加入 vbus 插入检测函数,防止读取不了日志。
--打开VBUS唤醒函数会增加功耗,请根据实际需求选择是否使用
local vbus_pin = 40 -- VBUS引脚
local vbus_state = 0 -- 记录VBUS脚状态
-- -- 设置VBUS脚为中断唤醒脚,模拟USB插拔状态
-- -- 在此处加入了唤醒_低功耗模式切换函数,不然USB插上后只能供电,无法查看日志
gpio.setup(vbus_pin, function()
vbus_state = gpio.get(vbus_pin) -- 记录VBUS脚状态
if vbus_state == 0 then -- USB拔出
log.info("sleep") -- 进入睡眠模式
pm.power(pm.USB, false) -- 关闭USB
elseif vbus_state == 1 then -- USB插入
log.info("wakeup") -- 退出睡眠模式
pm.power(pm.USB, true) -- 开启USB
log.info("USB插入") -- 打印日志
end
end, gpio.PULLUP, gpio.BOTH) -- 上拉模式(PULLUP), 双边缘触发(BOTH)
3.连接 tcp 服务器、设置深度定时器后进入休眠模式。
local function Task(ip, port)
local txData
if reason == 0 then
txData = "normal wakeup"
elseif reason == 1 then
txData = "timer wakeup"
elseif reason == 2 then
txData = "pad wakeup"
elseif reason == 3 then
txData = "uart1 wakeup"
end
if slp_state > 0 then
mobile.flymode(0,false) -- 退出飞行模式,进入psm+前进入飞行模式,唤醒后需要主动退出
end
local netc, needBreak
local result, param, is_err
netc = socket.create(nil, d1Name)
socket.debug(netc, false)
socket.config(netc) -- demo用TCP服务器,目前需要在用极致功耗模式时先断开服务器
local retry = 0
while retry < 3 do
log.info(rtos.meminfo("sys"))
result = libnet.waitLink(d1Name, 0, netc)
result = libnet.connect(d1Name, 5000, netc, ip, port)
if result then
log.info("服务器连上了")
result, param = libnet.tx(d1Name, 15000, netc, txData)
if not result then
log.info("服务器断开了", result, param)
break
else
needBreak = true
end
else
log.info("服务器连接失败")
end
libnet.close(d1Name, 5000, netc)
retry = retry + 1
if needBreak then
break
end
end
uart.setup(1, 9600) --配置uart1,外部唤醒用
pm.dtimerStart(3, period) --启动深度休眠定时器,period的值是3分钟
mobile.flymode(0,true) --进入飞行模式
pm.power(pm.USB, false) -- 关闭USB,如果打开了USB唤醒函数可注释掉
pm.power(pm.WORK_MODE,3) --进入极致功耗模式
log.info(rtos.meminfo("sys"))
sys.wait(15000) --demo演示唤醒时间是三分钟,如果15s后模块重启,则说明进入极致功耗模式失败,
log.info("进入极致功耗模式失败,尝试重启")
rtos.reboot()
end
6.1.2 运行结果展示
开机连接 tcp 服务器,然后进入超低功耗模式,设备内部设置了一个定时器,该定时器每隔三分钟会触发一次唤醒操作。当定时器触发时,设备会从超低功耗模式中唤醒,并重新建立与 TCP 服务器的连接(如果连接已经断开)。连接成功后,设备会发送一次预设的数据到 TCP 服务器。数据发送完成后,设备会再次进入超低功耗模式,等待下一次定时唤醒。因为设备的充电 IC 在会存在一个 20ua 的漏电流。由于这个硬件特性,那么 Air201 在超低功耗模式下实际的功耗(包括充电 IC 的漏电流)就是 25.07ua。
定时器每隔三分钟会触发一次唤醒操作,设备会从超低功耗模式中唤醒,并重新建立与 TCP 服务器的连接,并发送预设的数据
Air201 定时唤醒后,连接 tcp 平台发送数据时的功耗是 17.7898mA
7 个休眠发送周期为 21 分钟,平均功耗为 251.1095uA
6.2 添加 gesensor 功能,超低功耗模式下如果 gsenseor 中断产生,需要上报
6.2.1 代码介绍
1.gesensor 初始化
local function init()
i2c.close(i2cId)
i2c.setup(i2cId, i2c.SLOW)
i2c.send(i2cId, da267Addr, {0x00, 0x24}, 1)
sys.wait(20)
i2c.send(i2cId, da267Addr, {0x0F, 0x00}, 1)
i2c.send(i2cId, da267Addr, {0x11, 0x34}, 1)
i2c.send(i2cId, da267Addr, {0x10, 0x07}, 1)
sys.wait(50)
-- int set1
i2c.send(i2cId, da267Addr, {0x16, 0x87}, 1)
-- init active interrupt
i2c.send(i2cId, da267Addr, {0x38, 0x03}, 1)
i2c.send(i2cId, da267Addr, {0x39, 0x05}, 1)
i2c.send(i2cId, da267Addr, {0x3A, 0x05}, 1)
i2c.send(i2cId, da267Addr, {0x3B, 0x05}, 1)
i2c.send(i2cId, da267Addr, {0x19, 0x04}, 1)
-- enable active
i2c.send(i2cId, da267Addr, {0x11, 0x30}, 1)
-- init step counter
i2c.send(i2cId, da267Addr, {0x33, 0x80}, 1)
end
sys.taskInit(function()
mcu.altfun(mcu.I2C, i2cId, 23, 2, 0)
mcu.altfun(mcu.I2C, i2cId, 24, 2, 0)
while true do
init()
while true do
local result = sys.waitUntil("RESTORE_GSENSOR", 60 * 1000)
if result then
break
end
i2c.send(i2cId, da267Addr, 0x01, 1)
local data = i2c.recv(i2cId, da267Addr, 1)
if not data or data == "" or string.byte(data) ~= 0x13 then
break
end
end
end
end)
2.gesensor 触发中断回调
local function ind()
log.info("int", gpio.get(intPin))
if gpio.get(intPin) == 1 then
log.info("da267", "interrupt")
i2c.send(i2cId, da267Addr, 0x02, 1)
local data = i2c.recv(i2cId, da267Addr, 6)
if data and #data == 6 then
local xl, xm, yl, ym, zl, zm = string.byte(data, 1, 1), string.byte(data, 2, 2), string.byte(data, 3, 3), string.byte(data, 4, 4), string.byte(data, 5, 5), string.byte(data, 6, 6)
x, y, z = (xm << 8 | xl ) >> 4, (ym << 8 | yl) >> 4, (zm << 8 | zl ) >> 4
log.info("da267", "x:", x, "y:", y, "z:", z)
sys.publish("GSENSOR", x, y, z)
else
sys.publish("RESTORE_GSENSOR")
end
i2c.send(i2cId, da267Addr, 0x0D, 1)
local data = i2c.recv(i2cId, da267Addr, 2)
if data and #data == 2 then
local xl, xm = string.byte(data, 1, 1), string.byte(data, 2, 2)
local step = ((xl << 8) + xm) // 2
log.info("da267", "step:", step)
sys.publish("STEP_COUNTER", step)
else
sys.publish("RESTORE_GSENSOR")
end
end
end
6.2.2 运行结果展示
开机初始化 gesensor,连接 tcp 服务器,进入超低功耗模式;当 gesensor 触发时唤醒 Air201 并上传三轴参数到 tcp 服务器。
发送数据时的电流
七、总结
本章介绍了 Air201 的超低功耗模式定时三分钟上传,和一个 gsenser 拓展示例;在超低功耗模式下: 电流为 5.07ua 左右(注意 需要减去 ic 的漏电流),上传数据时的电流为 17ma;拓展示例:超低功耗模式下 电流为 236ua,触发 gesensor 唤醒 Air201,并上报三轴参数 上传数据时电流为 32.5ma;后续更多低功耗模式下玩法等你来探索。
常见问题
1.超低功耗模式下是否可以联网
超低功耗模式下会进入飞行模式,无法联网
2.无法进入超低功耗模式,功耗降不下来
检查是否关闭 usb 功能;其他不用的 agpio 可以关闭掉