ESP32學(xué)習(xí)筆記(41)——SNTP接口使用

一、SNTP簡介

簡單網(wǎng)絡(luò)時間協(xié)議(Simple Network Time Protocol),由 NTP 改編而來爽撒,主要用來同步因特網(wǎng)中的計算機時鐘垮衷。

SNTP 協(xié)議是用來同步本地的時間到 unix 時間戳队腐。通常嵌入式設(shè)備上電哥童,連接 AP(access point),獲取 IP 地址后,就需要使用 SNTP 協(xié)議獲取全球時間任斋。以便于下一步的應(yīng)用交互和使用。
SNTP 工作原理比較簡單, 通俗來說耻涛,就是設(shè)備向 SNTP server 發(fā)送一包 SNTP 請求废酷,服務(wù)器收到請求后回復(fù)一包 SNTP reply。其中 SNTP reply 中就含有 unix 時間戳抹缕。

ESP-IDF 編程指南——SNTP 時間同步

二澈蟆、API說明

以下 SNTP 接口位于 lwip/include/apps/esp_sntp.h

2.1 sntp_setoperatingmode

2.2 sntp_setservername

2.3 sntp_set_time_sync_notification_cb

2.4 sntp_init

2.5 sntp_get_sync_status

三卓研、示例代碼

根據(jù) examples\protocols\sntp 中的例程修改

在 menuconfig 中配置 SSID 和密碼

核心部分:

//設(shè)置單播模式
sntp_setoperatingmode(SNTP_OPMODE_POLL);
//設(shè)置訪問服務(wù)器
sntp_setservername(0, "pool.ntp.org");
//初始化SNTP模塊
sntp_init();

完整代碼:

