1
6
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
67
68
69
70
80
81
82
83
84
85
86
87
88
89
93
94
95
96
106
107
108
109
110
111
112
113
114
115
116
117
121
122
123
124
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
212
213
214
215
216
221
222
223
224
225
226
227
228
231
232
233
234
235
236
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
263
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
292
293
294
295
296
302
303
/* ... */
/* ... */
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
#include "esp_wifi.h"
#include "esp_phy.h"
#include "esp_log.h"
#include "esp_check.h"
#include "antenna_switch.h"9 includes
#define SOFT_SWITCHING_NAME "three ant auto"
#define SOFT_SWITCHING_PRIORITY 4
#define SOFT_SWITCHING_STACK 4096
#define WAIT_TIME 60
#define MONITOR_TIME 200
#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.0110 defines
static const char *TAG = "ANTENNA_SWITCH_EXAMPLE";
static wifi_antenna_auto_switch_config_t wifi_three_ant_auto_get_config = {
.ant_num = ANT_TOTAL_THREE,
.ant_zero = 0,
.ant_one = 1,
.ant_two = 3,
.ant_switch = 35
}{...};
static TaskHandle_t antenna_task_handle;
static void antenna_switch_function(const wifi_antenna_auto_switch_config_t *config)
{
esp_phy_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;
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT0;
wifi_ant_config.rx_ant_default = ESP_PHY_ANT_MODE_ANT0;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT0;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
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)) {
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);
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
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)) {
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) {
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant1 = config->ant_two;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
vTaskDelay(100/portTICK_PERIOD_MS);
while(ESP_OK != esp_wifi_sta_get_ap_info(&wifi_ap_record)) {
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)) {
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) {
ESP_LOGD(TAG, "Antenna soft switching selection ant0");
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT0;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT0;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
}{...}
if(rssi_ant1 > rssi_ant0 && rssi_ant1 > rssi_ant2) {
ESP_LOGD(TAG, "Antenna soft switching selection ant1");
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_one;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
}{...}
if(rssi_ant2 > rssi_ant0 && rssi_ant2 > rssi_ant1) {
ESP_LOGD(TAG, "Antenna soft switching selection ant2");
wifi_ant_config.rx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.tx_ant_mode = ESP_PHY_ANT_MODE_ANT1;
wifi_ant_config.enabled_ant0 = config->ant_zero;
wifi_ant_config.enabled_ant1 = config->ant_two;
ESP_ERROR_CHECK(esp_phy_set_ant(&wifi_ant_config));
}{...}
}{ ... }
static int16_t KalmanFilter(int16_t inData)
{
static float kalman = 0;
static float p = 10;
float q = 0.01;
float r = 0.2;
float kg = 0;
p += q;
kg = p / ( p + r );
kalman = kalman + (kg * (inData - kalman));
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)) {
vTaskDelay(100/portTICK_PERIOD_MS);
}{...}
rssi_data_in = KalmanFilter(wifi_ap_record.rssi);
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);
}{...}
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;
if( xQueueSend(xQueue_rssi_sum_handle, (void *)&rssi_sum, ( TickType_t ) 0) == pdPASS ) {
queue_rssi_sum_size++;
}{...}
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++;
if (rssi_flag > WAIT_TIME) {
ESP_LOGD(TAG, "End of listening rssi");
int16_t and = abs(rssi_save_sum - rssi_sum) - abs(rssi_last_sum - rssi_sum) * RSSI_KD;
rssi_flag = 0;
if(and > (config->ant_switch)) {
queue_rssi_sum_size = 0;
queue_rssi_single_size = 0;
ESP_LOGD(TAG, "monitor result:%d > %d", and, (config->ant_switch));
antenna_switch_function(config);
vTaskDelay(100 / portTICK_PERIOD_MS);
do
{
ret = xQueueReceive(xQueue_rssi_single_handle, &rssi_data_out, 0);
}{...} while (ret != pdFALSE);
do
{
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!");
wifi_three_ant_auto_get_config = *config;
antenna_switch_function(config);
ret = xTaskCreatePinnedToCore(antenna_soft_switching_task, SOFT_SWITCHING_NAME, SOFT_SWITCHING_STACK, (void *)config, SOFT_SWITCHING_PRIORITY, &antenna_task_handle, CONFIG_FREERTOS_NUMBER_OF_CORES - 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);
}{ ... }