ESP32扫描周围wifi及连接wifi

详细的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的缩写。

  • min=0,max=0:扫描在每个通道上停留120 ms。
  • min>0,max=0:扫描在每个通道上停留120 ms。
  • min=0,max>0:扫描驻留在每个通道上max女士。
  • 最小>0,最大>0:扫描停留在每个通道上的最短时间是min女士。如果在此时间段内没有找到AP,则扫描切换到下一个通道。否则,扫描将驻留在通道上。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<apCount; i++) {

        printf("(%d,\"%s\",%d,\""MACSTR" %d\")\r\n",list[i].authmode, list[i].ssid, list[i].rssi,
                 MAC2STR(list[i].bssid),list[i].primary);
                  
         }//将链表的数据信息打印出来
          free(list);//释放链表
          printf("\n\n");//换行
        wifi_config_t wifi_config = { 0 };
        memset(&wifi_config,0,sizeof(wifi_config));
        memcpy(wifi_config.sta.ssid, "tplink", strlen("tplink"));
        memcpy(wifi_config.sta.password,"7788990011",strlen("7788990011"));
        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_connect() );

         // scan again
         //  vTaskDelay(5000 / portTICK_PERIOD_MS);//调用延时函数,再次扫描
         //The true parameter cause the function to block until the scan is done.
         // ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1));//扫描所有可用的AP。
      }

 
 }

void Wifi_Init(void){
    printf("wifi scan!!!!!!!!!!!!!!!!!!!!!\n");
   tcpip_adapter_init();
    wifi_event_group = xEventGroupCreate();    //创建一个事件标志组
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));//创建事件的任务
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//设置默认的wifi栈参数
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));    //初始化WiFi Alloc资源为WiFi驱动,如WiFi控制结构,RX / TX缓冲区,WiFi NVS结构等,此WiFi也启动WiFi任务。
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));// Set the WiFi API configuration storage type
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));//Set the WiFi operating mode
    ESP_ERROR_CHECK(esp_wifi_start());
        xTaskCreate(&scan_task, "scan_task", 2048, NULL, 15, NULL);//创建扫描任务
    ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1));    //The true parameter cause the function to block 
}

void app_main()
{
    // 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 );
     
    Wifi_Init();

    //  wifi_scan();//
}

四、扫描到的结果及连接wifi

如果有多个相同的AP名字 搜索到AP再根据指定MAC连接wifi还是不错的。

  • 7
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做了不一定能实现但不做一定不会实现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值