最近使用 ESP32-C3 跑了下 softAP demo,阅读了 demo 源码及跑过 demo 之后,脑海中不禁有以下几个疑问:

  1. ESP32-C3 作为 SoftAP 时,默认的 IP 地址为 192.168.4.1,如何修改默认的 IP 地址?
  2. ESP32-C3 作为 SoftAP 时,有 Station 连接上了之后,如何获取 SoftAP 分配给这个 Station 的 IP 地址 ?

笔者认为 Espressif 虽然提供了较为丰富的文档和示例,但是值得改进的地方还是有很多的。就以 softAP demo 为例,这个 demo 仅仅只是做了一个简单的示例,而对于我以上的 2 个问题,却没有很好的展现出来。

在网上看了一大堆所谓的技术文章,全都是千篇一律的跑了一下 softAP demo,然后对 softAP demo 源码进行一堆所谓的分析,然后就没有然后了,没有深入的对这个 demo 进行发掘。所以笔者阅读文档,结合 softAP demo 源码,写了一份自己的 demo,对以上 2 个问题以代码的形式做了示例。

ESP32-C3 作为 SoftAP 时,默认的 IP 地址为 192.168.4.1,如何修改默认的 IP 地址?

要修改 SoftAP 的默认 IP 地址,核心的逻辑就是要先停止 DHCP,然后设置 IP 地址,子网掩码,网关,然后在启用 DHCP 即可。

void set_softap_ip(esp_netif_t *softap)
{esp_netif_ip_info_t ip = { 0 };ip.ip.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_IP);ip.netmask.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_NETMASK);ip.gw.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_GATEWAY);esp_netif_dhcps_stop(softap);esp_netif_set_ip_info(softap, &ip);esp_netif_dhcps_start(softap);return;
}
void wifi_init_softap(void)
{esp_log_level_set("wifi", ESP_LOG_ERROR);esp_netif_t *softap = esp_netif_create_default_wifi_ap();set_softap_ip(softap);wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));wifi_config_t wifi_config = {.ap = {.ssid = CONFIG_ESP_WIFI_SSID,.ssid_len = strlen(CONFIG_ESP_WIFI_SSID),.channel = CONFIG_ESP_WIFI_CHANNEL,.password = CONFIG_ESP_WIFI_PASSWORD,.max_connection = CONFIG_ESP_MAX_STA_CONN,.authmode = WIFI_AUTH_WPA_WPA2_PSK,.pmf_cfg = {.required = false,},},};if (strlen(CONFIG_ESP_WIFI_PASSWORD) == 0) {wifi_config.ap.authmode = WIFI_AUTH_OPEN;}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD, CONFIG_ESP_WIFI_CHANNEL);
}

ESP32-C3 作为 SoftAP 时,有 Station 连接上了之后,如何获取 SoftAP 分配给这个 Station 的 IP 地址 ?

Station 在连接 SoftAP 的过程中,其实可以分为两个阶段,在这两个阶段分别可以获取到 Station 的不同信息。

  1. Station 连接上 SoftAP,但还没有获取到 SoftAP 分配的 IP 地址,也就是在 DHCP 过程之前。此时只能获取到 Station 的 MAC 地址。
  2. Station 连接上 SoftAP,获取到 SoftAP 分配的 IP 地址,也就是在 DHCP 过程之后。此时能获取到 Station 的 IP 地址。

第一阶段属于 WiFi 驱动层,原生的 softAP demo 其实写的已经很好了,主要就是通过注册 WIFI_EVENT,在 event 回调中来获取到 Station 的 MAC 地址。

