低功耗
一、低功耗模式概述
1.1 背景说明
1) 低功耗是合宙工业引擎Air8101最重要的特性之一;
2) 合宙工业引擎Air8101有三种功耗模式,分别有各自的特点;
3) 合宙工业引擎Air8101优异的低功耗表现,既有硬件设计的加持,也有软件协议算法的帮助;
4) 不同的应用场景,按需选择不同的合宙工业引擎Air8101功耗模式,以及三种功耗模式之间的相互 转换;
5) 除实验室数据外,合宙更关注实网环境下的功耗表现,呈现给用户的效果更多以实网在线表现为准;
1.2 功耗模式
合宙低功耗模组三种功耗模式
常规模式 | 低功耗模式(DTIM1) | 低功耗模式(DTIM10) | PSM+ 模式 | |
---|---|---|---|---|
连接WIFI路由器状态 | 在线,长连接 | 在线,长连接 | 在线,长连接 | 离线 |
CPU 主频 | 满频 | 降频 | 降频 | 停止运行 |
定时器唤醒 | 支持 | 支持 | 支持 | 支持 |
中断唤醒 | 所有GPIO都可以唤醒 | 所有GPIO都可以唤醒 | 所有GPIO都可以唤醒 | 可同时配置不超过32个GPIO唤醒 |
串口唤醒 | 支持 | 不支持 | 不支持 | 不支持 |
服务器唤醒 | 支持,1 秒内 | 支持,1 秒内 | 支持,1 秒左右 | 不支持 |
上行发送 | 1 秒内响应 | 1 秒内响应 | 1 秒内响应 | 3 秒内响应 |
所有 GPIO 管脚是否可以控制输出电平 | 可以 | 可以 | 可以 | 可以 |
所有GPIO 管脚是否可以保持电平 | 可以 | 可以 | 可以 | 可以 |
RAM 供电及唤醒后软件运行状态 | RAM 供电,正常工作,满血状态 | RAM 供电,唤醒后保持原状态运行 | RAM 供电,唤醒后保持原状态运行 | RAM 掉电,唤醒后程序从初始状态运行(PSM+ 状态前运行数据丢失) |
典型功耗表现 | 较低(6.6mA) | 均衡(1.5mA) | 均衡(380uA) | 极低(13uA) |
测试环境 | 测试环境: 1)Air8101,供电电压 3.8V,心跳间隔 5 分钟,TCP 协议,合宙 netlab 服务器(https://netlab.luatos.com/); | 测试环境: 1)Air8101,供电电压 3.8V,心跳间隔 5 分钟,TCP 协议,合宙 netlab 服务器(https://netlab.luatos.com/); | 测试环境: 1)Air8101,供电电压 3.8V,心跳间隔 5 分钟,TCP 协议,合宙 netlab 服务器(https://netlab.luatos.com/); | 测试环境: 1)Air8101,供电电压 3.8V,待机功耗,不包含心跳包传输功耗。 |
看门狗 | 支持 | 支持 | 支持 | 支持 |
更多说明:
低功耗模式下,网络在线,随时响应服务器命令,CPU 降频运行,外设功能部分可用;3.3V供电,DTIM10的平均电流为380uA,DTIM1的平均电流为1.5mA;DTIM10和DTIM1的核心区别有:
DTIM1不会丢失WIFI AP路由器发送给WiFi station的广播帧和组播帧,DTIM10会丢失,一般来说,WiFi AP路由器发送Beacon帧的间隔是100毫秒,DTIM1最长延迟100毫秒可以收到WiFi AP路由器发送过来的数据,DTIM10最长延迟1000毫秒可以收到WiFi AP路由器发送过来的数据;丢失广播帧和组播帧对产品应用没有什么影响,只要单播帧不丢失就行;
可以根据自己项目对功耗以及数据收发时延的要求选择合适的DTIM配置;
1.3 三种功耗模式简捷定义
1)常规模式;
网络在线状态,随时响应服务器命令,CPU 满频运行,外设功能全部可用,比如,所有 GPIO 电平都可以控制;
2)低功耗模式;
网络在线状态,随时响应服务器命令,CPU 降频运行,可以通过软件设置所需的GPIO在低功耗中保持电平,所有GPIO均支持;
3)PSM+ 模式;
网络离线状态,无法响应服务器命令,CPU 停止运行,可以通过软件设置所需的GPIO在低功耗中保持电平,所有GPIO均支持;
二、演示功能概述
本文将给大家讲解工业引擎Air8101三种功耗模式与对应的效果演示。
三、准备硬件环境
在介绍本功能示例之前,我们首先需要确保以下硬件环境的准备工作已经完成。
3.1 工业引擎Air8101核心板
本次使用的核心板为工业引擎Air8101核心板,如下图所示:
点击链接购买: Air8101核心板
此核心板的详细使用说明参考:Air8101.cn 中的《Air8101核心板+配件板资料》。
3.2 可调电源
合宙功耗分析仪 Air9000P——合宙自研的一款功能齐全、稳定可靠、支持 PC 端软件的小型手持式高精度功耗测试仪表(电流范围 0~2A,最小分辨率 0.1μA;电压范围 0~5V,最小分辨率 1mV;硬件采样率 100KHz,PC 端软件采样率 10KHz)。合宙功耗分析仪 Air9000P 对于小电流的抓取能力及其对功耗数据的统计分析,尤其适合电池供电产品的动态功耗测试,可解决各类场景下的低功耗产品测试难题。
合宙功耗分析仪详细介绍链接:www.hezhouyibiao.com
3.3 组装硬件环境
参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。
四、准备软件环境
在开始实践本示例之前,先筹备一下软件环境:
1) Luatools工具;
2) 内核固件文件(底层core固件文件):使用低功耗时固件版本不能低于V1005;参考项目使用的内核固件;
3) luatos需要的脚本和资源文件
gitee 下载地址:低功耗模式测试脚本
准备好软件环境之后,接下来参考Air8101_core_核心板使用说明,将本篇文章中演示使用的项目文件烧录到Air8101核心板中。
五、软硬件资料
5.1 硬件设计资料
硬件可以参考这里 硬件参考设计
5.2 软件设计资料
5.2.1 软件 API 接口
1) pm 库
2) wlan库
3) socket库
以上均为核心库,代码中不需要require 可直接使用。
六、功耗模式简介
前面已经介绍过三种功耗模式了,这里就不再做过多重复解释了
6.1 常规模式简介
顾名思义,常规模式为模块不考虑功耗时处于的状态。
6.1.1 代码示例
mian.lua 中打开 require "normal"这句话
注释 -- require "low_power"
注释 -- require "psm+_power"
--选择需要体验的功耗模式,注释另外两个代码即可!快捷键Ctrl + /
require "normal"
-- require "low_power"
-- require "psm+_power"
tcp_client_main.lua 第20行和第21行,服务器 ip 端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP
打开后,如图所示位置即是 IP 和端口号
normal.lua
--[[
@module normal
@summary 常规模式主应用功能模块
@version 1.0
@date 2025.07.01
@author 陈取德
@usage
本文件为常规模式主应用功能模块,核心业务逻辑为:
1、进入常规模式
2、判断是否连接网络和发送平台心跳包
使用前请根据需要,变更功能变量。条件不同,功耗体现不同。
本文件没有对外接口,直接在main.lua中require "normal"就可以加载运行;
]] --
----是否需要连接WIFI,测试连接网络状态下功耗--------------------------------------
local wifi_mode = true -- true 需要 --false 不需要
-------------------------------------------------------------------------------
-----是否需要保持服务器心跳------------------------------------------------------
local tcp_mode = true -- true 需要,设置下方心跳包。 --false 不需要,不需要设置心跳包。
local tcp_heartbeat = 5 -- 常规模式和低功耗模式心跳包,单位(分钟),输入 1 为 一分钟一次心跳包。
local heart_data = string.rep("1234567890", 3) -- 心跳包数据内容,可自定义。
-------------------------------------------------------------------------------
function low_power_func()
-- 将电源模式调整为常规模式。
log.info("开始测试常规模式功耗。")
pm.power(pm.WORK_MODE, 0)
-- 判断是否连接WIFI,请注意WIFI账号密码是否正确。
if wifi_mode then
-- 导入WIFI_app功能,自动运行连接WIFI。
require "wifi_app"
-- 判断是否连接TCP平台。
if tcp_mode then
-- 导入tcp客户端收发功能模块,运行tcp客户端连接,自动处理TCP收发消息。
require "tcp_client_main"
-- 调用发送心跳信息功能函数。
send_tcp_heartbeat_func()
end
end
end
-- 定义一个发送心跳信息功能函数。
function send_tcp_heartbeat_func()
-- 通过网卡状态判断WIFI是否连接成功,WIFI连接成功后再运行消息发送。
while not socket.adapter(socket.LWIP_STA) do
-- 在此处阻塞等待WIFI连接成功的消息"IP_READY",避免联网过快,丢失了"IP_READY"信息而导致一直被卡住。
-- 或者等待30秒超时退出阻塞等待状态
log.warn("tcp_client_main_task_func", "wait IP_READY")
sys.waitUntil("IP_READY", 30000)
end
-- 起一个循环定时器,根据预设时间循环定时发送一次消息到TCP服务器。
while true do
sys.publish("SEND_DATA_REQ", "timer", heart_data)
sys.wait(tcp_heartbeat * 60 * 1000)
end
end
sys.taskInit(low_power_func)
6.1.2 硬件连接
功耗测试时将可调电源正极接在 vbat 的排针处,GND 即为电源负极接的位置,核心板上的USB断开,功耗测试开关拨到ON。
6.1.3 展示效果
下图为连接好服务器后5分钟发一次心跳包,平均电流为 6.6mA。
6.2 低功耗模式简介
该模式可以实现与服务器之间进行长连接,服务器可随时下发数据给客户端,实现在低功耗情况下还能实时远程控制的功能
6.2.1 代码示例
mian.lua 中打开require "low_power" 这句话
注释-- require "normal"
注释-- require "psm+_power"
--选择需要体验的功耗模式,注释另外两个代码即可!快捷键Ctrl + /
-- require "normal"
require "low_power"
-- require "psm+_power"
tcp_client_main.lua 第20行和第21行,服务器 ip 和端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP
打开后,如图所示位置即是 IP 和端口号
low_power.lua
--[[
@module low_power
@summary 低功耗模式主应用功能模块
@version 1.0
@date 2025.07.01
@author 陈取德
@usage
本文件为低功耗模式主应用功能模块,核心业务逻辑为:
1、进入低功耗模式
2、判断是否在低功耗模式下连接网络和发送平台心跳包
使用前请根据需要,变更功能变量。条件不同,功耗体现不同。
本文件没有对外接口,直接在main.lua中require "low_power"就可以加载运行;
]] --
----是否需要连接WIFI,测试连接网络状态下功耗--------------------------------------
local wifi_mode = true -- true 需要 --false 不需要
-------------------------------------------------------------------------------
-----是否需要保持服务器心跳------------------------------------------------------
local tcp_mode = true -- true 需要,设置下方心跳包。 --false 不需要,不需要设置心跳包。
local tcp_heartbeat = 5 -- 常规模式和低功耗模式心跳包,单位(分钟),输入 1 为 一分钟一次心跳包。
local heart_data = string.rep("1234567890", 3) -- 心跳包数据内容,可自定义。
-------------------------------------------------------------------------------
function low_power_func()
log.info("开始测试低功耗模式功耗。")
-- 判断是否连接WIFI,请注意WIFI账号密码是否正确。
if wifi_mode then
-- 导入WIFI_app功能,自动运行连接WIFI。
require "wifi_app"
-- 进入低功耗 MODE 1 模式
pm.power(pm.WORK_MODE, 1)
-- 判断是否连接TCP平台
if tcp_mode then
-- 导入tcp客户端收发功能模块,运行tcp客户端连接,自动处理TCP收发消息。
require "tcp_client_main"
-- 调用发送心跳信息功能函数。
send_tcp_heartbeat_func()
end
else
-- 如果不开启WIFI连接,就直接进入低功耗模式。
pm.power(pm.WORK_MODE, 1)
end
end
-- 定义一个发送心跳信息功能函数。
function send_tcp_heartbeat_func()
-- 通过网卡状态判断WIFI是否连接成功,WIFI连接成功后再运行消息发送。
while not socket.adapter(socket.LWIP_STA) do
-- 在此处阻塞等待WIFI连接成功的消息"IP_READY",避免联网过快,丢失了"IP_READY"信息而导致一直被卡住。
-- 或者等待30秒超时退出阻塞等待状态
log.warn("tcp_client_main_task_func", "wait IP_READY")
sys.waitUntil("IP_READY", 30000)
end
-- 起一个循环定时器,根据预设时间循环定时发送一次消息到TCP服务器。
while true do
sys.publish("SEND_DATA_REQ", "timer", heart_data)
sys.wait(tcp_heartbeat * 60 * 1000)
end
end
sys.taskInit(low_power_func)
6.2.2 硬件链接
功耗测试时将可调电源正极接在 vbat 的排针处,GND 即为电源负极接的位置,核心板上的USB断开,功耗测试开关拨到ON。
6.2.3 DTIM1 展示效果
下图为上面的低功耗模式代码在链接服务器并每5分钟发送一次数据包的功耗。平均1.5mA。
图中有两种电流情况需要关注:
1、短暂持续的柱状上升:这是链接平台后向平台发送数据时的电流表现,根据网络信号强弱会有差异,因为是跟平台保持长连接的,信号好时,基本在1S左右就会完成发送,功耗会再降回去。
2、瞬时的电流尖峰:这是在与WIFI AP保持链接时,STA和AP之间的TIM信息交互,默认100ms一次,获取AP上的广播帧、组播帧和单播帧信息。此处涉及一个参数,就是DTIM。默认是DTIM1。
下图是低功耗DTIM1模式下发送数据包时的电流情况,图中可以看出,保持链接时发送数据包的时间共100毫秒,平均电流22mA。
6.2.4 DTIM10 展示效果
体验DTIM10时需要在DEMO中修改DTIM配置:wifi_app.lua
----填写WIFI账号密码,选择是否使用DTIM10--------------------------------------
local ssid = "茶室-降功耗,找合宙!" -- WIFI名称
local password = "Air123456" -- WIFI密码
local DTIM10_mode = true -- 是否开启DTIM10模式。--true 需要 --false 不需要
--------------------------------------------------------------------------------
下图为上面的低功耗模式代码在链接服务器并每5分钟发送一次数据包的功耗。平均380uA,将数据包发送间隔拉的更长,功耗更低。
图中的尖峰间隔因为设置DTIM10以后被延长到了1000ms一次,在DTIM10模式下,会丢失WIFI AP的广播帧和组播帧,但是不会丢失单播帧,STA会告诉WIFI AP我1000ms才来获取一次单播帧。在1000ms后一次获取。请根据业务需要选择DTIM10模式。
下图为低功耗DTIM10模式下,发送心跳包时的功耗情况,只会产生细微的尖峰波动,耗时80毫秒,平均功耗23mA左右。
6.3 超低功耗模式(PSM+ 模式)简介
对于和服务器之间不需要保持长连接,仅仅需要间隔几小时甚至几天才发一次数据给服务器,希望电池待机时间更久一些的场景,可以使用第三种超低功耗 PSM+ 模式
6.3.1 代码示例
mian.lua 中打开require "psm+_power" 这句话
注释-- require "normal"
注释-- require "low_power"
--选择需要体验的功耗模式,注释另外两个代码即可!快捷键Ctrl + /
-- require "normal"
-- require "low_power"
require "psm+_power"
tcp_client_main.lua 第20行和第21行,服务器 ip 和端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP
打开后,如图所示位置即是 IP 和端口号
psm+_power.lua
--[[
@module psm+_power
@summary psm+超低功耗模式主应用功能模块
@version 1.0
@date 2025.07.01
@author 陈取德
@usage
本文件为psm+超低功耗模式主应用功能模块,核心业务逻辑为:
1、进入低功耗模式
2、判断是否在低功耗模式下连接网络和发送平台心跳包
使用前请根据需要,变更功能变量。条件不同,功耗体现不同。
本文件没有对外接口,直接在main.lua中require "psm+_power"就可以加载运行;
]] --
----是否需要连接WIFI,测试连接网络状态下功耗--------------------------------------
local wifi_mode = true -- true 需要 --false 不需要
-------------------------------------------------------------------------------
-----是否需要保持服务器心跳------------------------------------------------------
local tcp_mode = true -- true 需要,设置下方心跳包。 --false 不需要,不需要设置心跳包。
local tcp_heartbeat = 5 -- PSM+模式心跳包,单位(分钟),输入 1 为 一分钟一次心跳包。
local heart_data = string.rep("1234567890", 3) -- 心跳包数据内容,可自定义。
-------------------------------------------------------------------------------
-- 定义send_result函数用于获取tcp_client_sender中的信息发送是否成功
function send_result(a1, b1)
log.info("发送状态 :", a1, b1)
-- 获取tcp_client_sender发送状态后推送信息解除psm_power_func()的sys.waitUntil挂起状态。并返回发送状态a1。
sys.publish("send_success", a1, b1)
end
-- 定义一个表,将回调函数放在表中,因为tcp_client_sender处理回调函数时考虑到带参执行,所以要将函数和参数都放在表里
local send_result_func = {
func = send_result
}
function psm_power_func()
log.info("开始测试PSM+模式功耗。")
-- 判断是否连接WIFI,请注意WIFI账号密码是否正确。
if wifi_mode then
-- 导入WIFI_app功能,自动运行连接WIFI。
require "wifi_app"
-- 判断是否连接TCP平台。
if tcp_mode then
-- 导入tcp客户端收发功能模块,运行tcp客户端连接,自动处理TCP收发消息。
require "tcp_client_main"
while not socket.adapter(socket.LWIP_STA) do
log.warn("tcp_client_main_task_func", "wait IP_READY")
-- 在此处阻塞等待WIFI连接成功的消息"IP_READY",避免联网过快,丢失了"IP_READY"信息而导致一直被卡住。
-- 或者等待30秒超时退出阻塞等待状态
sys.waitUntil("IP_READY", 30000)
end
-- 推送"SEND_DATA_REQ"消息,该消息为tcp_client_sender的接口,带上tag和信息还有回调函数,可以实现自动发送和发送状态获取。
sys.publish("SEND_DATA_REQ", "timer", heart_data, send_result_func)
-- 通过变量获取回调函数在tcp_client_sender中获取的发送状态。
-- 第一个值为sys.waitUntil的结果,是否信息唤醒。
-- 第二个值为发送是否成功
-- 第三个值为回调函数带的参数
local _, a, b = sys.waitUntil("send_success")
-- 通过发送状态判断发送是否成功,并打印变量 a 的赋值
if a then
log.info("发送成功!", a)
else
log.info("发送失败!", a)
end
-- 进入PSM+前需要手动断开AP链接,不然无法正常进入PSM+
wlan.disconnect()
-- 等待断网事件确定已经断开AP
sys.waitUntil("IP_LOSE", 5000)
-- 判断完有没有发送成功后都进入PSM+模式,减少功耗损耗。
-- 配置dtimerStart唤醒定时器,根据预设时间唤醒Air8101上传心跳信息。
pm.dtimerStart(0, tcp_heartbeat * 60 * 1000)
-- 定完定时器即可进入PSM+,执行到这条代码后,CPU关机,后续代码不会执行。
pm.power(pm.WORK_MODE, 3)
else
-- 进入PSM+前需要手动断开AP链接,不然无法正常进入PSM+
wlan.disconnect()
-- 等待断网事件确定已经断开AP
sys.waitUntil("IP_LOSE", 5000)
-- 执行到这条代码后,CPU关机,后续代码不会执行。
pm.power(pm.WORK_MODE, 3)
end
else
-- 判断不需要连WIFI,直接进入PSM+
-- 执行到这条代码后,CPU关机,后续代码不会执行。
pm.power(pm.WORK_MODE, 3)
end
end
sys.taskInit(psm_power_func)
6.3.2 硬件链接
功耗测试时将可调电源正极接在 vbat 的排针处,GND 即为电源负极接的位置,核心板上的USB断开,功耗测试开关拨到ON。
6.3.3 展示效果
下图为进入PSM+模式后不做任何动作的电流情况,平均13uA。
下图为进入PSM+模式后发送心跳包时的电流变化情况,从起来到发完信息到再进入PSM+总共耗时3.2S,平均功耗26mA。