【Arduino】NTPClient:连接NTP服务器获取实时网络时间
概述
随着互联网的普及和发展,时间同步变得更加重要。准确的时间同步有助于确保计算机和其他设备的时间一致性,这对于许多任务来说至关重要,特别是对于需要进行数据同步的任务。
在开发基于ESP8266或ESP32的Arduino项目时,获取准确的网络时间是非常重要的。通过使用 NTP (网络时间协议)服务器,我们可以获取到当前的日期和时间,并在我们的项目中使用。
本文将详细介绍常用的NTP服务器地址及端口,让您的网络时钟精准同步!
一、什么是NTP
网络时间协议(Network Time Protocol,NTP)是一种用于同步计算机时钟的协议。它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正, 与标准时间的误差小于1ms。标准时间来源于原子钟,卫星,天文台等。
使用NTP可以确保计算机和其它设备的时间准确性,Arduino环境下的NTPClient库安装方法,主要函数使用方法,并提供可直接一个可完整运行的示例程序源代码实现。
二、常用的NTP服务器
NTP服务器是一种运行NTP服务的服务器,它可以向计算机和其他设备提供时间信息。这些服务器以UDP协议的形式在123端口进行通讯。在配置计算机的网络时钟时,需要使用NTP服务器的IP地址和端口。以下是常用的NTP服务器IP地址,默认端口号:123。
1、210.72.145.44
是由国家时间服务中心提供的,是中国官方的时间参考标准服务。使用国家授时中心的NTP服务器,可以实现对于中国境内的计算机时间的同步,特别是对于需要确保准确时间的业务来说,使用国家授时中心的NTP服务器可以提供更高的精度。
2、time.nist.gov
美国国家标准局提供了多个NTP服务器来保证全球网络时间的准确性,是全球使用最为普遍的时间参考之一,使用该服务器可以让您的计算机与美国标准时间同步。
3、ntp.ecb.int
欧洲央行提供了多个NTP服务器,它们分别位于欧洲不同的国家和城市,它可以确保计算机和其他设备的时间准确性,可以用于欧洲境内的计算机时钟同步。
4、pool.ntp.org
这是一个开放的NTP服务器池,它会根据你所在地区的网络条件自动分配最近的可用服务器。这也是Arduino NTPClient 默认NTP服务器。
/ NTPClient.h #pragma once #include "Arduino.h" #include #define SEVENZYYEARS 2208988800UL #define NTP_PACKET_SIZE 48 #define NTP_DEFAULT_LOCAL_PORT 1337 class NTPClient { private: UDP* _udp; bool _udpSetup = false; const char* _poolServerName = "pool.ntp.org"; // Default time server IPAddress _poolServerIP; unsigned int _port = NTP_DEFAULT_LOCAL_PORT; long _timeOffset = 0;
5、time.windows.com
微软官方提供的时间服务器,可用于Windows操作系统。
6、time.apple.com
苹果官方提供的时间服务器,可用于苹果设备。
7、cn.pool.ntp.org
中国地区的NTP服务器池,同样是根据你所在地区的网络条件自动分配最近的可用服务器。
8、ntp.aliyun.com
阿里云提供的NTP服务器,可用于阿里云服务器和其他云服务。
这些时间服务器地址都是常用且稳定的,可以根据自己的需求选择其中一个配置在计算机或设备上,以确保时间的准确性和同步性。
三、NTPClient 安装方法
首选,推荐使用Arduino IDE库管理器安装。其次,可以点击Github官方下载链接,请单击页面“Source code (ZIP)”下载,通过IDE菜单——项目——导入库——添加.zip库安装。最后,提供百度网盘下载链接, 提取码:91mn。
四、常用的NTP函数
1、NTPClient(UDP& udp):类构造函数,设置NTP对象实例化需要的基本参数。其参数主要包括:同步所依赖的WiFiUDP类对象、NTP服务器域名(IP)地址、NTP时间偏移(时区,以秒为单位)、更新最小时间间隔(以毫秒为单位)。
NTPClient(UDP& udp); NTPClient(UDP& udp, long timeOffset); NTPClient(UDP& udp, const char* poolServerName); NTPClient(UDP& udp, const char* poolServerName, long timeOffset); NTPClient(UDP& udp, const char* poolServerName, long timeOffset, unsigned long updateInterval); NTPClient(UDP& udp, IPAddress poolServerIP); NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset); NTPClient(UDP& udp, IPAddress poolServerIP, long timeOffset, unsigned long updateInterval); For example: NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60*60*8, 30*60*1000); //参数1 - ntp_udp:WiFiUDP对象 //参数2 - “ntp1.aliyun.com”:阿里云NTP服务器(任意NTP服务器都可) //参数3 - 60*60*8 :该参数单位为秒,60*60为东一区时间,北京时间为东八区,所以这里参数为 60*60*8 //参数4 - 30*60*1000:设置NTP更新最小时间间隔,参数单位为毫秒
2、void setPoolServerName(const char* poolServerName):用于设置或变更NTP时间服务器的域名或IP地址
// Set time server name, @param poolServerName // 设置或变更NTP时间服务器的域名或IP地址 void setPoolServerName(const char* poolServerName); for example: timeClient.setPoolServerName("ntp1.aliyun.com");
3、void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535):用于设置客户端(本地)随机使用端口号,最小值49152,最大值65535
/** * Set random local port */ void setRandomPort(unsigned int minValue = 49152, unsigned int maxValue = 65535);
4、void begin():启动NTPClient,并将开始客户端与NTP服务器同步、获取UTC时间。
/** * Starts the underlying UDP client with the default local port */ void begin();
5、void begin(unsigned int port):在指定的本地端口启动NTPClient,并将开始客户端与NTP服务器同步、获取UTC时间。
/** * Starts the underlying UDP client with the specified local port */ void begin(unsigned int port);
6、bool update():在应用程序的主循环中调用。默认情况下,NTP服务器仅每60秒进行一次更新,更新时间间隔可以在NTPClient构造函数中进行配置。调用成功时返回true,失败返回false。
/** * This should be called in the main loop of your application. By default an update from the NTP Server is only * made every 60 seconds. This can be configured in the NTPClient constructor. * * @return true on success, false on failure */ bool update();
7、 bool forceUpdate():将强制从NTP服务器进行更新。成功时返回trure,失败返回false。
/** * This will force the update from the NTP Server. * * @return true on success, false on failure */ bool forceUpdate();
8、bool isTimeSet() const:检查NTPClient是否成功接收到NTP数据包并设置时间。如果时间已成功设置则返回true,否则返回false。
/** * This allows to check if the NTPClient successfully received a NTP packet and set the time. * * @return true if time has been set, else false */ bool isTimeSet() const;
9、void setTimeOffset(int timeOffset):更改时间偏移量,主用于动态更改时区。
** * Changes the time offset. Useful for changing timezones dynamically */ void setTimeOffset(int timeOffset);
10、void setUpdateInterval(unsigned long updateInterval):将更新间隔设置为另一频率,例如,当构造函数中未设置时间偏移时很有用。
/** * Set the update interval to another frequency. E.g. useful when the * timeOffset should not be set in the constructor */ void setUpdateInterval(unsigned long updateInterval);
11、 String getFormattedTime() const:用于将接收到的UTC时间格式化为本地时区,返回时间格式为“hh:mm:ss”的字符串。
/** * @return time formatted like `hh:mm:ss` */ String getFormattedTime() const;
12、unsigned long getEpochTime() const:返回自1970年1月1日00:00:00(称为UNIX系统的Epoch时间)开始到当前时刻的秒数。
/** * @return time in seconds since Jan. 1, 1970 */ unsigned long getEpochTime() const;
13、void end():终止所依赖的UDP客户端。
/** * Stops the underlying UDP client */ void end();
五、示例程序演示及下载:使用096寸4引脚OLED屏幕显示系统日期和时间
该程序通过UDP协议访问阿里云NTP时间服务器,提取系统时间换算成北京时区日期和时间,显示在OLED屏幕上。附上该程序SSD1306_clock的完整代码,请点击下载, 提取码:tsqf。
特别提醒:编译上传该程序前,请修改成自己可用的WIFI路由器名称和密码。
ssd1306_12864OLED_I2C演示视频