使用Arduino开发ESP32(19):获取网络时间_Naisu Xu的博客-程序员宅基地

技术标签: 时间  网络  arduino  esp32  物联网  ESP32与ESP8266相关  

目的

时间是软硬件系统或设备中比较重要的东西,特别是需要和外部进行交互时就更加需要用到有个统一的时间了。目前来说只要能联网的设备的时间主要是从网络时间服务器(NTP)上获取的,这篇文章将对此做个简单的说明。

基础说明

在Arduino core for the ESP32中获取网络时间是非常简单的,只要下面几步就行:

  • 使用STA或ETH模式连上互联网;
  • 使用下面函数从网络时间服务器上获取并设置时间:
    void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1, const char* server2 = nullptr, const char* server3 = nullptr)
    网络时间服务器最常用的主机名是 pool.ntp.org
    通过网络时间服务器获得的时间是世界协调时间(UTC)/格林尼治时间(GMT),不同地区的时间可以通过时区换算, gmtOffset_sec 参数就是用来修正时区的,比如对于我们东八区(UTC/GMT+08:00)来说该参数就需要填写 8 * 3600
    如果使用夏令时 daylightOffset_sec 就填写3600,否则就填写0;
  • 设置完成后就可以使用下面函数读取当前时间了:
    bool getLocalTime(struct tm * info, uint32_t ms = 5000)
    ms 为该操作超时时间,超时则返回false;
    info 是一个 struct tm 结构体对象,用于接收当前时间;

示例演示

在Arduino core for the ESP32中获取网络时间是非常简单的,只要先连上网,然后就可以调用库中封装的方法获取网络时间了。下面是个简单的示例演示:

#include <WiFi.h>

const char *ssid = "********";    //你的网络名称
const char *password = "********"; //你的网络密码

const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;
const int daylightOffset_sec = 0;

void printLocalTime()
{
    
    struct tm timeinfo;
    if (!getLocalTime(&timeinfo))
    {
    
        Serial.println("Failed to obtain time");
        return;
    }
    Serial.println(&timeinfo, "%F %T %A"); // 格式化输出
}

void setup()
{
    
    Serial.begin(115200);
    Serial.println();

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
    
        delay(500);
        Serial.print(".");
    }
    Serial.println("WiFi connected!");

    // 从网络时间服务器上获取并设置时间
    // 获取成功后芯片会使用RTC时钟保持时间的更新
    configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
    printLocalTime();

    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
    Serial.println("WiFi disconnected!");
}

void loop()
{
    
    delay(1000);
    printLocalTime();
}

在这里插入图片描述

额外说明

网络时间服务器

可用的网络时间服务器主要有下面一些:

Area HostName
Worldwide pool.ntp.org
Asia asia.pool.ntp.org
Europe europe.pool.ntp.org
North America north-america.pool.ntp.org
South America south-america.pool.ntp.org
Oceania oceania.pool.ntp.org

struct tm结构体与格式化输出

该结构体代码如下:

struct tm {
    
int tm_sec; // 秒,取值0~59;
int tm_min; // 分,取值0~59;
int tm_hour; // 时,取值0~23;
int tm_mday; // 月中的日期,取值1~31;
int tm_mon; // 月,取值0~11;
int tm_year; // 年,其值等于实际年份减去1900;
int tm_wday; // 星期,取值0~6,0为周日,1为周一,依此类推;
int tm_yday; // 年中的日期,取值0~365,0代表1月1日,1代表1月2日,依此类推;
int tm_isdst; // 夏令时标识符,实行夏令时的时候,tm_isdst为正;不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负
};

该结构体可以格式化输出,格式化规则如下:

%a 星期几的简写
%A 星期几的全称
%b 月分的简写
%B 月份的全称
%c 标准的日期的时间串
%C 年份的后两位数字
%d 十进制表示的每月的第几天
%D 月/天/年
%e 在两字符域中,十进制表示的每月的第几天
%F 年-月-日
%g 年份的后两位数字,使用基于周的年
%G 年分,使用基于周的年
%h 简写的月份名
%H 24小时制的小时
%I 12小时制的小时
%j 十进制表示的每年的第几天
%m 十进制表示的月份
%M 十时制表示的分钟数
%p 本地的AM或PM的等价显示
%r 12小时的时间
%R 显示小时和分钟:hh:mm
%S 十进制的秒数
%t 水平制表符
%T 显示时分秒:hh:mm:ss
%u 每周的第几天,星期一为第一天 (值从0到6,星期一为0)
%U 第年的第几周,把星期日做为第一天(值从0到53)
%V 每年的第几周,使用基于周的年
%w 十进制表示的星期几(值从0到6,星期天为0)
%W 每年的第几周,把星期一做为第一天(值从0到53)
%x 标准的日期串
%X 标准的时间串
%y 不带世纪的十进制年份(值从0到99)
%Y 带世纪部分的十进制年份
%z,%Z 时区名称,如果不能得到时区名称则返回空字符

time_t 和 time()

