当前位置: 首页 > article >正文

ESP32 在IDF_V5.3.1版本下实现AP无线热点模式!(带WIFI事件处理)

一、什么是ESP32的AP无线热点模式?

        ESP32 的 AP(Access Point)模式 是指 ESP32 作为无线接入点运行,它自己创建一个 Wi-Fi 网络,允许其他设备(如手机、电脑、平板等)直接连接到它上面,而不依赖于现有的路由器或 Wi-Fi 网络。下面详细解释一下:

1. AP 模式的基本概念

  • 自建网络:在 AP 模式下,ESP32 会广播一个 SSID,成为一个小型无线热点。其他设备可以扫描到这个 SSID 并连接进去。

  • 无需依赖路由器:与 STA(Station)模式不同,STA 模式下 ESP32 作为客户端连接到已有的 Wi-Fi 网络,而 AP 模式下 ESP32 则提供一个网络供其他设备接入。

  • 局域通信:连接到 ESP32 的设备可以在局域网内进行数据通信,比如通过 TCP/IP 协议互相通信,或者通过 ESP32 提供的 Web 服务器、MQTT 服务等进行交互。

2. ESP32 AP 模式的应用场景

  • IoT 设备配置:许多 IoT 设备在首次启动时会开启 AP 模式,让用户连接后通过网页配置设备的参数,再切换到 STA 模式。

  • 局域网数据交换:在没有现成 Wi-Fi 网络的环境下,可以利用 ESP32 建立临时网络,实现局部设备之间的数据传输或远程控制。

  • 离线应用:在需要独立运行并不依赖互联网的场景下,ESP32 的 AP 模式可以提供稳定的局域网连接。

3. AP 模式的特点与优势

  • 简单部署:不需要额外的路由器或 Wi-Fi 基础设施,只需配置 ESP32 的 AP 参数(如 SSID、密码、最大连接数等)即可启动网络。

  • 安全性:可以设置 WPA/WPA2 加密,确保只有授权设备能够连接到 ESP32 创建的网络。

  • 灵活性:适用于设备初始配置、临时数据交换或局域网服务等场景,十分灵活。

4.总结

  • ESP32 的 AP 模式 是将 ESP32 变成一个无线热点,使它能够独立建立 Wi-Fi 网络供其他设备连接。
  • 它适用于需要离线配置、局域网通信和临时数据交换的场景,不需要依赖外部路由器。
  • 在实际项目中,通过配置相应的参数(SSID、密码、最大连接数等),就能很方便地使用 ESP32 搭建一个小型的无线网络。

二、如何在ESP32上实现AP热点模式?

1. 引入头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_mac.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
#include "esp_netif.h"
#include "lwip/inet.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "lwip/err.h"
#include "lwip/sys.h"
  • 标准库头文件:提供基础 C 语言函数支持。
  • FreeRTOS 头文件:支持多任务调度和实时操作系统功能。
  • ESP-IDF 系统和 NVS:用于系统初始化、重启和非易失性存储操作。
  • WiFi 和事件处理:使 ESP32 能够配置 WiFi、处理网络事件并打印调试信息。
  • 网络接口(esp-netif):管理网络连接接口和 TCP/IP 协议栈。
  • lwIP 库:提供底层的网络通信 API,支持 socket 编程等。

        这些头文件共同构成了 ESP32 应用程序的基础,使得开发者可以实现 WiFi 功能、网络通信和任务调度等功能。如果你正在编写或调试 ESP32 应用,这些头文件基本上是必不可少的。

2. 定义 WiFi AP 模式相关的宏

//定义目标AP名称和密码
#define ESP_WIFI_AP_SSID      "XiaoHai@iPhone"  
#define ESP_WIFI_AP_PASSWD    "123456788"
#define ESP_WIFI_CHANNEL 5
#define ESP_MAX_STA_CONN_AP 5 //定义设备连接AP最大重连次数

 这里定义了 WiFi 的基本参数:SSID、密码、通道和允许的最大连接数,根据实际需求可以修改。

3 . 定义 WiFi AP 模式下设备相关事件的宏和信息结构体

