跳转至

低功耗

一、低功耗模式概述

1.1 背景说明

1. 低功耗是合宙 4G Cat.1 模组最重要的特性之一; 2. 合宙 4G Cat.1 模组有三种功耗模式,分别有各自的特点; 3. 合宙 4G Cat.1 模组优异的低功耗表现,既有硬件设计的加持,也有软件协议算法的帮助; 4. 不同的应用场景,按需选择不同的合宙 4G Cat.1 模组功耗模式,以及三种功耗模式之间的相互转换; 5. 除实验室数据外,合宙更关注实网环境下的功耗表现,呈现给用户的效果更多以实网在线表现为准;

1.2 功耗模式

合宙低功耗模组三种功耗模式


常规模式
低功耗模式
PSM+ 模式
4G 在线状态
在线,长连接
在线,长连接
离线,飞行模式
CPU 主频
满频
降频
降频
定时器唤醒
支持
支持
支持
中断唤醒
支持
支持
支持
串口唤醒
支持
支持,唤醒时波特率需先设置为 9600bps
支持,唤醒时波特率需先设置为 9600bps
服务器 4G 唤醒
支持,1 秒内

支持,1 秒内
不支持
上行发送
1 秒内响应
1 秒内响应
1.5 秒内响应
VEXT 电源输出状态
保持输出
不能保持输出,也不能保持关闭,间歇性输出状态
不能保持输出,也不能保持关闭,间歇性输出状态
所有 GPIO 管脚是否可以控制输出电平
可以
不可以
不可以
常规 GPIO 管脚是否可以保持电平
可以
不可以
不可以
特殊 AGPIO 管脚是否可以保持电平
可以
可以
可以
RAM 供电及唤醒后软件运行状态
RAM 供电,正常工作,满血状态
RAM 供电,唤醒后保持原状态运行
RAM 掉电,唤醒后程序从初始状态运行(PSM+ 状态前运行数据丢失)
典型功耗表现
较低(5mA)
均衡(1mA)
极低(3uA)
测试环境:
1)Air780EP,供电电压 3.8V,移动网络,RSRP 值-88 附近,心跳间隔 5 分钟,心跳数据 100Byte,TCP 协议,合宙 netlab 服务器(https://netlab.luatos.com/);
2) 全 io 开发板,去掉了所有可能引起功耗加大器件,如 USB 下方的 ESD 器件








更多说明:

1.3 三种功耗模式简捷定义

1)常规模式;

网络在线状态,随时响应服务器命令,CPU 满频运行,外设功能全部可用,比如,所有 GPIO 电平都可以控制;

2)低功耗模式;

网络在线状态,随时响应服务器命令,CPU 降频运行,外设功能部份可用,比如,仅有 AGPIO 可以保持电平;

3)PSM+ 模式;

网络离线状态,无法响应服务器命令,CPU 降频运行,外设功能部份可用,比如,仅有 AGPIO 可以保持电平;

1.4 关于 GPIO 的相关说明

合宙 Air700 系列/Air780 系列模组在"低功耗模式/PSM+ 模式"下不同 GPIO 的功能表现不一致,请务必根据产品定义所需严谨选择,避免改版;

根据不同 GPIO 在"低功耗模式/PSM+ 模式下"的不同表现,可以将 GPIO 分为四类:

  • AGPIO,有些文档中有时也会被写为 AON_GPIO,AlwaysON,一直保持的意思; 低功耗模式下既可以保持输出高,也可以保持输出低,但不能高低变换;
  • AGPIOWU,也可以写为 AON_GPIO_WAKEUP,既能在低功耗模式下输出保持(输出高低都可以,但不能高低变换),也可以在低功耗模式下作为中断;
  • WAKEUP,仅能作为输入,低功耗模式下可以作为中断;
  • 普通 GPIO,低功耗模式下既不能保持输出高,也不能保持输出低;

