首页 > 其他分享 >ESP32 SNTP校时

ESP32 SNTP校时

时间:2022-10-26 10:14:45浏览次数:75  
标签:wifi SNTP ESP32 WIFI esp TAG ESP 校时 event

一、连接WIFI

在进行时间同步之前,先连接WIFI

#include "wifi.h"

#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wpa2.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"


static wifi_status_t wifi_status = WIFI_STATUS_DEINIT;          // WIFI 默认为未初始化状态
static EventGroupHandle_t s_wifi_event_group;                   // WIFI 事件组
esp_event_handler_instance_t instance_any_id;                   // 注册事件处理程的标识
esp_event_handler_instance_t instance_got_ip;                   //

/* 事件组允许有多个事件标志位 */
static const int WIFI_STATUS_INIT_BIT = BIT0;                   // WIFI 初始化状态
static const int WIFI_STATUS_START_BIT = BIT1;                  // WIFI 启动状态
static const int WIFI_STATUS_SCAN_BIT = BIT3;                   // WIFI 扫描状态
static const int WIFI_STATUS_CONNECTED_BIT = BIT4;              // WIFI 连接状态

/* 需要连接的WIFI名称和密码 */
static wifi_sta_config_t cfg_sta = {
    .ssid = "test",
    .password = "test8888",
};

/* 互斥锁 */
SemaphoreHandle_t xWifiSemaphore;

static const char *TAG = "WIFI";

/**
 * @brief WIFI 事件
 * 
 * @param arg 
 * @param event_base 
 * @param event_id 
 * @param event_data 
 */
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    /* WIFI事件 */
    if (event_base == WIFI_EVENT)
    {
        switch (event_id)
        {
            /* WIFI 就绪 */
            case WIFI_EVENT_WIFI_READY:
                ESP_LOGI(TAG,"ESP32 WiFi ready");
                break;
            /* WIFI 扫描完成 */
            case WIFI_EVENT_SCAN_DONE:
                ESP_LOGI(TAG,"ESP32 finish scanning AP");
                xEventGroupSetBits(s_wifi_event_group, WIFI_STATUS_SCAN_BIT);      // 设置WIFI标志位为打开状态
                break;
            /* WIFI 启动 */
            case WIFI_EVENT_STA_START:
                ESP_LOGI(TAG,"ESP32 station start");
                xEventGroupSetBits(s_wifi_event_group, WIFI_STATUS_START_BIT);      // 设置WIFI标志位为打开状态
                wifi_status = WIFI_STATUS_START;                                    // 设置WIFI为打开状态
                break;
            /* WIFI 关闭 */
            case WIFI_EVENT_STA_STOP:
                ESP_LOGI(TAG,"ESP32 station stop");
                xEventGroupClearBits(s_wifi_event_group, WIFI_STATUS_START_BIT);    // 设置WIFI标志位为关闭状态
                wifi_status = WIFI_STATUS_STOP;                                     // 设置WIFI为关闭状态
                break;
            /* WIFI 连接成功 */
            case WIFI_EVENT_STA_CONNECTED:
                ESP_LOGI(TAG,"ESP32 station connected to AP");
                xEventGroupSetBits(s_wifi_event_group, WIFI_STATUS_CONNECTED_BIT);          // 设置WIFI标志位为关闭状态
                wifi_status = WIFI_STATUS_CONNECTED;                                        // 设置WIFI为关闭状态
                break;
            /* WIFI 断开连接 */
            case WIFI_EVENT_STA_DISCONNECTED:
                ESP_LOGI(TAG,"ESP32 station disconnected from AP");
                xEventGroupClearBits(s_wifi_event_group, WIFI_STATUS_CONNECTED_BIT);        // 设置WIFI标志位为关闭状态
                wifi_status = WIFI_STATUS_DISCONNECTED;                                     // 设置WIFI为关闭状态
                break;
            /* WIFI 接入点认证方式改变 */
            case WIFI_EVENT_STA_AUTHMODE_CHANGE:
                ESP_LOGI(TAG,"the auth mode of AP connected by ESP32 station changed");
                break;

            default:
                ESP_LOGI(TAG,"Other status");
                break;
        }
    }
    
    if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "Got IP: " IPSTR,  IP2STR(&event->ip_info.ip));
    }
}


/**
 * @brief WIFI 初始化
 * 
 */
void app_wifi_init(void)
{
    // 初始化 NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    /* 初始化底层TCP/IP堆栈 */
    ESP_ERROR_CHECK(esp_netif_init());

    s_wifi_event_group = xEventGroupCreate();                           // 创建新的事件组
    ESP_ERROR_CHECK(esp_event_loop_create_default());                   // 创建默认事件循环
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();       // 创建默认WIFI STA
    assert(sta_netif);

    /* 使用默认参数初始化WIFI */
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );

    /* 向默认循环注册事件处理程序 */
    ESP_ERROR_CHECK( esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, instance_any_id) );
    ESP_ERROR_CHECK( esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, instance_got_ip) );

    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );                // 设置WIFI模式

    xEventGroupSetBits(s_wifi_event_group, WIFI_STATUS_INIT_BIT);       // 设置WIFI标志位为初始化状态
    wifi_status = WIFI_STATUS_INIT;                                     // 设置WIFI状态为初始化状态
    xWifiSemaphore = xSemaphoreCreateMutex();                           // 创建互斥锁
}

