Merge branch 'feature/multiple_antenna_example' into 'master'

add multiple antenna test example

Closes WIFI-5237 and WIFI-4985

See merge request espressif/esp-idf!22452
This commit is contained in:
Mu Hai Dong 2023-03-15 11:49:09 +08:00
commit 40cc39528c
8 changed files with 753 additions and 0 deletions

View File

@ -0,0 +1,6 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(wifi_antenna)

View File

@ -0,0 +1,136 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# Wi-Fi antenna soft switch Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to use multi-antenna software switching for ESP.
## How to use example
### Configure the project
Open the project configuration menu (`idf.py menuconfig`).
In the `Example Configuration` menu:
* Set the Wi-Fi configuration.
* Set `WiFi SSID`.
* Set `WiFi Password`.
Optional: If you need, change the other options according to your requirements.
### Build and Flash
Build the project and flash it to the board, then run the monitor tool to view the serial output:
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for all the steps to configure and use the ESP-IDF to build projects.
* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-C6](https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
* [ESP-IDF Getting Started Guide on ESP32-S3](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/index.html)
## Example Output
Note that the output, in particular the order of the output, may vary depending on the environment.
Console output if station connects to AP successfully:
```
I (589) multi-antenna example: ESP_WIFI_MODE_STA
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (629) wifi: wifi firmware version: 2d94f02
I (629) wifi: config NVS flash: enabled
I (629) wifi: config nano formating: disabled
I (629) wifi: Init dynamic tx buffer num: 32
I (629) wifi: Init data frame dynamic rx buffer num: 32
I (639) wifi: Init management frame dynamic rx buffer num: 32
I (639) wifi: Init management short buffer num: 32
I (649) wifi: Init static rx buffer size: 1600
I (649) wifi: Init static rx buffer num: 10
I (659) wifi: Init dynamic rx buffer num: 32
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
I (769) wifi: mode : sta (30:ae:a4:d9:bc:c4)
I (769) multi-antenna example: wifi_init_sta finished.
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
I (889) wifi: state: init -> auth (b0)
I (899) wifi: state: auth -> assoc (0)
I (909) wifi: state: assoc -> run (10)
I (939) wifi: connected with #!/bin/test, aid = 1, channel 6, BW20, bssid = ac:9e:17:7e:31:40
I (939) wifi: security type: 3, phy: bgn, rssi: -68
I (949) wifi: pm start, type: 1
I (1029) wifi: AP's beacon interval = 102400 us, DTIM period = 3
I (2089) esp_netif_handlers: sta ip: 192.168.77.89, mask: 255.255.255.0, gw: 192.168.77.1
I (2089) multi-antenna example: got ip:192.168.77.89
I (2089) multi-antenna example: connected to ap SSID:myssid password:mypassword
I (12268) multi-antenna example: GPIO: [0].pin = 21, [1].pin = 22
I (18568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (19068) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (19568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (20068) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (20568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (21068) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (21568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (22068) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (22568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (23068) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
I (23568) multi-antenna example: rx mode = 1, tx mode = 1, ant0_en = 0, ant1_en = 1
```
Console output if the station failed to connect to AP:
```
I (589) multi-antenna example: ESP_WIFI_MODE_STA
I (599) wifi: wifi driver task: 3ffc08b4, prio:23, stack:3584, core=0
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (599) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (629) wifi: wifi firmware version: 2d94f02
I (629) wifi: config NVS flash: enabled
I (629) wifi: config nano formating: disabled
I (629) wifi: Init dynamic tx buffer num: 32
I (629) wifi: Init data frame dynamic rx buffer num: 32
I (639) wifi: Init management frame dynamic rx buffer num: 32
I (639) wifi: Init management short buffer num: 32
I (649) wifi: Init static rx buffer size: 1600
I (649) wifi: Init static rx buffer num: 10
I (659) wifi: Init dynamic rx buffer num: 32
I (759) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0
I (759) wifi: mode : sta (30:ae:a4:d9:bc:c4)
I (769) multi-antenna example: wifi_init_sta finished.
I (889) wifi: new:<6,0>, old:<1,0>, ap:<255,255>, sta:<6,0>, prof:1
I (889) wifi: state: init -> auth (b0)
I (1889) wifi: state: auth -> init (200)
I (1889) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (1889) multi-antenna example: retry to connect to the AP
I (1899) multi-antenna example: connect to the AP fail
I (3949) multi-antenna example: retry to connect to the AP
I (3949) multi-antenna example: connect to the AP fail
I (4069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (4069) wifi: state: init -> auth (b0)
I (5069) wifi: state: auth -> init (200)
I (5069) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (5069) multi-antenna example: retry to connect to the AP
I (5069) multi-antenna example: connect to the AP fail
I (7129) multi-antenna example: retry to connect to the AP
I (7129) multi-antenna example: connect to the AP fail
I (7249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (7249) wifi: state: init -> auth (b0)
I (8249) wifi: state: auth -> init (200)
I (8249) wifi: new:<6,0>, old:<6,0>, ap:<255,255>, sta:<6,0>, prof:1
I (8249) multi-antenna example: retry to connect to the AP
I (8249) multi-antenna example: connect to the AP fail
I (10299) multi-antenna example: connect to the AP fail
I (10299) multi-antenna example: Failed to connect to SSID:myssid, password:mypassword
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@ -0,0 +1,3 @@
idf_component_register(SRCS "antenna_switch.c"
INCLUDE_DIRS "./include"
REQUIRES esp_wifi)

View File

@ -0,0 +1,304 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* Antenna soft switching Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_check.h"
#include "antenna_switch.h"
#define SOFT_SWITCHING_NAME "three ant auto"
#define SOFT_SWITCHING_PRIORITY 4
#define SOFT_SWITCHING_STACK 4096
#define WAIT_TIME 60 /**< unit 100ms*/
#define MONITOR_TIME 200 /**< unit 10ms*/
#define QUEUE_LENGTH_RSSI_SINGLE 10
#define QUEUE_LENGTH_RSSI_SUM 25
#define RSSI_SINGLE_SIZE sizeof(int8_t)
#define RSSI_SUM_SIZE sizeof(int16_t)
#define RSSI_KD 0.01
static const char *TAG = "ANTENNA_SWITCH_EXAMPLE";
static wifi_antenna_auto_switch_config_t wifi_three_ant_auto_get_config = {
.ant_num = 3,
.ant_zero = 0,
.ant_one = 1,
.ant_two = 3,
.ant_switch = 35
};
static TaskHandle_t antenna_task_handle;
/**< Select the optimal antenna*/
static void antenna_switch_function(const wifi_antenna_auto_switch_config_t *config)
{
wifi_ant_config_t wifi_ant_config;
wifi_ap_record_t wifi_ap_record;
int16_t rssi_ant0 = INT16_MIN, rssi_ant1 = INT16_MIN, rssi_ant2 = INT16_MIN, rssi_max, rssi_min;
/**< Monitor antenna zero signal strength*/
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT0;
wifi_ant_config.rx_ant_default = WIFI_ANT_MODE_ANT0;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT0;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
/**< Wait for parameters to take effect*/
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_ant0 = 0;
rssi_max = wifi_ap_record.rssi;
rssi_min = wifi_ap_record.rssi;
for(int i = 0; i < MONITOR_TIME; i++) {
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_max = rssi_max > wifi_ap_record.rssi ? rssi_max : wifi_ap_record.rssi;
rssi_min = rssi_min < wifi_ap_record.rssi ? rssi_min : wifi_ap_record.rssi;
rssi_ant0 += wifi_ap_record.rssi;
vTaskDelay(10/portTICK_PERIOD_MS);
}
rssi_ant0 = rssi_ant0 - rssi_max - rssi_min;
ESP_LOGD(TAG, "The signal strength of the antenna zero :%d", rssi_ant0);
/**< Monitor antenna one signal strength*/
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT1;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
/**< Wait for parameters to take effect*/
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_ant1 = 0;
rssi_max = wifi_ap_record.rssi;
rssi_min = wifi_ap_record.rssi;
for(int i = 0; i < MONITOR_TIME; i++) {
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_max = rssi_max > wifi_ap_record.rssi ? rssi_max : wifi_ap_record.rssi;
rssi_min = rssi_min < wifi_ap_record.rssi ? rssi_min : wifi_ap_record.rssi;
rssi_ant1 += wifi_ap_record.rssi;
vTaskDelay(10/portTICK_PERIOD_MS);
}
rssi_ant1 = rssi_ant1 - rssi_max - rssi_min;
ESP_LOGD(TAG, "The signal strength of the antenna one :%d", rssi_ant1);
if(config->ant_num == ANT_TOTAL_THREE) {
/**< Monitor antenna two signal strength*/
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant1 = config->ant_two;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
/**< Wait for parameters to take effect*/
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_ant2 = 0;
rssi_max = wifi_ap_record.rssi;
rssi_min = wifi_ap_record.rssi;
for(int i = 0; i < MONITOR_TIME; i++) {
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
rssi_max = rssi_max > wifi_ap_record.rssi ? rssi_max : wifi_ap_record.rssi;
rssi_min = rssi_min < wifi_ap_record.rssi ? rssi_min : wifi_ap_record.rssi;
rssi_ant2 += wifi_ap_record.rssi;
vTaskDelay(10/portTICK_PERIOD_MS);
}
rssi_ant2 = rssi_ant2 - rssi_max - rssi_min;
ESP_LOGD(TAG, "The signal strength of the antenna two :%d", rssi_ant2);
}
if(rssi_ant0 >= rssi_ant1 && rssi_ant0 >= rssi_ant2) {
/**< antenna zero signal strength best*/
ESP_LOGD(TAG, "Antenna soft switching selection ant0");
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT0;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT0;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
}
if(rssi_ant1 > rssi_ant0 && rssi_ant1 > rssi_ant2) {
/**< antenna one signal strength best*/
ESP_LOGD(TAG, "Antenna soft switching selection ant1");
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
}
if(rssi_ant2 > rssi_ant0 && rssi_ant2 > rssi_ant1) {
/**< antenna two signal strength best*/
ESP_LOGD(TAG, "Antenna soft switching selection ant2");
wifi_ant_config.rx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = WIFI_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_two;
ESP_ERROR_CHECK(esp_wifi_set_ant(&wifi_ant_config));
}
}
/**< Kalman filter function*/
static int16_t KalmanFilter(int16_t inData)
{
static float kalman = 0;
static float p = 10;
/**< Process noise*/
float q = 0.01;
/**< Measurement noise*/
float r = 0.2;
/**< Kalman gain*/
float kg = 0;
p += q;
/**< Calculate the Kalman gain*/
kg = p / ( p + r );
/**< Calculate the estimated value of this filtering*/
kalman = kalman + (kg * (inData - kalman));
/**< Updated measurement variance*/
p = (1 - kg) * p;
return (int16_t)(kalman + 0.5);
}
static void antenna_soft_switching_task(void *arg)
{
QueueHandle_t xQueue_rssi_single_handle, xQueue_rssi_sum_handle;
wifi_ap_record_t wifi_ap_record;
int8_t rssi_data_in = 0, rssi_data_out = 0;
int16_t rssi_sum = 0, rssi_last_sum = 0, rssi_save_sum = 0;
int8_t rssi_flag = 0;
uint16_t queue_rssi_single_size = 0, queue_rssi_sum_size = 0;
BaseType_t ret;
wifi_antenna_auto_switch_config_t *config = ( wifi_antenna_auto_switch_config_t *)arg;
xQueue_rssi_single_handle = xQueueCreate(QUEUE_LENGTH_RSSI_SINGLE, RSSI_SINGLE_SIZE);
xQueue_rssi_sum_handle = xQueueCreate(QUEUE_LENGTH_RSSI_SUM, RSSI_SUM_SIZE);
while(true) {
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
/**< Can't find AP*/
vTaskDelay(100/portTICK_PERIOD_MS);
}
/**< Filter the current rssi*/
rssi_data_in = KalmanFilter(wifi_ap_record.rssi);
/**< Save real-time rssi single*/
if (xQueueSend(xQueue_rssi_single_handle, (void *)&rssi_data_in, ( TickType_t ) 0) == pdPASS ) {
rssi_sum += rssi_data_in;
queue_rssi_single_size++;
ESP_LOGD(TAG, "rssi_data_in:%d", rssi_data_in);
}
/**< Rssi single queue full*/
if(queue_rssi_single_size >= RSSI_SINGLE_SIZE) {
xQueueReceive( xQueue_rssi_single_handle, &rssi_data_out, ( TickType_t ) 0);
queue_rssi_single_size--;
rssi_sum -= rssi_data_out;
/**< Save real-time rssi sum*/
if( xQueueSend(xQueue_rssi_sum_handle, (void *)&rssi_sum, ( TickType_t ) 0) == pdPASS ) {
queue_rssi_sum_size++;
}
/**< Rssi sum queue full*/
if (queue_rssi_sum_size >= RSSI_SUM_SIZE) {
xQueueReceive( xQueue_rssi_sum_handle, &rssi_last_sum, ( TickType_t ) 0);
queue_rssi_sum_size--;
if (abs(rssi_last_sum - rssi_sum)> ((config->ant_switch) * 2 / 3 ) && rssi_flag == 0) {
rssi_save_sum = rssi_last_sum;
rssi_flag = 1;
ESP_LOGD(TAG, "Start listening rssi change");
}
if(rssi_flag > 0) {
rssi_flag++;
/**< Wait for 6 seconds to check whether the environment is normal*/
if (rssi_flag > WAIT_TIME) {
ESP_LOGD(TAG, "End of listening rssi");
/**< Ambient noise factor: abs(rssi_last_sum - rssi_sum) * RSSI_KD*/
int16_t ans = abs(rssi_save_sum - rssi_sum) - abs(rssi_last_sum - rssi_sum) * RSSI_KD;
rssi_flag = 0;
if(ans > (config->ant_switch)) {
/**< Determine that the signal has changed*/
queue_rssi_sum_size = 0;
queue_rssi_single_size = 0;
ESP_LOGD(TAG, "monitor result:%d > %d", ans, (config->ant_switch));
/**< Select the optimal antenna*/
antenna_switch_function(config);
/**< Wait for parameters to take effect*/
vTaskDelay(100 / portTICK_PERIOD_MS);
do
{
/**< Clear the rssi single queue*/
ret = xQueueReceive(xQueue_rssi_single_handle, &rssi_data_out, 0);
} while (ret != pdFALSE);
do
{
/**< Clear the rssi sum queue*/
ret = xQueueReceive(xQueue_rssi_sum_handle, &rssi_data_out, 0);
} while (ret != pdFALSE);
}
}
}
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
esp_err_t esp_wifi_set_ant_soft_switch(const wifi_antenna_auto_switch_config_t *config)
{
BaseType_t ret;
ESP_RETURN_ON_FALSE(config->ant_num < ANT_TOTAL_MAX, ESP_ERR_INVALID_ARG, TAG, "antenna nunmbers error!");
/**< Refresh configuration parameters*/
wifi_three_ant_auto_get_config = *config;
/**< Select the optimal antenna*/
antenna_switch_function(config);
ret = xTaskCreatePinnedToCore(antenna_soft_switching_task, SOFT_SWITCHING_NAME, SOFT_SWITCHING_STACK, (void *)config, SOFT_SWITCHING_PRIORITY, &antenna_task_handle, portNUM_PROCESSORS - 1);
if (ret != pdPASS) {
ESP_LOGE(TAG, "create task %s failed", SOFT_SWITCHING_NAME);
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_wifi_get_ant_soft_switch_config(wifi_antenna_auto_switch_config_t *config)
{
*config = wifi_three_ant_auto_get_config;
return ESP_OK;
}
void esp_deinit_ant_soft_switch(void)
{
vTaskDelete(antenna_task_handle);
}

View File

@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/*
* Design of antenna soft switching : 2023.02.21
*
* version:v1.0
*/
#pragma once
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ANT_TOTAL_TWO, /**< Two antennas participate in the switch */
ANT_TOTAL_THREE, /**< Three antennas participate in the switch */
ANT_TOTAL_MAX
} ant_mun_t;
/**
* @brief WiFi antenna auto switch configuration
*
*/
typedef struct {
ant_mun_t ant_num; /**< WiFi use antenna numbers 2 or 3*/
uint8_t ant_zero; /**< WiFi antenna zero select*/
uint8_t ant_one; /**< WiFi antenna one select*/
uint8_t ant_two; /**< WiFi antenna two select*/
int16_t ant_switch; /**< WiFi antenna auto switch sensitive*/
} wifi_antenna_auto_switch_config_t;
/**
* @brief Set antenna auto configuration
*
* @param config Antenna auto configuration.
*
* @return
* - ESP_OK: succeed
* - ESP_FAIL: error
*/
esp_err_t esp_wifi_set_ant_soft_switch(const wifi_antenna_auto_switch_config_t *config);
/**
* @brief Get antenna auto configuration
*
* @param config Antenna auto configuration.
*
* @return
* - ESP_OK: succeed
*/
esp_err_t esp_wifi_get_ant_soft_switch_config(wifi_antenna_auto_switch_config_t *config);
/**
* @brief Delete antenna soft switching task
*/
void esp_deinit_ant_soft_switch(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "antenna_switch_example_main.c"
REQUIRES nvs_flash esp_wifi antenna_soft_switch)

View File

@ -0,0 +1,47 @@
menu "Example Configuration"
config ESP_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config ESP_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
config ESP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
prompt "WiFi Scan auth mode threshold"
default ESP_WIFI_AUTH_WPA2_PSK
help
The weakest authmode to accept in the scan mode.
This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present and ESP_WIFI_AUTH_OPEN is used.
Please select ESP_WIFI_AUTH_WEP/ESP_WIFI_AUTH_WPA_PSK incase AP is operating in WEP/WPA mode.
config ESP_WIFI_AUTH_OPEN
bool "OPEN"
config ESP_WIFI_AUTH_WEP
bool "WEP"
config ESP_WIFI_AUTH_WPA_PSK
bool "WPA PSK"
config ESP_WIFI_AUTH_WPA2_PSK
bool "WPA2 PSK"
config ESP_WIFI_AUTH_WPA_WPA2_PSK
bool "WPA/WPA2 PSK"
config ESP_WIFI_AUTH_WPA3_PSK
bool "WPA3 PSK"
config ESP_WIFI_AUTH_WPA2_WPA3_PSK
bool "WPA2/WPA3 PSK"
config ESP_WIFI_AUTH_WAPI_PSK
bool "WAPI PSK"
endchoice
endmenu

View File

@ -0,0 +1,191 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* WiFi station Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#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 "esp_wifi.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "antenna_switch.h"
/* The examples use WiFi configuration that you can set via project configuration menu
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#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
#if CONFIG_ESP_WIFI_AUTH_OPEN
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
#elif CONFIG_ESP_WIFI_AUTH_WEP
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
#elif CONFIG_ESP_WIFI_AUTH_WPA_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA_WPA2_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WPA2_WPA3_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
#elif CONFIG_ESP_WIFI_AUTH_WAPI_PSK
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
#endif
/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *TAG = "multi-antenna example";
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");
} 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);
}
}
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,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (pasword len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
},
};
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.");
/* 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) {
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");
}
}
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();
wifi_ant_gpio_config_t ant_gpio_config = {
// ESP32-WROOM-DA boards default antenna pins
.gpio_cfg[0] = {.gpio_select = 1, .gpio_num = 21},
.gpio_cfg[1] = {.gpio_select = 1, .gpio_num = 22},
};
ESP_ERROR_CHECK(esp_wifi_set_ant_gpio(&ant_gpio_config));
ESP_ERROR_CHECK(esp_wifi_get_ant_gpio(&ant_gpio_config));
ESP_LOGI(TAG, "GPIO: [0].pin = %d, [1].pin = %d",ant_gpio_config.gpio_cfg[0].gpio_num, ant_gpio_config.gpio_cfg[1].gpio_num);
wifi_antenna_auto_switch_config_t wifi_antenna_auto_switch_config;
wifi_antenna_auto_switch_config.ant_num = 3;
wifi_antenna_auto_switch_config.ant_zero = 0;
wifi_antenna_auto_switch_config.ant_one = 1;
wifi_antenna_auto_switch_config.ant_two = 3;
wifi_antenna_auto_switch_config.ant_switch = 35;
ESP_ERROR_CHECK(esp_wifi_set_ant_soft_switch(&wifi_antenna_auto_switch_config));
while(true) {
wifi_ant_config_t ant_config;
esp_wifi_get_ant(&ant_config);
ESP_LOGI(TAG, "rx mode = %d, tx mode = %d, ant0_en = %d, ant1_en = %d",ant_config.rx_ant_mode, ant_config.tx_ant_mode, ant_config.enabled_ant0, ant_config.enabled_ant1);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}