不需要低功耗,希望模块一直保持正常状态的,可以使用第一种 "常规模式",该模式下,CPU 正常工作,所有外设均可启用

电池供电,和服务器之间是长链接,又希望降低功耗的,可以使用第二种"低功耗模式",该模式下,CPU 自动降频,RAM 保持供电,定时器(sys.timerStart/sys.wait/sys.timerLoopStart)/网络事件/IO 中断均可自动唤醒,普通 GPIO 掉电,外设驱动掉电,AON_GPIO 保持电平唤醒后程序继续运行

电池供电,和服务器之间不需要保持长连接,仅仅需要间隔几小时甚至几天才发一次数据给服务器,希望电池待机时间更久一些的,可以使用第三种"PSM+"模式,该模式下CPU 自动降频,RAM 掉电, 保留 RAM 也掉电,普通 GPIO 掉电,外设驱动掉电,AON_GPIO 保持休眠前的电平,dtimer 定时器(深度休眠时使用的定时器,与普通 sys.timer 定时器不同)可唤醒,wakeup 脚可唤醒,唤醒后程序从头运行,休眠前的运行时数据全丢(部分重要数据可以使用 fskv 库存在 flash 中,实现掉电不丢失)

二、演示功能概述

本文将给大家讲解 Air780EP 三种功耗模式与对应的效果演示。

三、准备硬件环境

“古人云:‘工欲善其事,必先利其器。’在深入介绍本功能示例之前,我们首先需要确保以下硬件环境的准备工作已经完成。”

3.1 Air780EP 开发板(全 IO 低功耗板)

本次使用的开发板为 Air780EP 全 IO 低功耗板,如下图所示:

点击链接购买: Air780EP 全 IO 板

此核心板的详细使用说明参考:Air780EP 产品手册 中的《开发板EVB-Air780EP-IO使用说明VX.X.X.pdf》,写这篇文章时最新版本的使用说明为:《开发板EVB-Air780EP-IO使用说明V1.2.0.pdf》,使用过程中遇到任何问题,可以直接参考这份使用说明 pdf 文档。

3.2 SIM 卡

请准备一张可正常上网的 SIM 卡,该卡可以是物联网卡或您的个人手机卡。

特别提醒:请确保 SIM 卡未欠费且网络功能正常,以便顺利进行后续操作。

3.3 PC 电脑

请准备一台配备 USB 接口且能够正常上网的电脑。

电脑操作系统为:WIN10以及以上版本的WINDOWS系统。

3.4 数据通信线

请准备一根用于连接 Air780EP 开发板和 PC 电脑的数据线,该数据线将实现业务逻辑的控制与交互。

  • USB 数据线(其一端为 Type-C 接口,用于连接 Air780EP 开发板)。通常,这种数据线的外观如下示意图所示:

普通的手机 USB 数据线一般都可以直接使用;

在本教程中,我们将采用 USB 数据线配置进行测试和数据查看:

  • USB 数据线:此数据线不仅用于为测试板供电,还用于查看数据日志。其一端为 Type-C 接口,连接 Air780EP 开发板;另一端为标准 USB 接口,连接 PC 电脑。

3.5 可调电源

合宙功耗分析仪 Air9000P——合宙自研的一款功能齐全、稳定可靠、支持 PC 端软件的小型手持式高精度功耗测试仪表(电流范围 0~2A,最小分辨率 0.1μA;电压范围 0~5V,最小分辨率 1mV;硬件采样率 100KHz,PC 端软件采样率 10KHz)。合宙功耗分析仪 Air9000P 对于小电流的抓取能力及其对功耗数据的统计分析,尤其适合电池供电产品的动态功耗测试,可解决各类场景下的低功耗产品测试难题。

合宙功耗分析仪详细介绍链接:www.hezhouyibiao.com

3.6 组装硬件环境

3.6.1 请按照 SIM 卡槽上的指示方向正确插入 SIM 卡,务必确保插入方向正确,避免插反导致损坏!

