【NodeMCU实时天气时钟温湿度项目 4】通过NTPClient库获取实时网络时间并显示在TFT屏幕上

        今天是【实时天气时钟温湿度项目】第四专题,主要内容是:学习导入NTPClient库,通过这个库获取实时网络时间,显示在1.3寸TFT液晶屏幕上。此前三个专题,请选择查看以下链接。

        第一专题内容,请参考
        【NodeMCU实时天气时钟温湿度项目 1】连接点亮SPI-TFT屏幕和UI布局设计-CSDN博客
        第二专题内容,请参考
        【NodeMCU实时天气时钟温湿度项目 2】WIFI模式设置及连接-CSDN博客
        第三专题内容,请参考       
【NodeMCU实时天气时钟温湿度项目 3】连接SHT30传感器,获取并显示当前环境温湿度数据(I2C)-CSDN博客
        NTPClient功能库有关内容,请参考
        【Arduino】NTPClient:连接NTP服务器获取实时网络时间_ntpclient.h-CSDN博客

一、添加NTPClient库

        获取实时网络时间,一般通过 NTP (网络时间协议)服务器来实现。在Arduino框架下,我们通过NTPClient库提供的函数功能,连接到NTP服务器,从服务器获取时间,并保持同步。
        添加库的方法:打开 PlatformIO 界面,选择 Libraries 图标,在搜索栏内输入 NTPClient,在查询结果中选择NTPClient库,,添加到本项目中。

二、NTPClient官方示例代码及主要函数

        下面是NTPClient库官方示例 Advanced.info 的代码内容,将其全文复制到主文件 main.cpp 中,添加库,编译上传到NodeMCU开发板,就可以正常运行了。
        提醒:请务必将 ssid 和 password ,变更为您所在环境的 AP访问点名称和密码。       

#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     = "xcb940";
const char *password = "87589940abc";WiFiUDP ntpUDP;// You can specify the time server pool and the offset (in seconds, can be
// changed later with setTimeOffset() ). Additionally you can specify the
// update interval (in milliseconds, can be changed using setUpdateInterval() ).
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);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);
}

下图是程序正常运行后的模样。

        特别说明:关于NTPClient库的介绍和应用,我在前期曾发布过一个博文,对这个库作了详细介绍。官方示例中涉及到的功能函数,在博文中都有详细介绍,具体内容请点击下面的链接查看:【Arduino】NTPClient:连接NTP服务器获取实时网络时间_ntpclient.h-CSDN博客

三、本项目关于获取网络时间函数说明       

        通过NTPClient功能库获取网络时间的代码,封装在项目的 ntptime.h 文件中,主要有以下4个功能函数。
        (1)void initNtp(),启动NTPClient,开始客户端与NTP服务器同步、获取UTC时间,填充时日期时间数据结构 struct dt_data;设置时区偏移量(28800 = 60 * 60 * 8 秒)。

void initNtp() {timeClient.begin();//28800 = +8时区(我们的北京时间)timeClient.setTimeOffset(28800);loopNtp();
}
struct dt_data {String localDate = "";String localTime = "";String y;String m;String d;String h;String i;String s;uint16_t year;uint8_t month;uint8_t day;uint8_t hours;uint8_t minutes;uint8_t seconds;
} dt;

        (2)void loopNtp(),获取UTC时间,进行格式转换,填充时日期时间数据结构 struct dt_data;每调用一次,获取一次时间。

void loopNtp() {timeClient.update();Serial.println(timeClient.getFormattedTime());//获取unix时间戳(1970年至今的总秒数)unsigned long epochTime = timeClient.getEpochTime();Serial.print("epochTime: ");Serial.println(epochTime);//格式化得到 时:分:秒dt.localTime = timeClient.getFormattedTime();//重新计算得到 年-月-日time_t rawtime = epochTime;struct tm * ti;ti = localtime (&rawtime);dt.year = ti->tm_year + 1900;dt.y = String(dt.year);dt.month = ti->tm_mon + 1;dt.m = dt.month < 10 ? "0" + String(dt.month) : String(dt.month);dt.day = ti->tm_mday;dt.d = dt.day < 10 ? "0" + String(dt.day) : String(dt.day);dt.hours = ti->tm_hour;dt.h = dt.hours < 10 ? "0" + String(dt.hours) : String(dt.hours);dt.minutes = ti->tm_min;dt.i = dt.minutes < 10 ? "0" + String(dt.minutes) : String(dt.minutes);dt.seconds = ti->tm_sec;dt.s = dt.seconds < 10 ? "0" + String(dt.seconds) : String(dt.seconds);//将得到的年月日写入weather_data 结构体dt.localDate = dt.y + "-" + dt.m + "-" + dt.d;//Serial.println(dt.h + "-" + dt.i + "-" + dt.s);
}

        (3)LunarDate LunarCalendar(int year, int month, int day),将阳历的年月日转换成阴历的年月日,存放到结构体 struct LunarDate 中。

