使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

rtc 或实时时钟是电子和嵌入式设备中最常用的模块,用于跟踪时间。但是 rtc 的问题是计算机中的微芯片不是那么准确,它们只能提供本地设备的时间。另一方面,使用互联网从 ntp 服务器获取时间是获取时间的更好解决方案,因为它更准确并且可以提供世界上任何地理区域的时间。我们只需要一个 wi-fi 模块并访问互联网即可通过使用 ntp 服务器获取世界上任何位置的时间。在本教程中,我们将使用 esp8266 nodemcu 从 ntp 服务器获取当前时间和日期,并将其显示在 oled 显示屏上。
网络时间协议 (ntp)
ntp 是用于在计算机网络之间同步时钟的最古老的网络 internet 协议 (ip) 之一。它由特拉华大学的 david l. mills 于 1981 年设计。该协议可用于在几毫秒内将许多网络与协调世界时 (utc)同步。utc 是世界调节时钟和时间的主要时间标准。utc 不会因不同的地理位置而改变和变化。ntp 使用 utc 作为时间参考,并通过 internet 提供准确和同步的时间。
ntp 工作在分层的客户端-服务器模型上。顶级型号具有称为“stratum0”的参考时钟,如原子钟、无线电波、gps、gsm,可从卫星接收时间。从stratum0接收时间的服务器称为“stratum1”,从stratum1接收时间的服务器称为“stratum2”,依此类推。这种情况继续下去,时间的准确性在每个阶段之后都在下降。ntp 自动选择几个可用时间源中最好的一个进行同步,这使其具有容错能力。
所以在这个项目中,我们使用 esp8266 nodemcu 从 ntp 服务器获取时间并将其显示在 oled 显示器上。
esp8266 可以使用互联网访问 ntp 服务器以获取准确的时间。这里 ntp 工作在客户端-服务器模式,esp8266 作为客户端设备使用 udp(用户数据报协议)与ntp 服务器连接。客户端向 ntp 服务器发送一个请求包,然后 ntp 发送一个时间戳包,其中包含准确度、时区、unix 时间戳等信息。然后客户端将日期和时间详细信息分离出来,可以根据需要在应用程序中进一步使用。
所需组件
单色 7 针 ssd1306 0.96” oled 显示屏
esp8266 nodemcu
微型 usb 数据线
面包板
公对公跳线
电路图和连接
这款 7 针 oled 显示器使用 spi 协议与 esp8266 模块通信,下面是连接 oled spi 针与 nodemcu 以显示互联网时间的电路图和连接表。
代码说明
首先,我们必须将 ntp 库下载并安装到 esp8266 中。有许多可用于 ntp 客户端的库。您可以从 arduino ide 安装其中的任何一个。在本教程中,我安装了taranais 的 ntpclient 库,因为它易于使用并且具有从 ntp 服务器获取日期和时间的功能。
要安装 ntp 库,首先使用上面的链接下载库,然后使用 arduino ide 安装它。要安装它,请转到sketch 》 include library 》 add .zip library,然后通过转到您下载 zip 文件夹的位置打开 zip 文件夹并重新启动 arduino ide。
ntpclient 库附带示例。打开 arduino ide 并转到示例 》 ntpclient 》 高级。此草图中给出的代码在串行监视器上显示来自 ntp 服务器的时间。我们将使用此草图在 oled 显示屏上显示当前时间和日期。
本教程末尾提供了完整的代码,这里我解释了代码的几个重要部分。
esp8266wifi 库提供 esp8266 特定的 wi-fi 例程以连接到网络。wifiudp.h处理发送和接收 udp 包。由于我们使用 spi 协议将 oled 与 nodemcu 连接,因此我们将导入“spi.h”库。而“adafruit_gfx.h”和“adafruit_ssd1306.h”用于oled显示。
#include #include // 提供我们调用的 esp8266 特定 wi-fi 例程以连接到网络#include // 处理 udp 包的发送和接收#include // 用于将 oled 与 nodemcu 连接的 spi #include #include  
我们的 oled 尺寸为 128x64,因此我们将屏幕宽度和高度分别设置为 128 和 64。因此,为连接到 nodemcu 的 oled 引脚定义变量以进行 spi 通信。
#define screen_width 128 // oled 显示宽度,以像素为单位#define screen_height 64 // oled 显示高度,以像素为单位// 使用软件 spi 连接 ssd1306 显示器的声明(默认情况):#define oled_mosi d7 #define oled_clk d5 #define oled_dc d2 #define oled_cs d8 #define oled_reset d3  
adafruit_ssd1306 显示器(screen_width、screen_height、oled_mosi、oled_clk、oled_dc、oled_reset、oled_cs);
在下面的代码行中,将“your_ssid”和“your_password”替换为您的 wi-fi ssid 和密码。
const char *ssid = your_ssid; const char *password = your_password;  
通过向wifi.begin函数提供 ssid 和密码来设置 wi-fi 连接。esp8266 的连接需要一些时间才能连接到 nodemcu,所以我们必须等到它连接上。
wifi.begin(ssid, 密码); 而(wifi.status()!= wl_connected){ 延迟(500); serial.print(.); }  
要请求日期和时间,请使用 ntp 服务器的地址初始化时间客户端。为了获得更好的准确性,请选择靠近您的地理区域的 ntp 服务器的地址。在这里,我们使用“ pool.ntp.org ”,它提供来自世界各地的服务器。如果您想从亚洲选择服务器,您可以使用“ asia.pool.ntp.org ”。timeclient还采用您的时区的 utc 时间偏移量(以毫秒为单位)。例如,印度的 utc 偏移量为 +5:30,因此我们以毫秒为单位转换此偏移量,等于 5*60*60+30*60 = 19800。
wifiudp ntpudp;
ntpclient timeclient(ntpudp, pool.ntp.org, 19800,60000);  
ssd1306_switchcapvcc在内部产生 3.3v 电压来初始化显示。当 oled 启动时,它会显示“ welcome to circuit digest ”,文字大小为 2,颜色为蓝色,持续 3 秒。
if(!display.begin(ssd1306_switchcapvcc)) { serial.println(f(ssd1306 分配失败)); 为了(;;); // 不要继续,永远循环 } display.cleardisplay(); display.settextsize(2); // 绘制 2x 比例的文本 display.settextcolor(blue); display.setcursor(5, 2); display.println(欢迎来到); display.println(电路); display.println(摘要); 显示.显示(); 延迟(3000);  
ntp 客户端使用begin()函数初始化  ,以从 ntp 服务器设置日期和时间。
timeclient.begin();  
update()函数用于在我们向 ntp 服务器请求时接收日期和时间。
timeclient.update();  
波特率设置为 115200 以在串行监视器上打印时间。
序列号.开始(115200);serial.println(timeclient.getformattedtime());  
gethours()、getminutes()、getseconds()、getday是库函数,并从 ntp 服务器提供当前的小时、分钟、秒和天。下面的代码用于区分 am 和 pm 之间的时间。如果我们使用gethours()获得的小时数大于 12,那么我们将该时间设置为 pm,否则设置为 am。
int hh = timeclient.gethours(); int mm = timeclient.getminutes(); int ss = timeclient.getseconds(); int day = timeclient.getday();如果(hh>12) { hh=hh-12; 显示.打印(hh); display.print(:); 显示.打印(毫米); display.print(:); 显示.打印(ss); display.println(pm); } 其他 { display.print(hh); display.print(:); 显示.打印(毫米); display.print(:); 显示.打印(ss); display.println(am); } int day = timeclient.getday(); display.println('+arr_days[天]+');  
getformatteddate()用于从 ntp 服务器获取“yyyy-mm-dd”格式的日期。此函数以“yyyy-mm-dd t hh:mm:ss格式给出日期和时间。但是我们只需要日期,因此我们必须将这个以date_time格式存储的字符串拆分为由substring()函数完成的“t”,然后将日期存储在“date”变量中。
date_time = timeclient.getformatteddate(); int index_date = date_time.indexof(t); 字符串日期 = date_time.substring(0, index_date); 序列号.println(日期); display.println(日期); 显示.显示();  
这就是oled 互联网时钟最终的样子:
#include
#include // 提供我们调用的 esp8266 特定 wi-fi 例程以连接到网络
#include // 处理 udp 包的发送和接收
#include // 用于将 oled 与 nodemcu 连接的 spi
#include
#include
#define screen_width 128 // oled 显示宽度,以像素为单位
#define screen_height 64 // oled 显示高度,以像素为单位
// 使用软件 spi 连接的 ssd1306 显示器的声明(默认情况):
#define oled_mosi d7
#define oled_clk d5
#define oled_dc d2
#define oled_cs d8
#define oled_reset d3
adafruit_ssd1306 display(screen_width, screen_height,oled_mosi, oled_clk, oled_dc, oled_reset, oled_cs);
const char *ssid = circuitloop;
const char *password = circuitdigest101;
wifiudp ntpudp;
ntpclient timeclient(ntpudp, pool.ntp.org, 19800,60000);
字符串 arr_days[]={星期日,星期一,星期二,星期三,星期四,星期五,星期六};
字符串日期时间;
// 您可以指定时间服务器池和偏移量(以秒为单位,
// 稍后可以使用 settimeoffset() 更改)。另外,您可以指定
// 更新间隔(以毫秒为单位,可以使用 setupdateinterval() 更改)。
无效设置(){
serial.begin(115200);
wifi.begin(ssid, 密码);
而(wifi.status()!= wl_connected){
延迟(500);
serial.print(.);
}
if(!display.begin(ssd1306_switchcapvcc))
{
serial.println(f(ssd1306 分配失败));
为了(;;); // 不要继续,永远循环
}
display.cleardisplay();
display.settextsize(2); // 绘制 2x 比例的文本
display.settextcolor(white);
display.setcursor(5, 2);
display.println(欢迎来到);
display.println(电路);
display.println(摘要);
显示.显示();
延迟(3000);
timeclient.begin();
}
无效循环(){
timeclient.update();
display.cleardisplay();
serial.println(timeclient.getformattedtime());
display.settextsize(2); // 绘制 2x 比例的文本
display.settextcolor(blue);
display.setcursor(0, 2);
int hh = timeclient.gethours();
int mm = timeclient.getminutes();
int ss = timeclient.getseconds();
如果(hh>12)
{
hh=hh-12;
显示.打印(hh);
display.print(:);
显示.打印(毫米);
display.print(:);
显示.打印(ss);
display.println(pm);
}
其他
{
display.print(hh);
display.print(:);
显示.打印(毫米);
display.print(:);
显示.打印(ss);
display.println(am);
}
int day = timeclient.getday();
display.println('+arr_days[天]+');
date_time = timeclient.getformatteddate();
int index_date = date_time.indexof(t);
字符串日期 = date_time.substring(0, index_date);
序列号.println(日期);
display.println(日期);
显示.显示();// 显示初始文本
}

电子线束的基本生产流程是怎样的
PCB电路板散热设计技巧
PayPal将向符合条件的美国用户使用加密货币服务
vivo V5 Lite手机发布:并不支持指纹识别
外媒最新消息:骁龙875的代号为Lahaina,这可能是骁龙875+
使用ESP8266从NTP服务器获取时间并在OLED显示器上显示
618买耳机必看:最值得买的千元降噪蓝牙耳机品牌
三相异步电动机接线图 三相异步电动机的工作原理和基本接线
200W-300WLED电子负载-M9811的主要特点
ASW3642替代TS3DV642设计HDMI2.0切换方案
语音处理器电路图解说明
探讨一下PHEV电芯和电池系统的开发方向
要怎么去区分不同平台间有没有可能互联互通呢
豪威推出业界首款笔记本电脑 16:10 宽高比 5.2MP 图像传感器 OV05C10
扫描仪原理详细介绍
SAR ADC的隔离
Wi-Fi和WLAN的区别及常见技术标准
BGA焊接可靠性评价指引方案
三星为满足市场 计划将推出500万至600万部可折叠手机
iphone7s将于十周年新推红色版本