YFROBOT创客社区

标题: ESP8266 wifi 网络时钟(精准免校时时钟) NTP网络时间协议 OneNet NTP服务 [打印本页]

作者: AllBlue    时间: 2016-9-12 14:29
标题: ESP8266 wifi 网络时钟(精准免校时时钟) NTP网络时间协议 OneNet NTP服务
本帖最后由 AllBlue 于 2017-10-6 09:02 编辑

ESP8266 ntp网络时钟 永不校时时钟首先我们认识下NTP是什么?
NTP,Network Time Protocol,网络时间协议;它是用来使网络中的各个计算机时间同步的一种协议。它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达0.1ms,在互联网上绝大多数的地方其精度可以达到1-50ms。原理(看了上面的NTP介绍,原理就很简单了):
ESP8266连接到network,并获取NTP(Network Time Protocol,网络时间协议)。

提供NTP服务的有很多,windows系统就有自动更新时间,其实就是windows公司提供的NTP服务,根据下图找到window NTP服务器:[attach]1589[/attach]从图中可以看到有5个服务器支持:time.windows.com 、time.nist.gov 、time-nw.nist.gov 、time-a.nist.gov 、time-b.nist.gov。
你可以点击“立即更新”按钮试试看是否可以正常工作。
下面是测试例程,使用的是ESP8266 模块,arduino IDE开发):
[C] 纯文本查看 复制代码
/*
   NTP Clock Program -- 网络时钟
   Network Time Protocol (NTP)
   ESP8266 连接到NET WORK ,获取NTP

   https://github.com/PaulStoffregen/Time

   https://github.com/JChristensen/Timezone

   by: yfrobot
   http://www.yfrobot.com
*/

#include <ESP8266WiFi.h>
#include <Time.h>
#include <Timezone.h>
#include "NTP.h"


// Set your WiFi login credentials
#define WIFI_SSID "YFROBOT"       // 使用时请修改为当前你的 wifi ssid
#define WIFI_PASS "yfrobot2016"   // 使用时请修改为当前你的 wifi 密码

#define ledPin 14                          // 定义ledPin连接到GPIO14

// This clock is in the Mountain Time Zone
// Change this for your timezone
// 北京时间时区
#define STD_TIMEZONE_OFFSET +8    // Standard Time offset (-7 is mountain time)

// ***************************************************************
// TimeZone and Daylight Savings Time Rules
// ***************************************************************

// Define daylight savings time rules for the China
TimeChangeRule mySTD = {"", First,  Sun, Jan, 0, STD_TIMEZONE_OFFSET * 60};
Timezone myTZ(mySTD, mySTD);

WiFiClient client;

// This function is called once a second
void updateDisplay(void) {

  TimeChangeRule *tcr;        // Pointer to the time change rule

  // Read the current UTC time from the NTP provider
  time_t utc = now();

  // Convert to local time taking DST into consideration
  time_t localTime = myTZ.toLocal(utc, &tcr);

  // Map time to pixel positions
  int weekdays=   weekday(localTime);
  int days    =   day(localTime);
  int months  =   month(localTime);
  int years   =   year(localTime);
  int seconds =   second(localTime);
  int minutes =   minute(localTime);
  int hours   =   hour(localTime) ;   //12 hour format use : hourFormat12(localTime)  isPM()/isAM()
  Serial.println("");
  Serial.print("Current local time:");
  Serial.print(days);
  Serial.print("/");
  Serial.print(months);
  Serial.print("/");
  Serial.print(years);
  Serial.print(" - ");
  Serial.print(hours);
  Serial.print(":");
  Serial.print(minutes);
  Serial.print(":");
  Serial.print(seconds);
  Serial.print(" - ");
  Serial.print(dayStr(weekdays));
  Serial.println("");
}

void setup() {

  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  delay(10);

  // We start by connecting to a WiFi network
  initNTP(WIFI_SSID, WIFI_PASS);
}

// Previous seconds value
time_t previousSecond = 0;

void loop() {
  //  Update the display only if time has changed
  if (timeStatus() != timeNotSet) {
    if (second() != previousSecond) {
      previousSecond = second();
      // Update the display
      updateDisplay();
    }
  }
  delay(1000);
}

NTP.h 文件:
[C] 纯文本查看 复制代码
/*
   ESP8266 NeoPixel NTP Clock Program

    NTP.h - Network Time Protocol Functions

    Portions of this code were extracted from the
    Time library examples by Michael Margolis and
    Paul Stoffregen. Other portions from the NTPClient
    example program from the Arduino ESP8266 package.

    Concept, Design and Implementation by: Craig A. Lindley
    Last Update: 04/12/2016
*/