使用 time() 函数可以获取到一个包含从1970年开始到现在的秒数对象 time_t
在这里插入图片描述

总结

在Arduino core for the ESP32中获取网络时间比较简单,更多内容可以参考下面链接:
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Time/SimpleTime/SimpleTime.ino
https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-time.c
https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Naisu_kun/article/details/115627629

智能推荐

网络中NAT原理及应用_铭记_的博客-程序员宅基地_nat csdn

网络地址转换NAT原理及应用网路岗 发布于 2011/10/26 13:56:58 / 2489人围观 / 0人吐槽摘要:NAT 概述1.1 简介NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标

(转载)解决GDI闪烁_weixin_30929195的博客-程序员宅基地

一般的windows复杂的界面需要使用多层窗口而且要用贴图来美化,所以不可避免在窗口移动或者改变大小的时候出现闪烁。先来谈谈闪烁产生的原因原因一:如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕上只是写到了显存里,而显卡每隔一段时间把显存的内容输出到屏幕上,这就是刷新周期。一般显卡的刷新周期是1/80秒左右,具体数字可以自己设置的。这样问题就来了,一般...

wd2go java_go语言之行--基础部分_陈布谷的博客-程序员宅基地

一、数据类型布尔型布尔类型- 由两个预定义常量组成:true、false,默认值为falsepackage mainimport"fmt"func main() {var(abool //默认值为falseb bool = true)fmt.Println(a,b)}数字类型整型:uint8(无符号 8 位整型 (0 到 255))uint16(无符号 16 位整型 (0 到 65535))u...

webpack基本打包配置流程_huaqiangu1123的博客-程序员宅基地

项目搭建以及webpack打包配置流程创建文件夹EC(文件夹和文件名根据需求自定义)在EC文件夹下新建文件夹APP在APP文件夹下新建入口文件index.js 和运行该入口文件的index.html文件在APP文件夹下新建两个js文件:a,js   b.js   (当项目级别如react项目,可以根据需求创建components文件夹等等,用于更好地管理模块化项目)      AP

在/sys/class下创建访问节点_堵刻的博客-程序员宅基地_创建的节点在/sys/class/

在驱动开发中我们经常要提供应用层或者debug的访问节点,内核中有一个接口class_register可以创建这种节点,下面是我在一个项目中使用的代码,有需要的可以参考,static ssize_t headset_enable_store(struct class *class,struct class_attribute *attr, const char *buf, size_t c

IOS 字符串中去除特殊符号_搬砖程序员的博客-程序员宅基地

IOS 字符串中去除特殊符号 stringByTrimmingCharactersInSet 应该用于账号登录等先上个例子:NSString * str1 =[nameInput.text stringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]];NSString 

随便推点

tomcat 的原理_Williamwhc的博客-程序员宅基地

这个问题,可以参考“为什么使用Servlet” 中的解答;其中提到,在BS中如何运行serversocket 的服务类(假设命名为ServTomcat),说到底,就是在这个ServTomcat类中main 入口方法来启动一个线程处理客户端请求;该线程用来等待接收客户连接,当有客户连接sever.accept(),则得到socket 并且可以得到相应的流 bufferreader在ServTomca...

SpringBoot 2.1.6-RELEASE 整合 elasticsearch-6.2.2报错解决_AE86-打破常规的博客-程序员宅基地

一开始使用SpringBoot整合elasticsearch-7.0.0,运行报错:org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{h0Pdm8CjQwOtttzVQLXrww}{127.0.0.1...

解决win10+ubuntu20.04双系统(UEFI+GPT)删除ubuntu后启动项仍存在_ZChen1996的博客-程序员宅基地

解决win10+ubuntu20.04双系统 (UEFI+GPT)删除ubuntu后启动项仍存在 问题原因解决办法为 win10 的 EFI 系统分区 分配盘符进入 EFI 分区,找到 EFI 文件夹,删除其中的 ubuntu 文件夹删除为 win10 的 EFI 系统分区 分配的盘符问题原因这是因为在安装Ubuntu后,Ubuntu的引导信息也写在了win10的EFI启动分区里。解决办法修改 win10 的 EFI 分区在磁盘管理其中我们可以看到 win10 的 EFI 系统分区,但是没有盘符我

linux调试工具 strace 和pstack 编译及使用介绍_xinghuah的博客-程序员宅基地_pstack交叉编译

一、简介&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。&nbsp;&nbsp;&nbsp;&nbsp; 2、pstack是一个基于GDB的脚本命令,可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack...

表、视图、查询表的区别(关系的三种基本类型)_Suprit的博客-程序员宅基地_视图与数据表及查询的区别

视图概述视图是从一个或几个基本表(或视图)导出的表。它与基本表不同,是一个虚表。数据库中只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。所以一旦基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中自己感兴趣的数据及其变化。视图一经定义,就可以和基本表一样被查询、删除。也可以在一个视图之上再定义新的视图,但对视图的更新(增、删、改)操作则有一定的限制。视图只存定义,每次查看视图就相当于执行一次语句。视图的特点

推荐文章

热门文章

相关标签