//定义事件标志位
#define DEVICE_CONNECTED_AP_BIT     BIT0
#define DEVICE_DISCONNECTED_AP_BIT  BIT1
#define DEVICE_GET_IP_AP_BIT        BIT2
//存放WIFI AP 模式下客户端设备连接AP后的信息
typedef struct wifi_sta_connect_Info
{esp_ip4_addr_t dev_ip; //客户端设备连接AP后获取的IPuint8_t dev_mac[6]; //客户端设备MAC地址uint8_t ap_ssid[32]; //AP的名称uint8_t ap_password[64]; //AP的密码}wifi_ap_connect_info;

4. 初始化非易失性存储 (NVS)

        在使用 WiFi 功能之前,必须初始化 NVS,因为 WiFi 驱动会从 NVS 中读取配置信息。
流程:

  • 调用 nvs_flash_init() 初始化 NVS。
  • 如果返回错误(例如内存页不足或版本不匹配),则先擦除 NVS 再重新初始化。
    示例代码:
esp_err_t nvs_init(void)
{esp_err_t ret;ret = nvs_flash_init(); /* 初始化 NVS 第一次调用时,它会加载存储区域。如果存储区域有问题或不兼容,会抛出 ESP_ERR_NVS_NO_FREE_PAGES 或 ESP_ERR_NVS_NEW_VERSION_FOUND 错误。此时,我们会擦除存储并重新初始化。 */if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}return ret;
}

 5.WIFI AP模式初始化


/*
函数功能:WIFI AP模式初始化
形    参:wifi_ap_cfg:WIFI的配置
返 回 值:无
*/
void wifi_ap_init(wifi_config_t *wifi_ap_cfg)
{ ESP_LOGI(TAG_AP, "wifi_ap_init.....");//1.创建新的事件循环.ESP_ERROR_CHECK(esp_event_loop_create_default()); //2.初始化WIFI连接/断开的标志事件组wifi_event_group = xEventGroupCreate();//3.注册事件ID和IP获取服务函数ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVENT_AP_STAIPASSIGNED,&wifi_event_handler,NULL,NULL)); //4.网卡初始化.初始化底层TCP/IP堆栈ESP_ERROR_CHECK(esp_netif_init()); //5.使用默认WiFi Station配置创建esp_netif对象,将netif连接到WiFi并注册默认WiFi处理程序。esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); assert(ap_netif); //断言检查,确保程序在运行时满足特定的条件.//6.netif连接到WiFi并注册默认WiFi处理程序。esp_netif_set_default_netif(ap_netif);//7.初始化wifi配置参数为默认.wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //8.为 WiFi 驱动初始化 WiFi 分配资源,如 WiFi 控制结构、RX/TX 缓冲区、WiFi NVS 结构等,这个 WiFi 也启动 WiFi 任务。必须先调用此API,然后才能调用所有其他WiFi APIESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_LOGI(TAG_AP, "wifi init cfg !");//9.设置WIFI为AP模式ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_LOGI(TAG_AP, "wifi set ap mode !");//10.设置WIFI AP模式的配置ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, wifi_ap_cfg) );ESP_LOGI(TAG_AP, "wifi init ap finished !");//11.启动WIFIESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG_AP, "wifi start !");ESP_LOGI(TAG_AP, "wifi_init_softap finished. SSID:%s password:%s channel:%d",wifi_ap_cfg->ap.ssid,wifi_ap_cfg->ap.password,wifi_ap_cfg->ap.channel);}   

        这就是 ESP32 以 AP 模式初始化的详细流程。通过这些步骤,ESP32 将创建一个无线接入点,允许其他设备直接连接并进行局域网通信。

6.WIFI 连接相关事件处理

        在 ESP32 AP 模式下,当有客户端(站点,STA)连接或断开时,系统会产生相应的 WiFi 事件,通过这些事件可以获取连接设备的相关信息,并执行相应的处理逻辑。

ESP-IDF 中常用的 AP 模式连接事件包括:

  • WIFI_EVENT_AP_STACONNECTED
    当一个客户端成功连接到 ESP32 作为 AP 时,会触发此事件。事件数据通常包含客户端的 MAC 地址和分配给它的 AID(Association Identifier)。

  • WIFI_EVENT_AP_STADISCONNECTED
    当一个客户端从 AP 断开连接时,会触发此事件。同样,事件数据中包含断开连接设备的 MAC 地址和 AID。

  • IP_EVENT_AP_STAIPASSIGNED
    当一个客户端设备连接到 ESP32 的 AP 后,AP 内部运行的 DHCP 服务器会为该客户端分配一个 IP 地址。一旦分配成功,就会触发 IP_EVENT_AP_STAIPASSIGNED 事件。

WIFI AP模式下相关的WiFi事件处理服务实现:


/*
函数功能:WIFI连接事件回调服务函数,由于处理特定的WIFI事件
函数形参:arg:传入网卡控制块event_base:WIFI 事件event_id:事件 IDevent_data:事件数据
*/
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_AP_STACONNECTED) //有设备连接到到AP{wifi_event_ap_staconnected_t *eventData = (wifi_event_ap_staconnected_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));xEventGroupSetBits(wifi_event_group, DEVICE_CONNECTED_AP_BIT);ESP_LOGI(TAG_AP, "station "MACSTR" join, AID=%d",MAC2STR(eventData->mac), eventData->aid);}else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)  //有设备与AP断开连接{wifi_event_ap_staconnected_t *eventData = (wifi_event_ap_staconnected_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));ESP_LOGI(TAG_AP, "station "MACSTR" leave, AID=%d",MAC2STR(eventData->mac), eventData->aid);xEventGroupSetBits(wifi_event_group, DEVICE_DISCONNECTED_AP_BIT);}else if(event_base == IP_EVENT && event_id == IP_EVENT_AP_STAIPASSIGNED) //有设备连接到到AP并成功从AP分配到IP{ip_event_ap_staipassigned_t *eventData = (ip_event_ap_staipassigned_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));wifi_ap_net_info.dev_ip = eventData->ip;xEventGroupSetBits(wifi_event_group, DEVICE_GET_IP_AP_BIT);ESP_LOGI(TAG_AP, "DHCP server assigned IP to a client: MAC="MACSTR", IP="IPSTR"",MAC2STR(eventData->mac), IP2STR(&eventData->ip));}else{ESP_LOGI(TAG_AP,"Unexpected event ! event_id = %d \n",event_id);}
}