通常,放置 SIM 卡的步骤如下:

  • 将 SIM 卡的金属接触面朝下,对准卡槽的开口。
  • 平稳地将 SIM 卡放置卡槽,向上推金属盖直至听到“咔嚓”一声,表示 SIM 卡已正确安装到位。

3.6.2 USB 数据线,连接电脑和 Air780EP 全 IO 开发板,如下图所示:

四、准备软件环境

“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。

4.1 Luatools 工具

要想烧录 LuatOS 固件到 4G 模组中,需要用到合宙的强大的调试工具:Luatools;

下载地址:Luatools v3 下载调试工具

Luatools 工具集具备以下几大核心功能:

  • 一键获取最新固件:自动连接合宙服务器,轻松下载最新的合宙模组固件。
  • 固件与脚本烧录:便捷地将固件及脚本文件烧录至目标模组中。
  • 串口日志管理:实时查看模组通过串口输出的日志信息,并支持保存功能。
  • 串口调试助手:提供简洁的串口调试界面,满足基本的串口通信测试需求。

Luatools 下载之后, 无需安装, 解压到你的硬盘,点击 Luatools_v3.exe 运行,出现如下界面,就代表 Luatools 安装成功了:

4.2 烧录代码

首先要说明一点: 脚本代码, 要和固件的 LuatOS-SoC_V2002_Air780EP 文件一起烧录(特别说明:core 大于等于 V1112 的版本,才能支持这三种低功耗模式)。

要烧录的固件文件

官网下载,底层 core 下载地址:LuatOS 底层 core 注:本 demo 使用如图所示固件

要烧录的脚本文件

gitee 下载,gitee 下载地址:低功耗模式测试脚本

4.2.1 正确连接电脑和 4G 模组电路板

使用带有数据通信功能的数据线,不要使用仅有充电功能的数据线;

4.2.2 识别 4G 模组的 BOOT 引脚

在下载之前,要用模组的 BOOT 引脚触发下载, 也就是说,要把 4G 模组的 BOOT 引脚拉到 1.8v,或者直接把 BOOT 引脚和 VDD_EXT 引脚相连。我们要在按下 BOOT 按键时让模块开机,就可以进入下载模式了。

具体到 Air780EP 全 IO 开发板,

  • 当我们模块没开机时,按着 BOOT 键然后长按 PWR 开机。
  • 当我们模块开机时,按着 BOOT 键然后点按重启键即可。

4.2.3 识别电脑的正确端口

判断是否进入 BOOT 模式:模块上电,此时在电脑的设备管理器中,查看串口设备, 会出现一个端口表示进入了 BOOT 下载模式,如下图所示:

如果设备管理器出现了 3 个连续数字的 com 端口,这时候, 证明硬件连接就绪,模块正常开机且端口识别正常

此时按住 BOOT 按键,再按下重启按键就可以重启进入boot下载模式,然后就可以烧录了!

4.2.4 新建项目

首先,确保你的 Luatools 的版本大于或者等于 3.0.6 版本.

在 Luatools 的左上角上有版本显示的,如图所示:

Luatools 版本没问题的话, 就点击 Luatools 右上角的“项目管理测试”按钮,如下图所示:

这时会弹出项目管理和烧录管理的对话框,如下图:

点击下载后,我们需要进入 BOOT 模式才能正常下载。

五、低功耗模式软硬件资料

5.1 硬件设计资料

硬件可以参考这里 https://docs.openluat.com/Air780EP/product/

5.2 软件设计资料

5.2.1 软件 API 接口

pm 库以及 mobile.scell()接口

六、功耗模式简介

前面已经介绍过三种功耗模式了,这里就不再做过多重复解释了

6.1 常规模式简介

顾名思义,常规模式为模块不考虑功耗时处于的状态。

6.1.1 代码示例

测试 demo 链接

