ESP32-IDF05-1 WIFI-esp32联网

Posted Ciaran-byte

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP32-IDF05-1 WIFI-esp32联网相关的知识,希望对你有一定的参考价值。

esp32联网

1. 简介

  这个过程整体比较简单,联网过程可以参考官网教程

  写这篇文章主要是有一个坑,就是wifi配置结构体 wifi_config_t wifi_config 的处理方法。

  这里官网给出的初始化代码是

  wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_PASS,
            /* Setting a password implies station will connect to all security modes including WEP/WPA.
             * However these modes are deprecated and not advisable to be used. Incase your Access point
             * doesn't support WPA2, these mode can be enabled by commenting below line */
	     .threshold.authmode = WIFI_AUTH_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };

  但是不同标准的c或者c++不能支持这种初始化方法。所以我初始化的时候就进行了默认的初始化

wifi_config_t wifi_config;     

  但是如果就按直接默认初始化,然后后面配置其他参数,很大程度是不能用的。因为默认初始化使得很多位的配置都是随机的,所以要给这个结构体进行重新赋值,也就是把所有位都清零

  memset(&wifi_config, 0, sizeof(wifi_config));

  因为已经过了初始化阶段,再给结构体中的数组进行赋值其实是比较麻烦的。但是看了下,这个结构体里面的ssid和password数组使用的数据类型都是uint8_t 所以是可以用字符串赋值的方法的。所以我就使用了sprintf函数进行赋值


        sprintf((char*)wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID);        //配置wifi名称              
        sprintf((char*)wifi_config.sta.password, EXAMPLE_ESP_WIFI_PASS);    //配置wifi密码
        wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;            //配置加密协议
        wifi_config.sta.pmf_cfg.capable = true;                             
        wifi_config.sta.pmf_cfg.required = false;

  总而言之,wifi联网的配置方法还是很简单的,官网手册写的通俗易懂,但是我就是在结构体配置这一步卡了很久,把经验写出来进行分享。

2. 代码

  我写的wifi配置库代码如下。有三个文件

  • bsp_wifi_station.h
  • bsp_wifi_station.cpp
  • main.cpp

bsp_wifi_station.h

#ifndef _BSP_WIFI_STATION_H_
#define _BSP_WIFI_STATION_H_

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"


//定义联网相关的宏
#define EXAMPLE_ESP_WIFI_SSID      "my_ssid"            //账号
#define EXAMPLE_ESP_WIFI_PASS      "my_password"        //密码
#define EXAMPLE_ESP_MAXIMUM_RETRY  5					//wifi连接失败以后可以重新连接的次数
#define WIFI_CONNECTED_BIT BIT0                         //wifi连接成功标志位
#define WIFI_FAIL_BIT      BIT1							//wifi连接失败标志位

//定义联网所需要的变量
static EventGroupHandle_t s_wifi_event_group;  //事件组,用于对wifi响应结果进行标记
static const char* TAG = "wifi station";      //log标志位
static int s_retry_num = 0;                     //记录wifi重新连接尝试的次数


void bsp_wifi_init_sta();  //用于连接wifi


#endif

bsp_wifi_station.cpp


#include "bsp_wifi_station.h"

/**
@brief 处理wifi连接和ip分配时候事件的回调函数
**/

static void 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) {   //如果是wifi连接事件,就进行wifi连接
        esp_wifi_connect();
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {  //如果是wifi连接失败事件
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {   //如果没有达到最高尝试次数,继续尝试
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        }
        else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);   //如果达到了最高尝试次数,就停止尝试,并且标记连接失败
        }
        ESP_LOGI(TAG, "connect to the AP fail");
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {     //如果是ip获取事件,获取到了ip就打印出来
        ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);    //如果成功获取到了ip,就标记这次wifi连接成功
    }
}



/**
@brief 用于连接wifi的函数
@param[in] 无
@retval 无
@note 这里wifi连接选项设置了使用nvs,会把每次配置的参数存储在nvs中。因此请查看分区表中是否对nvs分区进行了设置

**/
void bsp_wifi_init_sta()
{

   //00 使能nvs
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)  //如果nvs空间满了,就进行擦除
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");

  //00 创建wifi事件的标志组
    s_wifi_event_group = xEventGroupCreate();

  //01 WIFI/LWIP初始化阶段

         //01-1 创建LWIP核心任务
        ESP_ERROR_CHECK(esp_netif_init());


         //01-2 创建系统事件任务
        ESP_ERROR_CHECK(esp_event_loop_create_default());

          //01-3 创建station实例
        esp_netif_create_default_wifi_sta();

          //01-4 创建wifi驱动程序任务,并初始化wifi驱动程序
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));

        //01-5 注册,用于处理wifi连接的过程中的事件
        esp_event_handler_instance_t instance_any_id;   //用于处理wifi连接时候的事件的句柄
        esp_event_handler_instance_t instance_got_ip;    //用于处理ip分配时候产生的事件的句柄
        ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,   //该句柄对wifi连接所有事件都产生响应,连接到event_handler回调函数
            ESP_EVENT_ANY_ID,
            &event_handler,
            NULL,
            &instance_any_id));
        ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,   //该句柄仅仅处理IP_EVENT事件组中的获取ip地址事件,连接到event_handler回调函数
            IP_EVENT_STA_GOT_IP, 
            &event_handler,
            NULL,
            &instance_got_ip));
//02 WIFI配置阶段

        //02-1 定义wifi配置参数
        wifi_config_t wifi_config;                                           //定义wifi配置参数结构体
        memset(&wifi_config, 0, sizeof(wifi_config));                       //对结构体进行初始化,把参数全部定义为0
        sprintf((char*)wifi_config.sta.ssid, EXAMPLE_ESP_WIFI_SSID);        //配置wifi名称              
        sprintf((char*)wifi_config.sta.password, EXAMPLE_ESP_WIFI_PASS);    //配置wifi密码
        wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;            //配置加密协议
        wifi_config.sta.pmf_cfg.capable = true;                             
        wifi_config.sta.pmf_cfg.required = false;

        //02-2 配置wifi工作模式
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

        //02-3 写入配置
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

     
 //03 wifi启动阶段

        //03-1 启动wifi驱动程序
        ESP_ERROR_CHECK(esp_wifi_start());   //会触发回调函数
        ESP_LOGI(TAG, "wifi_init_sta finished.");

  //04 输出wifi连接结果      
        EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);


        if (bits & WIFI_CONNECTED_BIT) {
            ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
        }
        else if (bits & WIFI_FAIL_BIT) {
            ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
        }
        else {
            ESP_LOGE(TAG, "UNEXPECTED EVENT");
        }

  
//05  事件解绑定

        ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
        ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
        vEventGroupDelete(s_wifi_event_group);
}

main.cpp




#include "bsp_wifi_station.h"

extern "C" void app_main(void)
{
 
   bsp_wifi_init_sta();
}


以上是关于ESP32-IDF05-1 WIFI-esp32联网的主要内容,如果未能解决你的问题,请参考以下文章

ESP32-IDF 05-2 WIFI-esp32获取温度和天气信息

ESP32 SDK 开发——ESP32/ESP-IDF环境搭建-linux

ESP32 ESP-IDF开发环境搭建,Windows下基于ESP-IDF | Cmake | VScode插件的 ESP32 开发环境搭建

ESP32-IDF编译问题

ESP32学习笔记之ESP32-idf环境搭载心得

ESP32-IDF03-1 系统-内存管理