【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://xiahunao.cn/news/3032009.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云和AWS负载均衡服务对比分析

在云计算时代,负载均衡作为一种关键的网络基础设施,承担着在多个服务器之间分发网络流量的重要任务。作为全球两大主要的云服务提供商,阿里云和Amazon Web Services(AWS)都提供了强大的负载均衡解决方案。本文将从性能、功能、可用性和成本等方面对两者进行对比分析。我们九河云…

this指针详解

目录 this指针this指针的引出this指针的特性this指针相关例题例题1例题2 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1f978;&#x1f978; C语言 &#x1f43f;️&#x1f43f;️…

【UE Niagara】在UI上生成粒子

效果 步骤 1. 在虚幻商城中将“Niagara UI Render”插件安装到引擎 2. 打开虚幻编辑器&#xff0c;勾选插件“Niagara UI Renderer”&#xff0c;然后重启编辑器 3. 先创建一个控件蓝图&#xff0c;该控件蓝图只包含一个按钮 这里设置尺寸框尺寸为200*50 4. 显示该控件 5. 新…

3月笔记本电脑行业线上市场销售数据分析

笔记本电脑市场在过去几年中经历了起伏&#xff0c;但总体上呈现出稳定增长的态势。特别是随着远程办公、在线学习等需求的增加&#xff0c;以及消费者对于便携性、高性能等方面的追求&#xff0c;笔记本电脑市场得到了进一步的发展。 据鲸参谋数据统计&#xff0c;线上平台&a…

杰理AC632N 通过写flash修改蓝牙名字

杰理修改蓝牙名字一般有他自己的一个工具的,如下图,在编译前修改 现在用写flash的方式更改: 主要看杰理CFG_BT_NAME这个宏里面的.c文件 杰理给这里的flash都定义好每个宏的信息,你需要读写就行,修改后记得重启上电才能生效.如果你要自定义数据写进去flash断电不丢失,估计就是在…

企业微信集成H5授权登录相关知识(二)

流程&#xff1a; 1.前端请求企业微信获取code&#xff1a;官网网页授权链接 2.企业微信返回的code请求后端判断是否已绑定系统账户 3.后端根据企业微信code&#xff0c;accessToken获得userId 4.userId获取user进行oauth2授权方式进行免密登录 相关知识&#xff1a; 一&a…

QT——tableWidget-跳变之舞V1.0-记录学习【1】

QT——tableWidget-跳变之舞V1.0-记录学习【1】 文章目录 QT——tableWidget-跳变之舞V1.0-记录学习【1】前言一、利用QT创建项目文件1.1 完整项目文件如下图所示:1.2 演示&#xff1a; 二、声明文件&#xff1a;2.1 主界面声明文件:mainwindow.h&#xff1b;2.2 控制窗口声明文…

【详细教程】基于pyEchart的封装(附代码)

目 录 一、项目结构 二、文件封装 2.1echart.py 2.2pyechartMock.py 三、结果 3.1柱状图 3.2折线图 3.3饼状图 最近在学习pyechart&#xff0c;老师要我们画几个简单的图&#xff0c;比如折线图&#xff0c;柱状图&#xff0c;饼状图&#xff0c;我这里在参考pyechart…

答辩PPT设计无从下手?哪些AI工具可以提供帮助

本科毕业论文答辩PPT该怎么做&#xff1f; 在我原本的认知里面&#xff0c;答辩PPT是要包含论文各个章节的&#xff0c;在答辩时需要方方面面都讲到的&#xff0c;什么摘要、文献综述、实证分析、研究结果样样不落。但是&#xff0c;这大错特错&#xff01; 答辩PPT环节时长…

luceda ipkiss教程 70:合并GDS版图

通过代码拼版&#xff1a; 所有代码如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3class Design1(i3.GDSCell):def _default_filename(self):return "Ring_Test.gds"def _default_name(self):return "Design1"class Des…