#ifndef NTP_H
#define NTP_H

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <TimeLib.h>
#include <WiFiUdp.h>

#define LOCALPORT     5000 // Local port to listen for UDP packets
#define NTP_PACKET_SIZE 48 // NTP time stamp is in the first 48 bytes of the message

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;

byte packetBuffer[NTP_PACKET_SIZE]; // Buffer to hold incoming and outgoing packets

// Don't hardwire the IP address or we won't get the benefits of the time server pool.
const char *ntpServerName ;//= "time.windows.com";//"1.cn.pool.ntp.org";
IPAddress timeServerIP(183,230,40,42);  //ONENET -- NTP


// Send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) {

  // Set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);

  // Initialize values needed to form NTP request
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // All NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  udp.beginPacket(address, 123); // NTP requests are to port 123
  udp.write(packetBuffer, NTP_PACKET_SIZE);
  udp.endPacket();
}

// NTP Time Provider Code
time_t getNTPTime() {

  int attempts = 10;

  // Try multiple attempts to return the NTP time
  while (attempts--) {

    // Get a server from the pool
    if(ntpServerName != NULL){
        WiFi.hostByName(ntpServerName, timeServerIP);
    }
    Serial.printf("Time server IP address: ");
    Serial.println(timeServerIP);

    while (udp.parsePacket() > 0); // Discard any previously received packets

    Serial.println("Transmitted NTP Request");
    sendNTPpacket(timeServerIP);

    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500) {
      int size = udp.parsePacket();
      if (size >= NTP_PACKET_SIZE) {
        Serial.println("Received NTP Response");
        udp.read(packetBuffer, NTP_PACKET_SIZE);  // Read packet into the buffer
        unsigned long secsSince1900;

        // Convert four bytes starting at location 40 to a long integer
        secsSince1900 =  (unsigned long) packetBuffer[40] << 24;
        secsSince1900 |= (unsigned long) packetBuffer[41] << 16;
        secsSince1900 |= (unsigned long) packetBuffer[42] << 8;
        secsSince1900 |= (unsigned long) packetBuffer[43];

        Serial.println("Got the time");

        return secsSince1900 - 2208988800UL;
      }
      delay(10);
    }
    Serial.println("Retrying NTP request");
    delay(4000);
  }
  Serial.println("No NTP Response");
  return 0;
}

// Login to WiFi network and assign the time sync provider
void initNTP(const char *ssid, const char *password) {

  // Set station mode
  WiFi.mode(WIFI_STA);   //set work mode:  WIFI_AP /WIFI_STA /WIFI_AP_STA

  // Start by connecting to a WiFi network
  WiFi.begin(ssid, password);

  int i = 0;
  while ((WiFi.status() != WL_CONNECTED) && (i++ < 30)) {
    delay(500);
    Serial.printf(".");
  }
  if (i == 31) {
    Serial.printf("\nCould not connect to: %s\n", ssid);
    return;
  }
  Serial.printf("\nConnected to: %s\n", ssid);
  delay(500);

  // Login suceeded so set UDP local port
  udp.begin(LOCALPORT);

  // Set the time provider to NTP
  setSyncProvider(getNTPTime);
}

#endif


程序下载:github 项目地址:https://github.com/YFROBOT-TM/YFRobot-NTPClock_OneNet

该例程中使用的是ONENET的NTP服务,服务器IP和端口号:183.230.40.42:80。测试可用!
想要使用上面提到的window NTP,定义NTP.h文件中的ntpServerName,像下面这样:
[C] 纯文本查看 复制代码

const char *ntpServerName = "time.windows.com";  //"1.cn.pool.ntp.org"
串口打印:
[attach]1590[/attach]
时区更改,在NTPClick.ino中,定义STD_TIMEZONE_OFFSET
[C++] 纯文本查看 复制代码
#define STD_TIMEZONE_OFFSET +8  

世界时区分布图:
[attach]1592[/attach]


库文件下载地址:



作者: lilho_e    时间: 2016-10-1 20:51
感谢分享,学习
作者: ROY_2016    时间: 2016-10-6 10:41
能说你的东西不好不,先标记个。
作者: squallwsx    时间: 2016-11-12 00:09
这个东西太好了,一直想找呢,LUA的容易,arduino的太少了。。。
作者: squallwsx    时间: 2016-11-12 00:35
经测试,无法编译。。。不知道是H文件存档目录的问题还是啥。。。楼主能细说以下么。。
作者: AllBlue    时间: 2016-11-12 08:57
squallwsx 发表于 2016-11-12 00:35
经测试,无法编译。。。不知道是H文件存档目录的问题还是啥。。。楼主能细说以下么。。

