STA mode application of ESP32 WIFI & regulating Bluetooth and WIFI transmission power

The following definitions of relevant API interfaces can be viewed in l Lexin's official website: Wi Fi Library - ESP32 - ESP-IDF programming guide v4 4 documents

STA mode configuration process:

#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      CONFIG_ESP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS      CONFIG_ESP_WIFI_PASSWORD
#define EXAMPLE_ESP_MAXIMUM_RETRY  CONFIG_ESP_MAXIMUM_RETRY


#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static const char *TAG = "wifi station";

static int s_retry_num = 0;

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 < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        }
        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;
    }
}

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 = 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
            },
        },
    };
    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.");
}

void app_main(void)
{
    //Initialize NVS
    esp_err_t ret = nvs_flash_init();
    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();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
}

STA process:

STA process analysis:

Initial stage of Wi Fi / LwIP

As shown in 1.1 \ 1.2 \ 1.3 \ 1.4 in the above figure, respectively

  • Initialize LwIP
    Create LwIP core tasks and initialize LwIP related work.
ESP_ERROR_CHECK(esp_netif_init());
// Create a system event task and initialize a callback function for application events.
ESP_ERROR_CHECK(esp_event_loop_create_default());
// Create a default network interface instance binding base station with TCP / IP stack.
esp_netif_create_default_wifi_sta();

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));
  • Initialize Wi Fi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

Wi Fi configuration phase

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
            },
        },
    };
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );

Wi Fi startup phase

call esp_wifi_start() To start the Wi Fi driver.

Wi Fi driver will WIFI_EVENT_STA_START release To event task; The event task then performs some general operations and invokes the application event callback function.

The application event callback function will WIFI_EVENT_STA_START Relay to application tasks. Called at this time esp_wifi_connect().

ESP_ERROR_CHECK(esp_wifi_start());

Wi Fi connection phase

once esp_wifi_connect() When called, the Wi Fi driver will start the internal scanning / connection process.

If the internal scan / connect process is successful, a WIFI_EVENT_STA_CONNECTED . In the event task, it will start the DHCP client, which will eventually trigger the DHCP process.

Wi Fi connection may fail due to reasons such as wrong password and unable to find AP. In this case, there will be WIFI_EVENT_STA_DISCONNECTED ,EXAMPLE_ESP_MAXIMUM_RETRY reconnection times can be set.

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 < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else
        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;
    }
}

Wi Fi "Got IP" phase

After initializing the DHCP client, the IP phase begins. If the IP address is successfully received from the DHCP server, the IP_EVENT_STA_GOT_IP And the event task will perform normal processing.

In the application event callback, IP_EVENT_STA_GOT_IP Relayed to application tasks. This event is very special for LwIP based applications, which means that the application is ready to start its tasks, such as creating TCP / UDP sockets, etc. A very common error is when receiving IP_EVENT_STA_GOT_IP Initialize socket before. Do not start socket related work until you receive the IP.

Bluetooth and WiFi transmission power settings:

1 Wi Fi TX power adjustment
There are two ways to modify Wi Fi TX power:

Modify Max WiFi TX power in menuconfig
Using API esp_wifi_set_max_tx_power()
1.1 modify Max WiFi TX power in menuconfig
Adjust Wi Fi TX power by modifying Max WiFi TX power in menuconfig - > component config - > PHY, with a maximum of 20 dB. As shown below:


1.2 using API esp_wifi_set_max_tx_power()
By calling esp_wifi_set_max_tx_power() to modify Wi Fi TX power.

2 BLE Tx Power adjustment
Low power Bluetooth transmit power can be through API esp_ble_tx_power_set(), see esp_bt.h.

Note: power level 4 is used by default in ESP32 SDK, and the corresponding transmission power is 0 dBm. The transmission power of ESP32 Bluetooth is from 0 to 7, with a total of 8 power levels, and the transmission power range is from – 12 dBm to 9 dBm. When the power level increases by 1, the transmission power increases by 3 dBm.

Keywords: socket Embedded system IoT bluetooth wifi

Added by munsiem on Thu, 10 Feb 2022 09:38:13 +0200