第二阶段属于 TCP/IP 协议栈层,也就是 LWIP。但原生的 softAP demo 没有对这一部分进行说明。以下代码是笔者根据官方文档自己写的。读者可以参考这部分代码来获取连接上的 Station 的 IP 地址。

  1. 首先注册 IP_EVENT

    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));
    
  2. 在 event 回调中对 IP_EVENT_AP_STAIPASSIGNED 这个 event_id 进行处理。

    static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
    {if (event_base == IP_EVENT) {ip_event_handler(arg, event_id, event_data);} else {wifi_event_handler(arg, event_id, event_data);}
    }
    
    static void ip_event_handler(void* arg, int32_t event_id, void* event_data)
    {if (event_id == IP_EVENT_AP_STAIPASSIGNED) {ip_event_ap_staipassigned_t *event = (ip_event_ap_staipassigned_t *) event_data;ESP_LOGI(TAG, "the IP address assigned by the SoftAP is" IPSTR, IP2STR(&event->ip));}
    }
    

    之所以说 Espressif 值的改进的地方还有很多,一是因为 softAP demo 展示的不够详细,另一个就是因为文档更新的不及时。在阅读 Espressif Event Handling 时,文档中写明了 event_idIP_EVENT_AP_STAIPASSIGNEDevent_data 是一个 n/a 结构:

    但是在阅读 esp-idf 源码的时候突然看到了 ip_event_ap_staipassigned_t 的定义:


    所以在 IP_EVENT_AP_STAIPASSIGNED 的处理中抱着试一试的想法将 event_data 强制转换成了 ip_event_ap_staipassigned_t 指针,没想到还真的可以获取到连接上的 Station 的 IP 地址。

最后附上笔者自己的 SoftAP 代码,编译后可以直接在 ESP32-C3 上运行,esp-idf 使用 master 分支,测试 commit 为 fde4afc67a

完整工程代码已经上传到我的 GitHub 仓库 esp-examples ,有需要的读者可以直接下载。

#include <string.h>
#include <netdb.h>
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "nvs_flash.h"
#include "esp_netif.h"static const char *TAG = "example";static void wifi_event_handler(void* arg, int32_t event_id, void* event_data)
{if (event_id == WIFI_EVENT_AP_STACONNECTED) {wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid);} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data;ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid);}
}static void ip_event_handler(void* arg, int32_t event_id, void* event_data)
{if (event_id == IP_EVENT_AP_STAIPASSIGNED) {ip_event_ap_staipassigned_t *event = (ip_event_ap_staipassigned_t *) event_data;ESP_LOGI(TAG, "the IP address assigned by the SoftAP is" IPSTR, IP2STR(&event->ip));}
}static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{if (event_base == IP_EVENT) {ip_event_handler(arg, event_id, event_data);} else {wifi_event_handler(arg, event_id, event_data);}
}void set_softap_ip(esp_netif_t *softap)
{esp_netif_ip_info_t ip = { 0 };ip.ip.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_IP);ip.netmask.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_NETMASK);ip.gw.addr = ipaddr_addr(CONFIG_ESP_SOFTAP_GATEWAY);esp_netif_dhcps_stop(softap);esp_netif_set_ip_info(softap, &ip);esp_netif_dhcps_start(softap);return;
}void wifi_init_softap(void)
{esp_log_level_set("wifi", ESP_LOG_ERROR);esp_netif_t *softap = esp_netif_create_default_wifi_ap();set_softap_ip(softap);wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));wifi_config_t wifi_config = {.ap = {.ssid = CONFIG_ESP_WIFI_SSID,.ssid_len = strlen(CONFIG_ESP_WIFI_SSID),.channel = CONFIG_ESP_WIFI_CHANNEL,.password = CONFIG_ESP_WIFI_PASSWORD,.max_connection = CONFIG_ESP_MAX_STA_CONN,.authmode = WIFI_AUTH_WPA_WPA2_PSK,.pmf_cfg = {.required = false,},},};if (strlen(CONFIG_ESP_WIFI_PASSWORD) == 0) {wifi_config.ap.authmode = WIFI_AUTH_OPEN;}ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d", CONFIG_ESP_WIFI_SSID, CONFIG_ESP_WIFI_PASSWORD, CONFIG_ESP_WIFI_CHANNEL);
}void app_main(void)
{ESP_ERROR_CHECK(nvs_flash_init());ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));wifi_init_softap();}

