找回密码
 立即注册
首页 业界区 业界 ESP32-WIFI-WebUI控制LED

ESP32-WIFI-WebUI控制LED

吟氅 2025-8-10 16:21:17
ESP32-WIFI-WebUI控制LED

逻辑流程(A = ESP32,B = 客户端)

  • A:将 ESP32 配置为 AP 模式,开启 Wi-Fi 热点并作为 HTTP 服务器运行。
  • B:电脑或手机连接到 ESP32 热点,建立局域网通信。
  • B → A:客户端在浏览器访问 192.168.4.1,向 ESP32 发送 HTTP GET 请求。
  • A → B:ESP32 响应请求,返回 HTML 网页文件。
  • B:浏览器接收并解析 HTML 文件,显示网页内容。
  • B → A:用户在网页上点击按钮,浏览器向 ESP32 发送带有控制参数的 HTTP GET 请求(如 led_on / led_off)。
  • A:ESP32 解析 URL 参数,根据指令触发对应的回调函数执行操作(如控制 LED 开关)。
Web界面

1.png
2.png

通过手机抓包软件分析

第一次进入192.168.4.1网址
3.png
可以看到响应内容格式为
text/html
对应代码段中处理根目录请求函数构造的数据响应格式(text/html)
4.png

按下按键(触发发送led_on事件)按下按键(触发发送led_off事件)
5.png
6.png
可以分析看到请求路径为/led
7.png

分析代码可知触发路径为/led的请求格式后,处理函数为led_handler
后面源码中有详细解释led_handler()作用
在此简略说明处理过程:获取URL,查询键值对,判断值,做出处理
重要代码段分析

初始化NVS
  1.     // 初始化NVS(非易失性存储)闪存,用于存储WiFi配置等数据
  2.             ESP_ERROR_CHECK(nvs_flash_init());
复制代码
初始化 Wi-Fi AP 模式
  1.             void wifi_init_softap(void)
  2.         {
  3.             // 初始化网络接口
  4.             ESP_ERROR_CHECK(esp_netif_init());
  5.             // 创建默认事件循环
  6.             ESP_ERROR_CHECK(esp_event_loop_create_default());
  7.             // 创建默认的Wi-Fi AP网络接口
  8.             esp_netif_create_default_wifi_ap();
  9.             // 初始化Wi-Fi配置
  10.             wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  11.             ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  12.             // 配置Wi-Fi AP参数
  13.             wifi_config_t wifi_config = {
  14.                 .ap = {
  15.                     .ssid = "ESP32_WEB", // 设置SSID名称
  16.                     .ssid_len = strlen("ESP32_WEB"), // SSID长度
  17.                     .password = "12345678", // 设置密码
  18.                     .max_connection = 2, // 最大连接数
  19.                     .authmode = WIFI_AUTH_WPA_WPA2_PSK // 设置认证模式为WPA/WPA2
  20.                 },
  21.             };
  22.             // 如果密码为空,则将认证模式设置为开放模式
  23.             if (strlen((char *)wifi_config.ap.password) == 0)
  24.                 wifi_config.ap.authmode = WIFI_AUTH_OPEN;
  25.             // 设置Wi-Fi模式为AP模式
  26.             ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
  27.             // 设置Wi-Fi配置
  28.             ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
  29.             // 启动Wi-Fi
  30.             ESP_ERROR_CHECK(esp_wifi_start());
  31.             // 打印日志,显示Wi-Fi AP已启动的信息
  32.             ESP_LOGI(TAG, "Wi-Fi AP started. SSID:%s password:%s", "ESP32_WEB", "12345678");
  33.         }
复制代码
初始化外设led(略)

启动HTTP服务器(注册服务器响应函数)
  1.    // 启动 HTTP 服务器
  2.         httpd_handle_t start_webserver(void)
  3.         {
  4.             httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  5.             httpd_handle_t server = NULL;
  6.             
  7.             if (httpd_start(&server, &config) == ESP_OK) {
  8.                 //注册根路径(/)的处理函数:
  9.                 httpd_uri_t index_uri = {
  10.                     .uri       = "/",
  11.                     .method    = HTTP_GET,
  12.                     .handler   = index_handler,// 设置处理函数为index_handler
  13.                     .user_ctx  = NULL           //回传html
  14.                 };
  15.                 httpd_register_uri_handler(server, &index_uri);//注册到服务器中
  16.                 //注册 /led 路径的处理函数
  17.                 // 定义一个httpd_uri_t类型的变量led_uri// 设置uri为"/led"
  18.                 httpd_uri_t led_uri = {
  19.                     .uri       = "/led",
  20.                     .method    = HTTP_GET,
  21.                     .handler   = led_handler,// 设置处理函数为led_handler
  22.                     .user_ctx  = NULL           //设置led
  23.                 };
  24.                 httpd_register_uri_handler(server, &led_uri);
  25.             }
  26.             return server;
  27.         }
复制代码
处理/根目录请求,返回 HTML
  1. static esp_err_t index_handler(httpd_req_t *req)——
  2.         {
  3.             httpd_resp_set_type(req, "text/html");
  4.             return httpd_resp_send(req, (const char *)_binary_index_html_start,
  5.                                 _binary_index_html_end - _binary_index_html_start);
  6.         }
