ACCESS·通过wifi_scan学习esp32wifi程序编写

    在ESP32的计划性出中,我们得会需要动用到wifi或ble功能,今天即令讲解下如何将WIFI功能纳入到ESP32受来。

初始化WiFi环境

   首先,WiFi子系统的初始化需要由咱们好来机关,当我们写自己之顺序时,需要通过调用 esp_wifi_init() 方法 来完成 。

    推荐的办法如下:

wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&config);

安装操作模式

  ESP32可是网被的一个站点,也得是其他设备的接入点。 请记住,当ESP32正好以一个立,它可以连续不断至长途一个
ACCESS点(您的WiFi中心),当当过渡抱点时,其他WiFi站可以连续至ESP32(想想ESP32改为WiFi集线器)。通过我们的设定,我们可择我们的设备实行怎样操作模式之属性(站,接入点或站点接入点)。

  这种设定是调用函数esp_wifi_set_mode()进行设定的,wifi_mode_t 其可拥有 WIFI_MODE_NULL,WIFI_MODE_STA,WIFI_MODE_AP 或 WIFI_MODE_APSTA的值。

  我们得调用 esp_wifi_get_mode()来查找我们脚下底模式。

环视接入点

  如果ESP32将执行一个电台的角色,我们以急需连续至一个切入点。 我们得以要求列有我们得用的可用接入点尝试连接。 我们该用 esp_wifi_scan_start() 函数来 完成 。

  WiFi扫描的结果存储在ESP32分红的动态存储器内部y,当我们调用 esp_wifi_scan_get_ap_records()
时,数据返回到我们 这也放内部y分配的存储。我们称为破坏性阅读。

  扫描记录包含在含蓄 wifi_ap_record_t 结构 的一个实例 如下:

uint8_t bssid[6]
uint8_t ssid[32]
uint8_t primary
wifi_second_chan_t second
int8_t rssi
wifi_auth_mode_t authmode

该 wifi_auth_mode_t 是以下选项中的一个:

•               WIFI_AUTH_OPEN – 没有安全性。

•               WIFI_AUTH_WEP – WEP安全性。

•               WIFI_AUTH_WPA_PSK – WPA安全性。

•               WIFI_AUTH_WPA2_PSK – WPA2安全。

•               WIFI_AUTH_WPA_WPA2_PSK – WPA或WPA2安全性。

于来开始实施扫描的请求后,我们用被通扫描。

当 SYSTEM_EVENT_SCAN_DONE 事件发表 完成 。 

事件数量包含找到的接入点的多少,我们可由此调用esp_wifi_scan_get_ap_num()来得到。