/* 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";

static void obtain_time(void);
static void initialize_sntp(void);

void time_sync_notification_cb(struct timeval *tv)
{
    ESP_LOGI(TAG, "Notification of a time synchronization event");
}

void app_main(void)
{
    time_t now;
    struct tm timeinfo;
    time(&now);
    localtime_r(&now, &timeinfo);
    // Is time set? If not, tm_year will be (1970 - 1900).
    if (timeinfo.tm_year < (2021 - 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);
    }

    char strftime_buf[64];

    while (1)
    {
        // update 'now' variable with current time
        time(&now);

        // 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 Shanghai is: %s", strftime_buf);

        vTaskDelay(10000 / portTICK_PERIOD_MS);
    }
}

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());

    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() );
}

static void initialize_sntp(void)
{
    ESP_LOGI(TAG, "Initializing SNTP");
    sntp_setoperatingmode(SNTP_OPMODE_POLL);
    sntp_setservername(0, "pool.ntp.org");
    sntp_set_time_sync_notification_cb(time_sync_notification_cb);
    sntp_init();
}

查看打优糠:


四、注意事項

  1. sntp_setservername 除了可以設(shè)置域名, 也可以設(shè)置 IP 地址, 例如 sntp_setservername(0, "120.25.115.20");
  2. 如果有必要, 請多設(shè)置幾個 SNTP server奏赘,防止某個 SNTP server 暫時關(guān)閉服務(wù)而導(dǎo)致產(chǎn)品部分功能無法使用, 例如:
sntp_setservername(0, "ntp1.aliyun.com");
sntp_setservername(1, "210.72.145.44");     // 國家授時中心服務(wù)器 IP 地址
sntp_setservername(2, "1.cn.pool.ntp.org");        

說明:
默認(rèn)情況下, ESP8266/ESP32 只允許開啟一個 SNTP server(節(jié)省資源考慮), 如果用戶需開啟多個 SNTP server, 請配置:

  • ESP8266 請在 make menuconfig -> Component config -> LWIP -> DHCP -> Maximum bumber of NTP servers 修改為 3
  • ESP32 請在 make menuconfig -> Component config -> LWIP -> SNTP -> Maximum bumber of NTP servers 修改為 3

配置多個 SNTP server 時, 不是同時發(fā)送多個 SNTP 請求報文, 而是輪循方式. 第一個處理超時后, 進(jìn)行和第二個 SNTP server 交互, 這樣依次進(jìn)行到最后一個, 最后一個處理超時后, 會再和第一個 SNTP server 交互

  1. 更新時間請求間隔SNTP_UPDATE_DELAY寥闪,到下一次發(fā)起更新時間請求的間隔時間,單位是ms磨淌,最小不能小于15s疲憋,也是通過make menuconfig修改CONFIG_LWIP_SNTP_UPDATE_DELAY
    在 make menuconfig -> Component config -> LWIP -> SNTP -> Request interval to update time (ms).
  1. 最好不在任何 callback 或中斷處理函數(shù)中調(diào)用 obtain_time(), callback/中斷中, 調(diào)用任何阻塞的 API, 理論上都有死鎖的可能.
  2. 任何有校驗服務(wù)器證書的 TLS 過程 (本地有 CA 證書), 請務(wù)必開啟 SNTP 功能, 否則會因為校驗服務(wù)器證書有效期失敗而導(dǎo)致 TLS 握手失敗
  3. NTP.ORG.cn中國NTP授時快速域名服務(wù)提供商
新加坡 sgp.ntp.org.cn 韓國 kr.ntp.org.cn
中國 cn.ntp.org.cn 中國教育網(wǎng) edu.ntp.org.cn
中國香港 hk.ntp.org.cn 中國臺灣 tw.ntp.org.cn
美國 us.ntp.org.cn 韓國 kr.ntp.org.cn
日本 jp.ntp.org.cn 德國 de.ntp.org.cn
印度尼西亞 ina.ntp.org.cn
  1. 時區(qū):
  • CST-8:這時區(qū)的表示有點混
    CST卻同時可以代表如下 4 個不同的時區(qū):
    Central Standard Time (USA) UT-6:00
    Central Standard Time (Australia) UT+9:30
    China Standard Time UT+8:00
    Cuba Standard Time UT-4:00
setenv("TZ", "CST-8", 1);
  • GMT:(Greenwich Mean Time)是格林尼治平時
    GMT+8正好是中國的標(biāo)準(zhǔn)時區(qū)
setenv("TZ", "GMT+8", 1);
  1. 在成功獲取了網(wǎng)絡(luò)時間后梁只,必須調(diào)用 sntp_stop(); 停止NTP請求柜某,不然設(shè)備重啟后會造成獲取網(wǎng)絡(luò)時間失敗的現(xiàn)象,大概是服務(wù)器時根據(jù)心跳時間來刪除客戶端的敛纲,如果不是stop結(jié)束的客戶端喂击,下次連接服務(wù)器時就會出錯

? 由 Leung 寫于 2021 年 7 月 30 日

? 參考:ESP8266/ESP32 基礎(chǔ)篇: 時間同步 SNTP 介紹和使用
    ESP32 SNTP配置
    ESP32的SDK開發(fā)之獲取SNTP網(wǎng)絡(luò)時間

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市淤翔,隨后出現(xiàn)的幾起案子翰绊,更是在濱河造成了極大的恐慌,老刑警劉巖旁壮,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件监嗜,死亡現(xiàn)場離奇詭異,居然都是意外死亡抡谐,警方通過查閱死者的電腦和手機裁奇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦撵,“玉大人刽肠,你說我怎么就攤上這事溃肪。” “怎么了音五?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵惫撰,是天一觀的道長。 經(jīng)常有香客問我躺涝,道長厨钻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任坚嗜,我火速辦了婚禮夯膀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苍蔬。我一直安慰自己诱建,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布银室。 她就那樣靜靜地躺著,像睡著了一般励翼。 火紅的嫁衣襯著肌膚如雪蜈敢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天汽抚,我揣著相機與錄音抓狭,去河邊找鬼。 笑死造烁,一個胖子當(dāng)著我的面吹牛否过,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惭蟋,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼苗桂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了告组?” 一聲冷哼從身側(cè)響起煤伟,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎木缝,沒想到半個月后便锨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡我碟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年放案,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矫俺。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡吱殉,死狀恐怖掸冤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情考婴,我是刑警寧澤贩虾,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站沥阱,受9級特大地震影響缎罢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜考杉,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一策精、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崇棠,春花似錦咽袜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萎坷,卻和暖如春凹联,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哆档。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工蔽挠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瓜浸。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓澳淑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親插佛。 傳聞我的和親對象是個殘疾皇子杠巡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容