mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
commit
40cc39528c
6
examples/wifi/antenna/CMakeLists.txt
Normal file
6
examples/wifi/antenna/CMakeLists.txt
Normal 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)
|
136
examples/wifi/antenna/README.md
Normal file
136
examples/wifi/antenna/README.md
Normal 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.
|
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "antenna_switch.c"
|
||||
INCLUDE_DIRS "./include"
|
||||
REQUIRES esp_wifi)
|
@ -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);
|
||||
}
|
@ -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
|
2
examples/wifi/antenna/main/CMakeLists.txt
Normal file
2
examples/wifi/antenna/main/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "antenna_switch_example_main.c"
|
||||
REQUIRES nvs_flash esp_wifi antenna_soft_switch)
|
47
examples/wifi/antenna/main/Kconfig.projbuild
Normal file
47
examples/wifi/antenna/main/Kconfig.projbuild
Normal 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
|
191
examples/wifi/antenna/main/antenna_switch_example_main.c
Normal file
191
examples/wifi/antenna/main/antenna_switch_example_main.c
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user