复制代码
处理 /led 控制请求
  1.         // 静态函数,用于处理LED控制请求
  2.         static esp_err_t led_handler(httpd_req_t *req)
  3.         {
  4.             // 定义一个字符数组,用于存储URL查询字符串
  5.             char buf[100];
  6.             // 获取URL查询字符串的长度,并加1
  7.             size_t len = httpd_req_get_url_query_len(req) + 1;
  8.             // 如果URL查询字符串的长度大于1
  9.             if (len > 1) {
  10.                 // 获取URL查询字符串
  11.                 httpd_req_get_url_query_str(req, buf, len);
  12.                 // 定义一个字符数组,用于存储查询参数
  13.                 char param[10];
  14.                 // 如果查询参数为"state"
  15.                 if (httpd_query_key_value(buf, "state", param, sizeof(param)) == ESP_OK) {
  16.                     // 打印查询参数
  17.                     ESP_LOGI(TAG, "LED state param: %s", param);
  18.                     // 如果查询参数为"on"
  19.                     if (strcmp(param, "on") == 0) {
  20.                         // 设置LED引脚为高电平
  21.                         gpio_set_level(LED_GPIO, 1);
  22.                         // 设置LED状态为打开
  23.                         led_on = true;
  24.                         // 发送响应,LED已打开
  25.                         httpd_resp_sendstr(req, "LED turned ON");
  26.                     // 如果查询参数为"off"
  27.                     } else if (strcmp(param, "off") == 0) {
  28.                         // 设置LED引脚为低电平
  29.                         gpio_set_level(LED_GPIO, 0);
  30.                         // 设置LED状态为关闭
  31.                         led_on = false;
  32.                         // 发送响应,LED已关闭
  33.                         httpd_resp_sendstr(req, "LED turned OFF");
  34.                     // 如果查询参数不为"on"或"off"
  35.                     } else {
  36.                         // 发送响应,LED状态无效
  37.                         httpd_resp_sendstr(req, "Invalid LED state");
  38.                     }
  39.                 // 如果查询参数不为"state"
  40.                 } else {
  41.                     // 发送响应,缺少"state"参数
  42.                     httpd_resp_sendstr(req, "Missing 'state' param");
  43.                 }
  44.             // 如果URL查询字符串的长度不大于1
  45.             } else {
  46.                 // 发送响应,未提供查询参数
  47.                 httpd_resp_sendstr(req, "No query provided");
  48.             }
  49.             // 返回ESP_OK
  50.             return ESP_OK;
  51.         }
复制代码
Web网页端(HTML)

触发部分
  1.   
复制代码
源码:

main.c

[code]    #include     #include "esp_event.h"    #include "esp_log.h"    #include "esp_netif.h"    #include "nvs_flash.h"    #include "esp_wifi.h"    #include "esp_http_server.h"    #include "driver/gpio.h"    #define LED_GPIO GPIO_NUM_48 // 可根据板子修改,比如GPIO2或GPIO5    static const char *TAG = "WEB_LED";    // 嵌入的 HTML 网页内容    extern const uint8_t _binary_index_html_start[];    extern const uint8_t _binary_index_html_end[];    // LED 控制状态    static bool led_on = false;    // 处理根目录请求,返回 HTML    static esp_err_t index_handler(httpd_req_t *req)    {        httpd_resp_set_type(req, "text/html");        return httpd_resp_send(req, (const char *)_binary_index_html_start,                            _binary_index_html_end - _binary_index_html_start);    }    // 处理 /led 控制请求    // 静态函数,用于处理LED控制请求    static esp_err_t led_handler(httpd_req_t *req)    {        // 定义一个字符数组,用于存储URL查询字符串        char buf[100];        // 获取URL查询字符串的长度,并加1        size_t len = httpd_req_get_url_query_len(req) + 1;        // 如果URL查询字符串的长度大于1        if (len > 1) {            // 获取URL查询字符串            httpd_req_get_url_query_str(req, buf, len);            // 定义一个字符数组,用于存储查询参数            char param[10];            // 如果查询参数为"state"            if (httpd_query_key_value(buf, "state", param, sizeof(param)) == ESP_OK) {                // 打印查询参数                ESP_LOGI(TAG, "LED state param: %s", param);                // 如果查询参数为"on"                if (strcmp(param, "on") == 0) {                    // 设置LED引脚为高电平                    gpio_set_level(LED_GPIO, 1);                    // 设置LED状态为打开                    led_on = true;                    // 发送响应,LED已打开                    httpd_resp_sendstr(req, "LED turned ON");                // 如果查询参数为"off"                } else if (strcmp(param, "off") == 0) {                    // 设置LED引脚为低电平                    gpio_set_level(LED_GPIO, 0);                    // 设置LED状态为关闭                    led_on = false;                    // 发送响应,LED已关闭                    httpd_resp_sendstr(req, "LED turned OFF");                // 如果查询参数不为"on"或"off"                } else {                    // 发送响应,LED状态无效                    httpd_resp_sendstr(req, "Invalid LED state");                }            // 如果查询参数不为"state"            } else {                // 发送响应,缺少"state"参数                httpd_resp_sendstr(req, "Missing 'state' param");            }        // 如果URL查询字符串的长度不大于1        } else {            // 发送响应,未提供查询参数            httpd_resp_sendstr(req, "No query provided");        }        // 返回ESP_OK        return ESP_OK;    }    // 初始化 GPIO    void led_gpio_init(void)    {        gpio_config_t io_conf = {            .pin_bit_mask = 1ULL
您需要登录后才可以回帖 登录 | 立即注册