我们意在在完成扫描之前自行取消扫描,我们得调用esp_wifi_scan_stop()。

    下面我们是一个一体化的WIFI_SCAN的事例,通常,我们以事件处理程序中履行工作,当我们检测及扫描完事件时,我们找定位的接入点并记下该详细信息。

 

  1 #include "freertos/FreeRTOS.h"
  2 #include "freertos/task.h"
  3 #include "freertos/event_groups.h"
  4 #include "esp_wifi.h"
  5 #include "esp_system.h"
  6 #include "esp_event.h"
  7 #include "esp_event_loop.h"
  8 #include "esp_log.h"
  9 #include "nvs_flash.h"
 10 
 11 
 12 static EventGroupHandle_t wifi_event_group;//定义一个事件的句柄
 13 const int SCAN_DONE_BIT = BIT0;//定义事件,占用事件变量的第0位,最多可以定义32个事件。
 14 static wifi_scan_config_t scanConf  = {
 15     .ssid = NULL,
 16     .bssid = NULL,
 17     .channel = 0,
 18     .show_hidden = 1
 19 };//定义scanConf结构体,供函数esp_wifi_scan_start调用
 20 
 21 static const char *TAG = "example";
 22 
 23 esp_err_t event_handler(void *ctx, system_event_t *event)
 24 {
 25     if (event->event_id == SYSTEM_EVENT_SCAN_DONE) {
 26         xEventGroupSetBits(wifi_event_group, SCAN_DONE_BIT);        //设置事件位
 27     }
 28     return ESP_OK;
 29 }
 30 
 31 static void initialise_wifi(void)        //define a static function ,it's scope is this file
 32 {
 33     wifi_event_group = xEventGroupCreate();    //创建一个事件标志组
 34     ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));//创建事件的任务
 35     wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//设置默认的wifi栈参数
 36     ESP_ERROR_CHECK(esp_wifi_init(&cfg));    //初始化WiFi Alloc资源为WiFi驱动,如WiFi控制结构,RX / TX缓冲区,WiFi NVS结构等,此WiFi也启动WiFi任务。
 37     ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));// Set the WiFi API configuration storage type
 38     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));//Set the WiFi operating mode
 39     ESP_ERROR_CHECK(esp_wifi_start());
 40     /*
 41     *           If mode is WIFI_MODE_STA, it create station control block and start station
 42     *          If mode is WIFI_MODE_AP, it create soft-AP control block and start soft-AP
 43     *          If mode is WIFI_MODE_APSTA, it create soft-AP and station control block and start soft-AP and station
 44      */
 45 }
 46 
 47 static void scan_task(void *pvParameters)
 48 {
 49     while(1) {
 50         xEventGroupWaitBits(wifi_event_group, SCAN_DONE_BIT, 0, 1, portMAX_DELAY);    //等待事件被置位,即等待扫描完成
 51         ESP_LOGI(TAG, "WIFI scan doen");
 52         xEventGroupClearBits(wifi_event_group, SCAN_DONE_BIT);//清除事件标志位
 53 
 54         uint16_t apCount = 0;
 55         esp_wifi_scan_get_ap_num(&apCount);//Get number of APs found in last scan
 56         printf("Number of access points found: %d\n", apCount);
 57         if (apCount == 0) {
 58             ESP_LOGI(TAG, "Nothing AP found");
 59             return;
 60         }//如果apCount没有受到数据,则说明没有路由器
 61         wifi_ap_record_t *list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);//定义一个wifi_ap_record_t的结构体的链表空间
 62         ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, list));//获取上次扫描中找到的AP列表。
 63         int i;
 64         printf("======================================================================\n");
 65         printf("             SSID             |    RSSI    |           AUTH           \n");
 66         printf("======================================================================\n");
 67         for (i=0; i<apCount; i++) {
 68             char *authmode;
 69             switch(list[i].authmode) {
 70             case WIFI_AUTH_OPEN:
 71                authmode = "WIFI_AUTH_OPEN";
 72                break;
 73             case WIFI_AUTH_WEP:
 74                authmode = "WIFI_AUTH_WEP";
 75                break;           
 76             case WIFI_AUTH_WPA_PSK:
 77                authmode = "WIFI_AUTH_WPA_PSK";
 78                break;           
 79             case WIFI_AUTH_WPA2_PSK:
 80                authmode = "WIFI_AUTH_WPA2_PSK";
 81                break;           
 82             case WIFI_AUTH_WPA_WPA2_PSK:
 83                authmode = "WIFI_AUTH_WPA_WPA2_PSK";
 84                break;
 85             default:
 86                authmode = "Unknown";
 87                break;
 88             }
 89             printf("%26.26s    |    % 4d    |    %22.22s\n",list[i].ssid, list[i].rssi, authmode);
 90         }//将链表的数据信息打印出来
 91         free(list);//释放链表
 92         printf("\n\n");//换行
 93 
 94         // scan again
 95         vTaskDelay(2000 / portTICK_PERIOD_MS);//调用延时函数,再次扫描
 96         //The true parameter cause the function to block until the scan is done.
 97         ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1));//扫描所有可用的AP。
 98     }
 99 
100 
101 }
102 
103 int app_main(void)
104 {
105     nvs_flash_init();//初始化NVS flash storage
106     tcpip_adapter_init();//初始化i本机TCP/IP协议
107     initialise_wifi();//初始化wifi
108 
109     xTaskCreate(&scan_task, "scan_task", 2048, NULL, 15, NULL);//创建扫描任务
110 
111     ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, 1));    //The true parameter cause the function to block until
112                                                               //the scan is done.
113     return 0;
114 }

 程序运行结果如下

      

 

 

 

 