大数据基础工程技术团队4篇论文入选ICLR,ICDE,WWW

近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导的四篇时间序列相关论文分别被国际顶会ICLR2024、ICDE2024和WWW2024接收。 论文成果是阿里云与华东师范大学、浙江大学、南京大学等高校共同研发&#xff0c;涉及时间序列与智能运维结合的多个应用场景。包括基于P…

recycleview和banner新闻列表轮播图

说明&#xff1a;最近碰到一个需求&#xff0c;弄一个新闻列表和轮播图&#xff0c;在首页显示&#xff0c;并且需要json解析&#xff0c;图片下载&#xff0c;轮播图和新闻列表一起滑动 ui效果图&#xff1a; 文件说明&#xff1a; step1:引用依赖包 图片下载 json解析 轮播…

Java入门基础学习笔记4——开发Helloworld入门程序

Java程序开发的三个步骤&#xff1a; 1&#xff09;编写代码 2&#xff09;编译代码 3&#xff09;运行代码 注意事项&#xff1a; 第一个java程序建议使用记事本来编写。 建议代码文件名全英文、首字母大写、满足驼峰模式&#xff0c;源代码文件的后缀必须是.java 注意&a…

企业破产重整:从“至暗时刻”到“涅槃重生”

今天我们不谈星辰大海&#xff0c;而是要潜入商业世界的深海区&#xff0c;探索那些濒临绝境的企业是如何借助“破产重整”的神秘力量&#xff0c;实现惊天大逆转的&#xff01; 一、破产重整&#xff0c;到底是个啥&#xff1f; 想象一下&#xff0c;企业像是一位远航的船长…

数据增强,迁移学习,Resnet分类实战

目录 1. 数据增强&#xff08;Data Augmentation&#xff09; 2. 迁移学习 3. 模型保存 4. 102种类花分类实战 1. 数据集 2.导入包 3. 数据读取与预处理操作 4. Datasets制作输入数据 5.将标签的名字读出 6.展示原始数据 7.加载models中提供的模型 8.初始化…

从静态PPT到智能演讲——人工智能在演示文稿中的应用

1.概述 在这个信息过载的时代&#xff0c;能够吸引并持续吸引观众的注意力无疑成为了一项艰巨的任务。公众演讲领域正经历着一场由人工智能&#xff08;AI&#xff09;引领的革命。AI不仅在制作引人入胜的内容方面发挥作用&#xff0c;而且在分析演讲的传递方式上也起着关键作…

【C++】 类的6个默认成员函数

目录 1. 类的6个默认成员函数 一.构造函数 1.基本概念 2 特性 注意&#xff1a;C11 中针对内置类型成员不初始化的缺陷&#xff0c;又打了补丁&#xff0c; 3.构造函数详解 3.1构造函数体赋值 3.2 初始化列表 3.3 explicit关键字 二.析构函数 1 概念 2 特性 两个栈实…

Vue路由拆分

1.在src下建立router&#xff0c;在router中建立文件index 2.将main.js中部分内容复制 App <template> <div><a href"#/friend">朋友</a><br><a href"#/info">信息</a><br><a href"#/music&quo…

Photoshop中图层的应用

Photoshop中图层的应用 前言Photoshop中的图层面板Photoshop中图层的基本操作新建图层复制/剪切图层链接图层修改图层名称及颜色背景图层与普通图层栅格化图层图层的对齐与分布图层的合并 前言 图层在Photoshop中就像一层一层的透明纸&#xff0c;可以透过图层的透明区域看到下…

动手学深度学习16 Pytorch神经网络基础

动手学深度学习16 Pytorch神经网络基础 1. 模型构造2. 参数管理1. state_dict()2. normal_() zeros_()3. xavier初始化共享参数的好处 3. 自定义层4. 读写文件net.eval() 评估模式 QA 1. 模型构造 定义隐藏层–模型结构定义前向函数–模型结构的调用 import torch from torch…