LunarDate LunarCalendar(int year, int month, int day)
{int Spring_NY, Sun_NY, StaticDayCount;int index, flag;//Spring_NY 记录春节离当年元旦的天数。//Sun_NY 记录阳历日离当年元旦的天数。if ( ((LunarCalendarTable[year - 1901] & 0x0060) >> 5) == 1)Spring_NY = (LunarCalendarTable[year - 1901] & 0x001F) - 1;elseSpring_NY = (LunarCalendarTable[year - 1901] & 0x001F) - 1 + 31;Sun_NY = MonthAdd[month - 1] + day - 1;if ( (!(year % 4)) && (month > 2))Sun_NY++;//StaticDayCount记录大小月的天数 29 或30//index 记录从哪个月开始来计算。//flag 是用来对闰月的特殊处理。//判断阳历日在春节前还是春节后if (Sun_NY >= Spring_NY)//阳历日在春节后(含春节那天){Sun_NY -= Spring_NY;month = 1;index = 1;flag = 0;if ( ( LunarCalendarTable[year - 1901] & (0x80000 >> (index - 1)) ) == 0)StaticDayCount = 29;elseStaticDayCount = 30;while (Sun_NY >= StaticDayCount){Sun_NY -= StaticDayCount;index++;if (month == ((LunarCalendarTable[year - 1901] & 0xF00000) >> 20) ){flag = ~flag;if (flag == 0)month++;}elsemonth++;if ( ( LunarCalendarTable[year - 1901] & (0x80000 >> (index - 1)) ) == 0)StaticDayCount = 29;elseStaticDayCount = 30;}day = Sun_NY + 1;}else //阳历日在春节前{Spring_NY -= Sun_NY;year--;month = 12;if ( ((LunarCalendarTable[year - 1901] & 0xF00000) >> 20) == 0)index = 12;elseindex = 13;flag = 0;if ( ( LunarCalendarTable[year - 1901] & (0x80000 >> (index - 1)) ) == 0)StaticDayCount = 29;elseStaticDayCount = 30;while (Spring_NY > StaticDayCount){Spring_NY -= StaticDayCount;index--;if (flag == 0)month--;if (month == ((LunarCalendarTable[year - 1901] & 0xF00000) >> 20))flag = ~flag;if ( ( LunarCalendarTable[year - 1901] & (0x80000 >> (index - 1)) ) == 0)StaticDayCount = 29;elseStaticDayCount = 30;}day = StaticDayCount - Spring_NY + 1;}LunarCalendarDay |= day;LunarCalendarDay |= (month << 6);LunarDate d;d.year = year;d.month = month;d.day = day;if (month == ((LunarCalendarTable[year - 1901] & 0xF00000) >> 20))d.leap =  1;elsed.leap =  0;return d;
}String outputLunarDate(int year, int month, int day) {LunarDate ld = LunarCalendar(year, month, day);String str = "";if (ld.leap) {str += "闰";} else {str += " ";}str += ChMonth[ld.month] + ChDay[ld.day];return str;
}

        (4)String weekOfDate1(int year, int month, int day),将阳历的年月日转换为星期几。

String weekOfDate1(int year, int month, int day)
{int adjustment, mm, yy;if (year < 2000) year += 2000;adjustment = (14 - month) / 12;mm = month + 12 * adjustment - 2;yy = year - adjustment;int week = (day + (13 * mm - 1) / 5 +yy + yy / 4 - yy / 100 + yy / 400) % 7;return weekly[week];
}

        说明:本程序主要内容,来源于网络大神,如有异议,请及时联系作者。

四、项目运行结果视频展示

        本阶段TFT屏幕上部,第一行,可以显示阳历日期、星期几、农历日期;第二行显示实时网络时间(东八东,偏移量28800秒),每秒更新一次;
        中部,实时天气和明天天气预报部分,目前仍显示静态画展,没有加入实时获取天气信息的代码。
        下部,显示当前所在环境实时的温度和湿度数据,每3秒更新一次。        

WeatherClock_exalmpl4

