Air系列模块同步时间功能汇总

                        <div style="border-top: none; border-right: none; border-left: none; border-image: initial; border-bottom: 1pt solid rgb(238, 238, 238); padding: 0cm 0cm 4pt; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;">

一、时间同步方案概述

            在使用Air系列模块开发项目时,有时会要求模块提供准确的时间,目前主要有三种同步时间的主流方案可供选择,分别是:

         1、基站同步时间

         2NTP同步时间

         3、自建服务器同步时间

        

         三种方案在可靠性和易用性上各有优势,您可以根据设备所需的安全等级和实际的产品逻辑灵活选择,方案对比如下图所示

 

基站同步

NTP同步

自建服务器同步

可靠性

一般

部分基站不支持时间同步功能

一般

取决于免费的公共NTP服务器稳定性,NTP服务器出问题之后,无法及时修复

可靠

自建服务器,命运掌握在自己手中,即使服务器出问题,也可以及时修复

易用性

容易

4G AT版本:困难

2G AT版本:困难

Lua版本:容易

一般

其他注意事项

4G版本的基站同步时间无法关闭,默认一直处于开启状态;只要掉网后或者重启后,再次注册上网络,如果基站支持时间同步功能,都会自动下发同步指令,模块更新本地时间

 

 

 

二、时间同步方案选择以及编码逻辑

            本章节根据两个典型的应用场景来阐述方案选择和编码逻辑,如果不能满足实际产品需求,可根据不同方案的特点自行修改

1、应用场景一:时间必须同步

       因为此场景要求时间必须同步,所以我们的同步逻辑直接使用“自建服务器同步”方案,下面从模块和版本两方面来详述

      1.14G AT版本/2G AT版本

            MCU端伪代码逻辑如下

uint8 bTimeSyned = 0 //时间同步标志初始化为“未同步”

 

if (收到了自建服务器的时间同步报文 && bTimeSyned==0)

{

    发送AT+CCLK=...命令来设置模块的系统时间

    if (AT+CCLK=...命令返回设置成功)

    {

        bTimeSyned = 1 //时间同步标志初始化为“已同步”

    }

    else

    {

        //自定义重试逻辑,建议请求服务器再次下发时间同步报文

        //如果一直设置失败,可以尝试软重启

    }

}

         MCU端可以通过AT+CCLK?命令来查询模块系统时间

 

         4G模块AT命令手册:http://www.openluat.com/Product/4g/Air720D.html

         资料下载->相关文档->[AT 手册] Luat 4G模块AT命令手册VX.X.X.pdf

 

         2G模块AT命令手册:http://www.openluat.com/Product/gprs/Air202.html

         资料下载->相关文档-> [使用手册] AirM2M 无线模块AT命令手册VX.XX

       1.24G Lua版本/2G Lua版本

            脚本伪代码逻辑如下

local bTimeSyned = false --时间同步标志初始化为“未同步”

 

if 收到了自建服务器的时间同步报文 and not bTimeSyned then

    misc.setClock(要设置的时间,

        function(tm,result)

            bTimeSyned = result

            if not result then

                --自定义重试逻辑,建议请求服务器再次下发时间同步报文

                --如果一直设置失败,可以尝试软重启

            end

        end

        )   

end

         脚本可以通过os.time()或者os.date("*t")来查询模块系统时间

2、应用场景二:时间可选同步

            因为此场景要求时间可选同步,所以我们的同步逻辑中可采用“基站同步+NTP同步”或者“基站同步+NTP同步+自建服务器同步”方案组合,下面从模块和版本两方面来详述

       2.14G AT版本

            MCU端伪代码逻辑如下

uint8 bTimeSyned = 0 //时间同步标志初始化为“未同步”

 

//检查基站同步是否成功

if (收到了类似于+NITZ: 19/08/02,09:19:33+32,0URC提示)

{

    bTimeSyned = 1 //时间同步标志初始化为“已同步”

}

 

// 如果基站时间同步失败,则参考AT命令手册,发送如下AT命令序列,尝试NTP同步

AT+SAPBR=3,1,"Contype","GPRS"

AT+SAPBR=3,1,"APN","CMNET"

AT+SAPBR=1,1

AT+CNTPCID=1

AT+CNTP

AT+SAPBR=0,1

 

//如果NTP时间同步失败,并且存在用户自建服务器同步时间的方案,则参考1.1章节的代码逻辑来同步

         MCU端可以通过AT+CCLK?命令来查询模块系统时间

 

         4G模块AT命令手册:http://www.openluat.com/Product/4g/Air720D.html

         资料下载->相关文档->[AT 手册] Luat 4G模块AT命令手册VX.X.X.pdf

       2.22G AT版本

            MCU端伪代码逻辑如下

