本次 ESP32-S3 开发实操聚焦WIFI 组件快速集成、网络时间同步校准、心知天气数据对接三大核心功能,基于前期 GUI 界面开发基础,实现了 “WIFI 连接 - 时间同步 - 数据可视化” 的完整链路。以下为详细实操流程、关键注意事项及项目开发思考,兼顾实操性与可复用性,方便技术复盘与同类型开发参考。

一、WIFI 组件创建与基础网络连接

WIFI 组件是 ESP32-S3 实现网络通信的核心,本次通过模块化开发创建独立 WIFI 组件,快速实现与 2.4GHz 移动热点的连接,为后续时间同步、天气数据请求奠定网络基础,具体步骤如下:

1. 组件核心文件配置

(1)wifi.h文件编辑:配置热点信息

核心修改网络账号与密码,需与电脑创建的 2.4GHz 移动热点信息完全一致,同时声明 WIFI 初始化函数,供主程序调用:

热点信息查询方法:在电脑 “网络设置” 中找到创建的移动热点,确认热点名称、密码及频段(必须为 2.4GHz,不支持 5GHz)。

(2)wifi.c文件实现:核心连接逻辑

该文件已封装 WIFI 事件处理、网络初始化、STA 模式配置等核心逻辑(参考前期 WIFI 开发基础代码),无需额外修改,确保调用Wifi_STA_Init()即可自动完成热点连接、断连重连等功能。

2. 主程序(main.c)集成 WIFI 组件

在原有 GUI 界面开发代码基础上,添加 WIFI 组件头文件引用和初始化函数调用,实现 “GUI 界面启动 + WIFI 自动连接” 的联动效果:

#include <stdio.h>
#include <inttypes.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "LCD/lcd.h"
#include "demos/lv_demos.h"
#include "timer.h"
#include "gui_guider.h"
#include "custom.h"
// 引入WIFI组件头文件
#include "wifi.h"

lv_ui guider_ui;

