当前位置 博文首页 > freemote的博客:【玩转ESP32】7、ESP32连接wifi

    freemote的博客:【玩转ESP32】7、ESP32连接wifi

    作者:[db:作者] 时间:2021-07-05 09:54

    系列文章:
    【玩转ESP32】1、开发环境搭建
    【玩转ESP32】2、开发参考资料
    【玩转ESP32】3、点亮LED,Blink,blink,blink
    【玩转ESP32】4、ESP32驱动DHT11
    【玩转ESP32】5、i2c-tools访问i2c设备
    【玩转ESP32】6、驱动i2c设备—0.96 OLED

    前言

    ESP32 WIFI功能支持STA、AP、APSTA三种模式,本文聊聊在STA模式下,连接到路由器。

    1、官方参考历程

    在examples\wifi\getting_started\station目录下就是官方的流程,只需要根据自己的实际情况改变ssid和password即可,官方代码以宏定义的形式定义,更改之后,编译、下载即可连接上。

    2、代码实现

    2.1、初始化

    void wifi_init_sta(void)
    {
        s_wifi_event_group = xEventGroupCreate();
    
        ESP_ERROR_CHECK(esp_netif_init());
        ESP_ERROR_CHECK(esp_event_loop_create_default());
        esp_netif_create_default_wifi_sta();
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    
        esp_event_handler_instance_t instance_any_id;
        esp_event_handler_instance_t instance_got_ip;
        ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                            ESP_EVENT_ANY_ID,
                                                            &event_handler,
                                                            NULL,
                                                            &instance_any_id));
        ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
                                                            IP_EVENT_STA_GOT_IP,
                                                            &event_handler,
                                                            NULL,
                                                            &instance_got_ip));
        wifi_config_t wifi_config = {
            .sta = {
                .ssid = IOT_CORE_ESP_WIFI_SSID,
                .password = IOT_CORE_ESP_WIFI_PASS,
    	        .threshold.authmode = WIFI_AUTH_WPA2_PSK,
                .pmf_cfg = {
                    .capable = true,
                    .required = false
                },
            },
        };
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
        ESP_ERROR_CHECK(esp_wifi_start() );
        ESP_LOGI(TAG, "wifi_init_sta finished.");
    }
    

    其中xEventGroupCreate()用于创建一个事件标志组,返回值是事件标志组句柄,属于frerertos里面的东西;
    esp_netif_init()用于初始化tcpip协议栈;
    esp_event_loop_create_default()创建一个默认系统事件调度循环,之后可以注册回调函数来处理系统的一些事件;
    esp_netif_create_default_wifi_sta()创建wifi sta;
    wifi_init_config_t cfg=WIFI_INIT_CONFIG_DEFAULT()用于获取wifi的默认配置;
    esp_wifi_init(&cfg)用于初始化wifi;
    esp_event_handler_instance_register 用于向上面的esp_event_loop_create_default()注册回调函数,在回调函数里面可以处理各种系统事件,比如wfi连接,断开等;
    wifi_config是一个结构体变量,用于设置wifi的参数,如ssid,password等;
    esp_wifi_set_mode用于设置wifi的模式,在这里使用sta模式;
    esp_wifi_set_config设置wifi参数;
    esp_wifi_start启动wifi。

    2.2、回调函数

    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) 
        {
            esp_wifi_connect();
        } 
        else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) 
        {
            if (s_retry_num < IOT_CORE_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_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);
        }
    }
    

    只要默认系统事件有变化,就会进这个函数,在这个函数里面可以处理wifi连接、断开事件等,事件发生后设置事件标志位。

    2.3、阻塞等待wifi连接

    void esp_wifi_sta_check_state(void)
    {
        /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
         * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
        EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
                WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
                pdFALSE,
                pdFALSE,
                portMAX_DELAY);
    
        /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
         * happened. */
        if (bits & WIFI_CONNECTED_BIT) 
        {
            xEventGroupClearBits(s_wifi_event_group,WIFI_CONNECTED_BIT);  
            ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                     IOT_CORE_ESP_WIFI_SSID, IOT_CORE_ESP_WIFI_PASS);
        } 
        else if (bits & WIFI_FAIL_BIT) 
        {
            xEventGroupClearBits(s_wifi_event_group,WIFI_FAIL_BIT);       
            ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                     IOT_CORE_ESP_WIFI_SSID, IOT_CORE_ESP_WIFI_PASS);
        } 
        else 
        {
            ESP_LOGE(TAG, "UNEXPECTED EVENT");
        }
    }
    

    在这个函数里面,调用xEventGroupWaitBits阻塞等待标志位,参数portMAX_DELAY是等待时间,表示一直等待,设置了两个WIFI_FAIL_BITIP_EVENT_STA_GOT_IP,其中IP_EVENT_STA_GOT_IP位设置后,就代表连接到了wifi,获取到了wifi。

    3、现象

    在这里插入图片描述
    esp32连接到了wifi,并且分配了ip地址;如果断开,会进行重连。

    欢迎关注微信公众号【物联网思考】,获取资料。在这里插入图片描述

    cs