4. 开关切换WiFi

任务目标

在ESP32上使用LVGL的开关(Switch)控件控制WiFi的连接与断开,并通过标签实时显示当前网络状态。拨动开关开启WiFi连接,关闭则断开连接。

环境依赖

  • ESP32开发板(推荐ESP32-WROOM-32)
  • LVGL v8.x(已移植至ESP32,显示驱动与触摸/输入设备已初始化)
  • Arduino-ESP32 或 ESP-IDF(本案例使用Arduino框架,便于快速验证)

核心实现

代码创建了一个LVGL开关控件和一个状态标签。开关回调函数中根据开关状态调用WiFi连接或断开API,并同步更新标签文字。WiFi连接状态通过事件标志或轮询方式反馈到UI。

#include <WiFi.h>
#include <lvgl.h>

// WiFi配置
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";

// UI对象
static lv_obj_t* wifi_switch;
static lv_obj_t* status_label;

// 状态标志
static bool wifi_connected = false;

// 更新状态标签
static void update_status_label(void) {
    if (wifi_connected) {
        lv_label_set_text(status_label, "WiFi: Connected");
        lv_obj_set_style_text_color(status_label, lv_palette_main(LV_PALETTE_GREEN), 0);
    } else {
        lv_label_set_text(status_label, "WiFi: Disconnected");
        lv_obj_set_style_text_color(status_label, lv_palette_main(LV_PALETTE_RED), 0);
    }
}

// 开关事件回调
static void switch_event_cb(lv_event_t* e) {
    lv_obj_t* sw = lv_event_get_target(e);
    bool is_on = lv_obj_has_state(sw, LV_STATE_CHECKED);

    if (is_on) {
        // 开启WiFi连接
        WiFi.begin(ssid, password);
        lv_label_set_text(status_label, "Connecting...");
        lv_obj_set_style_text_color(status_label, lv_palette_main(LV_PALETTE_ORANGE), 0);
    } else {
        // 断开WiFi
        WiFi.disconnect();
        wifi_connected = false;
        update_status_label();
    }
}

// 创建UI
static void create_ui(void) {
    // 创建开关
    wifi_switch = lv_switch_create(lv_scr_act());
    lv_obj_set_pos(wifi_switch, 100, 80);
    lv_obj_add_event_cb(wifi_switch, switch_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    // 创建状态标签
    status_label = lv_label_create(lv_scr_act());
    lv_obj_set_pos(status_label, 60, 150);
    lv_obj_set_width(status_label, 200);
    lv_label_set_text(status_label, "WiFi: Disconnected");
    lv_obj_set_style_text_color(status_label, lv_palette_main(LV_PALETTE_RED), 0);
}

void setup() {
    Serial.begin(115200);
    
    // LVGL初始化(假设显示驱动已配置)
    lv_init();
    // ... 显示驱动与输入设备初始化代码 ...

    create_ui();
}

void loop() {
    lv_timer_handler();
    delay(5);

    // 轮询WiFi连接状态(每500ms检查一次)
    static uint32_t last_check = 0;
    if (millis() - last_check > 500) {
        last_check = millis();
        if (WiFi.status() == WL_CONNECTED && !wifi_connected) {
            wifi_connected = true;
            update_status_label();
        } else if (WiFi.status() != WL_CONNECTED && wifi_connected) {
            wifi_connected = false;
            update_status_label();
        }
    }
}

运行与验证

  1. 将代码中的ssid和password替换为实际WiFi凭据。
  2. 编译并烧录到ESP32开发板。
  3. 上电后,屏幕显示一个开关和红色"WiFi: Disconnected"标签。
  4. 验证步骤:
    • 点击开关至ON位置,标签变为橙色"Connecting...",数秒后变为绿色"WiFi: Connected",表示连接成功。
    • 点击开关至OFF位置,标签立即变为红色"WiFi: Disconnected",WiFi断开。
    • 若WiFi密码错误或热点不存在,标签保持橙色"Connecting..."约10秒后自动变回红色"Disconnected"(WiFi.begin超时机制)。

判定标准

  • 开关ON时ESP32成功连接指定WiFi,标签显示绿色"Connected"。
  • 开关OFF时WiFi断开,标签显示红色"Disconnected"。
  • 开关状态与WiFi实际状态一致,无滞后超过2秒。
注意:LVGL显示驱动初始化代码(如lv_disp_drv_register)需根据你的屏幕型号配置,本案例未包含该部分。若使用ESP-IDF,将WiFi.begin()替换为esp_wifi_connect()并配置相应事件处理即可。