void app_main(void)
{
    // 底层硬件初始化:I2C总线、IO扩展芯片
    bsp_i2c_init();
    pca9557_init();
    // 启动LVGL图形库,初始化GUI界面
    bsp_lvgl_start();
    setup_ui(&guider_ui);
    custom_init(&guider_ui);
    // 初始化WIFI组件,自动连接2.4GHz热点
    Wifi_STA_Init();

    // 死循环维持程序运行,保证GUI界面和WIFI连接持续生效
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

工程配置文件(CMakeLists.txt)修改

添加 WIFI 组件的源文件和头文件目录,确保编译时能识别 WIFI 相关代码,同时保留原有 GUI、LCD 等组件的配置:

# 递归查找所有.c源文件
file(GLOB_RECURSE SOURCES ./*.c )

set(C_FILE "hello_world_main.c")
# 包含所有组件的头文件目录,新增WIFI目录
set(INCLUDE_DIRS "." 
        "LCD"
        "TIMER"
        "./ui/generated"
        "./ui/custom"
        "./ui/generated/guider_customer_fonts"
        "WIFI"  # WIFI组件头文件目录
)

idf_component_register(SRCS ${SOURCES} ${C_FILE}
                INCLUDE_DIRS ${INCLUDE_DIRS}
                # 根据需求启用依赖,如esp_wifi、esp_event等
                REQUIRES esp_wifi esp_event nvs_flash
                )

编译烧录与连接验证

  1. 执行编译(idf.py build)和烧录(idf.py flash)命令,确保无编译报错;
  2. 烧录完成后,打开电脑移动热点的 “已连接设备” 列表,若能看到名为ESP32-S3-XXXXX(基于 MAC 地址生成)的设备,即说明 WIFI 连接成功;
  3. 同时可通过串口终端查看连接日志,确认是否获取 IP 地址,进一步验证连接状态。

WIFI 组件创建关键注意事项

  1. 频段限制:ESP32-S3 本次开发仅支持 2.4GHz 热点,若连接失败,先检查热点频段是否为 5GHz,需切换为 2.4GHz 后重试;
  2. 热点信息一致性wifi.h中配置的 SSID 和密码必须与实际热点完全一致(区分大小写、特殊字符),否则会导致连接超时;
  3. 头文件与目录CMakeLists.txt必须添加 “WIFI” 头文件目录,且main.c正确引入wifi.h,否则会出现 “函数未声明”“头文件未找到” 的编译报错;
  4. 依赖配置REQUIRES中需添加esp_wifiesp_eventnvs_flash等核心依赖,确保 WIFI 相关库正常加载。
  5. 最后在移动热点看到你的esp就说明连上了

二、网络时间同步:基于网络校准实时时间并显示

在 WIFI 连接成功的基础上,通过网络获取标准时间,实现 ESP32-S3 的时间同步,并将实时时间显示在 GUI 界面的标签组件上,具体实现如下:

1. 主程序(main.c)代码修改

新增网络时间初始化函数调用和时间刷新逻辑,实现 “每秒更新一次时间” 并同步到 GUI 界面:

#include <stdio.h>
#include <inttypes.h>
#include <time.h>  // 时间相关头文件
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "LCD/lcd.h"
#include "demos/lv_demos.h"
#include "timer.h"
#include "gui_guider.h"
#include "custom.h"
#include "wifi.h"

lv_ui guider_ui;
time_t timer_sec;  // 存储当前秒数
struct tm timeinfo;  // 存储时间结构体

void app_main(void)
{
    // 底层硬件初始化
    bsp_i2c_init();
    pca9557_init();
    // 启动LVGL并初始化GUI界面
    bsp_lvgl_start();
    setup_ui(&guider_ui);
    custom_init(&guider_ui);
    // 连接WIFI网络
    Wifi_STA_Init();
    // 延时1秒,确保WIFI完全连接后再初始化网络时间
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    // 初始化网络时间(该函数需提前实现,负责从网络获取标准时间)
    ESP_Network_Init();
    // 记录初始秒数
    uint32_t sec = timer_sec;

    // 循环刷新时间并更新到GUI界面
    while(1)
    {
        // 获取当前时间戳
        timer_sec = time(NULL);
        // 每秒更新一次时间
        if(sec != timer_sec)
        {
            sec = timer_sec;
            // 将时间戳转换为本地时间结构体
            timeinfo = *localtime(&timer_sec);
            // 格式化时间为"时:分:秒"格式
            char str[20]={0};
            sprintf(str,"%02d:%02d:%02d",timeinfo.tm_hour,timeinfo.tm_min,timeinfo.tm_sec);
            // 锁定LVGL,避免多线程冲突,更新标签文本
            lvgl_port_lock(-1);
            lv_label_set_text(guider_ui.screen_label_1, str);  // screen_label_1为GUI界面时间显示标签
            lvgl_port_unlock();
            // 串口打印时间,便于调试
            printf("%s\n", str);
        }
        // 延时10ms,释放CPU资源
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}

网络时间同步关键注意事项

  1. 初始化顺序:必须先调用Wifi_STA_Init()完成 WIFI 连接,再执行ESP_Network_Init(),否则会因无网络导致时间获取失败;
  2. 延时等待:WIFI 连接后需添加 1 秒延时,确保网络稳定后再请求时间,避免因网络未就绪导致同步失败;
  3. LVGL 线程安全:更新 GUI 标签文本时,必须通过lvgl_port_lock()lvgl_port_unlock()锁定 / 解锁 LVGL,避免多线程操作导致界面卡顿或崩溃;
  4. 时间格式sprintf格式化时间时使用%02d确保位数统一(如 1 分钟显示为 “01”),提升界面显示美观度;
  5. 依赖头文件:需引入<time.h>头文件,否则time()localtime()等时间函数无法使用。

3. 效果验证

编译烧录后,ESP32-S3 板载 LCD 的screen_label_1标签会每秒更新一次实时时间,串口终端同步打印时间信息,实现网络时间的实时同步与可视化。

三、心知天气功能:对接 API 实现天气数据获取

在 WIFI 和时间同步功能基础上,进一步对接心知天气 API,获取指定城市的天气数据,核心需完成wifi.h文件的参数配置,具体操作如下:

1. wifi.h文件参数修改

新增心知天气 API 相关配置,核心修改热点信息、城市、私钥三大参数,其中私钥(UserKey)为必填项,具体配置如下:

#ifndef _WIFI_H_
#define _WIFI_H_

#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_http_client.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_mac.h"
#include <string.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "cJSON.h"

// 1. 修改为自己的2.4GHz热点信息
#define WiFi_STA_SSID "你的热点名称"
#define WiFi_STA_PASSWORD "你的热点密码"

// 2. 心知天气API配置(核心修改项)
#define TAG         "WIFI -> "
#define UserKey     "你的心知天气私钥"  // 必须替换为个人私钥
#define Location    "目标城市"          // 如"nanning"(南宁)、"beijing"(北京)
#define Language    "zh-Hans"          // 中文显示
#define Strat       "0"                // 从今天开始
#define Days        "3"                // 获取未来3天天气

// 天气数据结构体(存储解析后的天气信息)
typedef struct{
    char date[20];  // 日期
    char temp[20];  // 高低温
    char humi[20];  // 湿度
    char rain[20];  // 天气状况
    int code;       // 天气编码(对应天气图片)
}WEATHER_Type;
extern WEATHER_Type weather[3];

// 函数声明
void Wifi_STA_Init(void);
void Wifi_GLM_Init(void);

#endif

心知天气私钥获取方法

  1. 登录心知天气官网(https://www.seniverse.com/),注册账号并完成实名认证;
  2. 进入官网控制台,申请 “免费版” 天气产品,成功后即可查看个人私钥(UserKey);
  3. 私钥需妥善保存,不可泄露,否则可能导致 API 请求被滥用。

3. 心知天气功能关键注意事项

  1. 私钥有效性:必须使用个人注册的有效私钥,否则 API 请求会被服务端拒绝,返回 “权限不足” 错误;
  2. 城市参数格式Location参数需使用拼音(如 “guangzhou”),不可直接输入中文(如 “广州”),否则无法获取数据;
  3. 依赖补充:需在CMakeLists.txt中添加json依赖,支持 cJSON 库解析天气 API 返回的 JSON 数据;
  4. 数据可视化:解析后的天气数据(日期、温湿度、天气状况)可通过 GUI 界面的标签组件显示,天气编码可匹配对应的天气图片,实现 “文字 + 图片” 的可视化效果(参考前期天气图片联动开发逻辑)。

四、项目开发思考与总结

本次实操基于前期 GUI 界面开发基础,快速集成了 WIFI 组件、网络时间同步、心知天气对接三大核心功能,实现了 ESP32-S3 从 “单机运行” 到 “网络互联” 的升级,结合开发过程与嵌入式项目实际需求,形成以下思考与总结:

1. 本次实操核心技术收获

  1. 掌握了 ESP32-S3 模块化组件开发的方法,通过创建独立 WIFI 组件,实现代码的复用与维护,该思路可迁移到传感器、外设驱动等其他功能开发中;
  2. 学会了在已有项目中快速集成新功能的技巧,如在 GUI 项目中添加 WIFI 连接、时间同步,无需重构原有代码,仅需新增头文件引用、初始化函数调用和工程配置;
  3. 理解了 “网络 - 数据 - 可视化” 的完整开发链路,从 WIFI 连接建立网络通道,到网络时间、天气数据的获取,再到 GUI 界面的实时显示,形成闭环开发逻辑;
  4. 积累了嵌入式网络开发的细节处理经验,如 WIFI 连接后的延时等待、LVGL 线程安全、API 参数格式校验等,规避了常见的开发坑。

2. 项目开发关键思考

  1. 模块化与低耦合:将 WIFI、时间同步、天气功能拆分为独立模块,模块间通过全局变量或函数接口传递数据,降低代码耦合度,便于后续功能拓展(如新增多城市天气切换、时间格式自定义);
  2. 用户体验优化:网络时间同步时添加延时等待、时间显示位数统一、WIFI 断连自动重连等细节处理,提升设备的稳定性和用户体验,这是嵌入式产品开发的核心考量;
  3. 参数配置灵活性:将热点信息、城市、私钥等易变参数通过宏定义集中管理,修改时无需改动核心逻辑代码,仅需更新宏定义,提升项目的可维护性;
  4. 功能优先级设计:主程序中先初始化硬件和 GUI 界面,再启动 WIFI 和网络功能,确保用户先看到界面反馈,再等待网络数据加载,符合嵌入式设备 “先交互后数据” 的设计逻辑。

3. 后续优化方向

  1. WIFI 连接状态可视化:在 GUI 界面添加 WIFI 连接状态图标(如连接成功显示绿色图标、断开显示红色图标),让用户直观了解网络状态;
  2. 天气数据缓存与更新:将获取的天气数据缓存到 NVS 闪存,即使网络断连也能显示历史数据;设置定时更新(如每小时请求一次),避免频繁请求 API 导致限流;
  3. 错误处理强化:为网络时间同步、天气 API 请求添加错误处理逻辑(如请求失败后重试 3 次,仍失败则在界面显示 “数据获取失败”),提升设备的鲁棒性;

4. 实操最终效果

本次实操完成后,ESP32-S3 开发板可实现以下功能:

  1. 上电后自动初始化 GUI 界面,同时连接指定 2.4GHz 移动热点,电脑热点列表可识别设备;
  2. WIFI 连接成功后,自动同步网络时间,GUI 界面标签每秒更新一次实时时间,串口终端同步打印;
Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