void app_main(void)
{
    app_wifi_init();
    ESP_ERROR_CHECK( esp_wifi_start() );   // 启动WIFi

    /* 而直接将wifi_sta_config_t(或指针)转为wifi_config_t(或指针)是GCC的拓展语法,如下 */
    esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *) &cfg_sta);

    esp_wifi_connect();
}

二、时间同步

/**
 * @brief 同步时间完成后的回调函数
 * 
 * @param tv 
 */
void time_update_callback(struct timeval* tv) 
{
    /* 设置时区 */
    setenv("TZ", "CST-8", 1);
    tzset();
}

/**
 * @brief 在联网的情况下获取网络时间 
 * 
 */
static void get_network_time(void)
{
    /* 等待 WIFI 连接*/
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_STATUS_CONNECTED_BIT, pdFALSE, pdTRUE, portMAX_DELAY);

    /* SNTP校时 */
    sntp_setoperatingmode(SNTP_OPMODE_POLL);
    sntp_setservername(0, "ntp.aliyun.com");
    sntp_set_time_sync_notification_cb(time_update_callback);
    sntp_init();                                        // 启动校时 
}

注意:不使用sntp_set_time_sync_notification_cb()注册同步成功回调时,也可以使用sntp_get_sync_status()轮询检测同步是否完毕

三、获取系统时间

static struct tm timeinfo = {0};           // 时间寄存器
time_t now = 0;

time(&now);
localtime_r(&now, &timeinfo);

/* 打印获取到的时间 */
char str[64];
strftime(str, sizeof(str), "%c", &timeinfo);
ESP_LOGI(TAG, "time updated: %s", str);

ESP_LOGI(TAG, "%d%d:%d%d", timeinfo.tm_hour / 10, timeinfo.tm_hour % 10, timeinfo.tm_min / 10, timeinfo.tm_min % 10);
ESP_LOGI(TAG, "%d-%d-%d", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday);

switch (timeinfo.tm_wday)
{
case 0:
    ESP_LOGI(TAG, "星期日");
    break;
case 1:
    ESP_LOGI(TAG, "星期一");
    break;
case 2:
    ESP_LOGI(TAG, "星期二");
    break;
case 3:
    ESP_LOGI(TAG, "星期三");
    break;
case 4:
    ESP_LOGI(TAG, "星期四");
    break;
case 5:
    ESP_LOGI(TAG, "星期五");
    break;
case 6:
    ESP_LOGI(TAG, "星期六");
    break;
default:
    break;
}

参考文献

ESP32 之 ESP-IDF 教学(二十)—— SNTP校时:<https://blog.csdn.net/m0_50064262/article/details/126690030

标签:wifi,SNTP,ESP32,WIFI,esp,TAG,ESP,校时,event
From: https://www.cnblogs.com/jzcn/p/16827218.html

相关文章

  • ESP32 IDF 获取天气信息
    一、注册天气获取账号我使用的知心天气,没有获取天气账号的小伙伴可以去注册一下,知心天气官网:https://www.seniverse.com/取得天气获取的API后,可以直接在浏览器中访问测试......
  • esp32-s3-st7796-lvgl8
    1、先按照文档步骤,将基础框架搭建好https://blog.csdn.net/qq_20540901/article/details/1236086552、然后遇到一些花屏、显示不正确等等问题,使用以下的sdkconfig创建默......
  • 基于乐鑫ESP32-C3的2.4寸串口屏应用于智能体脂秤方案
    由于长期不合理饮食习惯的影响,我国肥胖人口数目不断增多,然而随着大众健康意识不断提升,减肥、健身人士增多,全民健身的时代已经到来,这无疑将带动智能体脂秤市场需求的攀升。......
  • esp32把玩记-④ 星星点灯 (点亮led)
    注意全程使用Micropython,不会安装看我第一篇文章感谢正式开始用Thonny烧录(运行)以下代码importtimefrommachineimportPinled=Pin(13,Pin.OUT)led.on()由......
  • 2022-08-12-esp32把玩记-②_用Micropython点ssd1306_oled屏幕
    layout:postcid:8title:esp32把玩记-②用Micropython点ssd1306oled屏幕slug:8date:2022/08/1215:12:39updated:2022/08/1215:12:39status:publishautho......
  • 2022-08-08-esp32把玩记-①
    layout:postcid:4title:esp32把玩记-①slug:4date:2022/08/0814:59:58updated:2022/08/0814:59:58status:publishauthor:admincategories:默认分类t......
  • ESP32 分区表
    当你编译程序,发现apppartitionistoosmallforbinary错误的时候,就涉及到ESP32分区表的内容了。一、基本概念在了解分区之前,先了解一下以下概率,便于ESPe32分区......
  • ESP32模拟鼠标键盘
     淘宝产品https://item.taobao.com/item.htm?spm=a230r.1.14.26.283812desb4ou0&id=669444818599&ns=1&abbucket=5#detail   硬件手册https://docs.qq.com/doc/......
  • esp32-lvgl-ST7796+GT911
    1、st7789在lvgl配置菜单中使用ILI9481的驱动,如果使用st7789的驱动会出现显示颜色不正确,用ili9481的就可以2、gt911的驱动文件需要修改,修改gt911.c文件中60行,取消错误后的......
  • ESP32开发环境搭建 IDF3.3.5+VScode
    1、 软件准备:①ESP-IDF:包含ESP32API和用于操作工具链的脚本。②工具链msys32:用于编译ESP32应用程序。③编辑工具VisualStudioCode  注意:工具链和ESP-IDF需......