玩转ESP32(2):WIFI的代码实现

玩转ESP32(2):WIFI的代码实现

ESP32作为一款WIFI+蓝牙芯片,WIFI的实现是其最基本的功能,而在ESP32中,利用WIFI可以实现STA、AP、STA+AP这三种方式。

STA代码实现

首先来看一个最简单的实现WIFI sta的例子。

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"

#include "nvs_flash.h"

#define EXAMPLE_WIFI_SSID "HUAWEI001"
#define EXAMPLE_WIFI_PASS "12345678"

static const char *TAG = "espressif";

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int CONNECTED_BIT = BIT0;

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch (event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        /* This is a workaround as ESP32 WiFi libs don't currently
           auto-reassociate. */
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}

static void initialise_wifi(void)
{
    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();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_WIFI_SSID,
            .password = EXAMPLE_WIFI_PASS,
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    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() );
}


void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    initialise_wifi();
}

上述例子主要实现连接SSID为espressif的路由器,并获得相应的IP。SSID和PASSWORD可以根据自己的路由信息进行更改,在拿到IP之后我们就可以进行相应的网络操作(TCP/UDP)。
其中:

STA代码详解

现在,开始对上面的代码进行详细分析。

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"

#include "nvs_flash.h"

上面是在实现WIFI sta所需要的头文件,其中前三个是freertos相关的头文件,后面几个都是espressif所定义的头文件,其中esp_system.h是系统相关头文件;esp_wifi.h是WIFI相关头文件;esp_event_loop.h是事件相关头文件。esp_log.h是espressif格式化输出的头文件。

#define EXAMPLE_WIFI_SSID "HUAWEI001"
#define EXAMPLE_WIFI_PASS "12345678"

static const char *TAG = "espressif";

/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t wifi_event_group;

/* The event group allows multiple bits for each event,
   but we only care about one event - are we connected
   to the AP with an IP? */
const int CONNECTED_BIT = BIT0;

上面是一些参数的定义,前面两个为ssid和密码,需要根据自己的路由器和密码进行更改。第3个是格式化输出的前缀,可以自由更改。wifi_event_group是我们定义的事件组,事件组主要是考虑到很多网络操作需要在我们连接到路由器并拿到IP之后才能进行。CONNECTED_BIT是我们定义的事件组Bit位,在此DEMO种只需要WIFI连接这一种事件。
*

Note.
事件组标志位和WIFI的事件组并不是一个东西,事件组标志位类似于原子操作,防止因为顺序错乱而导致程序问题。而WIFI事件组只是WIFI在连接过程中的某种状态。

*

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
    switch (event->event_id) {
    case SYSTEM_EVENT_STA_START:
        esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
        /* This is a workaround as ESP32 WiFi libs don't currently
           auto-reassociate. */
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
        break;
    default:
        break;
    }
    return ESP_OK;
}

WIFI在esp32中的连接是通过几组不同的事件处理来实现的,上述代码就是在作为STA连接WIFI中需要进行处理的事件。其中SYSTEM_EVENT_STA_START为初始事件状态,在此事情状态中,调用esp_wifi_connect()操作会连接到路由器(AP)上,连接成功后,事件状态位会变为SYSTEM_EVENT_STA_CONNECTED,此时会调用DHCP进行请求IP,在拿到IP之后事件状态会变更为SYSTEM_EVENT_STA_GOT_IP。在这里我们使用了xEventGroupSetBits,设置事件组标志,后续如果有需要在拿到IP后才进行的操作只需要调用xEventGroupWaitBits就可以避免在没有拿到IP之前进行网络交互操作。
在WIFI因为某些原因断开后,事件标志位变为SYSTEM_EVENT_STA_DISCONNECTED,此时需要调用esp_wifi_connect()重新连接,并清除事件组标志位。

static void initialise_wifi(void)
{
    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();
    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_WIFI_SSID,
            .password = EXAMPLE_WIFI_PASS,
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
    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() );
}

上述代码是实现初始化WIFI的核心代码,其中tcpip_adapter_init()用来初始化TCP/IP协议栈,xEventGroupCreate()用来创建事件组标志。esp_event_loop_init(event_handler, NULL)用来初始化事件event_handler,回调event_handler即我们刚刚处理的各种WIFI事件。ESP_ERROR_CHECK用来检查返回值是否为ESP_OK。WIFI_INIT_CONFIG_DEFAULT()指定需要初始化底层的参数信息,esp_wifi_init用上述信息来初始化WIFI硬件。esp_wifi_set_storage设置连接的WIFI信息(SSID和PASSWORD)保存在哪里,可选的有RAM和FLASH。wifi_config是WIFI连接时的配置信息,作为STA时只需要考虑sta的参数信息,上述代码只是制定了最基本的ssid和password信息,除此之外,还可以指定bssid和channel等相关信息。ESP_LOGI是espressif的格式化输出信息,其他还包括ESP_LOGE(错误信息)、ESP_LOGD(调试信息)。esp_wifi_set_mode设置WIFI模式,除了WIFI_MODE_STA以外还包括WIFI_MODE_AP,WIFI_MODE_APSTA。esp_wifi_set_config设置STA模式的配置信息。esp_wifi_start()根据当前配置信息开启WIFI。

