一、SNTP簡介
簡單網絡時間協議(Simple Network Time Protocol),由 NTP 改編而來,主要用來同步因特網中的計算機時鐘。
SNTP 協議是用來同步本地的時間到 unix 時間戳。通常嵌入式設備上電,連接 AP(access point),獲取 IP 地址后,就需要使用 SNTP 協議獲取全球時間。以便于下一步的應用交互和使用。
SNTP 工作原理比較簡單, 通俗來說,就是設備向 SNTP server 發送一包 SNTP 請求,服務器收到請求后回復一包 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
三、示例代碼
根據 examplesprotocolssntp 中的例程修改
在 menuconfig 中配置 SSID 和密碼
核心部分:
//設置單播模式
sntp_setoperatingmode(SNTP_OPMODE_POLL);
//設置訪問服務器
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 #include #include #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(); } 查看打印: sntp_setservername 除了可以設置域名, 也可以設置 IP 地址, 例如 sntp_setservername(0, '120.25.115.20'); 如果有必要, 請多設置幾個 SNTP server,防止某個 SNTP server 暫時關閉服務而導致產品部分功能無法使用, 例如: sntp_setservername(0, 'ntp1.aliyun.com'); sntp_setservername(1, '210.72.145.44'); // 國家授時中心服務器 IP 地址 sntp_setservername(2, '1.cn.pool.ntp.org'); 說明: 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 時, 不是同時發送多個 SNTP 請求報文, 而是輪循方式. 第一個處理超時后, 進行和第二個 SNTP server 交互, 這樣依次進行到最后一個, 最后一個處理超時后, 會再和第一個 SNTP server 交互 更新時間請求間隔SNTP_UPDATE_DELAY,到下一次發起更新時間請求的間隔時間,單位是ms,最小不能小于15s,也是通過make menuconfig修改CONFIG_LWIP_SNTP_UPDATE_DELAY。 最好不在任何 callback 或中斷處理函數中調用 obtain_time(), callback/中斷中, 調用任何阻塞的 API, 理論上都有死鎖的可能. 任何有校驗服務器證書的 TLS 過程 (本地有 CA 證書), 請務必開啟 SNTP 功能, 否則會因為校驗服務器證書有效期失敗而導致 TLS 握手失敗 NTP.ORG.cn中國NTP授時快速域名服務提供商 時區: CST-8:這時區的表示有點混 GMT:(Greenwich Mean Time)是格林尼治平時 在成功獲取了網絡時間后,必須調用 sntp_stop(); 停止NTP請求,不然設備重啟后會造成獲取網絡時間失敗的現象,大概是服務器時根據心跳時間來刪除客戶端的,如果不是stop結束的客戶端,下次連接服務器時就會出錯四、注意事項
默認情況下, ESP8266/ESP32 只允許開啟一個 SNTP server(節省資源考慮), 如果用戶需開啟多個 SNTP server, 請配置:
在 make menuconfig -> Component config -> LWIP -> SNTP -> Request interval to update time (ms).新加坡 sgp.ntp.org.cn 韓國 kr.ntp.org.cn 中國 cn.ntp.org.cn 中國教育網 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
CST卻同時可以代表如下 4 個不同的時區:
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:00setenv('TZ', 'CST-8', 1);
GMT+8正好是中國的標準時區setenv('TZ', 'GMT+8', 1);
上一篇:ESP32學習筆記(42)——硬件定時器接口使用
下一篇:ESP32學習筆記(40)——Watchdog看門狗使用
設計資源 培訓 開發板 精華推薦
- NCP1729開關電容電壓逆變器的典型應用
- 朱飛龍 1810300339
- 使用 Broadcom Inc 的 HCPL-7850 的參考設計
- C841191_TPS54xxx系列DC-DC芯片方案驗證板
- LT1634AIS8-5 微功率電壓和電流基準的典型應用
- TWR-MC36XSDEVB: 嵌入式組件:36V塔式系統eXtreme開關模塊
- 使用 Richtek Technology Corporation 的 RT8280 的參考設計
- STM32F030R8T6最小系統
- DC1332B-C,用于 LTC2631ACTS8-HM12 的演示板,12 位 I2C DAC(4.096V 參考,復位至零電平)
- LT3091HFE 正輸出電流監視器的典型應用
- 芯原超低能耗NPU可為移動端大語言模型推理提供超40 TOPS算力
- 芯原AI-ISP芯片定制方案助力客戶智能手機量產出貨
- AI加持,安森美一站式服務推動助聽器市場持續進步
- 意法半導體推出用于匹配遠距離無線微控制器STM32WL33的集成的匹配濾波芯片
- 如何為您的應用選擇光傳感器
- Samtec新型農業漫談系列二 | 垂直農業案列分享
- Samtec應用科普 | C-V2X技術在汽車領域的應用
- 尼得科運動&能源事業本部在印度卡納塔克邦胡布利舉行新工廠竣工儀式
- 貿澤開售Qorvo適用于5G和mMIMO應用的新型QPA9822線性5G高增益/高驅動放大器
- 邊緣計算網關工業物聯網應用:空壓機遠程運維監控管理