7.WIFI AP模式测试


/*
函数功能:WIFI AP模式连接AP测试
形    参:无
返 回 值:无
*/
void wifi_ap_test(void *pvParameters)
{nvs_init();uint8_t displayFlag=0;wifi_config_t wifi_ap_config = {.ap ={.ssid = ESP_WIFI_AP_SSID,.ssid_len = strlen(ESP_WIFI_AP_SSID),.channel = ESP_WIFI_CHANNEL,.password = ESP_WIFI_AP_PASSWD,.max_connection = ESP_MAX_STA_CONN_AP,.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg.required = false,}};if (strlen(ESP_WIFI_AP_PASSWD) == 0) {wifi_ap_config.ap.authmode = WIFI_AUTH_OPEN;}memcpy(wifi_ap_net_info.ap_ssid,ESP_WIFI_AP_SSID,sizeof(ESP_WIFI_AP_SSID));memcpy(wifi_ap_net_info.ap_password,ESP_WIFI_AP_PASSWD,sizeof(ESP_WIFI_AP_PASSWD));st7789v_clearScreen(WHITE,USE_HORIZONTAL);wifi_ap_init(&wifi_ap_config);//*(uint8_t *)pvParameters = 1;display_wifi_ap_connect_info_to_lcd(4);while(1) {//等待事件标志位:等待网络连接成功/失败。成功和失败的bits会在上面注册的wifi_event_handler函数中被设置。//xEventGroupWaitBits(事件组句柄,要等待的事件位,是否在函数返回前清除触发的标志位,是否等待所有指定的标志位,等待的时间(以系统滴答为单位) );EventBits_t bits = xEventGroupWaitBits(wifi_event_group,DEVICE_CONNECTED_AP_BIT | DEVICE_DISCONNECTED_AP_BIT | DEVICE_GET_IP_AP_BIT,pdTRUE,pdFALSE,portMAX_DELAY); if(bits & DEVICE_CONNECTED_AP_BIT){display_wifi_ap_connect_info_to_lcd(1);}else if(bits & DEVICE_DISCONNECTED_AP_BIT) {display_wifi_ap_connect_info_to_lcd(2);}else if(bits & DEVICE_GET_IP_AP_BIT){display_wifi_ap_connect_info_to_lcd(3);}}
}

附录:WIFI AP 模式代码整合

 bsp_wifi_ap.h:

#ifndef __BSP_WIFI_AP_H
#define __BSP_WIFI_AP_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_mac.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
#include "esp_netif.h"
#include "lwip/inet.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#include "lwip/err.h"
#include "lwip/sys.h"void wifi_ap_test(void *pvParameters);#endif

bsp_wifi_ap.c

