Arduino ESP32 获取网络时间方法

Arduino ESP32 获取网络时间方法


✨在 ArduinoESP32核心支持库当中已经包含相关的获取时间的库,所有获取网络时间,只需要连接好网络,调用相关的库函数即可实现NTP时间的获取,免去的额外加载扩展库的头文件。

  • 最容易掉坑的地方:
  • ✨在获取本地时间的时候,一定要先判断一下getLocalTime()布尔类型函数的返回值:
struct tm timeInfo; //声明一个结构体
  if (!getLocalTime(&timeInfo))
  { //一定要加这个条件判断,否则内存溢出
    Serial.println("Failed to obtain time");
    return;
  }
  • 🔖这一点和ESP8266库的类似API有写差异,只要申请了全局的时间结构体的变量,就随便可以直接调用本地时间。
  • 🌿如果想将访问到的本地时间,来作为OLED显示输出的话,读取本地时间特别要注意,很容易造成内存溢出,导致系统重启,所以操作相关的时间函数时,特别要小心。

📓示例程序代码一

#include <Arduino.h>
#include <WiFi.h>

#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
//填写WIFI入网信息
const char *ssid = "MERCURY_D268G";                                                                                // WIFI账户
const char *password = "pba5ayzk";                                                                                 // WIFI密码
const String WDAY_NAMES[] = {"星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};                //星期
const String MONTH_NAMES[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; //月份

//time_t now; //实例化时间
void setClock()
{

  struct tm timeInfo; //声明一个结构体
  if (!getLocalTime(&timeInfo))
  { //一定要加这个条件判断,否则内存溢出
    Serial.println("Failed to obtain time");
    return;
  }
  //Serial.print(asctime(&timeInfo)); //默认打印格式:Mon Oct 25 11:13:29 2021
  String date = WDAY_NAMES[timeInfo.tm_wday];
  Serial.println(date.c_str());
  // sprintf_P(buff1, PSTR("%04d-%02d-%02d %s"), timeInfo.tm_year + 1900, timeInfo.tm_mon + 1, timeInfo.tm_mday, WDAY_NAMES[timeInfo.tm_wday].c_str());
  String shuju = String(timeInfo.tm_year + 1900); //年
  shuju += "-";
  shuju += timeInfo.tm_mon + 1; //月
  shuju += "-";
  shuju += timeInfo.tm_mday; //日
  shuju += " ";
  shuju += timeInfo.tm_hour; //时
  shuju += ":";
  shuju += timeInfo.tm_min;
  shuju += ":";
  shuju += timeInfo.tm_sec;
  shuju += " ";
  shuju += WDAY_NAMES[timeInfo.tm_wday].c_str(); //星期
  Serial.println(shuju.c_str());
}

void setup()
{
  Serial.begin(115200);
  Serial.println();
  //设置ESP32工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected!");
  configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
}

void loop()
{
  Serial.println("Waiting 10s before the next round...");
  delay(10000);
  setClock();
  // printLocalTime();
}
  • 📜串口打印输出
    在这里插入图片描述

📝示例程序代码二

  • 🔖来自固件自带例程的时间同步,最终都是通过调用configTime函数实现。
#include <WiFi.h>
#include "time.h"//固件自带
#include "sntp.h"//固件自带

const char* ssid       = "#######";//填写个人WIFI信息
const char* password   = "*******";

const char* ntpServer1 = "ntp.aliyun.com";
const char* ntpServer2 = "ntp2.aliyun.com";
const char* ntpServer3 = "time.nist.gov";
const long  gmtOffset_sec = 28800;//时区偏移:8*60*60
const int   daylightOffset_sec = 0;

const char* time_zone = "CET-1CEST,M3.5.0,M10.5.0/3";  // TimeZone rule for Europe/Rome including daylight adjustment rules (optional)

void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

//回调函数(通过NTP调整时间时调用)
void timeavailable(struct timeval *t)
{
  Serial.println("Got time adjustment from NTP!");
  printLocalTime();
}

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

  // 设置回调功能
  sntp_set_time_sync_notification_cb( timeavailable );

  /**
   * NTP server address could be aquired via DHCP,
   *
   * NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP,
   * otherwise SNTP option 42 would be rejected by default.
   * NOTE: configTime() function call if made AFTER DHCP-client run
   * will OVERRIDE aquired NTP server address
   */
  sntp_servermode_dhcp(1);    // (optional)

  /**
   * This will set configured ntp servers and constant TimeZone/daylightOffset
   * should be OK if your time zone does not need to adjust daylightOffset twice a year,
   * in such a case time adjustment won't be handled automagicaly.
   */
 // configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2);
 configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2,ntpServer3);
  /**
   * A more convenient approach to handle TimeZones with daylightOffset 
   * would be to specify a environmnet variable with TimeZone definition including daylight adjustmnet rules.
   * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h
   */
  //configTzTime(time_zone, ntpServer1, ntpServer2);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

}

void loop()
{
  delay(5000);
  printLocalTime();     // it will take some time to sync time :)
}

在这里插入图片描述

📘网络同步到内部RTC中

#include <WiFi.h>

#define NTP  "ntp.aliyun.com"	

//填写自己的WIFI信息
const char *ssid = "#######";
const char *password = "********";

void wifi_init(){
  
  WiFi.mode(WIFI_STA);//配置ESP32 工作模式
  WiFi.begin(ssid, password);
  Serial.println("正在连接 WiFi.");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("WiFi connected!");

}

void time_init() {
  struct tm timeinfo;  // 定义时间信息
  //如果获取失败,就开启联网模式,获取时间
  if (!getLocalTime(&timeinfo)){
    Serial.println("获取时间失败");
    //开启网络  
    wifi_init();
    // 从网络时间服务器上获取并设置时间
    configTime(8 * 3600, 0, NTP);//时区,夏令时,NTP地址
    return;
  }
  // 格式化输出:2021-10-24 23:00:44 Sunday
  Serial.println(&timeinfo, "%F %T %A"); 
  //   WiFi.disconnect(true);//在不需要开启网络的情况下,可以主动断开网络连接。
}

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

}

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

📓示例程序代码三


#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
//  #include <WiFiClient.h>//3.0.2新增
//  #include <ESP8266HTTPClient.h>
#endif
// 获取网络时间相关库
#include <NTPClient.h>//需要自行搜索并安装此库
#include <WiFiUdp.h>//固件自带

const char* ssid       = "########";//填写个人WIFI信息
const char* password   = "********";

const char* ntpServer = "ntp.aliyun.com";
const char* ntpServer2 = "ntp2.aliyun.com";
const char* ntpServer3 = "time.nist.gov";
const long gmtOffset = 28800; // 如果需要校准时区,可以根据需要进行调整
const int daylightOffset = 0;

uint32_t targetTime = 0;  // for next 1 second timeout

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer, gmtOffset, daylightOffset);

void setup() {
  // put your setup code here, to run once:
// 连接WiFi网络
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  
  // 启动NTP客户端
  timeClient.begin();
  targetTime = millis() + 1000;
}

void loop() {
  // put your main code here, to run repeatedly:
    if (targetTime < millis()) {
    targetTime = millis() + 1000;
// 获取NTP时间
  timeClient.update();
  // 获取NTP时间的小时、分钟和秒
  int hours = timeClient.getHours();
  int minutes = timeClient.getMinutes();
  int seconds = timeClient.getSeconds();
  printf("%02d:%02d:%02d\r\n",hours,minutes,seconds);
    }
 
}

在这里插入图片描述

  • 29
    点赞
  • 169
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值