【ESP32-C3-DevKitM-1】ESP32-C3获取网络时间
本帖最后由 怀揣少年梦 于 2021-7-6 10:55 编辑<p style="text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt"> ESP32-C3获取网络时间,可以通过SNTP获取。简单了解了一下SNTP,翻译过来就是简单网络时间协议,是从NTP改过来的,我的理解就是通过这个SNTP协议,可以与NTP服务器进行通信,然后获取服务器的时间即可更新系统时间。</span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">1、本次还是直接复制官方例子-sntp到自己的工程目录,然后在VScode 里面,在编译之前先设置一下menuconfig的wifi密码和SSID。具体设置方法是在界面左下角有一个齿轮。点击齿轮即可进入设置界面。如图。</span></span></span></p>
<p style="text-indent:21.0000pt; text-align:justify"> </p>
<p style="text-indent:21.0000pt; text-align:justify"></p>
<ol start="2">
<li style="text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">找到wifi设置。输入密码和SSID,保存即可。</span></span></span></li>
</ol>
<p></p>
<ol start="3">
<li align="justify" style="text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">最后编译下载,</span></span></span><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">效果如图。看到GuangZhou时间,显示星期,月,日,时,分,秒,年</span></span></span>。</li>
</ol>
<p style="text-align:justify"> </p>
<p style="text-align:justify"></p>
<p style="text-align:justify"> </p>
<ol start="4">
<li align="justify" style="text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">程序解释。</span></span></span></li>
</ol>
<p align="justify" style="margin-left:28px; text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">先上一张流程图。</span></span></span></p>
<p align="justify" style="margin-left:28px; text-align:justify"> </p>
<p align="justify" style="margin-left:28px; text-align:justify"></p>
<p align="justify" style="margin-left:28px; text-align:justify"> </p>
<p align="justify" style="margin-left:28px; text-align:justify"><span style="font-family:楷体;"><span style="font-size:10.5pt"><span style="font-size:10.5000pt">5.最后就是代码注释,比较详细。</span></span></span></p>
<pre>
<code>/* LwIP SNTP example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_sleep.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "esp_sntp.h"
static const char *TAG = "example";
/* Variable holding number of times ESP32 restarted since first boot.
* It is placed into RTC memory using RTC_DATA_ATTR and
* maintains its value when ESP32 wakes from deep sleep.
*/
RTC_DATA_ATTR static int boot_count = 0;
static void obtain_time(void);
static void initialize_sntp(void);
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_CUSTOM
void sntp_sync_time(struct timeval *tv)//同步系统时间,弱定义,由于使用time_sync_notification_cb回调,
//那么时间同步后会调用该函数
{
settimeofday(tv, NULL);
ESP_LOGI(TAG, "Time is synchronized from custom code");
sntp_set_sync_status(SNTP_SYNC_STATUS_COMPLETED);//时间同步时,sntp同步标志置1.
}
#endif
void time_sync_notification_cb(struct timeval *tv)//通知时间同步事件
{
ESP_LOGI(TAG, "Notification of a time synchronization event");
}
void app_main(void)
{
++boot_count;//ESP32自第一次BOOT,重启的次数
ESP_LOGI(TAG, "Boot count: %d", boot_count);
time_t now;//声明当前时间变量
struct tm timeinfo;//声明时间信息结构体,具体内容在time.h里面
time(&now);
localtime_r(&now, &timeinfo);
// Is time set? If not, tm_year will be (1970 - 1900). 判断时间是否设置,没有设置则连接wifi,并通过NTP获取时间
if (timeinfo.tm_year < (2016 - 1900)) {
ESP_LOGI(TAG, "Time is not set yet. Connecting to WiFi and getting time over NTP.");
obtain_time();//获取时间
// update 'now' variable with current time
time(&now);//
}
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH
else {
// add 500 ms error to the current system time.
// Only to demonstrate a work of adjusting method!
{
ESP_LOGI(TAG, "Add a error for test adjtime");
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
int64_t cpu_time = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
int64_t error_time = cpu_time + 500 * 1000L;
struct timeval tv_error = { .tv_sec = error_time / 1000000L, .tv_usec = error_time % 1000000L };
settimeofday(&tv_error, NULL);
}
ESP_LOGI(TAG, "Time was set, now just adjusting it. Use SMOOTH SYNC method.");
obtain_time();
// update 'now' variable with current time
time(&now);
}
#endif
char strftime_buf;//定义时间数组
// Set timezone to Eastern Standard Time and print local time。设置时区(美国)东部时间
setenv("TZ", "EST5EDT,M3.2.0/2,M11.1.0", 1);
tzset();//时区设置
localtime_r(&now, &timeinfo);//更新当地时间
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
ESP_LOGI(TAG, "The current date/time in New York is: %s", strftime_buf);//打印时间
// Set timezone to China Standard Time。设置时区中国标准时间
setenv("TZ", "CST-8", 1);
tzset();
localtime_r(&now, &timeinfo);//更新当地时间
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
ESP_LOGI(TAG, "The current date/time in GuangZhou is: %s", strftime_buf);//打印时间
if (sntp_get_sync_mode() == SNTP_SYNC_MODE_SMOOTH) {
struct timeval outdelta;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_IN_PROGRESS) {
adjtime(NULL, &outdelta);
ESP_LOGI(TAG, "Waiting for adjusting time ... outdelta = %li sec: %li ms: %li us",
(long)outdelta.tv_sec,
outdelta.tv_usec/1000,
outdelta.tv_usec%1000);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}//等待时间被调整
}
const int deep_sleep_sec = 10; //深度休眠时间
ESP_LOGI(TAG, "Entering deep sleep for %d seconds", deep_sleep_sec);
esp_deep_sleep(1000000LL * deep_sleep_sec);//ESP32进入深度休眠,10秒退出休眠
}
//获取NTP服务器的时间
static void obtain_time(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK( esp_event_loop_create_default() );
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());//这个函数配置WIFI功能,通过读取menuconfig里面的wifi密码和SSID,即可连接wifi
initialize_sntp();
// wait for time to be set
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int retry_count = 10;
while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET && ++retry < retry_count) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}//获取时间同步标志,等待系统时间更新
time(&now);
localtime_r(&now, &timeinfo);
ESP_ERROR_CHECK( example_disconnect() );//时间更新后,断开连接
}
//初始化SNTP相关函数
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
/*1,2,3函数主要作用就是通过SNTP,同步时间*/
sntp_setoperatingmode(SNTP_OPMODE_POLL);//1,设置SNTP操作模式
sntp_setservername(0, "pool.ntp.org");//2,设置时间服务器链接
sntp_set_time_sync_notification_cb(time_sync_notification_cb);//设置时间同步通知事件
#ifdef CONFIG_SNTP_TIME_SYNC_METHOD_SMOOTH //定义同步平滑模式
sntp_set_sync_mode(SNTP_SYNC_MODE_SMOOTH);//设置SNTP时间同步模式:平滑模式,是通过调整时间函数逐步缩小误差。
#endif
sntp_init();//3,SNTP初始化
}
</code></pre>
<p align="justify" style="margin-left:28px; text-align:justify">6、最后说明一下,SNTP的函数相关说明在ESP-IDF编程指南的system-API中的systemtime里面。</p>
<p align="justify" style="margin-left:28px; text-align:justify"> </p>
<p align="justify" style="margin-left:28px; text-align:justify"> </p>
<p>pool.ntp.org 这个时间服务器好用吗? 速度快吗?</p>
tagetage 发表于 2021-7-6 14:02
pool.ntp.org 这个时间服务器好用吗? 速度快吗?
<p>我是一个小白,我是10秒更新一次时间,还没有做到实时更新。这个服务器反正挺多人用来做做获取时间,应该速度还可以</p>
<p>10秒更新一次时间会被拒绝服务的,一般24小时更新一次就可以了。</p>
tagetage 发表于 2021-7-6 17:33
10秒更新一次时间会被拒绝服务的,一般24小时更新一次就可以了。
<p>这我还没了解到额,只是10秒之后重新获取时间</p>
页:
[1]