处理WiFi事件

   以作WiFi设备运行的长河被,ESP32恐怕会见有一些事件需要懂得。 这些或许对应用程序的运行很重点,我们掌握不可知让咱们的应用程序块等他们发​​生,因为咱们无懂得呀时候工作会生出,以及事件是否会见生。因此,我们当定义一个回归函数,如果事件发生的口舌就受调用,该函数就是齐例被之esp_event_loop_init(), 它注册一个功力当ESP32检测及某些项目的WiFi相关事件不时调用。该回调函数被调用并传递一个添加的数据结构,其中包括事件的种类及相应于该事件的关系数据。 

    导致回调发生的波类:

•               我们连接受接入点

•               我们 从一个连贯点 断开连接

•               授权模式已改成

•               当我们处于接入点模式时,与我们连的一个站点

•               当我们处于接入点模式时,站暨我们断开连接

•               SSID扫描完

    当ESP32
WiFi环境运行时,它见面当好几情况下发表“事件”发生WiFi级别,例如新站连接。 我们可以登记一个回调发布事件时调用的函数。 

    回调识别函数是:

esp_err_t eventHandler(void *ctx, system_event_t *event) {
   // Handle event here ...
   return ESP_OK;
}

    通常咱们用include下面.h文件

•               #include <esp_event.h>

•               #include <esp_event_loop.h>

•               #include <esp_wifi.h>

•               #include <esp_err.h>

假如登记回调函数,我们调用:esp_event_loop_init(eventHandler,NULL);

假定我们要跟着更改和我们的WiFi处理相互关联的事件处理程序我们得以

             esp_event_loop_set_cb(eventHandler,NULL);

当事件处理程序为调用时,事件参数将受填事件。

其一参数的数据类型是一个“system_event_t”,让我们今天看传递让system_event_t中之事件处理程序的有限独属性数据结构,其中含:

system_event_id_t event_id
system_event_info_t event_info

这里event_id描述检测事件的色,同时event_info包含基于在
event_id标识的路事件之实际细节 。

•               EVENT_ID – 一个枚举类型,有下列潜在价值:

    ◦ SYSTEM_EVENT_WIFI_READY – ESP32的WiFi我 已经准备好。

    ◦
SYSTEM_EVENT_SCAN_DONE – 接抱点扫描了。 该scan_done 数据字段是行得通之顾。

    ◦  SYSTEM_EVENT_STA_START – 作为一个station开始。

    ◦  SYSTEM_EVENT_STA_STOP – 停止作为一个station。

    ◦  SYSTEM_EVENT_STA_CONNECTED – 连接到的接入点作为站。所连接的多少字段是立竿见影的,可以展开走访。

      ◦  SYSTEM_EVENT_STA_DISCONNECTED – 从ACCESS点作为一个站断开连接,断开连接的数字段是可以使得的造访的。

    ◦SYSTEM_EVENT_STA_AUTHMODE_CHANGE – 身份验证模式已经转移。该auth_change 数据字段是可有效之顾的。

    ◦SYSTEM_EVENT_STA_GOT_IP – 得到了 来自接入 分配的 IP地址指为我们并接受一个站点。 该 got_ip 数据字段是足以中访问的。

    ◦  SYSTEM_EVENT_AP_START – 开始当过渡抱点。

    ◦SYSTEM_EVENT_AP_STOP – 停止作为过渡抱点。

    ◦SYSTEM_EVENT_AP_STACONNECTED – 连接到一个站作为过渡抱点。 该 sta_connected 数据字段是可以中的看的。

    ◦
SYSTEM_EVENT_AP_STADISCONNECTED – 从正在接点断开一个站, 该 sta_disconnected 数据字段是足以中的走访的。

    ◦
 SYSTEM_EVENT_AP_PROBEREQRECVED – 作为连接抱点接的探测请求,该 ap_probereqrecved 数据字段是足以中的拜会。

 

 


event_info – 这是 键控关闭不同 的 数据类型 的C语言联合该事项标识 。其中蕴藏的异结构是:

      结构体                    领域                    事件           

system_event_sta_connected_t              connected           
 SYSTEM_EVENT_STA_CONNECTED

system_event_sta_disconnected_t             disconnected          
 SYSTEM_EVENT_STA_DISCONNECTED