uint8 bTimeSyned = 0 //时间同步标志初始化为“未同步”

 

//模块开机后,AT命令通道准备就绪之后(一定要在网络注册成功之前)

//向模块发送AT+CLTS=1命令,打开基站同步时间功能

 

//检查基站同步是否成功

if (收到了类似于*PSUTTZ: 2019,8,2,23,59,52,"+32",0URC提示)

{

    bTimeSyned = 1 //时间同步标志初始化为“已同步”

}

 

// 如果基站时间同步失败,则参考AT命令手册,发送如下AT命令序列,尝试NTP同步

AT+SAPBR=3,1,"Contype","GPRS"

AT+SAPBR=3,1,"APN","CMNET"

AT+SAPBR=1,1

AT+CNTPCID=1

AT+CNTP

AT+SAPBR=0,1

 

//如果NTP时间同步失败,并且存在用户自建服务器同步时间的方案,则参考1.1章节的代码逻辑来同步

         MCU端可以通过AT+CCLK?命令来查询模块系统时间

 

         2G模块AT命令手册:http://www.openluat.com/Product/gprs/Air202.html

         资料下载->相关文档-> [使用手册] AirM2M 无线模块AT命令手册VX.XX

       2.34G Lua版本

            脚本代码如下(timeSync.lua

--- 模块功能:时间同步.

-- 注意:本文件仅仅演示了基站同步和NTP同步两种方案,此两种方案都不是百分百可靠

-- 如果产品需要百分百时间同步,则建议使用自建服务器方案来实现

-- @author openLuat

module(...,package.seeall)

 

require"ril"

require"ntp"

 

local function printTime()

    local tClock = os.date("*t")

    log.info("printTime",

        string.format("%04d-%02d-%02d %02d:%02d:%02d",tClock.year,tClock.month,tClock.day,tClock.hour,tClock.min,tClock.sec))

end

 

--每隔1秒输出1次当前模块系统时间

sys.timerLoopStart(printTime,1000)

 

--bTimeSyned :时间是否已经成功同步过

local bTimeSyned

 

--注册基站时间同步的URC消息处理函数

ril.regUrc("+NITZ", function()   

    log.info("cell.timeSync")

    printTime()   

    bTimeSyned = true

end)

 

--IP网络准备就绪后,如果基站尚未成功同步时间,则尝试使用NTP同步时间

sys.subscribe("IP_READY_IND", function()

    if not bTimeSyned then                         

        ntp.timeSync(nil,function(tClock,success)       

            log.info("ntp.timeSync",success)

            printTime()

            bTimeSyned = success

        end)

    end

end)

 

--如果NTP时间同步失败,并且存在用户自建服务器同步时间的方案,则自行实现自建服务器同步时间代码

 

         脚本可以通过os.time()或者os.date("*t")来查询模块系统时间

       2.42G Lua版本

            脚本代码如下(timeSync.lua

--- 模块功能:时间同步.

-- 注意:本文件仅仅演示了基站同步和NTP同步两种方案,此两种方案都不是百分百可靠

-- 如果产品需要百分百时间同步,则建议使用自建服务器方案来实现

-- @author openLuat

module(...,package.seeall)

 

require"ril"

require"ntp"

 

local function printTime()

    local tClock = os.date("*t")

    log.info("printTime",

        string.format("%04d-%02d-%02d %02d:%02d:%02d",tClock.year,tClock.month,tClock.day,tClock.hour,tClock.min,tClock.sec))

end

 

--每隔1秒输出1次当前模块系统时间

sys.timerLoopStart(printTime,1000)

 

--bTimeSyned :时间是否已经成功同步过

local bTimeSyned

 

--发送AT+CLTS=1,打开基站同步时间功能

ril.request("AT+CLTS=1")

--注册基站时间同步的URC消息处理函数

ril.regUrc("*PSUTTZ", function()   

    log.info("cell.timeSync")

    printTime()   

    bTimeSyned = true

end)

 

--IP网络准备就绪后,如果基站尚未成功同步时间,则尝试使用NTP同步时间

sys.subscribe("IP_READY_IND", function()

    if not bTimeSyned then                         

        ntp.timeSync(nil,function(tClock,success)       

            log.info("ntp.timeSync",success)

            printTime()

            bTimeSyned = success

        end)

    end

end)

 

--如果NTP时间同步失败,并且存在用户自建服务器同步时间的方案,则自行实现自建服务器同步时间代码

 

         脚本可以通过os.time()或者os.date("*t")来查询模块系统时间

三、其他补充

            其他还有很多方案可以同步时间,参考:http://oldask.openluat.com/article/30

 

 

上次更新 2021-01-28