admin管理员组

文章数量:1619733

1.硬件设计

① 开发板型号:ESP32-WROOM-32

2.软件设计

2.1 软件逻辑

①初始化WiFi —> ② 创建获取时间任务 —>③ 在任务中循环获取时间

2.2 学习中遇到的问题

使用VSCODE创建项目,参考很多个教程初始化 WiFi 有几个教程是基于 ESP-IDF 4.4 CMD 环境配置的,这个会导致初始化WiFi有函数找不到,在B站找到一个教程视频,找到了源码,对应配置就没有问题了,B站网站如下:
获取B站教程源码

2.3 配置操作过程

1.创建两个组件分别:WiFi组件和获取时间组件
创建方式: Ctrl+Shift+p

创建wifi组件和ntp_time两个组件,

2.初始化wifi,完整的wifi.c和wifi.h文件,一定要修改下面自己的wifi名称和密码

#define WIFI_SSID       "OnePlus 9" //修改为自己的wifi名称
#define WIFI_PASSWORD   "12345654321" //修改为自己的wifi密码

如下:

#ifndef __WIFI_H
#define __WIFI_H
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "nvs_flash.h"

#define WIFI_SSID       "OnePlus 9" //修改为自己的wifi名称
#define WIFI_PASSWORD   "12345654321" //修改为自己的wifi密码

void wifi_init(void);
void wifi_start(void);
void wifi_stop(void);

#endif // DEBUG
#include <stdio.h>
#include "wifi.h"
static const char *TAG = "scan";
uint16_t wifi_ip_addr[4];
bool wifi_ip_got_state;

static void wifi_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_CONNECTED)
    {
        ESP_LOGI(TAG, "CONNECTED");
        wifi_ip_got_state = false;
    }
    else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        ESP_LOGI(TAG, "DISCONNECTED:");
        wifi_ip_got_state = false;
        esp_wifi_connect();
    }
    else 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;
  
        wifi_ip_addr[0] = esp_ip4_addr1_16(&event->ip_info.ip);
        wifi_ip_addr[1] = esp_ip4_addr2_16(&event->ip_info.ip);
        wifi_ip_addr[2] = esp_ip4_addr3_16(&event->ip_info.ip);
        wifi_ip_addr[3] = esp_ip4_addr4_16(&event->ip_info.ip);
        wifi_ip_got_state = true;
        ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP: %d.%d.%d.%d", wifi_ip_addr[0], wifi_ip_addr[1], wifi_ip_addr[2], wifi_ip_addr[3]);
    }
}

void wifi_init(void)
{
    esp_err_t ret = nvs_flash_init();
    if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    ESP_ERROR_CHECK(esp_netif_init());                      
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();  
    
    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, 
                                                        NULL));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                        IP_EVENT_STA_GOT_IP,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        NULL));     
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PASSWORD,              
            .scan_method = WIFI_FAST_SCAN,                  
            .sort_method = WIFI_CONNECT_AP_BY_SECURITY,     
            .threshold.rssi = -127,                         
            .threshold.authmode = WIFI_AUTH_OPEN            
        },
    };   
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
    esp_wifi_start(); 
    esp_wifi_stop();  
}
void wifi_start(void)
{
    esp_wifi_start();
    esp_wifi_connect(); 
}
void wifi_stop(void)
{
    esp_wifi_stop();
}

3.获取网络时间 ntp_time.h 和 ntp_time.c 如下:

#include <stdio.h>
#include "ntp_time.h"
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
#include <sys/time.h>
#include "esp_sntp.h"
static const char *TAG = "ntp";
static struct tm timeinfo;
static void esp_initialize_sntp(void)
{
    sntp_setoperatingmode(SNTP_OPMODE_POLL);    // 设置单播模式
    sntp_setservername(0, "cn.ntp");	    // 设置访问服务器
    sntp_setservername(1, "ntp1.aliyun");
    sntp_setservername(2, "210.72.145.44");     // 国家授时中心服务器 IP 地址
    setenv("TZ", "CST-8", 1);                   //东八区
    sntp_init();                                //初始化
}

/**
 * @brief 启动sntp获取网络时间
 * @param 无
 * @return 无
 * @note tm_mon: 从0开始            tm_year: 距离1900年的差值,默认是70
 *       tm_yday: 一年的过去的天数   tm_isdst: 是否为夏时制
 */
void sntp_task(void *param)
{
    time_t now;
    esp_initialize_sntp();
    // 延时等待SNTP初始化完成
    do {
        vTaskDelay(100 / portTICK_PERIOD_MS);
    } while (sntp_get_sync_status() == SNTP_SYNC_STATUS_RESET);

    // 成功获取网络时间后停止NTP请求,不然设备重启后会造成获取网络时间失败的现象
    // 大概是服务器时根据心跳时间来删除客户端的,如果不是stop结束的客户端,下次连接服务器时就会出错
	sntp_stop();
    while(1)
    {
        time(&now);                         // 获取网络时间, 64bit的秒计数 
        tzset();                            // 更新本地C库时间
        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);
        ESP_LOGI(TAG, "%4d-%02d-%02d %02d:%02d:%02d week:%d", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, 
        timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_wday); 
        vTaskDelay(1000 / portTICK_PERIOD_MS);   
    }
}
struct tm* get_time(void)
{
    return &timeinfo;
}

ntp_time.h如下:

#ifndef __NTP_TIME_H
#define __NTP_TIME_H

void sntp_task(void *param);
struct tm* get_time(void);

#endif 

main.c 文件如下:

#include <stdio.h>
#include <errno.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <errno.h>
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_err.h"
#include <string.h>
#include <stdlib.h>
#include "wifi.h"
#include "ntp_time.h"

void app_main(void)
{
    int cnt = 0;
    wifi_init();
    wifi_start();
    vTaskDelay(10000 / portTICK_PERIOD_MS);
    xTaskCreatePinnedToCore(sntp_task, "sntp_task", 2048, NULL, 1, NULL, 0);
    vTaskDelay(5000 / portTICK_PERIOD_MS);
    //wifi_stop();
    while (1)
    {
        //led_prog();
        printf("cnt: %d\n", cnt);
        //ledc_prog();
        //key_prog();
        vTaskDelay(10000 / portTICK_PERIOD_MS);
    }
}

测试结果

串口打印如下:

本文标签: 入门时间网络wifi