ESP32-C3 ESP-IDF 配置smartconfig 和 sntp 获取网络时间

本文介绍ESP32-C3使用ESP-IDF进行智能配置(smartconfig)和简单网络时间协议(SNTP)获取网络时间的过程。通过智能配置实现无线网络连接,并利用SNTP同步设备时间。

ESP32-C3 ESP-IDF 配置smartconfig 和 sntp 获取网络时间

/* Esptouch 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 <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.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"
#include "esp_smartconfig.h"
#include "protocol_examples_common.h"

#include "esp_sntp.h"
#include "driver/gpio.h"
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t s_wifi_event_group;
#define LED1 10 //定义LED1 PIN

/* 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.
 */


static void init_gpio(void);
static void obtain_time(void);
static void initialize_sntp(void);
/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "smartconfig_example";

static void smartconfig_example_task(void *parm);

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

static void event_handler(void *arg, esp_event_base_t event_base,
                          int32_t event_id, void *event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        esp_wifi_connect();
        xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE)
    {
        ESP_LOGI(TAG, "Scan done");
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL)
    {
        ESP_LOGI(TAG, "Found channel");
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD)
    {
        ESP_LOGI(TAG, "Got SSID and password");

        smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
        wifi_config_t wifi_config;
        uint8_t ssid[33] = {0};
        uint8_t password[65] = {0};
        uint8_t rvd_data[33] = {0};

        bzero(&wifi_config, sizeof(wifi_config_t));
        memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
        memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
        wifi_config.sta.bssid_set = evt->bssid_set;
        if (wifi_config.sta.bssid_set == true)
        {
            memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
        }

        memcpy(ssid, evt->ssid, sizeof(evt->ssid));
        memcpy(password, evt->password, sizeof(evt->password));
        ESP_LOGI(TAG, "SSID:%s", ssid);
        ESP_LOGI(TAG, "PASSWORD:%s", password);
        if (evt->type == SC_TYPE_ESPTOUCH_V2)
        {
            ESP_ERROR_CHECK(esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)));
            ESP_LOGI(TAG, "RVD_DATA:");
            for (int i = 0; i < 33; i++)
            {
                printf("%02x ", rvd_data[i]);
            }
            printf("\n");
        }

        ESP_ERROR_CHECK(esp_wifi_disconnect());
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
        esp_wifi_connect();
    }
    else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE)
    {
        xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
    }
}

static void initialise_wifi(void)
{
    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();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
}

static void smartconfig_example_task(void *parm)
{
    EventBits_t uxBits;
    ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH));
    smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_smartconfig_start(&cfg));
    while (1)
    {
        uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
        if (uxBits & CONNECTED_BIT)
        {
            ESP_LOGI(TAG, "WiFi Connected to ap");
        }
        if (uxBits & ESPTOUCH_DONE_BIT)
        {
            ESP_LOGI(TAG, "smartconfig over");
            esp_smartconfig_stop();
            vTaskDelete(NULL);
        }
    }
}

void app_main(void)
{
    int i=0;
    time_t now;         //定义一个now 存放unix 时间戳
    struct tm timeinfo; //定义tm时间结构体,具体百度c标准库的time定义
        /******************************************************
            int tm_sec;         秒,范围从 0 到 59
            int tm_min;         分,范围从 0 到 59
            int tm_hour;        小时,范围从 0 到 23
            int tm_mday;       一月中的第几天,范围从 1 到 31
            int tm_mon;         月份,范围从 0 到 11
            int tm_year;        注意是自 1900 起的年数
            int tm_wday;      一周中的第几天,范围从 0 到 6
            int tm_yday;        一年中的第几天,范围从 0 到 365
            int tm_isdst;       夏令时
    ************************************************************/
    ESP_ERROR_CHECK(nvs_flash_init());//nvsflash初始化
    initialise_wifi();               //初始化wifi
    obtain_time();                //获取时间
    time(&now);                   //获取总秒数时间
    localtime_r(&now, &timeinfo); //将now unix时间戳格式转为timeinfo时间结构体
    init_gpio();                  //初始化GPIO
    while (1)
    {
        i++;
        gpio_set_level(LED1,i%2);//flash led
    // Is time set? If not, tm_year will be (1970 - 1900).
    if (timeinfo.tm_year < (2016 - 1900)) //判断timeinfo是否正确否者重新获取
    {
        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); //获取总秒数时间
    }
        time(&now);//获取unix时间戳
        setenv("TZ", "CST-8", 1);//设置为东八区,中国是东八区
        tzset();
        localtime_r(&now, &timeinfo);//转为tm结构体
        ESP_LOGI(TAG, "实时时间:周%d,%d年:%d月:%d日,%d:%d:%d", timeinfo.tm_wday, timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        //vTaskDelay(1000 / 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(500 / portTICK_PERIOD_MS);
    }
    time(&now);
    localtime_r(&now, &timeinfo);

   //  ESP_ERROR_CHECK(example_disconnect());
}