mian.lua 中打开 require "normal"这句话,屏蔽--require "low_power_dissipation" --低功耗模式和 -- require "ultra_low_power" --超低功耗模式(PSM+ 模式)这两句话

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "socket_low_power"
VERSION = "1.0"
PRODUCT_KEY = "123" --换成自己的
-- sys库是标配
_G.sys = require("sys")
_G.sysplus = require("sysplus")
log.style(1)

require "normal" --常规模式
--require "low_power_dissipation" --低功耗模式
-- require "ultra_low_power" --超低功耗模式(PSM+模式)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

normal.lua 第一行和第二行,服务器 iphe 端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP/UDP(根据用户服务器类型自行选择)

打开后,如图所示位置即是 IP 和端口号

-- netlab.luatos.com上打开TCP,然后修改IP和端口号,自动回复netlab下发的数据,自收自发测试

local server_ip = "112.125.89.8"
local server_port = 44204

local rxbuf = zbuff.create(8192)

sys.subscribe("IP_READY", function(ip, adapter)
    log.info("mobile", "IP_READY", ip, (adapter or -1) == socket.LWIP_GP)
    sys.publish("net_ready")
end)

local function netCB(netc, event, param)
    if param ~= 0 then
        sys.publish("socket_disconnect")
        return
    end
    if event == socket.LINK then
    elseif event == socket.ON_LINE then
        socket.tx(netc, "hello,luatos!")
    elseif event == socket.EVENT then
        socket.rx(netc, rxbuf)
        socket.wait(netc)
        if rxbuf:used() > 0 then
            log.info("收到", rxbuf:toStr(0,rxbuf:used()):toHex())
            log.info("发送", rxbuf:used(), "bytes")
            socket.tx(netc, rxbuf)
        end
        rxbuf:del()
    elseif event == socket.TX_OK then
        socket.wait(netc)
        log.info("发送完成")
    elseif event == socket.CLOSED then
        sys.publish("socket_disconnect")
    end
end

local function socketTask()
    sys.waitUntil("net_ready")
    log.info("联网成功,准备链接服务器")
    pm.power(pm.WORK_MODE,0) --进入常规模式
    local netc = socket.create(nil, netCB)
    socket.debug(netc, true)
    socket.config(netc, nil, nil, nil, 300, 5, 6)   --开启TCP保活,防止长时间无数据交互被运营商断线
    while true do
        log.info("开始链接服务器")
        local succ, result = socket.connect(netc, server_ip, server_port)
        if not succ then
            log.info("未知错误,5秒后重连")
        else
            log.info("链接服务器成功")
            local result, msg = sys.waitUntil("socket_disconnect")
        end
        log.info("服务器断开了,5秒后重连")
        socket.close(netc)
        log.info(rtos.meminfo("sys"))
        sys.wait(5000)
    end
end

function socketDemo()
    sys.taskInit(socketTask)
end

socketDemo()

6.1.2 硬件链接

测试时将可调电源正极接在 USB 下方的排针处,VBAT 即为电源正极所接的位置,GND 即为电源负极接的位置

6.1.3 展示效果

下图为链接好服务器后什么都不做的功耗,其中平均电流为 29.6890mA,每一个尖峰均为和基站进行一些底层的数据交互导致的电流增大,这些交互不能省,均是 3GPP 协议规定的交互,如果省去,都有可能导致掉网。

6.2 低功耗模式简介

该模式可以实现与服务器之间进行长连接,服务器可随时下发数据给客户端,实现在低功耗情况下还能实时远程控制的功能

6.2.1 代码示例

demo 链接

mian.lua 中打开--require "low_power_dissipation" --低功耗模式这句话,屏蔽 require "normal"和 -- require "ultra_low_power" --超低功耗模式(PSM+ 模式)这两句话

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "socket_low_power"
VERSION = "1.0"
PRODUCT_KEY = "123" --换成自己的
-- sys库是标配
_G.sys = require("sys")
_G.sysplus = require("sysplus")
log.style(1)

