一、实现功能概述
项目目标
通过 ESP32-S3 构建 WebSocket 服务器,接收客户端指令(“1”/“0”)控制 LED 亮灭,并实时返回状态响应。
最终效果
客户端(网页 / Postman)与 ESP32-S3 建立长连接,发送指令即可控制 LED,同时接收设备返回的状态反馈。
二、准备工作与环境配置
1. 硬件清单
- ESP32-S3 开发板(我这里使用的是正点原子esp32s3的开发板) 、

2. 开发环境搭建
- 开发环境:ESP-IDF 5.2
- 工具链:在 Linux 系统里,直接用 ESP-IDF 自带的 idf.py 工具就行,能完成编译、烧录和监控这些操作。
3. 项目创建
自己创建一个项目,记得选择esp32s3,如果型号不对使用命令
idf.py set-target esp32s3 //切换型号
4. menuconfig 关键配置(必须项)
进入配置界面:idf.py menuconfig
- 启用 HTTP 服务器 WebSocket 支持:
Component config → HTTP Server → Enable WebSocket support


按空格选中

三、项目整体流程
-
设备启动与基础准备
- 初始化 NVS(非易失性存储):用于保存 WiFi 配置等信息,避免重复设置。
- 完成必要的系统初始化,为后续操作提供基础环境。
-
WiFi 连接流程
- 配置 WiFi 为 STA 模式(作为客户端),填入目标路由器的 SSID 和密码。
- 自动发起连接,通过“事件”监控连接状态:
- 连接失败时自动重试(有限次数);
- 成功连接后获取 IP 地址,标记网络就绪。
-
服务器启动流程
- 网络就绪后,启动支持 WebSocket 的 HTTP 服务器(默认使用 80 端口)。
- 注册 WebSocket 服务路径(如
/ws),用于客户端连接。
-
客户端与服务器交互流程
- 建立连接:客户端通过
ws://[ESP32的IP]/ws发起请求,先经 HTTP 协议完成“握手”,再升级为 WebSocket 长连接。 - 指令传输:客户端发送“1”(开灯)或“0”(关灯)指令,ESP32 实时接收。
- 执行与反馈:ESP32 根据指令控制 LED 状态,并通过 WebSocket 实时返回操作结果(如“LED已开启”)。
- 建立连接:客户端通过
四、完整代码展示
#include "esp_log.h"
#include "esp_http_server.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "driver/gpio.h"
static const char *TAG = "websocket_server";
static httpd_handle_t server = NULL;
// LED配置
#define LED_GPIO 1 // 使用GPIO1控制LED
#define LED_ON 0 // 低电平点亮LED(已修正)
#define LED_OFF 1 // 高电平关闭LED(已修正)
// WiFi配置
#define WIFI_SSID "cqlbdz"
#define WIFI_PASS "cqlbdz123456798"
#define MAX_RETRIES 10
// 全局变量
static int s_retry_num = 0;
static bool wifi_connected = false;
// 函数声明
static httpd_handle_t start_webserver(void);
// 初始化LED
static void led_init(void) {
gpio_reset_pin(LED_GPIO);
gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);
gpio_set_level(LED_GPIO, LED_OFF); // 默认关灯(高电平)
ESP_LOGI(TAG, "LED初始化完成,GPIO: %d", LED_GPIO);
}
// 控制LED(已修正逻辑)
static void set_led_state(bool on) {
gpio_set_level(LED_GPIO, on ? LED_ON : LED_OFF);
ESP_LOGI(TAG, "LED已%s", on ? "开启" : "关闭"); // 修正日志信息
}
// WiFi事件处理
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_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < MAX_RETRIES) {
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(TAG, "重连 WiFi (尝试 %d/%d)...", s_retry_num, MAX_RETRIES);
}
wifi_connected = false;
} 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;
ESP_LOGI(TAG, "WiFi 已连接! IP地址: " IPSTR,
IP2STR(&event->ip_info.ip));
wifi_connected = true;
// 获取IP地址字符串
char ip_str[16];
snprintf(ip_str, sizeof(ip_str), IPSTR, IP2STR(&event->ip_info.ip));
// 启动WebSocket服务器
i

408

被折叠的 条评论
为什么被折叠?