五、项目第四专题代码下载

        百度网盘下载链接:
        https://pan.baidu.com/s/1tBrHF5KNcwBR-2-HXvNQdw?pwd=bw9e,提取码:bw9e

        参考文档
        1. NTPClient 部分源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/688396.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言神奇的经典程序

因为C语言语法格式的特殊性&#xff0c;还诞生了一个C语言乱码大赛&#xff0c;从1984年开始&#xff0c;一直办到现在。在它官网上能看到历年所有的参赛获奖的作品。 官网链接&#xff1a; https://www.ioccc.orghttps://github.com/ioccc-src/temp-test-ioccc 这个比赛的目…

美国政府发布新的国际网络空间和数字政策战略(上)

文章目录 前言一、战略内容介绍二、数字团结的含义三、如何建立数字团结前言 美国务院5月6日正式发布《美国国际网络空间和数字政策战略:迈向创新、安全和尊重权利的数字未来》,旨在指导国际社会参与技术外交并推动《美国国家安全战略》和《美国国家网络安全战略》。 美国务…

界面组件DevExpress Reporting中文教程 - 标记(可访问)PDF导出增强

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 可访问性支持在DevExpress这里仍然是一个高优先…

深入理解卷积函数torch.nn.Conv2d的各个参数以及计算公式(看完写模型就很简单了)

代码解释帮助理解&#xff1a; torch.randn(10, 3, 32, 32)&#xff0c;初始数据&#xff1a;(10, 3, 32, 32)代表有10张图片&#xff0c;每张图片的像素点用三个数表示&#xff0c;每张图片大小为32x32。&#xff08;重点理解这个下面就好理解了&#xff09; nn.Conv2d(3, 64…

独家丨美团直播积极寻求MCN公司合作,却意外成商家刷单圣地?

图片&#xff5c;《扫黑决战》截图 ©自象限原创 作者丨薛黎 编辑丨程心 2023年4月18日&#xff0c;美团直播在“神券节”中正式上线。整整一年之后&#xff0c;美团直播又在持续加码。 据「自象限」独家获悉&#xff0c;在去年12月美团上线达人直播后&#xff0c;近期…

Verilog_学习路线(小白)

#前言&#xff1a; 自从专心学习专业课后&#xff0c;发现知识点得用&#xff0c;越用越熟练&#xff0c;工具也一样&#xff0c;高级工具的学习可帮助我们在工作中极大地提高效率&#xff0c;但这里要记住一点&#xff0c;任何工具都是为解决实际问题出现的&#xff0c;即落脚…

Spring Cloud Gateway 全局过滤器

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 全局过滤器作用于所…

可以直接用的搭建训练一个气象深度学习模型全流程代码--part1 以预报预测为例

本期内容分享一套全流程搭建训练气象深度学习模型的代码&#xff0c;并考虑在基础的预报预测领域的应用。 本期内容的目标是&#xff1a;尽量让看过本文的读者&#xff0c;可以直接在本地一键跑通如SmaAtUNet、UNet等卷积网络&#xff0c;ConvLSTM、TrajGRU、PhyDNet、STPhy等…

Android Studio 读不到Android设备

Android Studio 读不到Android设备 在进行Android应用开发时&#xff0c;我们经常会遇到一种情况&#xff0c;就是Android Studio无法读取到连接在电脑上的Android设备。这个问题可能出现在不同的场景中&#xff0c;比如在运行应用程序时&#xff0c;设备列表中找不到连接的设…

CSS-背景属性

目录 背景属性 background-color (背景颜色 ) background-image (背景图片 ) background-repeat (背景图平铺方式 ) no-repeat 不平铺 repeat-x 水平方向平铺 repeat-y 垂直方向平铺 repeat 平铺 background-position (背景图位置) background-size (背景缩…

通过单总线实现单片机之间的数据传输

单总线、没有时钟线的通信时&#xff0c;不能使用简单的高低电平来通信&#xff0c;因为接收方不知道此时发送的数据是第几位数据&#xff0c;容易造成错乱。 因此在使用一根线对外传输数据时&#xff0c;需要自定义一个通信协议&#xff0c;它至少要包含格式头数据&#xff0c…

使用 AI Assistant for Observability 和组织的运行手册增强 SRE 故障排除

作者&#xff1a;Almudena Sanz Oliv, Katrin Freihofner, Tom Grabowski 通过本指南&#xff0c;你的 SRE 团队可以实现增强的警报修复和事件管理。 可观测性 AI 助手可帮助用户使用自然语言界面探索和分析可观测性数据&#xff0c;利用自动函数调用来请求、分析和可视化数据…