详细的wifi连接设置可以参考这里
设置wifi连接的步骤
1、WIFI和LWIP的初始化阶段
a.主任务调用tcpip_adapter_init()创建LWIP核心任务并初始化与LWIP相关的工作
b.主任务调用esp_event_loop_init()来创建系统事件任务,并初始化应用程序事件的回调函数。
c.主任务调用esp_wifi_init()来创建Wi-Fi驱动程序任务并初始化Wi-Fi驱动程序.
d.主任务调用OS API来创建应用程序任务。
2、wifi的配置
a.调用esp_wifi_set_mode(WIFI_MODE_STA)设置模式
b.如果你想直接连接wifi这里是可以直接配置连接wifi
3、启动wifi
调用esp_wifi_start()来启动wifi,启动wifi之后就会进入esp_event_loop_init()创建的事件里面。
4、启动扫描周围wifi(这一步不是必须的,实现前面三步就可以实现wifi连接)
调用esp_wifi_scan_start(const wifi_scan_config_t *config, bool block);启动扫描
typedef struct {
uint8_t *ssid; /**< SSID of AP */
uint8_t *bssid; /**< MAC address of AP */
uint8_t channel; /**< channel, scan the specific channel */
bool show_hidden; /**< enable to scan AP whose SSID is hidden */
wifi_scan_type_t scan_type; /**< scan type, active or passive */
wifi_scan_time_t scan_time; /**< scan time per channel */
} wifi_scan_config_t;
扫描类型和其他每次扫描属性由esp_wifi_scan_start配置。下表提供了wifi_scan_config_t的详细说明。
场域 | 描述 |
---|---|
SSID | 如果SSID不是NULL,则只能扫描具有相同SSID的AP。 |
BSSID | 如果BSSID不是NULL,则只能扫描具有相同BSSID的AP。 |
通道 | 如果“通道”为0,则将进行全通道扫描;否则,将进行特定通道扫描。 |
显示隐藏 | 如果“显示_隐藏”为0,则扫描会忽略带有隐藏SSID的AP;否则,扫描会将隐藏AP视为正常AP。 |
扫描类型 | 如果“Scan_type”是WiFi_SCAN_TYPE_ACTIVE,则扫描是“主动”的;否则,它是“被动的”扫描。 |
扫描时间 | 此字段用于控制扫描在每个通道上停留多长时间。 对于被动扫描,扫描时间。被动指定每个通道的驻留时间。 对于活动扫描,每个通道的驻留时间列于下表。在这里,min是扫描时间的缩写。active.min和max是scan_time.active.max的缩写。
如果要提高扫描的性能,可以尝试修改这两个参数。
|
当扫描完成的时候回产生一个SYSTEM_EVENT_SCAN_DONE事件,然后可以通过esp_wifi_scan_get_ap_num()函数获取到搜索到的AP个数,通过esp_err_t esp_wifi_scan_get_ap_records(uint16_t *number, wifi_ap_record_t *ap_records);获取搜索的具体AP信息。 具体可以参见 第三步提供的代码 ---- 一个简单的是扫描到AP,之后再连接的demo
二、提供一个简单的wifi连接的demo
#include "freertos/FreeRTOS.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
esp_err_t event_handler(void *ctx, system_event_t *event)
{
return ESP_OK;
}
void app_main(void)
{
nvs_flash_init();
tcpip_adapter_init();
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
wifi_config_t sta_config = {
.sta = {
.ssid = CONFIG_ESP_WIFI_SSID,
.password = CONFIG_ESP_WIFI_PASSWORD,
.bssid_set = false
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
ESP_ERROR_CHECK( esp_wifi_connect() );
gpio_set_direction(GPIO_NUM_4, GPIO_MODE_OUTPUT);
int level = 0;
while (true) {
gpio_set_level(GPIO_NUM_4, level);
level = !level;
vTaskDelay(300 / portTICK_PERIOD_MS);
}
}
三、一个简单的是扫描到AP,之后再连接的demo
/* Scan 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.
*/
/*
This example shows how to use the All Channel Scan or Fast Scan to connect
to a Wi-Fi network.
In the Fast Scan mode, the scan will stop as soon as the first network matching
the SSID is found. In this mode, an application can set threshold for the
authentication mode and the Signal strength. Networks that do not meet the
threshold requirements will be ignored.
In the All Channel Scan mode, the scan will end only after all the channels
are scanned, and connection will start with the best network. The networks
can be sorted based on Authentication Mode or Signal Strength. The priority
for the Authentication mode is: WPA2 > WPA > WEP > Open
*/
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "string.h"
#include "stdio.h"
/*Set the SSID and Password via "make menuconfig"*/
#define DEFAULT_SSID CONFIG_WIFI_SSID
#define DEFAULT_PWD CONFIG_WIFI_PASSWORD
#if CONFIG_WIFI_ALL_CHANNEL_SCAN
#define DEFAULT_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
#elif CONFIG_WIFI_FAST_SCAN
#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
#else
#define DEFAULT_SCAN_METHOD WIFI_FAST_SCAN
#endif /*CONFIG_SCAN_METHOD*/
#if CONFIG_WIFI_CONNECT_AP_BY_SIGNAL
#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
#elif CONFIG_WIFI_CONNECT_AP_BY_SECURITY
#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
#else
#define DEFAULT_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
#endif /*CONFIG_SORT_METHOD*/
#if CONFIG_FAST_SCAN_THRESHOLD
#define DEFAULT_RSSI CONFIG_FAST_SCAN_MINIMUM_SIGNAL
#if CONFIG_EXAMPLE_OPEN
#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
#elif CONFIG_EXAMPLE_WEP
#define DEFAULT_AUTHMODE WIFI_AUTH_WEP
#elif CONFIG_EXAMPLE_WPA
#define DEFAULT_AUTHMODE WIFI_AUTH_WPA_PSK
#elif CONFIG_EXAMPLE_WPA2
#define DEFAULT_AUTHMODE WIFI_AUTH_WPA2_PSK
#else
#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
#endif
#else
#define DEFAULT_RSSI -127
#define DEFAULT_AUTHMODE WIFI_AUTH_OPEN
#endif /*CONFIG_FAST_SCAN_THRESHOLD*/
static const char *TAG = "scan";
static EventGroupHandle_t wifi_event_group;//定义一个事件的句柄
const int SCAN_DONE_BIT = BIT0;//定义事件,占用事件变量的第0位,最多可以定义32个事件。
static wifi_scan_config_t scanConf = {
.ssid = NULL,
.bssid = NULL,
.channel = 0,
.show_hidden = 1
};//定义scanConf结构体,供函数esp_wifi_scan_start调用
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id) {
case SYSTEM_EVENT_STA_START:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
// ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "Got IP: %s\n",
ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
ESP_ERROR_CHECK(esp_wifi_connect());
break;
case SYSTEM_EVENT_SCAN_DONE:
xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT); //设置事件位
break;
default:
break;
}
return ESP_OK;
}
/* Initialize Wi-Fi as sta and set scan method */
static void wifi_scan(void)
{
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
wifi_config_t wifi_config = {
.sta = {
.ssid = DEFAULT_SSID,
.password = DEFAULT_PWD,
.scan_method = DEFAULT_SCAN_METHOD,
.sort_method = DEFAULT_SORT_METHOD,
.threshold.rssi = DEFAULT_RSSI,
.threshold.authmode = DEFAULT_AUTHMODE,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void scan_task(void *pvParameters)
{
while(1) {
xEventGroupWaitBits(wifi_event_group, SCAN_DONE_BIT, 0, 1, portMAX_DELAY); //等待事件被置位,即等待扫描完成
ESP_LOGI(TAG, "WIFI scan doen");
xEventGroupClearBits(wifi_event_group, SCAN_DONE_BIT);//清除事件标志位
uint16_t apCount = 0;
esp_wifi_scan_get_ap_num(&apCount);//Get number of APs found in last scan
printf("Number of access points found: %d\n", apCount);
if (apCount == 0) {
ESP_LOGI(TAG, "Nothing AP found");
return;
}//如果apCount没有受到数据,则说明没有路由器
wifi_ap_record_t *list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);//定义一个wifi_ap_record_t的结构体的链表空间
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, list));//获取上次扫描中找到的AP列表。
int i;
or (i=0; i
四、扫描到的结果及连接wifi
如果有多个相同的AP名字 搜索到AP再根据指定MAC连接wifi还是不错的。