--require "normal" --常规模式
require "low_power_dissipation" --低功耗模式
-- require "ultra_low_power" --超低功耗模式(PSM+模式)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

low_power_dissipation.lua 第一行和第二行,服务器 ip 和端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP/UDP(根据用户服务器类型自行选择)

打开后,如图所示位置即是 IP 和端口号

low_power_dissipation.lua

local server_ip = "112.125.89.8"
local server_port = 44204
local is_udp = flase--用户根据自己实际情况选择
--是UDP服务器就赋值为true,是TCP服务器就赋值为flase
--这里选择UDP服务器的原因是UDP服务器比TCP服务器功耗低
--如果用户对数据的丢包率有极为苛刻的要求,最好不要选择UDP

local Heartbeat_interval = 5 -- 发送数据的间隔时间,单位分钟

-- 数据内容  
local heart_data = string.rep("1234567890", 10)
local rxbuf = zbuff.create(8192)

local function netCB(netc, event, param)
    if param ~= 0 then
        sys.publish("socket_disconnect")
        return
    end
    if event == socket.LINK then
    elseif event == socket.ON_LINE then
        -- 链接上服务器以后发送的第一包数据是 hello,luatos
        socket.tx(netc, "hello,luatos!")

    elseif event == socket.EVENT then
        socket.rx(netc, rxbuf)
        socket.wait(netc)
        if rxbuf:used() > 0 then
            log.info("收到", rxbuf:toStr(0, rxbuf:used()), "数据长度", rxbuf:used())
        end
        rxbuf:del()
    elseif event == socket.TX_OK then
        socket.wait(netc)
        log.info("发送完成")
    elseif event == socket.CLOSED then
        sys.publish("socket_disconnect")
    end
end

local function socketTask()
    local netc = socket.create(nil, netCB) --创建一个链接
    socket.debug(netc, true)--开启socket层的debug日志,方便寻找问题
    socket.config(netc, nil, is_udp, nil, 300, 5, 6)  --配置链接的参数
    while true do
        --真正去链接服务器
        local succ, result = socket.connect(netc, server_ip, server_port)
        --链接成功后循环发送数据
        while succ do
            local Heartbeat_interval = Heartbeat_interval * 60 * 1000
            sys.wait(Heartbeat_interval)
            socket.tx(netc, heart_data)
        end
        --链接不成功5S重连一次
        if not succ then
            log.info("未知错误,5秒后重连")
            uart.write(1, "未知错误,5秒后重连")
        else
            local result, msg = sys.waitUntil("socket_disconnect")
        end
        log.info("服务器断开了,5秒后重连")
        uart.write(1, "服务器断开了,5秒后重连")
        socket.close(netc)
        sys.wait(5000)
    end
end

function socketDemo()

    --配置GPIO以达到最低功耗的目的
    gpio.setup(23, nil)
    gpio.close(33) -- 如果功耗偏高,开始尝试关闭WAKEUPPAD1
    gpio.close(35) -- 这里pwrkey接地才需要,不接地通过按键控制的不需要

    --关闭USB以后可以降低约150ua左右的功耗,如果不需要USB可以关闭
    pm.power(pm.USB, false)

     --进入低功耗长连接模式
    pm.power(pm.WORK_MODE, 1)

    sys.taskInit(socketTask)

end

sys.taskInit(socketDemo)

6.2.2 硬件链接

特别注意,由于 2.1 版本全 IO 开发板 USB 下方的 ESD 会影响功耗,所以测试时需要将该 ESD 吹掉后测试。

测试时将可调电源正极接在 USB 下方的排针处,VBAT 即为电源正极所接的位置,GND 即为电源负极接的位置

6.2.3 展示效果

