① 开发板型号:ESP32-WROOM-32
①初始化WiFi —> ② 创建获取时间任务 —>③ 在任务中循环获取时间
使用VSCODE创建项目,参考很多个教程初始化 WiFi 有几个教程是基于 ESP-IDF 4.4 CMD 环境配置的,这个会导致初始化WiFi有函数找不到,在B站找到一个教程视频,找到了源码,对应配置就没有问题了,B站网站如下:
获取B站教程源码
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
#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
#include "ntp_time.h"
#include
#include
#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
#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.org.cn"); // 设置访问服务器
sntp_setservername(1, "ntp1.aliyun.com");
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
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include
#include "freertos/event_groups.h"
#include "esp_log.h"
#include "esp_err.h"
#include
#include
#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);
}
}