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

作者: 谢mingmin | 来源:发表于2017-01-14 22:12 被阅读1679次

    rtc  utc  esp8266  nodeMCU

    闲言碎语

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

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

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

    百度上找的

    模块函数

    序号 函数名 参数 返回值
    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秒的频率调用第二个函数,打印出时间。

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

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

    更多内容

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

    相关文章

      网友评论

        本文标题:14、nodeMCU学习笔记--“时间”模块

        本文链接:https://www.haomeiwen.com/subject/xkbebttx.html