使用Arduino开发ESP32(19):获取网络时间

2023-11-07

目的

时间是软硬件系统或设备中比较重要的东西,特别是需要和外部进行交互时就更加需要用到有个统一的时间了。目前来说只要能联网的设备的时间主要是从网络时间服务器(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/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Arduino开发ESP32(19):获取网络时间 的相关文章

  • 网络安全行业热门认证证书合集

    网络安全认证证书 就和学历一样是敲门砖 拿到了可以用不到 但不能没有 技术大牛可以没有证书 但普通人不能没有 1 初级入门 就像学历在职场上展示一个人的基本素养一样 网络安全认证证书可以展示一个人在网络安全领域具备的基本知识和技能 它为初学
  • 批处理文件:从串口接收数据并将其写入txt文件

    我正在尝试通过 USB 串行端口从 Arduino 提取一些数据并将其写入 txt 文件 因此 我使用批处理文件 Windows 7 普通cmd 它发送例如 d 从 Arduino 请求所需的数据 收到 d 后 Arduino 开始向 PC
  • Arduino:字符串到整数得到奇怪的值

    我想转换一个String to an int 我所能找到的就是你必须将 String 转换为 char 数组 然后将该数组转换为int 但我的代码产生奇怪的值 我无法弄清楚问题是什么 void ledDimm String command
  • 如何在 Arduino 上比较 __FlashStringHelper* 和 char*?

    我有一个将文本行输出到串行的板 我需要将这些文本行与我所知道的文本进行比较 本质上 我想做strcmp thestring F knownstring 但是似乎没有一个采用 FlashStringHelper 类型的 strcmp 版本 有
  • 经典蓝牙 (2.1) 设备可实现的最小数据包延迟是多少?

    我正在使用 RN42 http www microchip com wwwproducts en RN42 http www microchip com wwwproducts en RN42 蓝牙模块以 115200 波特率 UART S
  • Android BLE 扫描与 UUID 过滤器列表混淆

    我正在 Android 移动设备 A 上执行 UUID 过滤扫描 并且有两个测试用例 一个人在另一台 Android 设备 移动设备 b 上使用名为 BLE Scanner 的应用程序来创建具有两个测试服务 每个服务都有自己唯一的 UUID
  • 同时使用 GPRS 和 GSM

    我正在尝试使用 GSM GPRS 调制解调器的 GPRS 功能将数据发送到远程服务器 但我无法这样做 我在 Arduino 论坛上发布了一个问题 但没有得到任何回复 这是问题的链接 https robotics stackexchange
  • C-如何使用PROGMEM存储和读取char数组

    我有三个字符数组 我不希望 Arduino 将它们存储在SRAM http en wikipedia org wiki Static random access memory 所以我想使用PROGMEM来存储和读入flash http en
  • 是否有通用 I2C 命令来查看设备是否仍然存在于总线上?

    是否有通用的 I2C 命令来查看设备在初始化一次后是否仍然存在于总线上 例如 OLED 显示器 我问这个的原因是为了避免主程序由于库代码中存在无限循环而冻结 当设备断开连接时 例如 Wire 库 在 MCU 启动时 我想检查设备是否可用 并
  • 为什么使用 libnfc 和 PN532 SHIELD 时“找不到 NFC 设备”

    我在 ArchLinux 上安装了 libnfc 并通过我的 Adafruit PN532 arduino SHIELD 使用它 nfc list返回消息 未找到 NFC 设备 我在 etc nfc devices d pn532 conf
  • 如何为 Arduino 或类似的微控制器编写 JavaScript 编译器? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我意识到这个问题会引起一些人的注意 并且我意识到 JavaScript 传统上是一种解释性语言 请让我解释一下 我是一名专门从事 We
  • SIM900 GSM/GPRS 未获得正确的 AT+CREG?回答

    我使用的是带有 IComsat SIM900 GSM GPRS 扩展板的 Arduino UNO 使用以下教程 Arduino 实时 GPS 追踪器 http www samaria me uk 2011 12 arduino live g
  • 是否可以在 Arduino 上运行 ZeroMQ

    我想知道是否可以通过 ZeroMQ 与 Arduino 进行通信 我想使用 Arduino 来控制一些设备 并希望将大部分应用程序放在计算机上 为此 如果 Arduino 和控制器可以通过 Zeromq 以及 WiFi 或以太网扩展板进行通
  • Arduino串口数据解析

    我正在编写一个应用程序 通过蓝牙用我的 Android 手机控制我的机器人 一切都很顺利 数据得到回显和验证 但我在协议方面遇到了一些问题 特别是我希望我的机器人的轮子在我发送时转动一个命令 例如s 10 100 or s 30 10 数值
  • Arduino Nano 33 IoT 的软件序列号

    我计划从旧的 5V Arduino Nano 迁移到新的 Arduino Nano 33 IoT 我已经使用软件串行 SoftwareSerial h 为旧的 5V Arduino Nano 编写了一个功能代码 以便与 Sim800L 模块
  • Arduino 高低

    我有一个 Arduino 我想知道到底是什么HIGH and LOW意思是 就实际值而言 它们是否有符号ints unsigned ints unsigned char是 他们的价值观是什么 我猜HIGH and LOW可能是unsigne
  • 带 firebase 的 Nodemcu(ESP8266)

    这是我上传到 ESP8266 以连接到 firebase 的代码 include
  • Arduino Uno 上传失败

    我收到了一个 arduino uno 和一些代码 作为我正在从事的项目的一部分 我以前从未与他们合作过 所以这对我来说是一次全新的体验 我正在使用他们网站上的 Arduino 应用程序 当我编译代码时 它工作正常 然而 当我上传时 我收到错
  • Arduino 上的串行消息到整数

    我希望我的 Arduino 通过串行通信接收一个整数 你能帮我解决这个问题吗 它应该是这样的形式 int value strtoint Serial read 有多种方法可以读取整数Serial 很大程度上取决于数据发送时的编码方式 Ser
  • 使用 avr-gcc 编译器/链接器对链接 avrfix 库中函数的未定义引用

    我正在尝试使用avrfix 库 http avrfix sourceforge net 在一个项目中 使用Eclipse v4 2 2 作为IDE avr gcc作为编译器 头文件 avrfix h 和库文件 libavrfix a 都包含

随机推荐

  • Harbor仓库介绍与搭建过程

    一 介绍 Harbor 是一个英文单词 意思是港湾 港湾是干什么的呢 就是停放货物的 而货物呢 是装在集装箱中的 说到集装箱 就不得不提到Docker容器 因为docker容器的技术正是借鉴了集装箱的原理 所以 Harbor正是一个用于存储
  • 代码块和执行顺序

    1 什么是代码块 使用 定义的一段代码我们称之为代码块 一般分为 1 普通代码块 2 实例代码块 3 静态代码块 2 普通代码块 定义在方法中的代码块 可以用于限定局部变量的生命周期 public class Main public sta
  • 决策树的实现原理与matlab代码

    很久不写博客了 感觉很长一段时间只是一味的看书 疏不知一味地看书 写代码会导致自己的思考以及总结能力变得衰弱 所以 我决定还是继续写博客 废话不多说了 今天想主要记录数据挖掘中的决策树 希望能够将自己的理解写得通俗易懂 决策树是一种对实例分
  • windows使用cmd运行jar点击黑窗口项目停止运行问题

    windows使用cmd运行jar点击黑窗口项目停止运行问题 问题 解决 问题 近期做的项目部署在windows服务器下 使用cmd运行jar包的方式 出现项目停了运行问题 原因是误点击了黑窗口里的位置 导致项目停止运行 解决 取消勾选即可
  • java数组 contains_java怎么判断一个元素是否在数组中存在

    我是前端出身 写这个判断是否存在或者是去重的方法 前端js基本上有好多种方法 但是貌似都有点麻烦 js与Java其实也大差不差 只要思路正确 只是实现的代码不同罢了 起初我想的是通过双层for循环 但貌似依旧有点麻烦 查工具书发现 Java
  • 增强for循环

    package structure loop 增强for循环 重点是用来循环数组和集合的 public class ForDemo05 public static void main String args int nembers 5 2
  • 锂电池的充电原理

    一 锂电池的充电原理 锂离子电池的充电过程可以分为三个阶段 涓流充电 低压预充 恒流充电 恒压充电 锂电池的充电方式是限压恒流 都是由IC芯片控制的 典型的充电方式是 先检测待充电电池的电压 如果电 压低于3V 要先进行预充电 充电电流为设
  • 微信电脑版不断崩溃

    目录 文章背景 目录 问题介绍 解决问题 说明 参考文章 版本记录 文章背景 之前不知道为什么 突然发生微信不断崩溃的状况 更新微信没用尝试网上的各种方法都没用 不过索性最后解决了 想看解决方案的话看最后了 中间记录的是崩溃日志 目录 问题
  • nrm 安装后报错

    Error ERR REQUIRE ESM require of ES Module D npm node modules nrm node modules open index js from D npm node modules nrm
  • python async 异步

    1 requests 包不支持异步 使用 requests async import asyncio import threading import time from aiohttp import ClientSession import
  • g++配置选项-std=c++11

    如何配置g 选项 std c 11 g 命令改为 g std c 11 qt配置std的c 11 QMAKE CXXFLAGS std c 11 如果没有配置c 11 就会报如下错
  • Comparable、compareTo、Comparator、compare之间有什么区别

    Comparable和Comparator是Java的接口 而compareTo是Comparable接口中的方法 compare是Comparator中的方法 在Scala中Ordered相当于Java中的Comparable 在Scal
  • UML2面向对象分析与设计(第2版) 谭火彬 杂记

    首先 来讲讲我对泛化的理解 其实这是站在的视角的不同而表述的不同 泛化是站在父类的角度 父类给孩子的方式叫泛化 而继承是站在孩子的角度 儿子继承父类的方式叫继承 其实上了谭老师大概一章的课程 并且我觉得谭老师真的是对面向对象很有认识的 这门
  • java设计模式之建造者模式

    定义 建造者模式将一个复杂对象的构建过程与它的表示分离 使得同样的构建过程可以创建不同的表示 属于创建型设计模式 对于用户而言 使用建造者模式只需指定需要创建的类型就可以获得对象 创建过程及细节不需要了解 根据建造者模式的定义 可以简单的理
  • 关于udelay(); mdelay(); ndelay(); msleep();

    在 inux river开发中 经常要用到延迟函数 msleep mdelay udelay 虽然msleep和mdelay都有延迟的作用 但他们是有区别的 mdeday还忙等待函数 在延迟过程中无法运行其他任务 这个延迟的时间是准确的 是
  • 分享几个直接访问的GPT项目,ChatGPT智能最佳实践

    自美国时间12月2日上线以来 美国硅谷的初创公司OpenAI推出的ChatGPT 已经拥有超过一百万的用户 受到热烈的讨论 它既能完成包括写代码 修bug 代码改错 翻译文献 写小说 写商业文案 创作菜谱 做作业 评价作业等一系列常见文字输
  • 在linux系统启动springboot项目

    1 springboot项目打包 在项目根目录的地址栏输入cmd并回车 执行如下命令 生成jar mvn clean package 2 部署并执行 传到linux系统的指定位置 在安装好jdk和数据库等相关环境 执行jar 1 java
  • 【TA-霜狼_may-《百人计划》】美术2.7 Metallic 与 Speculer流程

    TA 霜狼 may 百人计划 美术2 7 Metallic 与 Speculer流程 TOC TA 霜狼 may 百人计划 美术2 7 Metallic 与 Speculer流程 2 7 1 概念 2 7 2 两种流程 通用贴图 2 7 3
  • Sass 条件语句

    本节我们来学习 Sass 中的条件语句 可以使用 if 指令来判断条件表达式的值 然后控制输出 Sass 中的 if else 等指令和 JS 中的 if else 类似 if 指令 当 if 指令后面的表达式返回值为 true 时 输出花
  • 使用Arduino开发ESP32(19):获取网络时间

    文章目录 目的 基础说明 示例演示 额外说明 网络时间服务器 struct tm结构体与格式化输出 time t 和 time 总结 目的 时间是软硬件系统或设备中比较重要的东西 特别是需要和外部进行交互时就更加需要用到有个统一的时间了 目