Microduino W5500网络(十二)————用NTP获取Internet时间/zh

来自Microduino Wikipedia
跳转至: 导航搜索

目的

本教程将教大家如何通过NTP(网络时间协议)从互联网得到一个准确的时间。

设备

  • 其他硬件设备
    • USB数据连接线 一根

NTP

NTP是一个客户端-服务器协议,他工作在应用层,采用UDP传输协议,使用端口为123。

如果你发送一个请求到某个时间服务器,时间服务器会返回一个64位的值(时间戳):

  • 前32位表示自1900年1月1日间隔的秒数;
  • 后32位用以表示秒以下的部份,并加上网络延时量的估计.理论上可以精确到到2的-32次方秒,实际使用大约只有50ms(广域网)左右,在局域网可达1ms。在实际中您应找最近而且最稳定的时间服务器作为时间源。
NTP.jpg


原理图

  • Microduino-W5500
  • Microduino-RJ45
  • Microduino-Core
  • Microduino-USBTTL

层层堆叠,再插上网线。

如下图所示:

MicroduinoW5500Show.png

程序

[MicroduinoW5500Twelven]

调试

步骤一:首先需要确保你的IDE中有_02_Microduino_Ethernet_WIZ库,如果没有下载放到你的IDE的libraries文件夹中,重启IDE。

步骤二:如果你的IDE的libraries文件夹中还有之前的Ethernet库的话,需要删除掉,因为之前的Ethernet是根据W5100协议编写的。

然后需要改动一下_02_Microduino_Ethernet_WIZ文件以使库函数与Microduino-W5500模块的引脚对应:

先找到_02_Microduino_Ethernet_WIZ库中的utility文件夹里的w5100.h

把代码中的 #define wiz_cs_pin 8 //CS_PIN 改为 #define wiz_cs_pin 10 //CS_PIN 就可以了。

步骤三:解释一下代码:

在互联网上有很多时间服务器:比如美国的 NIST (National Institute of Standards and Technology) 提供整个互联网的时间服务;

这里我们使用:IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server

首先发送NTP包到timeserver:

sendNTPpacket(timeServer); // send an NTP packet to a time server

然后,如果从tiemServer接收到数据包之后就解析数据包:

 if ( Udp.parsePacket() ) {  
   // We've received a packet, read the data from it
   Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer
   //the timestamp starts at byte 40 of the received packet and is four bytes,
   // or two words, long. First, esxtract the two words:
   unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
   unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
   // combine the four bytes (two words) into a long integer
   // this is NTP time (seconds since Jan 1 1900):
   unsigned long secsSince1900 = highWord << 16 | lowWord;  
   Serial.print("Seconds since Jan 1 1900 = " );
   Serial.println(secsSince1900);               
   // now convert NTP time into everyday time:
   Serial.print("Unix time = ");
   // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
   const unsigned long seventyYears = 2208988800UL;     
   // subtract seventy years:
   unsigned long epoch = secsSince1900 - seventyYears;  
   // print Unix time:
   Serial.println(epoch);                               
   // print the hour, minute and second:
   Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
   Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
   Serial.print(':');  
   if ( ((epoch % 3600) / 60) < 10 ) {
     // In the first 10 minutes of each hour, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
   Serial.print(':'); 
   if ( (epoch % 60) < 10 ) {
     // In the first 10 seconds of each minute, we'll want a leading '0'
     Serial.print('0');
   }
   Serial.println(epoch %60); // print the second
 }


步骤四:下载代码并编译通过。

步骤五:打开串口看看是否显示了时间。

结果

串口里显示了时间:

扩展

为了看时间更加方便美观,你可以使用Microduino OLED来显示时间:

视频