有截图错误截图吗?库文件是否添加进去了
作者: squallwsx    时间: 2016-11-12 10:49
AllBlue 发表于 2016-11-12 08:57
有截图错误截图吗?库文件是否添加进去了

[attach]1622[/attach]

如图,就错误应该是H头文件没有加载到的样子。但是我是有好好的把Time.h和Timezone.h都放arduino\libraries里各自建立的同文件名的文件夹里面的。。。另,为何NTP.h加载用的是引号,这个文件我也一样放到libraries里新建同文件名的文件夹或者和ino放一起都试过,还是不行。。。

作者: AllBlue    时间: 2016-11-12 16:32
squallwsx 发表于 2016-11-12 10:49
如图,就错误应该是H头文件没有加载到的样子。但是我是有好好的把Time.h和Timezone.h都放arduino\lib ...

Time 和Timezone 都是库,不单单是 time.h文件就够的,需要将整个库文件下载放到libraries 文件夹中,NTP.h文件不需要放到库文件中,和主程序放在一个文件夹中即可随主程序打开!Q2912630748 不行就联系

作者: shai8151    时间: 2016-12-4 16:54
開心進入YFRobot工作室
作者: GARY0711    时间: 2016-12-14 15:25
谢谢 分享 正在做网络时间项目
作者: y0532    时间: 2016-12-15 22:43
很有创意,顶一下
作者: FJ51    时间: 2016-12-22 21:29
好东西上,先收藏!
作者: 落花萧然    时间: 2017-1-22 11:21
谢谢分享
就是timelib报错
作者: AllBlue    时间: 2017-1-24 14:12
落花萧然 发表于 2017-1-22 11:21
谢谢分享
就是timelib报错

Time 库在程序里面有下载链接!安装下就可以了!
如果还不行的话,上图看下错误
作者: tpluntan    时间: 2017-1-24 15:48
感谢分享
作者: bluewood    时间: 2017-2-5 17:37
学习学习,谢谢
作者: hds    时间: 2017-2-7 11:33
我找了好久,终于找到这里了。
作者: guigle    时间: 2017-2-23 01:19
好东西,感谢楼主!
作者: tangjc    时间: 2017-2-23 15:16
感谢分享  !!!学习学习
作者: jldqc    时间: 2017-3-3 10:02
学习学习
作者: AllBlue    时间: 2017-3-3 13:46
jldqc 发表于 2017-3-3 10:02
学习学习

感谢支持
作者: hszhouw    时间: 2017-3-18 02:51
感谢分享,学习
作者: aaa666    时间: 2017-3-28 21:54
46255962
565555
作者: lianfutiana    时间: 2017-4-13 16:43
几个网址,咋就没有一个能登陆的,楼主能解释一下吧??我在网页直接输入的网址
作者: AllBlue    时间: 2017-4-14 15:32
lianfutiana 发表于 2017-4-13 16:43
几个网址,咋就没有一个能登陆的,楼主能解释一下吧??我在网页直接输入的网址

NTP都这样的,网页无法访问;用程序试,就知道是否可以获取时间信息了,或者到电脑上的时间设置里测试也行
作者: alanj    时间: 2017-4-19 23:44
bucuo,yizhi zai zhao
作者: lf8013    时间: 2017-4-26 11:11
这个东西太好了,一直想找呢。。。
作者: hljlijun    时间: 2017-4-27 14:48
感谢分享,学习中。
作者: 暗夜星辰    时间: 2017-5-9 09:35
学习了,支持一下!
作者: fsj5098    时间: 2017-5-21 17:45
arduino的太少了。。。
作者: fsj5098    时间: 2017-5-25 23:30
很有创意,顶一下
作者: simonliu009    时间: 2017-5-27 01:53
这个是每秒钟和NTP服务器通讯一次?
作者: AllBlue    时间: 2017-5-27 14:41
simonliu009 发表于 2017-5-27 01:53
这个是每秒钟和NTP服务器通讯一次?

是的,一般不会这样用的;你可以单片机自行计时,每隔一段时间获取下NTP。
作者: lml62    时间: 2017-5-31 23:43
感谢分享,学习
作者: aa799412717    时间: 2017-7-5 10:11
赞一个
作者: Platycodon    时间: 2017-7-6 16:13
入门学习
作者: JimmY2018    时间: 2017-7-7 16:08
学习学习
作者: t28    时间: 2017-7-8 14:37
感谢分享
好像window NTP不总是可以校时
作者: AllBlue    时间: 2017-7-9 09:19
t28 发表于 2017-7-8 14:37
感谢分享
好像window NTP不总是可以校时