#include"bsp_wifi_ap.h"
#include"bsp_delay.h"
#include"bsp_lcd_st7789v_spi.h"static const char *TAG_AP = "WIFI_AP";
void wifi_ap_init(wifi_config_t *wifi_ap_cfg);
void display_wifi_ap_connect_info_to_lcd(uint8_t displayFlag);//定义目标AP名称和密码
#define ESP_WIFI_AP_SSID      "XiaoHai@iPhone"  
#define ESP_WIFI_AP_PASSWD    "123456788"
#define ESP_WIFI_CHANNEL 5
#define ESP_MAX_STA_CONN_AP 5 //定义设备连接AP最大重连次数//定义事件标志位
#define DEVICE_CONNECTED_AP_BIT     BIT0
#define DEVICE_DISCONNECTED_AP_BIT  BIT1
#define DEVICE_GET_IP_AP_BIT        BIT2//存放WIFI AP 模式下客户端设备连接AP后的信息
typedef struct wifi_sta_connect_Info
{esp_ip4_addr_t dev_ip; //客户端设备连接AP后获取的IPuint8_t dev_mac[6]; //客户端设备MAC地址uint8_t ap_ssid[32]; //AP的名称uint8_t ap_password[64]; //AP的密码}wifi_ap_connect_info;wifi_ap_connect_info  wifi_ap_net_info={0}; 
static int s_retry_num = 0; //重连目标AP的次数
static EventGroupHandle_t wifi_event_group; //定义一个事件标志组,用于WIFI连接/断开的标志
uint8_t ap_lcd_display_buff[100]={0}; //定义LCD显示缓存/*
函数功能:WIFI连接事件回调服务函数,由于处理特定的WIFI事件
函数形参:arg:传入网卡控制块event_base:WIFI 事件event_id:事件 IDevent_data:事件数据
*/
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_AP_STACONNECTED) //有设备连接到到AP{wifi_event_ap_staconnected_t *eventData = (wifi_event_ap_staconnected_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));xEventGroupSetBits(wifi_event_group, DEVICE_CONNECTED_AP_BIT);ESP_LOGI(TAG_AP, "station "MACSTR" join, AID=%d",MAC2STR(eventData->mac), eventData->aid);}else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED)  //有设备与AP断开连接{wifi_event_ap_staconnected_t *eventData = (wifi_event_ap_staconnected_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));ESP_LOGI(TAG_AP, "station "MACSTR" leave, AID=%d",MAC2STR(eventData->mac), eventData->aid);xEventGroupSetBits(wifi_event_group, DEVICE_DISCONNECTED_AP_BIT);}else if(event_base == IP_EVENT && event_id == IP_EVENT_AP_STAIPASSIGNED) //有设备连接到到AP并成功从AP分配到IP{ip_event_ap_staipassigned_t *eventData = (ip_event_ap_staipassigned_t *)event_data;memcpy(wifi_ap_net_info.dev_mac,eventData->mac,sizeof(eventData->mac));wifi_ap_net_info.dev_ip = eventData->ip;xEventGroupSetBits(wifi_event_group, DEVICE_GET_IP_AP_BIT);ESP_LOGI(TAG_AP, "DHCP server assigned IP to a client: MAC="MACSTR", IP="IPSTR"",MAC2STR(eventData->mac), IP2STR(&eventData->ip));}else{ESP_LOGI(TAG_AP,"Unexpected event ! event_id = %d \n",event_id);}
}esp_err_t nvs_init(void)
{esp_err_t ret;ret = nvs_flash_init(); /* 初始化 NVS 第一次调用时,它会加载存储区域。如果存储区域有问题或不兼容,会抛出 ESP_ERR_NVS_NO_FREE_PAGES 或 ESP_ERR_NVS_NEW_VERSION_FOUND 错误。此时,我们会擦除存储并重新初始化。 */if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}return ret;
}/*
函数功能:WIFI AP模式初始化
形    参:wifi_ap_cfg:WIFI的配置
返 回 值:无
*/
void wifi_ap_init(wifi_config_t *wifi_ap_cfg)
{ ESP_LOGI(TAG_AP, "wifi_ap_init.....");//1.创建新的事件循环.ESP_ERROR_CHECK(esp_event_loop_create_default()); //2.初始化WIFI连接/断开的标志事件组wifi_event_group = xEventGroupCreate();//3.注册事件ID和IP获取服务函数ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVENT_AP_STAIPASSIGNED,&wifi_event_handler,NULL,NULL)); //4.网卡初始化.初始化底层TCP/IP堆栈ESP_ERROR_CHECK(esp_netif_init()); //5.使用默认WiFi Station配置创建esp_netif对象,将netif连接到WiFi并注册默认WiFi处理程序。esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); assert(ap_netif); //断言检查,确保程序在运行时满足特定的条件.//6.netif连接到WiFi并注册默认WiFi处理程序。esp_netif_set_default_netif(ap_netif);//7.初始化wifi配置参数为默认.wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //8.为 WiFi 驱动初始化 WiFi 分配资源,如 WiFi 控制结构、RX/TX 缓冲区、WiFi NVS 结构等,这个 WiFi 也启动 WiFi 任务。必须先调用此API,然后才能调用所有其他WiFi APIESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_LOGI(TAG_AP, "wifi init cfg !");//9.设置WIFI为AP模式ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_LOGI(TAG_AP, "wifi set ap mode !");//10.设置WIFI AP模式的配置ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, wifi_ap_cfg) );ESP_LOGI(TAG_AP, "wifi init ap finished !");//11.启动WIFIESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG_AP, "wifi start !");ESP_LOGI(TAG_AP, "wifi_init_softap finished. SSID:%s password:%s channel:%d",wifi_ap_cfg->ap.ssid,wifi_ap_cfg->ap.password,wifi_ap_cfg->ap.channel);}   /*
函数功能:WIFI AP模式连接AP测试
形    参:无
返 回 值:无
*/
void wifi_ap_test(void *pvParameters)
{nvs_init();uint8_t displayFlag=0;wifi_config_t wifi_ap_config = {.ap ={.ssid = ESP_WIFI_AP_SSID,.ssid_len = strlen(ESP_WIFI_AP_SSID),.channel = ESP_WIFI_CHANNEL,.password = ESP_WIFI_AP_PASSWD,.max_connection = ESP_MAX_STA_CONN_AP,.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg.required = false,}};if (strlen(ESP_WIFI_AP_PASSWD) == 0) {wifi_ap_config.ap.authmode = WIFI_AUTH_OPEN;}memcpy(wifi_ap_net_info.ap_ssid,ESP_WIFI_AP_SSID,sizeof(ESP_WIFI_AP_SSID));memcpy(wifi_ap_net_info.ap_password,ESP_WIFI_AP_PASSWD,sizeof(ESP_WIFI_AP_PASSWD));st7789v_clearScreen(WHITE,USE_HORIZONTAL);wifi_ap_init(&wifi_ap_config);//*(uint8_t *)pvParameters = 1;display_wifi_ap_connect_info_to_lcd(4);while(1) {//等待事件标志位:等待网络连接成功/失败。成功和失败的bits会在上面注册的wifi_event_handler函数中被设置。//xEventGroupWaitBits(事件组句柄,要等待的事件位,是否在函数返回前清除触发的标志位,是否等待所有指定的标志位,等待的时间(以系统滴答为单位) );EventBits_t bits = xEventGroupWaitBits(wifi_event_group,DEVICE_CONNECTED_AP_BIT | DEVICE_DISCONNECTED_AP_BIT | DEVICE_GET_IP_AP_BIT,pdTRUE,pdFALSE,portMAX_DELAY); if(bits & DEVICE_CONNECTED_AP_BIT){display_wifi_ap_connect_info_to_lcd(1);}else if(bits & DEVICE_DISCONNECTED_AP_BIT) {display_wifi_ap_connect_info_to_lcd(2);}else if(bits & DEVICE_GET_IP_AP_BIT){display_wifi_ap_connect_info_to_lcd(3);}}
}/*
函数功能:WIFI连接AP信息显示
形    参:displayMode:1:有设备连接到AP!  2:有设备从AP上离开 3:有设备连接到AP,并已分配到ip! 4:显示AP名称和密码
返 回 值:无
*/
void display_wifi_ap_connect_info_to_lcd(uint8_t displayMode)
{static uint8_t old_displayMode = 0;if(displayMode != old_displayMode){st7789v_clearScreen(WHITE,USE_HORIZONTAL);}if(displayMode == 1) //有设备连接到AP!{old_displayMode = 1;st7789v_displayString(10,10,(uint8_t *)" WIFI AP TEST :",RED,WHITE,24,0,USE_HORIZONTAL);st7789v_displayString(10,40,(uint8_t *)"One device connect to ap !",BLUE,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_SSID: %-20s",wifi_ap_net_info.ap_ssid);st7789v_displayString(10,80,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_PWD: %-20s",wifi_ap_net_info.ap_password);st7789v_displayString(10,100,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"DEV_MAC: %02x:%02x:%02x:%02x:%02x:%02x",MAC2STR(wifi_ap_net_info.dev_mac));st7789v_displayString(10,120,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);}else if(displayMode == 2)//有设备从AP上离开{old_displayMode = 2;st7789v_displayString(10,10,(uint8_t *)" WIFI AP TEST :",RED,WHITE,24,0,USE_HORIZONTAL);st7789v_displayString(10,40,(uint8_t *)"One device leave ap !",RED,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_SSID: %-20s",ESP_WIFI_AP_SSID);st7789v_displayString(10,80,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_PWD: %-20s",ESP_WIFI_AP_PASSWD);st7789v_displayString(10,100,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"DEV_MAC: %02x:%02x:%02x:%02x:%02x:%02x",MAC2STR(wifi_ap_net_info.dev_mac));st7789v_displayString(10,120,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);}else if(displayMode == 3) //有设备连接到AP,并已分配到ip!{old_displayMode = 8;st7789v_displayString(10,10,(uint8_t *)" WIFI AP TEST :",RED,WHITE,24,0,USE_HORIZONTAL);st7789v_displayString(10,40,(uint8_t *)"Client get ip from DHCP !",BLUE,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_SSID: %-20s",ESP_WIFI_AP_SSID);st7789v_displayString(10,80,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_PWD: %-20s",ESP_WIFI_AP_PASSWD);st7789v_displayString(10,100,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"DEV_IP: %d.%d.%d.%d",IP2STR(&wifi_ap_net_info.dev_ip));st7789v_displayString(10,120,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"DEV_MAC: %02x:%02x:%02x:%02x:%02x:%02x",MAC2STR(wifi_ap_net_info.dev_mac));st7789v_displayString(10,140,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);}else if(displayMode == 4)//显示AP名称和密码{old_displayMode = 4;st7789v_displayString(10,10,(uint8_t *)" WIFI AP TEST :",RED,WHITE,24,0,USE_HORIZONTAL);st7789v_displayString(10,40,(uint8_t *)"Watting device to connect ap!",RED,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_SSID: %-20s",ESP_WIFI_AP_SSID);st7789v_displayString(10,80,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);sprintf(ap_lcd_display_buff,"AP_PWD: %-20s",ESP_WIFI_AP_PASSWD);st7789v_displayString(10,100,ap_lcd_display_buff,BLACK,WHITE,16,0,USE_HORIZONTAL);}
}

相关文章:

ESP32 在IDF_V5.3.1版本下实现AP无线热点模式!(带WIFI事件处理)

一、什么是ESP32的AP无线热点模式&#xff1f; ESP32 的 AP&#xff08;Access Point&#xff09;模式 是指 ESP32 作为无线接入点运行&#xff0c;它自己创建一个 Wi-Fi 网络&#xff0c;允许其他设备&#xff08;如手机、电脑、平板等&#xff09;直接连接到它上面&#xff0…...

Elasticsearch:探索 CLIP 替代方案

作者&#xff1a;来自 Elastic Jeffrey Rengifo 及 Toms Mura 分析图像到图像和文本到图像搜索的 CLIP 模型的替代方案。 在本文中&#xff0c;我们将通过一个模拟房地产网站的实际示例介绍 CLIP 多模态模型&#xff0c;探索替代方案&#xff0c;并分析它们的优缺点&#xff0c…...

Nginx 在Linux中安装、使用

Nginx 在Linux中安装、使用 一、官网下载Nginx 官网地址&#xff1a;http://nginx.org/en/download.html 二、上传到服务器解压 1、上传到指定的服务器地址 上传的地址自己决定&#xff0c;我上传到 /data/home/prod/nginx/ 2、解压 使用命令&#xff1a; tar -zxvf “你的N…...

CodeGPT 使用教程(适用于 VSCode)

CodeGPT 使用教程&#xff08;适用于 VSCode&#xff09; CodeGPT 是一个 VSCode 插件&#xff0c;可以让你在代码编辑器中直接调用 GPT 进行代码补全、优化、调试等操作。以下是详细的安装和使用步骤&#xff1a; 1. 安装 CodeGPT 方式 1&#xff1a;从 VSCode 插件市场安装…...

Python常见面试题的详解9

1. 如何找出整数数组中第二大的数 要点 定义一个函数用于在整数数组里找出第二大的数。 若数组元素少于 2 个&#xff0c;则返回 None。 借助两个变量 first 和 second 来跟踪最大数和第二大数。 可以添加异常处理&#xff0c;以应对输入非整数数组的情况。 若数组包含重复…...

【Spring+MyBatis】_图书管理系统(下篇)

图书管理系统上篇、中篇如下&#xff1a; 【SpringMyBatis】_图书管理系统&#xff08;上篇&#xff09;-CSDN博客 【SpringMyBatis】_图书管理系统&#xff08;中篇&#xff09;-CSDN博客 目录 功能5&#xff1a;删除图书 6.1 约定前后端交互接口 6.2 后端接口 6.3 前端…...

若依-@Excel新增注解numberFormat

Excel注解中原本的scale会四舍五入小数&#xff0c;导致进度丢失 想要的效果 显示的时候保留两个小数真正的数值是保留之前的数值 还原过程 若以中有一個專門的工具类&#xff0c;用来处理excel的 找到EXCEL导出方法exportExcel()找到writeSheet,写表格的方法找到填充数据的方法…...

Cherry-Studio下载安装教程,AI面向开发者的工具或平台(付安装包)

文章目录 一、Cherry Studio是什么&#xff1f;二、功能特点 一、Cherry Studio是什么&#xff1f; Cherry Studio 是一款开源跨平台的多模型服务桌面客户端&#xff0c;集成超 300 个大语言模型&#xff0c;内置 300 多个预配置 AI 助手&#xff0c;支持多格式文件处理、全局…...

多信道接收机

线性调频&#xff08;LFM&#xff09;信号&#xff0c;模拟多个目标反射的回波信号&#xff0c;并进行混频和滤波处理。 % 参数设置 c 3e8; % 光速 (m/s) f0 8.566e9; % 载波频率 (Hz) T 10e-6; % 脉冲持续时间 (s) B 100e6; % 信号带宽 (Hz) mu B / T; % 调频斜率 (Hz/s…...

修改项目的一些前端记录(自用)

<div style"background:#f2f2f2;position:absolute;top:75px;width:10%;bottom:0px">\<ol class"tree">\<li>\<label for"folder1" class"folderOne foldertop"><img src"common/img/时间.png" …...

阿里云虚机的远程桌面登录提示帐户被锁定了

提示由于安全原因&#xff0c;帐户被锁定。 阿里云虚机ECS的远程桌面登录提示帐户被锁定了&#xff0c;只能登录阿里云处理 阿里云-计算&#xff0c;为了无法计算的价值 需选择通过VNC连接 然后计算机管理&#xff0c;解除帐户锁定即可。...

AD(Altium Designer)器件封装——立创商城导出原理图和PCB完成器件封装操作指南

1、立创商城下载原理图和PCB图 1.1 打开立创商城 官网:www.SZLCSC.COM 1.2 寻找所需器件 以芯片为例 器件类——>芯片类——>对应芯片 1.3 确定所需芯片 确定芯片——>数据手册 1.4 打开原理图和PCB图 1:原理图 2:PCB 3:打开 1.5 导出原理图 操作...

【DeepSeek系列】04 DeepSeek-R1:带有冷启动的强化学习

文章目录 1、简介2、主要改进点3、两个重要观点4、四阶段后训练详细步骤4.1 冷启动4.2 推理导向的强化学习4.3 拒绝采样和有监督微调4.4 针对所有场景的强化学习 5、蒸馏与强化学习对比6、评估6.1 DeepSeek-R1 评估6.2 蒸馏模型评估 7、结论8、局限性与未来方向 1、简介 DeepS…...

【C++八股】野指针和悬空指针

野指针&#xff08;Wild Pointer&#xff09;是指未被初始化或指向非法内存地址的指针。在 C/C 等语言中&#xff0c;指针变量如果在定义时未被初始化&#xff0c;其值是随机的&#xff0c;可能指向任意内存位置&#xff0c;这种指针被称为野指针。使用野指针进行解引用操作会导…...

Mac 清理缓存,提高内存空间

步骤 1.打开【访达】 2.菜单栏第五个功能【前往】&#xff0c;点击【个人】 3.【command shift J】显示所有文件&#xff0c;打开【资源库】 4.删除【Containers】和【Caches】文件 Containers 文件夹&#xff1a;用于存储每个应用程序的沙盒数据&#xff0c;确保应用程序…...

fpga助教面试题

第一题 module sfp_pwm( input wire clk, //clk is 200M input wire rst_n, input wire clk_10M_i, input wire PPS_i, output reg pwm ) reg [6:0] cunt ;always (posedge clk ) beginif(!rst_n)cunt<0;else if(cunt19) //200M是10M的20倍cunt<0;elsecunt<cunt1;…...

DeepSeek与ChatGPT:会取代搜索引擎和人工客服的人工智能革命

云边有个稻草人-CSDN博客 在众多创新技术中&#xff0c;DeepSeek和ChatGPT无疑是最为引人注目的。它们通过强大的搜索和对话生成能力&#xff0c;能够改变我们与计算机交互的方式&#xff0c;帮助我们高效地获取信息&#xff0c;增强智能服务。本文将深入探讨这两项技术如何结合…...

有没有其他技术可以替代本地 RAG?

知识图谱 原理&#xff1a;知识图谱是一种结构化的语义网络&#xff0c;用于描述实体之间的关系。它以图的形式表示知识&#xff0c;节点代表实体&#xff0c;边代表实体之间的关系。通过知识图谱&#xff0c;模型可以直接获取结构化的知识&#xff0c;从而生成更准确和相关的回…...

【强化学习】Q-learning算法详解:含MATLAB和Python实现代码

Q-learning算法详解 1. Q-learning算法简介Q-Learning算法的基本概念Q-Learning算法的核心思想Q-learning算法步骤Q-Learning算法的特点 MATLAB 实现 Q-learningPython 实现 Q-learning参考 强化学习属于机器学习&#xff0c;但与以前的监督学习和无监督学习的处理对象和任务都…...

Java 多数据源时事务回滚问题

目录 问题描述 1、Atomikos事务管理器 2、MyBatis-Plus多数据源支持 dynamic-datasource 特性 约定 使用方法 mybatis-mate 特性 使用方法 问题描述 在多数据源的情况下&#xff0c;如果一个事务跨越多个数据源&#xff0c;当其中一个数据源的操作失败时&#xff0c;我…...

怎麼防止爬蟲IP被網站封鎖?

隨著越來越多的網站加強其反爬蟲措施&#xff0c;爬蟲IP被封鎖成為了常見的問題。如何有效地避免IP被封&#xff0c;從而讓數據採集工作更加順利&#xff1f; 常見的反爬策略包括&#xff1a; 頻率限制&#xff1a;設置請求頻率&#xff0c;對於發出請求過於頻繁的IP進行封鎖…...

DeepSeek + Claude 提升效果

案例1&#xff1a;分布式锁 问题 spring boot 和 mybatis 实现分布式锁 Deepseek R1 思考过程 嗯&#xff0c;用户问的是如何在Spring Boot和MyBatis中实现分布式锁。首先&#xff0c;我得回忆一下分布式锁的基本概念。分布式锁是为了在分布式系统中协调多个服务实例对共享…...

使用html css js 开发一个 教育机构前端静态网站模板

这个教育机构网站模板是专为前端开发初学者设计的练习项目&#xff0c;适合正在学习前端的学生或自学者使用。网站内容包括首页、课程体系、师资力量、关于我们和联系我们等基础页面&#xff0c;帮助学习者熟悉网页布局、样式设计和交互功能的实现。 静态页面 简单截图 应用…...

ranges::set_intersection set_union set_difference set_symmetric_difference

std::ranges::set_intersection&#xff1a;是 C20 引入的一个算法&#xff0c;用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 std::ranges::set_intersection 用于计算两个已排序范围的交集。它将两个范围的交集元素复制到输出范围中。 注意事项…...

在IDEA的Maven中(同步所有Maven项目)和(重新加载所有Maven项目)的区别

特性同步所有 Maven 项目 (Sync All Maven Projects)重新加载所有 Maven 项目 (Reload All Maven Projects)主要作用使 IDEA 项目结构、依赖关系与 pom.xml 文件同步。强制重新读取所有 pom.xml 文件&#xff0c;并重建 IDEA 的 Maven 项目模型。缓存使用 IDEA 缓存的 Maven 项…...

如何查询网站是否被百度蜘蛛收录?

一、使用site命令查询 这是最直接的方法。在百度搜索框中输入“site:你的网站域名”&#xff0c;例如“site.com”&#xff08;请将“example.com”替换为你实际的网站域名&#xff09;。如果搜索结果显示了你的网站页面&#xff0c;并且显示了收录的页面数量&#xff08;如“…...

el-table树状表格,默认展开第一个节点的每一层

效果如图 <template><el-table:data"tableData"style"width: 100%":tree-props"{ children: children, hasChildren: hasChildren }":expand-row-keys"expandRowKeys"row-key"id"expand-change"handleExpan…...

express-validator 数据校验详解

express-validator 是一个用于在 Express 应用中进行数据验证和清理的中间件。 一、安装 # 使用 npm 安装npm install express-validator 二、基本使用 1. 引入和初始化 const express require("express");const { body, validationResult } require("ex…...

使用VSCODE开发C语言程序

使用vscode配置C语言开发环境 一、安装VSCODE 1、下载vscode ​ 从官方网站&#xff08;https://code.visualstudio.com/Download&#xff09;上&#xff0c;下载windows版本的vscode 2、安装vscode ​ 下载完毕后&#xff0c;按照提示进行安装即可&#xff08;尽可能不要安…...

Python学习心得常用的内置函数

常用的内置函数&#xff1a; 1.数据类型转换函数&#xff1a; 描述说明 描述说明 bool(obj) 获取指定对象 obj 的布尔值 str(obj) 将指定对象 obj 转成字符串类型 int(x) 将 x 转成 int 类型 float(x) 将 x 转成 float 类型 list(sequence) 将序列转成列表类型 tu…...