ESP32系列--第五篇 WiFi Station模式

一、目的

        在上一篇《ESP32系列--第四篇 WiFi概述》我们已经将ESP32 WiFi的基本框图、功能以及API做了简单介绍,本篇我们以源代码的形式来讲讲如何使用WiFi Station功能进行联网。

二、准备

        首先我们从esp-idf里面拷贝一份官方的示例代码

        1、首先初始化esp-idf开发环境,命令行输入以下命令(不清楚去看《ESP32系列--第二篇 开发环境搭建-Ubuntu系统》)

get_idf

        2、拷贝工程并进入到station目录中

cp -r  ~/workspace/third/esp32/esp-idf/examples/wifi/getting_started/station ~/workspace/work/esp32/
cd workspace/work/esp32/station/

        3、设置芯片平台并进入配置菜单设置WiFi相关信息  

idf.py set-target esp32
idf.py menuconfig

        根据自己的ESP32模组选择合适的Flash大小

        如果不知道自己的模组的Flash大小,请查看此链接

查看ESP32模组中Flash颗粒以及芯片信息_coder.mark的博客-CSDN博客一、目的 我们在使用二、介绍SPI Flash Modes - ESP32 - — esptool.py latest documentation (espressif.com)https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/spi-flash-modes.html三、实战...https://blog.csdn.net/tianizimark/article/details/124676861

        4、设置你自己的WiFi名称和密码并保存

         5、编译并烧写

idf.py build flash monitor

        正常编译成功如下图

三、实战

        我们打开main/station_example_main.c文件定位到app_main函数

        注意此处的app_main是在线程环境中执行,是用户代码的入口(后面会专门写一篇博文介绍esp32的启动过程)

        首先调用nvs_flash_init()函数进行nvs flash分区的初始化,此分区用于存储一些K-V对信息;由于WiFi驱动里面有些信息需要存储,故在使用WiFi之前需要先初始化nvs分区;然后我们就看到wifi_init_sta函数         

        在wifi_init_sta函数先创建了一个FreeRTOS事件组(FreeRTOS事件组一般用于多个线程间同步),然后调用esp_netif_init初始化TCP/IP协议栈,调用esp_netif_create_default_wifi_sta初始化默认的sta接口,然后通过esp_wifi_init接口初始化了WiFi(我们在前一篇博文中介绍过此函数)。

        在上一篇中我们讲到WiFi功能框图,每个方框可以认为一个模块(模块内高度聚合,有的模块可能是单个线程,有的可能是多个线程),用户任务(application task)要与event task这个任务做一些同步,所以我们此处使用FreeRTOS event group来实现(什么是FreeRTOS事件组?又是知识点,先自行查资料理解一下,本篇暂不扩展)。

         event task使用esp_event_loop_create_default()来初始化,并注册了WIFI_EVENT相关的所有事件和IP_EVENT相关的所有事件,这样当对应的事件发生时,就会调用我们注册的回调,当前我们注册的回调为event_handler;

        WIFI_EVENT那肯定是跟WiFi Driver相关的

