专栏首页单片机爱好者ESP8266_17简单网络时间协议-SNTP

ESP8266_17简单网络时间协议-SNTP

连续说了好几节的TCP通信,我自己已经烦的不行了。一样东西说多了,其实是很容易烦躁的。但有的时候不学是不行的,所以这一节穿插点别的东西。

SNTP,根据百度百科的定义:简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟。

SNTP协议采用客户端/服务器的工作方式,可以采用单播(点对点)或者广播(一点对多点)模式操作。SNTP服务器通过接收GPS信号或自带的原子钟作为系统的时间基准。单播模式下,SNTP客户端能够通过定期访问SNTP服务器获得准确的时间信息,用于调整客户端自身所在系统的时间,达到同步时间的目的。广播模式下,SNTP服务器周期性地发送消息给指定的IP广播地址或者IP多播地址。SNTP客户端通过监听这些地址来获得时间信息。

说白点,但凡联网的设备,都可以通过这个协议来获取时间。使用方法也很简单,连接SNTP的服务器,然后读取时间就行了。

这么简单?

是的,就这么简单。使用步骤共分为5步:

1、添加相关文件

#include "sntp.h"
#include "wifi.h"

还有wifi.c

2、联网

前面的代码中,联网一般是先设置8266的工作模式,然后扫描当前环境下的AP,再然后连接咱们家里的wifi。这一节使用了另一个函数:

WIFI_Connect("mcu", "88888888", wifiConnectCb);

从内容可以看出来,wifi的账号、密码做为参数传入,同时注册了一个回调函数。WIFI_Connect函数根据传入的参数进行wifi连接,每隔1秒检测一下连接状态。

而注册的回调函数,则在wifi连接成功后连接SNTP服务器。这里可以看一下函数wifiConnectCb的代码:

void wifiConnectCb(uint8_t status){
    if(status == STATION_GOT_IP){
        sntp_setservername(0, "pool.ntp.org");        // set sntp server after got ip address        sntp_init();
        os_timer_disarm(&sntp_timer);
        os_timer_setfn(&sntp_timer, (os_timer_func_t *)sntpfn, NULL);
        os_timer_arm(&sntp_timer, 10000, 1);//10s    } else {
        os_printf("we are connecting!please waite!\r\n");
    }
}

这里说一下,无论是函数WIFI_Connect,还是函数wifiConnectCb,手册里都没有找到说明(2c-esp8266_sdk_api_guide_cn_v1.5.4)。那么它们是哪里来的?

是的,官方的SDK,最后我会说明。

3、连接SNTP服务器,并初始化

很简单,直接上代码:

//通过域名设置SNTP服务器,一次最多支持设置3个。
sntp_setservername(0, "pool.ntp.org");   
//SNTP初始化
sntp_init();

为什么可以设置多个服务器?万一其中一个挂了,其它的还能维持正常工作。此处参照手册2c-esp8266_sdk_api_guide_cn_v1.5.4,第132页。

4、获取时间戳

什么是时间戳?

时间戳是指格林威治时间自1970年1月1日(00:00:00 GMT)至当前时间的总秒数。它也被称为Unix时间戳(Unix Timestamp)。通俗的讲,时间戳是一份能够表示一份数据在一个特定时间点已经存在的完整的可验证的数据。

很简单,两行代码搞定:

u32_t ts = 0;
ts = sntp_get_current_timestamp();

5、转换为真实时间

时间戳只是一堆秒数,我们要把它换算成日常用的时间,一行代码搞定:

os_printf("current time : %s\n", sntp_get_real_time(ts));

主要是函数sntp_get_real_time实现的功能,返回的数据是一串字符,最终通过os_printf打印出来。

程序修改完成,保存、清理、编译、下载一条龙,然后重新上电。这里借助串口助手来查看效果。效果如下所示:

从截图上可以看到,通过程序解析,已经成功获取到了当前的时间,每隔10秒打印输出一下。经过对比,和我当前电脑上的时间是一致的。

最后说一下,这一节的代码其实是从官网SDK中的一个例程里摘出来的。而下一节的内容,也和这个例程有关。感兴趣的童鞋,可以先去ONENET注册一个账号,了解一下物联网平台的基本设置有哪些。下一节会说一下如何把ESP8266接入到物联网平台。

链接:

https://pan.baidu.com/s/18ykdgsI7ruHjWCMRPKL91A

提取码:ma7g

本文分享自微信公众号 - 单片机爱好者(mcucoder),作者:MCU启航

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VS Code的keil插件使用方法_真香!

    作为一个51单片机或STM32单片机的使用者,keil一直是我们的必备的一款工具之一。但kei的一些问题也一直存在,被人吐槽最多的就是编辑器功能单一、提示功能不...

    MCU起航
  • 一个小技巧在SMT32程序HEX文件中加入固件版本信息

    分享一个小技巧,使用MDK编译器,让STM32程序HEX文件中加入固件版本信息,估计很多老手都已经在使用(你有好的方法欢迎分享,希望我的砖能引来你的玉),该方法...

    MCU起航
  • 应届生:月薪10K和月薪8K,我该怎么选?

    很多人会觉得,这有什么可考虑的,当然是选钱多的!但你有没有想过,一线城市的10K和三线城市的8K,价值是否一样?

    MCU起航
  • 3 disconf在springboot下动态配置各个属性,基于docker环境

    在上一篇中,我们在springboot项目中简单使用了disconf的配置功能,这一篇我们主要来详解一下disconf的配置文件的动态配置。

    天涯泪小武
  • 自己动手实现一个WEB服务器

    最近在重温WEB服务器的相关机制和原理,为了方便记忆和理解,就尝试自己用Java写一个简化的WEB SERVER的实现,功能简单,简化了常规服务器的大部分功能和...

    朝雨忆轻尘
  • 腾讯云容器服务监控体系详解

    腾讯云容器服务监控系统可以监控集群中所有的节点,服务,实例,容器的相关信息,并且以曲线的方式展示给用户,同时支持多种粒度的统计方式。本文将讲解容器监控框架和指标...

    腾讯云容器服务团队
  • 使用CompletionService非阻塞获取多线程返回值

    Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异...

    神秘的寇先森
  • java之hiberante之集合映射之list映射

    1.通常对于集合,在hibernate中的处理都是使用set来完成。但是hibernate也提供了对于其他几种集合的映射。

    Vincent-yuan
  • java之hibernate之关联映射之多对一单向关联

    1.在之前学习了单表的crud操作。在实际应用中,大都是多表关联操作,这篇会学习如何处理多表之间的关系。

    Vincent-yuan
  • java之hibernate之双向的多对一关联映射

    Vincent-yuan

扫码关注云+社区

领取腾讯云代金券