下图为上面的低功耗模式代码在链接服务器并发送完第一包数据以后 30 分钟的功耗,共计发送了 6 次数据包,所以整体的功耗里有 6 个较大的尖峰

下图为低功耗模式下,不发数据时,模块的功耗情况,每一处尖峰都是与基站之间进行必要的通讯带来的电流增大

下图红框内为收到服务器下发数据时的功耗数据,可以看出从唤醒到收到服务器数据总计花费约 3S,平均电流约为 40.6mA

下图为给服务器发数据时候的功耗,可以看出,从唤醒到发送数据最后继续休眠总计用时 2.5S 左右,此段的平均电流约为 44.5mA

6.3 超低功耗模式(PSM+ 模式)简介

对于 和服务器之间不需要保持长连接,仅仅需要间隔几小时甚至几天才发一次数据给服务器,希望电池待机时间更久一些的场景,可以使用第三种超低功耗("PSM+")模式

6.3.1 代码示例

测试 demo 链接

mian.lua 中打开--require "low_power_dissipation" --低功耗模式这句话,屏蔽 require "normal"和 require "ultra_low_power" --超低功耗模式(PSM+ 模式)这两句话

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "socket_low_power"
VERSION = "1.0"
PRODUCT_KEY = "123" --换成自己的
-- sys库是标配
_G.sys = require("sys")
_G.sysplus = require("sysplus")
log.style(1)

--require "normal" --常规模式
require "low_power_dissipation" --低功耗模式
-- require "ultra_low_power" --超低功耗模式(PSM+模式)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

ultra_low_power.lua 第一行和第二行,服务器 ip 和端口号的地方改成用户自己使用的服务的 IP/域名以及端口号,如果仅作测试,也可以使用合宙提供的测试服务器,测试服务器相关资料可以点击此处 https://netlab.luatos.com/ 进入后选择打开 TCP/UDP(根据用户服务器类型自行选择)

打开后,如图所示位置即是 IP 和端口号

ultra_low_power.lua

-- 测试服务器可以使用https://netlab.luatos.com/
local server_ip = "112.125.89.8"
local server_port = 44204 -- 端口号换成自己的
local period = 5 * 60 * 1000 -- 5分钟唤醒一次

--相比于TCP的三次握手四次挥手,UDP更省电,但是可能会出现丢包现象,对数据稳定性要求较高的,还是使用TCP稳妥
local is_dup = false 

local reason, slp_state = pm.lastReson() -- 获取唤醒原因
log.info("wakeup state", pm.lastReson())
local libnet = require "libnet"

local d1Name = "D1_TASK"
local function netCB(msg)
    log.info("未处理消息", msg[1], msg[2], msg[3], msg[4])
end

local function testTask(ip, port)
    local txData
    --如果是开机唤醒的,给服务器发的数据为normal wakeup
    --如果是底层定时器唤醒的,给服务器发的数据为timer wakeup
    --如果是wakeup脚或者GPIO脚唤醒的,给服务器发的数据为pad wakeup
    --如果是串口唤醒的,给服务器发的数据为uart1 wakeup
    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

    gpio.close(32)

    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,外部唤醒用

    -- 配置GPIO达到最低功耗
    gpio.setup(23, nil)
    gpio.close(35) -- 这里pwrkey接地才需要,不接地通过按键控制的不需要
    gpio.setup(32, function() -- 配置wakeup中断,外部唤醒用
        log.info("gpio")
    end, gpio.PULLUP, gpio.FALLING)

    pm.dtimerStart(3, period) -- 启动深度休眠定时器
    mobile.flymode(0, true) -- 进低功耗模式前先进飞行模式,避免因为网络波动导致的意外唤醒或功耗异常
    pm.power(pm.WORK_MODE, 3) -- 进入极致功耗模式

    sys.wait(15000) -- demo演示唤醒时间是五分钟,如果15s后模块重启,则说明进入极致功耗模式失败,
    log.info("进入极致功耗模式失败,尝试重启")
    rtos.reboot()