void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    initialise_wifi();
}

void app_main()是espressif工程的入口,类似与C语言中的main,nvs_flash_init是初始化NVS存储,initialise_wifi即初始化WIFI。在程序的后面,当需要实现其他功能时,使用vTaskCreate来创建即可。
至此,WIFI的整个连接过程结束,
WIFI STA

AP实现

AP的实现与STA的实现很类似,只需要更改一些配置信息即可。


#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "esp_log.h"

#include "nvs_flash.h"

const static char *TAG = "espressif";

static void initialise_wifi(void)
{
    tcpip_adapter_init();
    ESP_ERROR_CHECK( esp_event_loop_init(NULL, 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) );
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = "TestAp",
            .authmode = WIFI_AUTH_OPEN,
            .max_connection = 3,
        .channel = 12,
        },
    };
    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.ap.ssid);
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &wifi_config) );
    ESP_ERROR_CHECK( esp_wifi_start() );
}

void app_main(void)
{
    ESP_ERROR_CHECK(nvs_flash_init());
    initialise_wifi();
}

在设置AP时,相对STA,大体相似,只有一小部分需要更改为AP信息。

    ESP_ERROR_CHECK( esp_event_loop_init(NULL, NULL) );

在AP模式下,可以不需要回调函数,当然也可以写回调来获取更多信息,可以参考esp_event.h中的定义。

    wifi_config_t wifi_config = {
        .ap = {
            .ssid = "TestAp",
            .authmode = WIFI_AUTH_OPEN,
            .max_connection = 3,
        .channel = 12,
        },
    };

在此DEMO中,我设置的SSID为TestAp,authmode是open,即不加密,如果设置成加密,还需要添加.password。max_connection为支持的最大连接数。channel即信道为12。其他参数可以参考esp_wifi_types.h中的wifi_ap_config_t定义。

    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.ap.ssid);
    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );
    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &wifi_config) );

wifi_config.ap.ssid打印当前配置的AP的SSID信息, esp_wifi_set_mode(WIFI_MODE_AP)设置为AP模式,esp_wifi_set_config(WIFI_IF_AP, &wifi_config)按照当前的配置信息来设置AP。
运行之后,用手机连接测试SSID:TestAp,会出现如下界面:
这里写图片描述
AP模式也设置成功。

1. 安装Arduino IDE 首先,您需要安装Arduino IDE。您可以在官方网站上下载最新版本的Arduino IDE:https://www.arduino.cc/en/software 2. 安装ESP32开发板 接下来,您需要安装ESP32的开发板。打开Arduino IDE,选择“文件”>“首选项”,在“附加开发板管理器URL”中添加以下网址: https://dl.espressif.com/dl/package_esp32_index.json 然后,打开“工具”>“开发板”>“开发板管理器”,搜索“ESP32”,选择“esp32 by Espressif Systems”,然后点击“安装”。 3. 连接ESP32ESP32板连接到电脑上,并确保已选择正确的开发板和端口。您可以在“工具”>“开发板”>“ESP32 Dev Module”中选择正确的开发板,然后在“工具”>“端口”中选择正确的端口。 4. 编写程序 现在,您可以开始编写程序了。您可以使用Arduino IDE的标准库和函数,也可以使用ESP32的专有库和函数。例如,您可以使用以下代码ESP32连接到Wi-Fi网络: #include <WiFi.h> const char* ssid = "YourNetworkName"; const char* password = "YourNetworkPassword"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); } void loop() { } 5. 上传程序 编写完程序后,您需要将其上传到ESP32。在Arduino IDE中,单击“上传”按钮,然后等待上传完成。 6. 测试ESP32 上传程序后,您可以打开串口监视器,查看ESP32的输出,以确保它已连接到Wi-Fi网络。您可以使用以下代码在串口监视器中输出消息: void setup() { Serial.begin(115200); Serial.println("Hello, world!"); } void loop() { } 在串口监视器中,您应该看到“Hello, world!”的消息。 7. 尝试其他功能 ESP32具有许多功能,例如蓝牙、GPIO、SPI、I2C等。您可以使用ESP32的专有库和函数,或使用Arduino IDE的标准库和函数来控制这些功能。尝试使用这些功能来扩展您的ESP32项目!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值