本文开发环境:
- MCU型号:ESP8266
- IDE环境 : Arduino IDE
本文内容:
- 使用 esp8266 在线获取实时时间
NTP 服务 简介
NTP是网络时间协议(Network Time Protocol),它是用来同步网络中各个计算机的时间的协议。esp8266也可以通过建立与NTP服务的连接,来获取实时时间。
NTPClient 库的安装
本文使用的环境为 arduino 1.8.3 版本,2021年1月17日 升级为 1.8.13 版本后,发现该库需要重新安装,这里可能是由于升级后造成的库丢失,不过简单安装即可。
使用NTP服务需要先安装 NTPClient 库,按组合件 Crtrl + Shift + I 调出库管理 具体操作如下所示:
打开库 Demo 程序
库自带了一个建议的demo程序,方便用户快速开发,具体操作如下所示:
打开以后弹出一个窗口:
接着我们就可以将窗口缩放到合适大小,开始代码的编辑。
程序设计
配置WiFi密码和名字
需要设置路由器的密码(Password)和名称(SSID)这样才可以esp8266才可以上网,具体操作如下:
... ...
const char *ssid = "602"; // 路由器名称
const char *password = "602602602"; // 路由器密码
... ...
校准时区
由于全球的时间是不同的,所以需要校准时间,以北京时间为例,在创建实例的时候,见校准参数传入即可,具体操作如下:
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com",60*60*8, 30*60*1000);
程序示例
修改工程以后,完整的示例代码如下所示,如果你已经安装好库,也可以直接复制以下代码到工程中,直接编译运行查看打印信息:
#include <NTPClient.h>
// change next line to use with another board/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>
const char *ssid = "602";
const char *password = "602602602";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com",60*60*8, 30*60*1000);
void setup(){
Serial.begin(115200);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
}
void loop() {
timeClient.update();
Serial.println(timeClient.getFormattedTime());
delay(1000);
}
运行程序以后,就可以从串口助手中观察到时间:
进一步的,获取时分秒的API函数如下:
- getHours()
- getMinutes()
- getSeconds()
所以,可以通过以上API函数将数据单独获取:
#include <NTPClient.h>
// change next line to use with another board/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>
const char *ssid = "602";
const char *password = "602602602";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
}
void loop() {
timeClient.update();
int hours = timeClient.getHours();
int minu = timeClient.getMinutes();
int sece = timeClient.getSeconds();
Serial.printf("hour:%d minu:%d sece:%d\n", hours,minu,sece);
delay(1000);
}
运行可在串口窗口中观察:
注意到,通常其他的arduino板子不使用格式化这种,它们总是数据和字符串分开的输出的,而ESP8266/ESP32可以直接使用这种格式化输出(像C或者C++),详情:Do you know Arduino? – sprintf and floating point