end
sysplus.taskInitEx(testTask, d1Name, netCB, server_ip, server_port)

6.3.2 硬件链接

特别注意,由于 2.1 版本全 IO 开发板 USB 下方的 ESD 会影响功耗,所以测试时需要将该 ESD 吹掉后测试。

测试时将可调电源正极接在 USB 下方的排针处,VBAT 即为电源正极所接的位置,GND 即为电源负极接的位置

6.3.3 展示效果

下图红框内为 PSM+ 模式下,发送数据时的功耗,从发送数据到最后进入休眠总计花费约 2S,这 2S 内平均电流约为 27mA

下图为 PSM+ 模式下,模块待机时的功耗

七、 常见问题

7.1 我的硬件板子上还是需要一个 USB 口的,如果拆了或者不加 ESD 可能会有外部电流窜进来有可能会击穿模块,但加了全 IO 开发板上的 ESD 会有额外的功耗增加,具体会增加多少,有数据吗

TCP(ESD 吹掉)数传周期 5 分钟 测试总时长 30 分钟

由左右两幅图所示,ESD 去掉后功耗大约降了 10%

7.2 注释里说 UDP 比 TCP 更省电,有数据支撑吗,具体省多少

由左右两幅图可得,TCP 要比 UDP 高 10% 左右,如果数传周期拉长到 10 分钟、一个小时、甚至一天,则差的会更多。

7.3 为什么我的测试结果和你的测试结果大相径庭,甚至是你测试的 2 倍、5 倍不止

针对此类问题,可以先购买全 IO 开发板进行测试,购买链接:https://item.taobao.com/item.htm?id=724722276597&spm=a1z10.3-c-s.w4002-24045920836.11.386d6ee5KIyXU3&skuId=5208106143672

如果使用的是全 io 开发板,且使用的是超低功耗(PSM+)模式,仍然没有到 3uA 左右,可以参考 7.3.1 和 7.3.2 两个排查方案

如果使用的是全 io 开发板,且使用的是低功耗长连接模式,和上面 6.2.3 描述的电流差异较大,可以参考 7.3.1、7.3.2 和 7.3.3 三种排查方案

如果使用的用户自行设计的 PCB,可以先按照 7.3.2、7.3.3 和 7.3.4 方向进行排查

7.3.1 检查 ESD 和 io 选择引脚

全 IO 开发板 V2.1 版本 USB 下方的 ESD 有没有吹下来(如下图 7.3.1 图一所示),该 ESD 会影响功耗 10uA 左右,io 选择引脚是否短接到了 1.8V 这边(如下图 7.3.1 图二所示),3.3V 和 1.8V 引脚所需要的电流也不一样

7.3.2 检查代码

超低功耗模式中,有 uart 口唤醒/AGPIO 唤醒/wakeup 脚唤醒的代码,检查下自己是否使用了对应引脚,例如串口有什么数传任务没关,wakeup 脚是否碰到了高电平管脚等。

7.3.3 检查模块天线链接与驻网频段

可以在代码“循环发送数据” socket.tx(netc, heart_data)后面

--链接成功后循环发送数据
        while succ do
            local Heartbeat_interval = Heartbeat_interval * 60 * 1000
            sys.wait(Heartbeat_interval)
            socket.tx(netc, heart_data)
            --在这里加上下面那一段
        end

加上一段

local rsrp_data = mobile.rsrp()--当前信号质量
local cid = mobile.eci()--当前小区ID
uart.write(1,  "当前RSRP:" .. rsrp_data .. "  当前小区ID:" .. cid)
uart.write(1, "\r\n当前服务小区的其他信息" .. json.encode(mobile.scell()))

然后走串口 1,查看当前信号值和小区其他信息

该接口回复示例

{"mnc": 11,"mcc": 460,"rssi": -78,"pci": 115,"rsrp": -107,"tac": 30005,"eci": 124045360,"cid": 124045360,"rsrq": -9,"snr": 15,"earfcn": 1850}