system_event_sta_scan_done_t              scan_done          
     SYSTEM_EVENT_SCAN_DONE

system_event_sta_ authmode_change_t          auth_change         
    SYSTEM_EVENT_STA_AUTHMODE_CHANGE

system_event_sta_got_ip_t                got_ip             
 SYSTEM_EVENT_STA_GOT_IP

system_event_ap_staconnected_t             sta_connected          
 SYSTEM_EVENT_AP_STACONNECTED

system_event_ao_stadisconnected_t            ap_probereqrecved        SYSTEM_EVENT_AP_PROBEREQRECVED

这些数据结构包含与吸纳的波类有关的音。

 

 

 

system_event_sta_connected_t

其一数据类型与 SYSTEM_EVENT_STA_CONNECT 事件 相关联 。

uint8_t ssid[32]    //SSID 是,这是咱们总是WiFi网络名称。

uint8_t
ssid_len    //该 ssid_len 是于富含名称 SSID 字段中 的字节数 。

uint8_t bssid[6]    //BSSID 是MAC地址之接入点

uint8_t channel    //信道 是用以该连的无线信道

wifi_auth_mode_t
authmode    //该authmode 是连接过程遭到动用的安康身份验证模式。

 

 

system_event_sta_disconnected_t

斯数据类型与 SYSTEM_EVENT_STA_DISCONNECTED 事件 相关联 。

uint8_t ssid[32]

uint8_t ssid_len

uint8_t bssid[6]

uint8_t reason

由来代码reason是胡我们断开连接的指令。 符号定义也每个数字原因,下面是因代码:

•               WIFI_REASON_UNSPECIFIED – 1

•               WIFI_REASON_AUTH_EXPIRE – 2

•               WIFI_REASON_AUTH_LEAVE – 3

•               WIFI_REASON_ASSOC_EXPIRE – 4

•               WIFI_REASON_ASSOC_TOOMANY – 5

•               WIFI_REASON_NOT_AUTHED – 6

•               WIFI_REASON_NOT_ASSOCED – 7

•               WIFI_REASON_ASSOC_LEAVE – 8

•               WIFI_REASON_ASSOC_NOT_AUTHED – 9

•               WIFI_REASON_DISASSOC_PWRCAP_BAD – 10

•               WIFI_REASON_DISASSOC_SUPCHAN_BAD – 11

•               WIFI_REASON_IE_INVALID – 13

•               WIFI_REASON_MIC_FAILURE – 14

•               WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT – 15

•               WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT – 16

•               WIFI_REASON_IE_IN_4WAY_DIFFERS – 17

•               WIFI_REASON_GROUP_CIPHER_INVALIð – 18

•               WIFI_REASON_PAIRWISE_CIPHER_INVALID – 19

•               WIFI_REASON_AKMP_INVALID – 20

•               WIFI_REASON_UNSUPP_RSN_IE_VERSION – 21

•               WIFI_REASON_INVALID_RSN_IE_CAP – 22

•               WIFI_REASON_802_1X_AUTH_FAILED – 23

•               WIFI_REASON_CIPHER_SUITE_REJECTED – 24

•               WIFI_REASON_BE ACON_TIMEOUT – 200

•               WIFI_REASON_NO_AP_FOUND – 201

•               WIFI_REASON_AUTH_FAIL – 202

•               WIFI_REASON_ASSOC_FAIL – 203

•               WIFI_REASON_HANDSHAKE_TIMEOUT – 204

 

 

 

system_event_sta_scan_done_t

这个数据类型与 SYSTEM_EVENT_SCAN_DONE 事件 相关联 。

uint32_t status

uint8_t number

uint8_t scan_id

 

 

system_event_authmode_change_t

这数据类型与 SYSTEM_EVENT_STA_AUTHMODE_CHANGE 事件 相关联 。

wifi_auth_mode_t old_mode

wifi_auth_mode_t new_mode

 

system_event_sta_got_ip_t

此数据类型与 SYSTEM_EVENT_STA_GOT_IP 事件 相关联 。

tcpip_adapter_ip_info_t ip_info

所述ip_info元件是 包含三只 一 tcpip_adapter_ip_info_t 的一个实例