static void initialize_sntp(void)
{
    ESP_LOGI(TAG, "Initializing SNTP");
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    sntp_stop();//不加这段ntp会报错
    sntp_enabled();//不加这段ntp会报错
    sntp_setoperatingmode(SNTP_OPMODE_POLL);
    sntp_setservername(0, "pool.ntp.org");
    sntp_setservername(3, "cn.pool.ntp.org"); // 中国区NTP服务的虚拟集群
    sntp_setservername(1, "210.72.145.44"); // 国家授时中心服务器 IP 地址
    sntp_setservername(2, "ntp1.aliyun.com");
    sntp_init();
}

static void init_gpio(void)
{
    gpio_set_direction(LED1, GPIO_MODE_OUTPUT);
}

串口打印日志:

Waiting for the device to reconnect...............................................
I (116518) smartconfig_example: Initializing SNTP
I (117518) smartconfig_example: Waiting for system time to be set... (1/10)
I (118018) smartconfig_example: Waiting for system time to be set... (2/10)
I (118518) smartconfig_example: Waiting for system time to be set... (3/10)
I (119018) smartconfig_example: Waiting for system time to be set... (4/10)
I (119518) smartconfig_example: Waiting for system time to be set... (5/10)
I (120018) smartconfig_example: Waiting for system time to be set... (6/10)
I (120518) smartconfig_example: Waiting for system time to be set... (7/10)
I (121018) smartconfig_example: Waiting for system time to be set... (8/10)
I (121518) smartconfig_example: Waiting for system time to be set... (9/10)
I (122018) smartconfig_example: 实时时间:周4,1970年:1月:1日,8:2:1
I (123018) smartconfig_example: Time is not set yet. Connecting to WiFi and getting time over NTP.
I (123018) smartconfig_example: Initializing SNTP
I (124018) smartconfig_example: Waiting for system time to be set... (1/10)
I (124518) smartconfig_example: Waiting for system time to be set... (2/10)
I (125018) smartconfig_example: Waiting for system time to be set... (3/10)
I (125518) smartconfig_example: Waiting for system time to be set... (4/10)
I (126018) smartconfig_example: Waiting for system time to be set... (5/10)
I (126398) smartconfig: TYPE: ESPTOUCH
I (126398) smartconfig: T|AP MAC: 34:2e:b6:63:12:f0
I (126398) smartconfig: Found channel on 1-0. Start to get ssid and password...
I (126408) smartconfig_example: Found channel
I (126518) smartconfig_example: Waiting for system time to be set... (6/10)
I (127018) smartconfig_example: Waiting for system time to be set... (7/10)
I (127518) smartconfig_example: Waiting for system time to be set... (8/10)
I (127918) smartconfig: T|pswd: TPlink@123
I (127918) smartconfig: T|ssid: TP-LINK_B
I (127918) wifi:ic_disable_sniffer
I (127918) smartconfig_example: Got SSID and password
I (127918) smartconfig_example: SSID:TP-LINK_B
I (127928) smartconfig_example: PASSWORD:TPlink@123
I (127938) wifi:new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:1
I (127938) wifi:state: init -> auth (b0)
I (127948) wifi:state: auth -> assoc (0)
I (127958) wifi:state: assoc -> run (10)
I (127968) wifi:connected with LR-LINK_B, aid = 101, channel 1, BW20, bssid = 34:2e:b6:63:12:f0
I (127978) wifi:security: WPA2-PSK, phy: bgn, rssi: -58
I (127978) wifi:pm start, type: 1

I (127978) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 0, mt_pti: 25000, mt_time: 10000
I (127998) wifi:BcnInt:102400, DTIM:1
I (128018) smartconfig_example: Waiting for system time to be set... (9/10)
I (128518) smartconfig_example: 实时时间:周4,1970年:1月:1日,8:2:8
I (128858) esp_netif_handlers: sta ip: 192.168.11.188, mask: 255.255.255.0, gw: 192.168.11.1
I (128858) smartconfig_example: WiFi Connected to ap
I (129518) smartconfig_example: Time is not set yet. Connecting to WiFi and getting time over NTP.
I (129518) smartconfig_example: Initializing SNTP
I (130518) smartconfig_example: Waiting for system time to be set... (1/10)
I (131018) smartconfig_example: Waiting for system time to be set... (2/10)
I (131518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:51
I (131928) smartconfig_example: smartconfig over
I (132518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:52
I (133518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:53
I (134518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:54
I (135518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:55
I (136518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:56
I (137518) smartconfig_example: 实时时间:周3,2022年:5月:25日,20:36:57

在这里插入图片描述

吐槽下安信可居然拿rev2样品阶段的芯片来卖。esp32c3 版本rev2 是样品版,rev3才是量产的。

rev2官方放弃支持了。兼容性奇差无比不能用arduino和platformio

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoqi976633690

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值