Espressif 玩转 SoftAP相关推荐

  1. Espressif 玩转 固件下载

    今天来撸一下 Espressif 的 Serial Protocol.虽然 Espressif 已经提供了 esptool 工具用于固件下载,但架不住还是有将下载功能集成到自己工具中的需求呀. 对于 ...

  2. Espressif 玩转 PWM

    本文只针对 ESP32-C3. Espressif 素来以完善的文档著称,但在使用 PWM 用来控灯时却产生了诸多疑问,翻遍 datasheet 和 ESP-IDF Programming Guide ...

  3. Espressif 玩转 High Resolution Timer

    应用中经常需要用到 timer,对于 ms 级别的定时需求,FREERTOS 中的 Software Timer 完全就可以满足需求,唯一不足的是 FREERTOS 中的 Software Timer ...

  4. Espressif 玩转 编译环境

    Espressif 的 ESP-IDF 最近发布了 release/v5.0,之前一直在 release/v4.3 上开发,不知不觉已经落后了 2 个版本(中间还有一个 release/4.4 版本) ...

  5. Espressif 玩转串口解析(FreeRTOS-Plus-CLI)

    最近想用 ESP32-C3 做一个串口解析的应用程序.类似 ESP-AT,但实现的功能比 ESP-AT 少的多.使用 ESP-IDF 的版本为 release/v4.4,本来是想基于 uart_eve ...

  6. 【打卡帖】7日玩转ESP32——(第7日) 通过SoftAP的WiFi配网

    文章目录 一.知识要点 二.参考例程 三.课后作业 四.参考答案 五.打卡~ 一.知识要点 基于前一日Day 6的课程内容,今日增加了WiFi配网功能. 可以参考DAY 5的课程里面WiFi配网功能的 ...

  7. arduino nano 蓝牙_用Arduino玩转掌控板(ESP32):ESP32概述与Arduino软件准备

    前言 近年来,掌控板(英文名:mPython)在创客教育中应用越来越广泛.掌控板集成了 ESP32 高性能双核芯片,具备 WiFi 和蓝牙连接功能,同时在板子上又配置了丰富的传感器,最重要的是它是专门 ...

  8. ESP32开发 -- 试玩ESP32

    前文要测试网络调试助手,手头正好有个ESP32一直没有试过.这次正好拿来试玩一下. 一.ESP32官网查看 官网:ESP32官网 这款最小系统开发板搭载了乐鑫最新的系统级芯片 ESP32, 支持 Wi ...

  9. 小明分享:Esp32下softAP+tcp_server的简单实现

    ***提示:对于初学者尽量选择ESP32开发板来完成***原因如下: [ ]WT-ESP32-DevKitC V4的射频性能已经调试完善,用户进行应用设计和开发时无需考虑射频和天线设计.此开发板包含了 ...

最新文章

  1. 图论 ---- 构造DFS树的思想 K - Boomerangs Gym - 102001K
  2. python中文名的发件人邮件读取解析_如何使用python收取读取邮件?
  3. Oracle Study之--Oracle触发器(Trigger)
  4. 功能式Python中的探索性数据分析
  5. sklearn之pipeline:pipeline的简介、使用技巧、案例应用之详细攻略
  6. 基于Struts2的供求信息网设计(二)
  7. 【Powershell】【性能计数器】基础信息的获取
  8. [今日干货]短视频获得种子用户的途径
  9. JDK+Tomcat搭建JSP运行环境--JSP基础
  10. WEB安全基础-文件下载漏洞以及文件包含漏洞演示
  11. vue3.x 自定义事件 emits
  12. linux中crontab的用法
  13. 阿里云:linux 一键安装web环境
  14. synchronized 线程同步
  15. 如何拯救无法「深度学习」的制造业,2019工业智能灵魂10问
  16. 2022最新可用网页百度分享按钮安装教程【网站添加百度分享按钮代码】
  17. 最新的 iPad开发项目 - Fotoboard for iPad
  18. 使用TensorFlow识别交通标志
  19. 阿里宣布史上最大调整:加强敏捷,做薄中台,“大中台” 将何去何从?
  20. Android 自定义View实现文本水平方向的跑马灯效果

热门文章

  1. 杰理之播放电话来电号码声音,前面播放“嘟嘟”声【篇】
  2. vux-upload组件
  3. 安卓cpu调速器和IO策略
  4. 孩子“窝里横,出门怂”,如何解决?
  5. 本原勾股数(毕达哥拉斯三元组)的个数
  6. 关于SuperSlide的使用方法 以及 调用属性参数的介绍
  7. dbfmpi——树莓派豆瓣电台fm发射器
  8. CSS选择器有哪些?选择器的优先级如何排序?
  9. 【Vue】vue中的路由导航守卫(路由的生命周期)
  10. Community detection (2)