14、nodeMCU学习笔记--“时间”模块

rtc  utc  esp8266  nodeMCU

闲言碎语

nodeMCU的模块中,能吹的差不多没了,其他一些传感器的手上没有,估计也没机会介绍了。这回来说说nodeMCU的时间,涉及了2个模块sntp和rtctime。虽然需要两个模块,不过内容还是比较简单的。一起来看看。

sntp是一个可以用来获取网络时间的模块,也就是通过网络进行授时。

nodeMCU总共有三个和RTC有关的模块,分别是rtcmem、rtcfifo和rtctime。其中rtctime才是和时间相关的模块。

14、nodeMCU学习笔记--“时间”模块_第1张图片
百度上找的

模块函数

序号 函数名 参数 返回值
1 sntp.sync() [server_ip], [callback], [errcallback]

sntp就一个函数,用法也是很简单。指定一个授时服务器的IP地址,比如上海交通大学网络中心202.120.2.101。也可以不传入任何参数,这时候会使用上一次授时过的IP。

当然了,使用这个函数的前提条件是要连入网络!如果打算在设备上电后校准时间,那需要连入WIFI后在使用这个函数。否则,不能正确授时。授时失败主要有下面4种情况:

  • 1: DNS lookup failed
  • 2: Memory allocation failure
  • 3: UDP send failed
  • 4: Timeout, no NTP response received

接着,来看看rtctime的函数,函数也不多。就5个,其中2个是睡眠相关的函数。

序号 函数名 参数 返回值
1 rtctime.dsleep() microseconds [, option]
2 rtctime.dsleep_aligned() aligned_us, minsleep_us [, option]
3 rtctime.epoch2cal() timestamp table
4 rtctime.get() sec, usec
5 rtctime.set() seconds, microseconds

.get()函数返回从1970/01/01到使用get函数那时的秒和微秒(时间戳)。对应的set函数就不用多说了。如果使用了.sync()并授时成功,rct的时间也会被更新,可以认为是调用了.set()函数。

get函数得到的时间是秒,我想没有多少人可以知道这个秒对应的年月日时分秒吧。这个时候就需要.epoch2cal()函数了,这个函数可以把时间戳变成时间。需要注意的是,这个时间没有时区和夏令时的概念,是个UTC时间。如果要换成北京时间,需要+8小时。

实践一下

例子只有一个,不过代码也不少,分开来看。首先是判断是否连上了wifi,判断依据是有没有IP地址。这部分写成独立的函数。

function isConnect()
    ip, _, _ = wifi.sta.getip()
    if ip ~= nil then
        print(ip)
        return true
    else
        print("without ip")
        return false
    end
end

接着是一个打印时间的函数,也是本文的主要内容啦 O(∩_∩)O

function refreshTime()
    time = rtctime.epoch2cal(rtctime.get())
    print(string.format("%04d/%02d/%02d %02d:%02d:%02d", 
                        time["year"], 
                        time["mon"], 
                        time["day"], 
                        time["hour"] + 8, 
                        time["min"], 
                        time["sec"]))
end

使用.get()函数获取时间戳。不过这个时间戳是秒,还需要使用..epoch2cal()把这个时间戳变成UTC。咱们这里是东8区,所以在小时time["hour"]这地方加8,变成北京时间。

这里的做法有误, 详见评论区!!!

tmr.alarm(0, 1000, tmr.ALARM_AUTO, function() 
    if isConnect() == true then
        tmr.stop(0)
        sntp.sync("202.120.2.101", 
            function()
                print("sync succeeded")
                tmr.alarm(0, 1000, tmr.ALARM_AUTO, refreshTime)
            end,
            function(index)
                print("failed : "..index)
            end
        )
    end
end)

设置一个定时器以1秒的频率调用第一个函数,当连上wifi的时候,使用.sync()函数,同步一下时间。接着,设置一个定时器以1秒的频率调用第二个函数,打印出时间。

14、nodeMCU学习笔记--“时间”模块_第2张图片
来看个效果

把代码save到nodeMCU,你就可以看到上面的效果了。建议把文件名写成init.lua。

别忘记了配置连入wifi的密码和SSID要用wifi.sta.config()函数!

更多内容

↑ 点击上面的标题可用查看同文集的其它文章。

评论不能贴图, 如有需要可以到我的GitHub上提issues

你可能感兴趣的:(14、nodeMCU学习笔记--“时间”模块)