/** WiFi event declarations */                                                     
typedef enum {                                                                     
    WIFI_EVENT_WIFI_READY = 0,           /**< ESP32 WiFi ready */                  
    WIFI_EVENT_SCAN_DONE,                /**< ESP32 finish scanning AP */          
    WIFI_EVENT_STA_START,                /**< ESP32 station start */               
    WIFI_EVENT_STA_STOP,                 /**< ESP32 station stop */                
    WIFI_EVENT_STA_CONNECTED,            /**< ESP32 station connected to AP */  
    WIFI_EVENT_STA_DISCONNECTED,         /**< ESP32 station disconnected from AP */
    WIFI_EVENT_STA_AUTHMODE_CHANGE,      /**< the auth mode of AP connected by ESP32 station changed */
                                                                                   
    WIFI_EVENT_STA_WPS_ER_SUCCESS,       /**< ESP32 station wps succeeds in enrollee mode */
    WIFI_EVENT_STA_WPS_ER_FAILED,        /**< ESP32 station wps fails in enrollee mode */
    WIFI_EVENT_STA_WPS_ER_TIMEOUT,       /**< ESP32 station wps timeout in enrollee mode */
    WIFI_EVENT_STA_WPS_ER_PIN,           /**< ESP32 station wps pin code in enrollee mode */
    WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP,   /**< ESP32 station wps overlap in enrollee mode */
                                                                                   
    WIFI_EVENT_AP_START,                 /**< ESP32 soft-AP start */               
    WIFI_EVENT_AP_STOP,                  /**< ESP32 soft-AP stop */                
    WIFI_EVENT_AP_STACONNECTED,          /**< a station connected to ESP32 soft-AP */
    WIFI_EVENT_AP_STADISCONNECTED,       /**< a station disconnected from ESP32 soft-AP */
    WIFI_EVENT_AP_PROBEREQRECVED,        /**< Receive probe request packet in soft-AP interface */
                                                                                   
    WIFI_EVENT_FTM_REPORT,               /**< Receive report of FTM procedure */
                                                                                   
    /* Add next events after this only */                                          
    WIFI_EVENT_STA_BSS_RSSI_LOW,         /**< AP's RSSI crossed configured threshold */
    WIFI_EVENT_ACTION_TX_STATUS,         /**< Status indication of Action Tx operation */
    WIFI_EVENT_ROC_DONE,                 /**< Remain-on-Channel operation complete */
                                                                                   
    WIFI_EVENT_STA_BEACON_TIMEOUT,       /**< ESP32 station beacon timeout */   
                                                                                   
    WIFI_EVENT_MAX,                      /**< Invalid WiFi event ID */             
} wifi_event_t;

        IP_EVENT那肯定是跟TCP/IP协议栈相关的

/** IP event declarations */                                                       
typedef enum {                                                                     
    IP_EVENT_STA_GOT_IP,               /*!< station got IP from connected AP */                                                      
    IP_EVENT_STA_LOST_IP,              /*!< station lost IP and the IP is reset to 0 */
    IP_EVENT_AP_STAIPASSIGNED,         /*!< soft-AP assign an IP to a connected station */
    IP_EVENT_GOT_IP6,                  /*!< station or ap or ethernet interface v6IP addr is preferred */
    IP_EVENT_ETH_GOT_IP,               /*!< ethernet got IP from connected AP */   
    IP_EVENT_ETH_LOST_IP,              /*!< ethernet lost IP and the IP is reset to 0 */
    IP_EVENT_PPP_GOT_IP,               /*!< PPP interface got IP */                
    IP_EVENT_PPP_LOST_IP,              /*!< PPP interface lost IP */               
} ip_event_t;

        

        wifi初始化后需要设置wifi模式为WIFI_MODE_STA ,然后我们设置了我们需要连接的WiFi信息(通过wifi_config_t这个结构体),这些都完成后,我们通过esp_wifi_start启动了WiFi功能。(那什么时候WiFi算正常启动呢?请看下面的分析)

        xEventGroupWaitBits用于等待事件的发生,此处我们只等待两个事件,一个是WiFi连接成功事件,一个是WiFi连接失败事件,也就是说任务阻塞在此处等待事件的发生。

        那初学的小伙伴要问了,谁会触发这些事件呢?

        下面进入到本篇最重要的环节,事件回调函数event_handler

        调用esp_wifi_start接口后,WiFi驱动开始工作,并通过event_task告知用户WiFi正常启动,此时我们调用了esp_wifi_connect接口去主动连接我们已经配置好WiFi。

        注意event_base用于区分不同模块的事件的,如果能够正常连接我们自己配置好的wifi,在调用了esp_wifi_connect接口后就会触发IP_EVENT事件,我们通过IP_EVENT_STA_GOT_IP这个子事件就可以知道是否已经正常联网,在这个子事件中我们通过xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);告知用户线程联网完成。

        上图显示的是由于配置的WiFi信息错误为能成功联网

         

        上图是正常连接上WiFi的情况

关于esp_event_group的更多介绍请查看

Event Loop Library - ESP32 - — ESP-IDF Programming Guide latest documentationhttps://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_event.html?highlight=esp_event_loop_create

好了,以上就是ESP32联网的最基本实现。 

        

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值