下面给出一个使用ESP32-S3作为随身WiFi(Portable WiFi Hotspot)的方案示例。此方案的目标是:通过ESP32-S3连接4G Cat.1模组建立PPP网络,然后将数据通过ESP32-S3的Wi-Fi AP功能对外分享,实现类似“随身WiFi”的功能。该方案可在没有有线网络和固定Wi-Fi接入点的情况下,为周围设备提供移动宽带热点。
1. 系统功能与总体设计
功能目标:
- ESP32-S3通过USB Host与4G Cat.1模块(支持CDC-ACM)建立PPP连接。
- 当无固定Wi-Fi STA连接(或不需要使用已有Wi-Fi)时,ESP32-S3直接通过4G网络接入互联网。
- ESP32-S3开启Wi-Fi AP模式,对周围设备提供Wi-Fi接入点(SSID和密码可配置)。
- 数据通过LwIP的NAT功能在Wi-Fi AP与PPP接口之间转发,从而实现随身路由功能。
1.1 硬件组成
- 主控芯片:ESP32-S3
- 4G Cat.1模块:通过USB接口与ESP32-S3相连接,ESP32-S3充当USB Host,4G模块作为USB Device提供CDC-ACM接口。常见的Cat.1模块包括SIM7600、EC20等(需参考其CDC-ACM驱动和AT指令)。
- 电源:对4G模块提供稳定的电源,满足峰值电流。ESP32-S3使用常规5V→3.3V电源模块。
1.2 软件框架
- ESP-IDF框架:使用官方开发环境
- USB Host驱动:ESP32-S3内置USB OTG外设,可以在主机模式下运行,加载CDC-ACM驱动与4G模块通信。
- PPP协议栈:通过LwIP PPPoS(PPP-over-Serial)功能进行拨号连接。底层的“Serial”接口由USB CDC实现。
- Wi-Fi驱动:启用AP模式和(可选)STA模式。
- NAT功能:在LwIP中启用NAT,将PPP接口作为外网口,Wi-Fi AP作为内网口,实现内网设备上网。
1.3 系统工作流程
-
上电初始化:
- 初始化NVS、日志系统、事件循环。
- 初始化Wi-Fi子系统,配置AP模式参数。
- 初始化USB Host并等待4G模块接入。
-
PPP拨号:
- 对4G模块发送AT指令配置APN和拨号命令(如
AT+CGDCONT
和ATD*99#
)。 - 启动PPP会话,完成IP协商,获得IP地址、DNS等信息。
- 对4G模块发送AT指令配置APN和拨号命令(如
-
启用NAT:
- 当PPP建立后,将PPP接口IP地址加入NAT表。
- Wi-Fi AP客户端连接后,其数据包通过NAT转发到PPP接口访问互联网。
-
运行与管理:
- 实时监控PPP连接状态,若断线则重拨。
- 可通过Web服务器或串口命令行更改AP SSID、密码、APN等参数。
- 若需要,可增加Wi-Fi STA模式支持,以在特定场景下让ESP32-S3连接上已有Wi-Fi,并将该Wi-Fi作为WAN,对外仍提供AP热点。
2. 开发环境与配置
- 硬件:ESP32-S3开发板、支持CDC的4G Cat.1模块(USB接口)
- 软件:ESP-IDF最新稳定版本(例如v4.4或v5.0及以上)
- 菜单配置:
- 启用USB Host和CDC-ACM驱动
- 启用LwIP的PPP和NAT功能
- 配置Wi-Fi为AP模式启用
示例配置选项(在menuconfig
中):
Component config → USB Host Library → Enable USB Host
Component config → LWIP → Enable PPP Support
Component config → LWIP → Enable NAT (NAPT) Support
3. 代码结构示例
project/
├─ main/
│ ├─ main.c // 主程序入口,初始化任务和事件循环
│ ├─ ppp_manager.c // PPP管理相关代码
│ ├─ usb_cdc.c // USB CDC的封装代码
│ ├─ wifi_ap.c // Wi-Fi AP初始化与管理代码
│ ├─ nat_config.c // NAT相关配置代码
│ ├─ Kconfig.projbuild
│ └─ CMakeLists.txt
└─ CMakeLists.txt
4. 关键代码示例
以下代码片段仅供参考,实际使用时需根据4G模块要求和ESP-IDF版本进行适配。
4.1 初始化Wi-Fi AP
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_event.h"
static esp_netif_t *wifi_ap_netif = NULL;
void wifi_init_ap(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_ap_netif = esp_netif_create_default_wifi_ap();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t ap_config = {
.ap = {
.ssid = "ESP32_Portable_WiFi",
.ssid_len = strlen("ESP32_Portable_WiFi"),
.password = "12345678",
.max_connection = 10,
.authmode = WIFI_AUTH_WPA2_PSK
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI("WIFI", "WiFi AP started. SSID: %s, Password: %s",
ap_config.ap.ssid, ap_config.ap.password);
}
4.2 USB CDC初始化与等待4G模块
#include "usb/usb_host.h"
#include "usb/cdc_acm_host.h"
static cdc_acm_dev_handle_t cdc_dev = NULL;
void usb_cdc_init(void)
{
ESP_ERROR_CHECK(usb_host_install(NULL));
// 简单轮询等待4G模块接入
while (1) {
size_t dev_count = 0;
cdc_acm_host_device_info_t *dev_list = NULL;
cdc_acm_host_device_list(&dev_list, &dev_count);
if (dev_count > 0) {
if (cdc_acm_host_open(dev_list[0].dev_handle, &cdc_dev) == ESP_OK) {
free(dev_list);
break;
}
}
if (dev_list) free(dev_list);
vTaskDelay(pdMS_TO_TICKS(1000));
}
cdc_acm_line_coding_t line_coding = {
.dwDTERate = 115200,
.bCharFormat = CDC_ACM_1_STOP_BITS,
.bParityType = CDC_ACM_NO_PARITY,
.bDataBits = 8,
};
cdc_acm_host_line_coding_set(cdc_dev, &line_coding);
cdc_acm_host_set_control_line_state(cdc_dev, true, true);
ESP_LOGI("USB_CDC", "4G Module detected and CDC ready");
}
4.3 PPP管理与拨号
#include "lwip/netif.h"
#include "lwip/pppapi.h"
#include "lwip/sio.h"
static ppp_pcb *ppp = NULL;
static esp_netif_t *ppp_netif = NULL;
u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len) {
size_t written;
if (cdc_acm_host_data_tx(cdc_dev, data, len, &written, 1000) == ESP_OK) {
return (u32_t)written;
}
return 0;
}
u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) {
size_t readed;
if (cdc_acm_host_data_rx(cdc_dev, data, len, &readed, 1000) == ESP_OK) {
return (u32_t)readed;
}
return 0;
}
sio_fd_t sio_open(u8_t devnum) {
return (sio_fd_t)&cdc_dev; // 仅有一个设备
}
static void ppp_status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
struct netif *pppif = ppp_netif(pcb);
if (err_code == PPPERR_NONE) {
ESP_LOGI("PPP", "PPP connected: IP=%s", ipaddr_ntoa(&pppif->ip_addr));
// PPP连上后启用NAT
enable_nat(pppif);
}
}
static u32_t ppp_output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) {
return sio_write((sio_fd_t)ctx, data, len);
}
void ppp_start(void)
{
sio_fd_t fd = sio_open(0);
// 发送AT指令配置APN并拨号(根据模块要求)
const char* at_cmds[] = {
"AT\r\n",
"AT+CGDCONT=1,\"IP\",\"your_apn\"\r\n",
"ATD*99#\r\n"
};
for (int i = 0; i < sizeof(at_cmds)/sizeof(at_cmds[0]); i++) {
sio_write(fd, (uint8_t*)at_cmds[i], strlen(at_cmds[i]));
vTaskDelay(pdMS_TO_TICKS(500));
}
ppp = pppapi_new();
ppp_set_default(ppp);
ppp_set_usepeerdns(ppp, 1);
pppapi_set_status_callback(ppp, ppp_status_cb);
pppapi_over_serial_open(ppp, ppp_output_cb, fd);
pppapi_open(ppp, 0);
ESP_LOGI("PPP", "PPP session started");
}
4.4 NAT配置
使用LWIP NAT,需要在获取PPP地址后启用:
#include "lwip/lwip_napt.h"
void enable_nat(struct netif *pppif)
{
// 获取AP接口netif
struct netif *apif = esp_netif_get_netif_impl(wifi_ap_netif);
// 启用NAPT
ip_napt_enable(ip4_addr_get_u32(&pppif->ip_addr), 1);
ESP_LOGI("NAT", "NAT enabled on PPP interface");
}
4.5 主程序(main.c)
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"
#include "esp_log.h"
extern void wifi_init_ap(void);
extern void usb_cdc_init(void);
extern void ppp_start(void);
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
wifi_init_ap(); // 启动Wi-Fi AP
usb_cdc_init(); // 初始化USB CDC
ppp_start(); // 启动PPP拨号
// 主任务空转,用于保留运行状态
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
5. 测试步骤
-
硬件连接:
- 将4G模块通过USB线(OTG线)接入ESP32-S3的USB Host接口。
- 确保4G模块SIM卡已插入且具备APN可用。
-
烧录代码并上电:
- 查看串口日志,等待
4G Module detected and CDC ready
和PPP connected
等日志出现。 - 当PPP连接成功后,手机或电脑连接到ESP32_S3的WiFi热点(ESP32_Portable_WiFi/12345678)。
- 打开浏览器或Ping公共IP(如8.8.8.8)测试是否能上网。
- 查看串口日志,等待
-
调试与优化:
- 若无法拨号成功,请检查AT指令和APN设置。
- 若无法上网,请检查NAT配置和PPP状态。
- 根据4G模块的数据手册进行参数优化。
6. 总结
以上是一个使用ESP32-S3+4G Cat.1模块打造“随身WiFi”的基础方案。通过PPP拨号建立移动数据网络,再利用ESP32-S3的Wi-Fi AP特性和LwIP NAT功能,对周边设备提供热点上网服务。实际项目中可根据需求增加配置页面、状态指示、自动故障重拨、以及Wi-Fi STA模式的自动切换等高级功能。