字段:

•               IP -The IP地址。

•              netmask – 网络掩码。

•               gw- 通信网关。

具有这三单领域是 ip4_addr_t 这是一个IP的32员代表地址。 在出中,您可能用考虑记录的IP地址设备。 为者,您得 使用:

ESP_LOGD(tag, "Got an IP: " IPSTR, IP2STR(&event->event_info.got_ip.ip_info.ip));

 

system_event_ap_staconnected_t

此数据类型与 SYSTEM_EVENT_AP_STACONNECTED 事件 相关联 。

uint8_t mac [6]

uint8_t aid

 

system_event_ap_stadisconnected_t

斯数据类型与 SYSTEM_EVENT_AP_STADISCCONNECTED 事件 相关联 。

uint8_t mac[6]

uint8_t aid

 

system_event_ap_probe_req_rx_t

是数据类型与 SYSTEM_EVENT_AP_PROBREQRECVED 事件 相关联 。

int rssi

uint8_t mac [6]

如若我们启用正确的日志记录级别,我们可见见事件到及其内容。

例如:

D (2168) event: SYSTEM_EVENT_STA_CONNECTED, ssid:RASPI3, ssid_len:6,
bssid:00:00:13:80:3d:bd, channel:6, authmode:3
V (2168) event: enter default callback
V (2174) event: exit default callback

D (9036) event: SYSTEM_EVENT_STA_GOTIP, ip:192.168.5.62, mask:255.255.255.0,
gw:192.168.5.1
V (9036) event: enter default callback
I (9037) event: ip: 192.168.5.62, mask: 255.255.255.0, gw: 192.168.5.1
V (9043) event: exit default callback

 

 

站配置

当我们想就此到ESP32当做wifi站,之后咱们用认识及,在其余一个时光, 它不得不连续至一个接入点。 换句话说,该装在同一时间连接到少独或重多只接入点。

随即是咱盼望赢得有关的接入点的标识设置数据结构称为 wifi_sta_config_t。该 wifi_sta_config_t 包含:

char ssid[32]
char password[64]
bool bssid_set
uint8_t bssid[6]

拖欠组织被富含两个老关键之天地“SSID” 和“ password”。 SSID 字段是接入点的SSID,这是咱拿连续至之AP的称谓。password字段是密码的明文值将用来将我们的装置验证到对象接入点以允许连接。

 

对于这么的一个例初始化结构或是:

 

wifi_config_t staConfig = {
   .sta = {
      .ssid="<access point name>",
      .password="<password>",
      .bssid_set=false
   }
};

要是我们填写了此布局的实例,我们就好指示ESP32之使用了。

esp_wifi_set_config(WIFI_IF_STA, (wifi_config_t *)&staConfig);

 

我们之前说到的模式设置也得以应用了

esp_wifi_set_mode(WIFI_MO DE_STA)
或
esp_wifi_set_mode(WIFI_MODE_APSTA)

 

 

 

启动WiFi环境

  当WiFi声明通过后,可能会问的题目是“什么时WiFi可以采取?”通常对ESP32咱若报她它是一个站点或接入点,然后配置它参数如连续到谁接入点(如果是站)或协调的接入点身份应该是(如果它们用变成接入点)。 鉴于这些是平层层之步子,我们实际不欲ESP32行这些任务直到我们完成了拥有的装置。  例如,如果我们启动一个ESP32并设置它是一个接入点,如果他随即作为接入点的话,可能会见面世错误,或者少作为不当的接入点存在,这是我们无期望观看的。因此,我们务必上最后之通令指示到WiFi子系统开始工作。 那个令是esp_wifi_start()。在调用这个函数之前,我们在召开的是起环境。只有经调用 esp_wifi_start() ,WiFi子系统才起来举行其他实际工作。同样的发出个照应的命令esp_wifi_stop(),其得以住WIFI子系统。

 

连接到接入点

  通过前的教学,已经基本教学了wifi的基本操作,ES32连接抱接入点AP的实例请看下一致首稿子

关于esp32之省电模式之WiFi连接

 

 

 

相关文化:wifi相关的API接口

 

 

 

 

 

 

 

相关文章