0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

科技观察员 来源:circuitdigest 作者:阿布舍克 ·巴科利 2022-09-01 16:09 次阅读

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 显示器上。

poYBAGMQaEyACYWZAACuCOPQix8528.png

ESP8266 可以使用互联网访问 NTP 服务器以获取准确的时间。这里 NTP 工作在客户端-服务器模式,ESP8266 作为客户端设备使用 UDP(用户数据报协议)与NTP 服务器连接。客户端向 NTP 服务器发送一个请求包,然后 NTP 发送一个时间戳包,其中包含准确度、时区、UNIX 时间戳等信息。然后客户端将日期和时间详细信息分离出来,可以根据需要在应用程序中进一步使用。

所需组件

单色 7 针 SSD1306 0.96” OLED 显示屏

ESP8266 NodeMCU

微型 USB 数据线

面包板

公对公跳线

电路图和连接

这款 7 针 OLED 显示器使用 SPI 协议与 ESP8266 模块通信,下面是连接 OLED SPI 针与 NodeMCU 以显示互联网时间的电路图和连接表。

pYYBAGMQaEiAF2QUAACs4o6h844777.png

poYBAGMQaESAJ86uAAASpfea0-g790.png

代码说明

首先,我们必须将 NTP 库下载并安装到 ESP8266 中。有许多可用于 NTP 客户端的库。您可以从 Arduino IDE 安装其中的任何一个。在本教程中,我安装了Taranais 的 NTPClient 库,因为它易于使用并且具有从 NTP 服务器获取日期和时间的功能。

pYYBAGMQaECAVL1dAAEZmMdDWOI454.png

要安装 NTP 库,首先使用上面的链接下载库,然后使用 Arduino IDE 安装它。要安装它,请转到Sketch 》 Include Library 》 Add .ZIP Library,然后通过转到您下载 zip 文件夹的位置打开 Zip 文件夹并重新启动 Arduino IDE。

poYBAGMQaDyADpGrAAFpdLh1_Zo294.png

poYBAGMQaDiAGjIMAAD3Mbz7ggw937.png

NTPClient 库附带示例。打开 Arduino IDE 并转到示例 》 NTPClient 》 高级。此草图中给出的代码在串行监视器上显示来自 NTP 服务器的时间。我们将使用此草图在 OLED 显示屏上显示当前时间和日期。

pYYBAGMQaDSAVEv5AAESrJPutls545.png

本教程末尾提供了完整的代码,这里我解释了代码的几个重要部分。

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。

poYBAGMQaC6ABfuVAAAOV_lz7e4762.png

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 互联网时钟最终的样子:

poYBAGMQaCeAM_9xAART_b8c-6U898.png

#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(日期);

显示.显示();// 显示初始文本

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • OLED
    +关注

    关注

    118

    文章

    5986

    浏览量

    221444
  • NTP
    NTP
    +关注

    关注

    1

    文章

    93

    浏览量

    13779
  • ESP8266
    +关注

    关注

    50

    文章

    947

    浏览量

    43939