我之前用的时候还好,onenet NTP服务挺稳定的,就是不知道会不会长久支持
作者: 2083759    时间: 2017-7-9 11:47
想用单片机试试
作者: gfgfgf    时间: 2017-8-19 09:45
感谢楼主分享
作者: ct814489097    时间: 2017-10-5 20:11
编译提醒有错,学习中
作者: ct814489097    时间: 2017-10-5 21:35
编译找不到TimeLib.h
Arduino:1.8.4 (Windows 10), 开发板:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Serial, 115200, 4M (3M SPIFFS)"

In file included from F:\Arduino\ESP8266-Arduino-NTP\ESP8266-Arduino-NTP\ESP8266-Arduino-NTP.ino:17:0:

sketch\NTP.h:20:21: fatal error: TimeLib.h: No such file or directory

#include <TimeLib.h>

                     ^

compilation terminated.

exit status 1
为开发板 NodeMCU 1.0 (ESP-12E Module) 编译时出错。

在文件 -> 首选项开启
“编译过程中显示详细输出”选项
这份报告会包含更多信息。
C:\Users\Administrator\Desktop\捕获.PNG
作者: AllBlue    时间: 2017-10-6 09:04
ct814489097 发表于 2017-10-5 21:35
编译找不到TimeLib.h
Arduino:1.8.4 (Windows 10), 开发板:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Seri ...

下载地址和文件都已更新到文章中,文章底部可见
作者: ahahaha    时间: 2018-3-14 17:03
看哈里面有些什么东西
作者: 名字真难取    时间: 2018-4-7 11:30
感谢分享
作者: zhutr99    时间: 2018-4-15 17:11
回复查看下载地址
作者: duocool    时间: 2018-4-15 21:24
好东西
作者: lipeixian44    时间: 2018-4-27 23:32

作者: devcang    时间: 2018-4-28 11:51
ESP8266 wifi 网络时钟(精准免校时时钟) NTP网络时间协议 OneNet NTP服务
作者: liguoqi8    时间: 2018-5-11 22:50
谢谢!又学到东西了
作者: liuxu    时间: 2018-5-25 22:48
vb 好,学习一下!!!
作者: nongcj    时间: 2018-6-4 23:47
初学者,看看程序 谢谢
作者: Qi20160213    时间: 2018-6-6 18:06
8affect啊发
作者: Qi20160213    时间: 2018-6-7 09:00
dsfsdfeww
作者: cool_angel    时间: 2018-6-8 18:43
ddddddddddddddddddddddddddddd
作者: 後輪追前輪    时间: 2018-6-28 00:56
学习学习
作者: 作业小斗士    时间: 2018-7-5 13:36
66666
作者: smrgh    时间: 2018-7-9 00:47
网络时钟(精准免校时时钟)
作者: JokerZ    时间: 2018-7-24 11:47
下载备用
作者: zbl340    时间: 2018-9-9 13:52
新人报道,回复学习
作者: 皮卡皮卡皮卡丘    时间: 2018-11-19 16:11
学习学习
作者: yznj    时间: 2018-11-26 22:50
谢楼主分享。。。。。。
作者: nr6tszow    时间: 2019-2-12 15:54
666666666666666666666666666666666
作者: sj18819468746    时间: 2019-3-7 02:20
学习中
作者: sj18819468746    时间: 2019-3-13 16:11
学习一下
作者: shipperyoung    时间: 2019-4-24 12:06
谢谢楼主分享
作者: tiantianyouyou    时间: 2019-4-28 17:26
感谢分享,学习
作者: tiantianyouyou    时间: 2019-5-6 17:28
非常感谢!非常实用!!
作者: tiantianyouyou    时间: 2019-5-7 16:27
不错,很值得学习一下
作者: tiantianyouyou    时间: 2019-5-20 08:40
不错,很值得学习
作者: jamespo    时间: 2019-9-17 14:51

謝樓主分享。。。。。。。
作者: jamespo    时间: 2019-9-19 11:40
感謝分享,學習
作者: sbtr5651    时间: 2019-9-22 07:28
谢谢分享!
作者: xfsss    时间: 2019-10-2 14:48
感谢分享,学习
作者: 用户名被谁抢注    时间: 2019-10-23 10:42
ESP8266 wifi 网络时钟(精准免校时时钟) NTP网络时间协议
作者: MR1FC    时间: 2020-3-1 08:16
谢谢楼主  想半天也想不出来怎么做
作者: ccdos    时间: 2020-3-21 20:12
ESP8266 wifi 网络时钟(精准免校时时钟) NTP网络时间协议 OneNet NTP服务




欢迎光临 YFROBOT创客社区 (http://yfrobot.com.cn/) Powered by Discuz! X3.1