• 欢迎大家分享资料!前往留言板评论即可!

同步时模块时钟的N种方法

合宙 模组资料网 2年前 (2021-05-15) 315次浏览 0个评论 扫描二维码

很多场景中,由于业务需要,模块需要保持正确的系统时钟,才能正常工作。但是模块上电后的初试时间戳是1338516000(即2012/06/01,10:00:00),所以同步时钟成为了开发者要解决的重要问题。

首先我们捋一下思路——模块要如何执行动作,执行何种动作,才可以同步时钟呢?基于这个疑问,我们先做一个定义:

只有当模块和外界以某种方式产生数据交互,且模块收到完整数据并正确解析时,才可以完成对应操作。

定义中指的“某种方式”是没有局限性的,也就是说开发者可以自由发挥想象力,只有你想不到,没有它做不到。接下来为大家介绍一些常见的和不常见的方式,方便开发者根据不同场景选择合适的方式。

(下文中,如无额外说明,均指Lua方式的二次开发)

一、常见且常用的NTP

NTP是大家众所周知的、广泛使用的、精确可靠的时钟同步方式。具有高效、准确、流量少,易实现的特点。NTP这种方式,就是使用“定义”中的蜂窝网络,和远端NTP服务器交互数据,收到服务器的回应并解析,重新设定系统时钟,完成同步。

我司的lua代码也提供了相应的基础库,开发者只需要简单的调用相应的函数,即可实现同步时钟:

luaScript:

require”ntp”                                         对,就这一行代码即可哦

luaTask:

require”ntp”

ntp.timeSync()                                      只同步一次

–ntp.timeSync(1)                                 1小时同步一次

实际运行一下,看看效果如何:

同步时模块时钟的N种方法

需要注意的是,NTP使用的是多个免费公共的NTP服务器来同步时钟,所以不能保证任何时间任何地点都能百分百同步到正确的时间。如果开发者项目中的业务逻辑严格依赖于时钟同步功能,建议使用开发者自己的服务器进行同步。

二、精确到纳秒的GPS

如果开发者使用的是Air8xx系列模块,或者是其他挂载GPS模块的Air2xx系列产品,那么可以是用这个方式进行同步。

由于卫星定位系统的特性,每颗卫星都有精确到纳秒级的铯原子钟,才能实现全球的精确定位。故此,当开发者使用含GPS功能的模块时,可以使用GPS授时特性实现同步时钟。此种方式,就是使用“定义”中的GPS卫星信号,解析数据,设定模块系统时钟,完成同步。

实现原理并不复杂,只要解析GPS模块上报GGA即可:

格式:$–GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh

示例:$GPGGA,065545.789,2109.9551,N,12023.4047,E,1,9,0.85,18.1,M,8.0,M,,*5E

名称 样例 单位 描述
消息ID $GPGGA   GGA 协议头
UTC 时间 065545.789   hhmmss.sss
纬度 2109.9551   ddmm.mmmm
N/S N   N=北,S=
经度 12023.4047   dddmm.mmmm
E/W     W=西,E=
定位指示     0:未定位
1:SPS 模式,定位有效
2:差分,SPS 模式,定位有效
3:PPS 模式,定位有效
卫星数目 9   范围 0 12
HDOP 0.85   水平精度
MSL 幅度 18.1  
单位 M  
大地 -2.2  
单位 M  
差分时间 8.0 当没有 DGPS 时,无效
差分 ID 0000    
校验和 *5E    
    消息结束

 

当然,解析RMC亦可哦:

格式:$–RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a*hh

例句:$GPRMC,100646.000,A,3109.9704,N,12123.4219,E,0.257,335.62,291216,,,A*59

 

名称 样例 单位 描述
消息ID $GPRMC   RMC 协议头
UTC 时间 100646.000   hhmmss.sss
状态 A   A=数据有效;V=数据无效
纬度 2109.9704   ddmm.mmmm
N/S N   N=北,S=
经度 11123.4219   dddmm.mmmm
E/W     W=西,E=
地面速度 0.257 Knot(节)  
方位 335.62  
日期 291216   ddmmyy
磁变量    
校验和 *59    
    消息结束

 

我司的lua代码也提供了相应的基础库,开发者只需要简单的调用相应的函数,即可实现同步时钟:

luaScript:

require”gps”

gps.init()                                                                             初始化

gps.setfixmode(0)                                                            –GPS+BD定位

gps.settimezone(gps.GPS_BEIJING_TIME)                设置时区为北京

gps.open(gps.DEFAULT,{cause=”time_sync”})          打开gps

剩下的gps.lua都会自动处理好了

同步时模块时钟的N种方法

luaTask:

require”gps”

require”sys”

require”misc”

gps.open(gps.DEFAULT,{tag=”time_sync”})

sys.timeLoopStart(   function()

If gps.isFix then

misc.setClock(gps.getUtcTime())

end

end, 60000)

相对于使用NTP等方式,此方法不受蜂窝网络限制,即使无卡或者卡欠费,也可以准确校时。但是需要注意的是,此种方法略有局限性:

  1. 必须使用有GPS芯片的模块,或者挂在GPS模块,且必须可以搜到1颗以上卫星才能获取时间;
  2. 卫星播发的时间是UTC,所以开发者还需要根据经度判断时区做对应的加减才可以;
  3. 要注意定位数据的有效性。

三、薅基站羊毛的AT+CLTS

如果我告诉你,基站也有授时服务哦,惊不惊喜,意不意外?

模块首次搜到基站的时候,即可获得基站下发的时间信息。发AT+CLTS即可。

由于此方法通用性并不是非常强,所以仅贴出AT交互流程,有能力的开发者请自行改写lua代码吧:

同步时模块时钟的N种方法

需要注意的是,此方法存在一定局限性:1、不是所有的基站都会下发,存在返回是nil的情况(具体要看基站的配置);2、只有附着的那一刻是准确的,随后再发AT+CLTS都是恒定值(即附着时),除非进入飞行模式后再离开飞行模式,重新获取一次;3、需要有卡才能使用。

四、让运营商来给你打工的SMS

有什么办法让运营商来给你打工吗?当然啦,今天就让运营商来出一次血——利用运营商下行短信的时间同步模块时钟。

luaScript & luaTask:

require”sms”

local function
procnewsms(num, data, datetime)

         print(“procnewsms”, num, data,
datetime)

end

sms.regnewsmscb(procnewsms)

sms.send(“10086”,
“hi, china mobile”)

10068发一条内容为“hi, china mobile”的短信,等他返回短信的时候,就自带datetime啦,开发者可以根据datetime同步时系统时钟。

此种方法基本上百试百灵,而且给运营商发短信时双向免费的哦;不过一定要注意使用的SIM卡是否又短信功能。如果没有,是无法使用这个方法同步时钟的。

结束语

不论是直接去访问time.123cha.com这种提时钟的网页,抓取关键数据;还是通过mqtt传输时间字符串;哪怕打电话给模块,通过DTMF设置时间,都是完全没问题的。


正如“定义”所言,只要能产生数据交互,一切就皆有可能。


转载请注明原文链接:同步时模块时钟的N种方法
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址