收藏 人收藏

    评论

    相关推荐

    ESP8266驱动OLED显示屏的方法

      ESP8266驱动OLED显示屏。使用SPI协议将单色7引脚SSD1306 0.96 OLED显示屏与NodeMCU连接,学习其基本的使
    发表于 11-03 08:53

    使用EsP8266(NodeMCU)连接阿里云服务器

      使用EsP8266(NodeMCU)连接阿里云服务器并在服务器控制台点亮板载LED灯,进行数据上传和下传的测试。创建阿里云产品功能定义:先选择编辑草稿,才可以看到最下面的布尔值那
    发表于 11-24 06:23

    如何利用WIFI模块获取NTP服务器中的网络时间

    There are different ways to be brave.勇敢有不同种方式。一、需求在单片机上实现RTC的驱动,利用WIFI模块获取NTP服务器中的网络时间,并将其更新
    发表于 01-21 07:32

    求解关于AT ESP8266 无法实现NTP时间同步的问题?

    有影响。另外PING3个NTP服务器都能够正常通信,应该说通信已经建立,分析应该是AT SOCKET部分问题,但是目前水平有限,折腾多半天,没有任何进展,项目时间紧,希望高手们能多多帮助。谢谢!
    发表于 03-15 14:36

    使用DHT11传感创建ESP8266 Web服务器数据记录

    同的板创建了许多网络服务器。在这里,我们还将使用 DHT11 传感创建 ESP8266 Web 服务器数据记录。这里的温度和湿度数据将使
    发表于 06-23 06:39

    使用ESP8266和ST7735 TFT显示屏设计气象站

    服务器同步,而不管位置和时区的差异。它将如何为我们工作:ESP8266 等客户端设备使用端口 123 的用户数据报协议 (UDP) 连接到服务器。客户端然后将请求数据包传输到
    发表于 09-01 06:52

    有人知道使用GPS/RTC模块作为时间源的ESP8266 NTP服务器吗?

    有人知道使用 GPS/RTC 模块作为时间源的 ESP8266 NTP 服务器吗?我有一个 WiFi 项目,我想在其中联网很多 ESP 板。
    发表于 02-24 07:48

    如何PCF8591 ADC获取输入并将它们显示OLED显示器

    我想从 PCF8591 ADC 获取输入并将它们显示OLED 显示器。 我正在为 SSD1306
    发表于 06-02 07:37

    无法ESP8266连接我的本地服务器怎么解决?

    我无法 ESP8266 连接我的本地服务器,我在 Windows 7 使用 WAMP 服务器, 当我给出这个命令 AT+CIPSTART
    发表于 06-05 08:06

    ESP8266获取网络时间获取天气

    ESP8266获取网络时间1、注意事项:本文用到了我自己的阿里云服务器,请各位使用的时候频率稍微低一点,不然压力很大哈。2、登录可以用esp8266
    发表于 11-30 16:21 12次下载
    <b class='flag-5'>ESP8266</b><b class='flag-5'>获取</b>网络<b class='flag-5'>时间</b>、<b class='flag-5'>获取</b>天气

    如何利用ESP8266和Neopixel Ring实现时钟的彩色显示

    本文将介绍一个基于 ESP8266(从 NTP 服务器获取时间)和 Neopixel Ring 的简单时钟,以彩色
    的头像 发表于 04-06 15:30 2277次阅读
    如何利用<b class='flag-5'>ESP8266</b>和Neopixel Ring实现时钟的彩色<b class='flag-5'>显示</b>

    OLED显示器与NodeMCU ESP8266连接的过程

    在本教程中,我们将使用SPI 协议将 Monochrome 7-pin SSD1306 0.96 OLED Display 与 NodeMCU 连接,并将学习使用 NodeMCU ESP8266OLED 屏幕上
    的头像 发表于 09-05 15:05 8484次阅读
    将<b class='flag-5'>OLED</b><b class='flag-5'>显示器</b>与NodeMCU <b class='flag-5'>ESP8266</b>连接的过程

    SSD1306 OLED上的ESP8266 NTP时钟

    电子发烧友网站提供《SSD1306 OLED上的ESP8266 NTP时钟.zip》资料免费下载
    发表于 11-09 11:28 0次下载
    SSD1306 <b class='flag-5'>OLED</b>上的<b class='flag-5'>ESP8266</b> <b class='flag-5'>NTP</b>时钟

    基于ESP8266NTP时钟

    电子发烧友网站提供《基于ESP8266NTP时钟.zip》资料免费下载
    发表于 11-11 10:06 3次下载
    基于<b class='flag-5'>ESP8266</b>的<b class='flag-5'>NTP</b>时钟

    使用ESP8266 OLED和Visuino从NIST TIME服务器获取日期和时间

    电子发烧友网站提供《使用ESP8266 OLED和Visuino从NIST TIME服务器获取日期和时间.zip》资料免费下载
    发表于 06-28 09:55 0次下载
    使用<b class='flag-5'>ESP8266</b> <b class='flag-5'>OLED</b>和Visuino从NIST TIME<b class='flag-5'>服务器</b><b class='flag-5'>获取</b>日期和<b class='flag-5'>时间</b>