Microduino ENC网络(十二)————用NTP获取Internet时间/zh
Language | English |
---|
目的本教程将教大家如何通过NTP(网络时间协议)从互联网得到一个准确的时间。 设备
NTPNTP是一个客户端-服务器协议,他工作在应用层,采用UDP传输协议,使用端口为123。 如果你发送一个请求到某个时间服务器,时间服务器会返回一个64位的值(时间戳):
原理图
层层堆叠,再插上网线。 如下图所示:
程序https://github.com/Microduino/Microduino_Tutorials/tree/master/Microduino_ENC/ENCnetworktwelve
调试步骤一:首先需要下载EtherCard库:https://github.com/jcw/ethercard 放到你的IDE的libraries文件夹中,重启IDE。 步骤二:解释一下代码: 在互联网上有很多时间服务器:比如美国的 NIST (National Institute of Standards and Technology) 提供整个互联网的时间服务;这里有一个意大利的 INRiM (Istituto Nazionale di Ricerca Metereologica)提供的时间服务器: static byte ntpServer[] = {193,204,114,232}; 在EtherCard库针对NTP请求有两个方法:
srcPort参数是用来在众多的enc28J60模块接收的包中发现一个包含NTP服务器回应的数据包:你可以自己选择这个值,但是ntpRequest方法和ntpProcessAnswer方法中这个参数应该一致。 取得时间戳的值后,你必须转换成date-time格式。这个方法过程如下:
几个容易弄错的地方: 可能是闰年:如果是闰年必须用366*86500秒替代365*86500秒,判断是否为闰年可以用下面的方法: boolean isLeapYear(unsigned int year) { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); } 每个月份的天数是变化的:把这些值存入一个数组,格式如下: static int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 如果是闰年,二月份为29天: if(isLeapYear(year) && month == 1) seconds = SECONDS_IN_DAY * 29; 最后,时间戳是参考的GMT(格林尼治标准时间),如果你居住在不同的时区,你必须修正这个值: #define TIME_ZONE +1 [...] printDate(timeStamp + 3600 * TIME_ZONE);
步骤四:下载代码并编译通过。 步骤五:打开串口看看是否显示了时间。 结果串口里显示了时间: 扩展为了看时间更加方便美观,你可以使用Microduino OLED来显示时间: 视频 |