其中 earfcn 和频段关系的对照表如下

不同的信号值和不同的频段,功耗也不一样,其中信号值的影响更大一些,因为信号差的地方,需要射频电路发射功率更大才能维持和基站之间的正常通讯,当然,不同频段射频电路的发射/接收功率也不同。

如果信号较差,可以看下天线接触是否正常,全 IO 开发板的弹簧天线,没有做过阻抗匹配,所以信号可能不会特别的好,可以先用斜口钳剪断弹簧天线,再使用开发板上的 ipx1 座子,接一根天线出来,如下 7.3.3 图一所示

还有一种较小概率的情况,就是当前模块信号特别好,但是测试出的功耗数据很差,甚至比我上面的数据大了好几倍,有可能遇到了特殊基站,可以参考 https://docs.openluat.com/howtouselog/#_5 这篇文章,抓底层日志给合宙看看是什么情况了

如果遇到功耗差异比较大的情况,可以先查看下周围的频段,再锁频段进行测试,具体操作如下:

准备一台安卓手机(注意安卓版本要 7.0 以上),安装“Cellular-Z”这个 APP。(在 APP 商城搜索 Cellular-Z)。

其次,在手机的设置里,将"5G"关闭,打开 celular-z,看看当前小区频段和 RSRP,以及邻小区的 rsrp 的值,选择一个最好的 rsrp,并且记下对应的频段

接下来使用对应的手机卡,插入全 IO 开发板的 sim1 卡槽内

代码在最开头的地方加入锁频段的语句(根据你搜到的频段填入对应频段,不能直接复制粘贴过去):

local buff = zbuff.create(40)
buff[0] = 3 --band3
buff[1] = 5 --band5
buff[2] = 8 --band8
buff[3] = 40 --band40
mobile.setBand(buff, 4) --设置使用的band一共4个,为3,5,8,40

如果只需要锁一个频段测试,可以这么写

local buff = zbuff.create(40)
buff[0] = 3 --band3
mobile.setBand(buff, 1) --设置使用的band为band3

7.3.4 检查硬件 PCB 设计

例如 DCDC,很多客户使用的是 5V 转 4V 的 DCDC 给 vbat 供电,此时就需要计算下 DCDC 的损耗了

再比如,漏电流,又或者电源管理芯片的选择。可以对比全 io 开发板的 PCB 和自己的 PCB 来进行功耗问题的排查

7.4 我想先链接服务器,然后再进入低功耗模式,为什么模块掉线了

切换任意一种模式,底层都会自动进出一次飞行模式和基站进行一些网络方面配置交互, 会触发掉网和联网过程,所以不建议用户在前两种模式下这么使用,因为代码中有掉线重连的尝试,可能会导致一直重连一直连不上的问题。当然 PSM+ 模式下可以这么用,因为 PSM+ 下本来就和服务器不是长连接状态。

7.5 超低功耗(PSM+)模式下,我设置的 3 个小时唤醒一次,为什么不到一个小时就会唤醒一次

可以检查下代码里是否在进入 PSM+ 模式之前进入了飞行模式,如果没有进飞行模式,按照 3GPP 协议规定,PSM+ 模式下,需要 54 分钟和基站进行交互一次,会启动一下模块

7.6 特别注意 必须使用 V1112 及其以上版本,之前的版本肯能会遇到断网/重连不上等一系列问题!!!!!

给读者的话

本篇文章由 黄何 开发;

本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;

请先登录合宙技术交流论坛,然后点击右边链接文档找错赢奖金-Air780EP-LuatOS-软件指南-低功耗指南-低功耗

用截图标注 + 文字描述的方式跟帖回复,记录清楚您发现的问题;

我们会迅速核实并且修改文档;

同时也会为您累计找错积分,您还可能赢取月度找错奖金!