Środowisko ESP-IDF (3). Wi-Fi i podstawowe tryby pracy

Środowisko ESP-IDF (3). Wi-Fi i podstawowe tryby pracy

Wszystkie układy ESP32 są obecnie wyposażone w sprzętowy interfejs Wi-Fi. Pozwala to na budowanie aplikacji wymagających łączności z siecią i przekazywania dużych ilości danych. Środowisko ESP-IDF oczywiście wspiera ten interfejs. Udostępnione biblioteki programistyczne umożliwiają pracę układu w różnych trybach Wi-Fi, a także ułatwiają konfigurację.

Zmiana wersji lub uaktualnienie ESP-IDF

Rodzina układów ESP32 wciąż się rozbudowuje, a za zmianami podąża również środowisko ESP-IDF. W kolejnych wersjach uwzględniana jest obsługa nowszych modeli ESP32, oferujących często całkiem nowe możliwości. Także samo środowisko podlega zmianom – poprzez modernizowanie wersji bibliotek: usuwanie błędów i optymalizację procedur. Nowe aplikacje użytkownika warto zatem pisać używając najświeższych stabilnych wersji środowiska ESP-IDF, z kolei drobne poprawki starszych aplikacji mogą wymagać tej wersji ESP-IDF, w której zostały napisane. W przypadku pracy z edytorem opartym o Eclipse, pobranie nowej wersji środowiska lub przełączenie na inną wersję można wykonać klikając opcję Espressif → Download and Configure ESP-IDF. Wyświetli się plansza podobna do tej z rysunku 1.

Rysunek 1. Okno wyboru wersji środowiska ESP-IDF

Zaznaczając opcję Use an existing ESP-IDF directory from file system możemy wskazać katalog z wcześniej pobranymi wersjami ESP-IDF. Jedną z nich będzie można ustawić jako aktywną i używaną w procesie kompilacji programów użytkownika. Jeżeli opcja pozostanie niezaznaczona, można wybrać wersję środowiska do pobrania z sieci spod adresu https://dl.espressif.com/dl/idf-eclipse-plugin/updates/latest/. Pliki wersji po pobraniu zostaną rozpakowane do wskazanego folderu i mogą być użyte jako aktywna wersja ESP-IDF.

Standard Wi-Fi w modułach rodziny ESP32

Starsze warianty ESP32 mogą pracować jako Wi-Fi (standard 802.11 b/g/n) o następujących parametrach:

  • prędkość do 150 Mb/s,
  • obsługa wielu połączeń (do 255),
  • tryby pracy: stacja, punkt dostępowy, mieszany.

Nowe układy (np. ESP32-S3) są przystosowane do standardu Wi-Fi 6 802.11 b/g/n/ax, który od starszej wersji różni się:

  • prędkością do 300 Mb/s,
  • standardem szyfrowania WPA3,
  • niższym zużyciem energii.

Nowy standard Wi-Fi 6 jest kompatybilny ze starszymi wersjami Wi-Fi.

Tryb stacji

Praca w trybie stacji oznacza, że moduł ESP32 może po zalogowaniu łączyć się z innymi uczestnikami lokalnej sieci Wi-Fi. Jest to sytuacja pokazana na rysunku 2. Lokalną sieć tworzy w tym przykładzie router oraz dwa inne urządzenia działające w trybie stacji: komputer PC i telefon. Moduł ESP32, po uwierzytelnieniu się właściwym hasłem, otrzymuje swój numer IP przydzielony przez router. Od tego momentu staje się widoczny w ramach sieci lokalnej – może za pośrednictwem routera łączyć się z pozostałymi uczestnikami sieci i wymieniać dane. Prosty program pokazany na kolejnych listingach zademonstruje kroki niezbędne do tego, aby moduł – pracując w trybie stacji – stał się osiągalny w ramach sieci.

Rysunek 2. Topologia sieci z modułem ESP32 trybie stacji

Na początku, co widać na listingu 1, włączamy wszystkie pliki nagłówkowe bibliotek, które będą używane w dalszej części programu. Zamiast „twój ssid” i „twoje hasło” trzeba wpisać rzeczywistą nazwę sieci – do której moduł ma się podłączyć – oraz hasło.

#include <stdio.h> //obsługa komendy printf
#include <string.h> //obsługa ciągów znaków
#include "freertos/FreeRTOS.h" //dla operacji rtos: delay,mutexs,semphrs
#include "esp_system.h" //dla funkcji esp_err_t
#include "esp_wifi.h" //dla funkcji i operacji Wi-Fi
#include "esp_log.h" //dla wyświetlania logów
#include "esp_event.h" //dla obsługi zdarzeń Wi-Fi
#include "nvs_flash.h" //dla obsługi pamięci nieulotnej
#include "lwip/err.h" //obsługa błędów lwip
#include "lwip/sys.h" //aplikacje systemowe dla lwip
const char *your_ssid = "twój ssid";
const char *your_pass = "twoje hasło";
int retry_num=0;

Listing 1. Pliki nagłówkowe oraz najważniejsze stałe i zmienne używane do obsługi Wi-Fi

Na listingu 2 pokazano, jak utworzyć procedurę obsługi zdarzeń (są to różne sytuacje, w tym przypadku występujące podczas włączania modułu ESP32 do sieci). Przykładem zdarzenia może być start trybu stacji, podłączenie do sieci, uzyskanie numeru IP czy też odłączenie od sieci. Gdy któraś z wymienionych sytuacji wystąpi, wywołana zostanie funkcja obsługi z przekazanym w parametrze event_id identyfikatorem zdarzenia. Dzięki identyfikatorowi wiadomo, które zdarzenie wymaga obsługi w danym momencie. W analizowanym przykładzie najczęściej będzie to tylko wysłanie komunikatu, który wyświetli się na monitorze portu szeregowego przez polecenie printf. W przypadku zdarzenia WIFI_EVENT_STA_DISCONNECTED będzie to podejmowana 5 razy próba nawiązania połączenia.

static void wifi_event_handler ( void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
if (event_id == WIFI_EVENT_STA_START)
{
printf ( "ŁĄCZENIE Z WIFI....\n" );
}
else if (event_id == WIFI_EVENT_STA_CONNECTED)
{
printf ( "Wi-Fi POŁĄCZONE\n" );
}
else if (event_id == WIFI_EVENT_STA_DISCONNECTED)
{
printf ( "Utracono połączenie Wi-Fi\n" );
if (retry_num< 5 ){esp_wifi_connect();retry_num++; printf ( "Ponowna próba połączenia...\n" );}
}
else if (event_id == IP_EVENT_STA_GOT_IP)
{
printf ( "Wi-Fi ma adres IP...\n\n" );
}
}

Listing 2. Procedura obsługi zdarzeń

Listing 3 zawiera główną procedurę realizującą podłączenie modułu ESP32 – pracującego w trybie stacji – do wybranej sieci Wi-Fi. Poszczególne kroki opatrzono zwięzłymi opisami w komentarzach. Najpierw przeprowadzane są niezbędne konfiguracje, włączane obsługi zdarzeń, tworzona struktura zadeklarowanych wcześniej stałych zawierających nazwę sieci i hasło dostępu. Na końcu funkcji wifi_connection() wywoływane są procedury podłączeniowe. Listing 4 pokazuje funkcję main() łączącą wszystko razem.

void wifi_connection(){
esp_netif_init(); //inicjalizacja interfejsu sieciowego
esp_event_loop_create_default(); //włączenie obsługi zdarzeń
esp_netif_create_default_wifi_sta(); //konfiguracja struktury danych dla interfejsu
//stacji Wi-Fi
wifi_init_config_t wifi_initiation = WIFI_INIT_CONFIG_DEFAULT(); //struktura wifi_init_config
//z wartościami domyślnymi
esp_wifi_init(&wifi_initiation); //inicjacja wifi warościami domyślnymi
esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL); //tworzenie rejestru obsługi zdarzeń dla Wi-Fi
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler,NULL); //tworzenie rejestru obsługi zdarzeń dla
//zdarzenia IP
wifi_config_t wifi_configuration ={ //struktura wifi_configuration dla nazwy sieci
//i hasła
.sta= {
.ssid = "",
.password= "",
}
};
strcpy((char*)wifi_configuration.sta.ssid,your_ssid); //kopiowanie do struktury łańcuchów znaków
strcpy((char*)wifi_configuration.sta.password,your_pass);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_configuration); //konfiguracja po zdarzeniu //ESP_IF_WIFI_STA
esp_wifi_start(); //start połączenia
esp_wifi_set_mode(WIFI_MODE_STA); //wybranie trybu pracy stacja
esp_wifi_connect(); //łączenie z wykorzystaniem podanych ssid
//i pass
printf( "wifi_init_softap finished. SSID:%s password:%s",your_ssid,your_pass);
}

Listing 3. Główna procedura realizująca podłączenie modułu ESP32 do sieci Wi-Fi w trybie stacji
void app_main(void){
nvs_flash_init(); //inicjacja pamięci do przechowywania konfiguracji Wi-Fi
wifi_connection();
}

Listing 4. Funkcja main programu

Po kompilacji programu i wgraniu do pamięci ESP32, układ zaczyna szukać sieci o podanej w stałej your_ssid nazwie i próbuje się do niej zalogować. W przypadku sukcesu nadawany jest modułowi numer IP. W monitorze można podejrzeć komunikaty generowane podczas tego procesu, podobne do tych widocznych na rysunku 3. Z komunikatu logu wynika, że router dodał moduł ESP32 pracujący w trybie stacji do sieci – i nadał mu numer IP 192.168.0.192.

Rysunek 3. Komunikaty wyświetlane w terminalu szeregowym podczas nawiązywania połączenia z siecią przez moduł ESP32

Przykładowa procedura oparta została na materiale dostępnym tutaj [1].

Tryb punktu dostępowego

Tryb punktu dostępowego w dokumentacji nosi nazwę soft Acces Point (softAP). Pracując w tym trybie ESP32 tworzy lokalną sieć Wi-Fi, do której mogą się podłączać urządzenia będące stacjami Wi-Fi. Utworzona sieć umożliwia podłączonym stacjom komunikację i wymianę danych pomiędzy sobą, przy skorzystaniu z pośrednictwa softAP. Taką konfigurację zaprezentowano na rysunku 4. Trzy stacje: komputer PC, telefon oraz moduł ESP32 podłączone są do sieci utworzonej przez inny moduł ESP32, pracujący jako softAP.

Rysunek 4. Topologia sieci z modułem ESP32 trybie softAP

Na kolejnych listingach pokazano składowe programu demonstrującego, jak przy pomocy modułu ESP32 utworzyć w pełni funkcjonalny softAP.

Na listingu 5 wyliczone zostały wszystkie potrzebne pliki nagłówkowe.

#include <string.h> //obsługa ciągów znaków
#include "freertos/FreeRTOS.h" //dla operacji rtos: delay,mutexs,semphrs
#include "freertos/task.h" //dla operacji rtos: task
#include "esp_system.h" //dla funkcji esp_err_t
#include "esp_wifi.h" //dla funkcji i operacji Wi-Fi
#include "esp_event.h" //dla obsługi zdarzeń Wi-Fi
#include "esp_log.h" //dla wyświetlania logów
#include "nvs_flash.h" //dla obsługi pamięci nieulotnej

#include "lwip/err.h" //lwip kody błędów
#include "lwip/sys.h" //lwip system

Listing 5. Pliki nagłówkowe używane w drugim programie testowym

Listing 6 zawiera deklaracje kluczowych ustawień tworzonej sieci Wi-Fi. Do EXAMPLE_ESP_WIFI_SSID przypisujemy nazwę sieci, np. „esp32_moja_siec”, a do EXAMPLE_ESP_WIFI_PASS – hasło logowania.

#define EXAMPLE_ESP_WIFI_SSID "twoja_nazwa_sieci"
#define EXAMPLE_ESP_WIFI_PASS "hasło_do_twojej_sieci"
#define EXAMPLE_ESP_WIFI_CHANNEL 1 //kanał radiowy twojej sieci
#define EXAMPLE_MAX_STA_CONN 4 //maksymalna ilość stacji w twojej sieci Wi-Fi

static const char *TAG = "wifi softAP"; //znacznik logu

Listing 6. Najważniejsze stałe i zmienne używane do obsługi Wi-Fi w trybie softAP

Na listingu 7 można obejrzeć przykładową procedurę obsługi zdarzeń Wi-Fi. Obsługiwane są dwa zdarzenia: WIFI_EVENT_AP_STACONNECTED (zdarzenie podłączenia do sieci nowej stacji), a także WIFI_EVENT_AP_STADISCONNECTED (zdarzenie odłączenia stacji od sieci).

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
MAC2STR(event->mac), event->aid);
} else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
MAC2STR(event->mac), event->aid);
}
}

Listing 7. Przykładowa procedura obsługi zdarzeń Wi-Fi w trybie softAP

Na listingu 8 pokazana została funkcja wifi_init_softap(), inicjalizująca Wi-Fi ESP32 w trybie softAP. Ostatni listing 9 zawiera główną funkcję main() programu.

void wifi_init_softap(void)
{
ESP_ERROR_CHECK(esp_netif_init()); //inicjalizacja interfejsu sieciowego
ESP_ERROR_CHECK(esp_event_loop_create_default()); //włączenie obsługi zdarzeń
esp_netif_create_default_wifi_ap(); //konfiguracja struktury danych dla interfejsu AP Wi-Fi

wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //struktura cfg z wartościami domyślnymi
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //inicjacja wifi wartościami domyślnymi
//tworzenie rejestru obsługi zdarzeń
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL));

wifi_config_t wifi_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_PASS,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA_WPA2_PSK
},
};
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
//inicjacja trybu Wi-Fi softAP
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());

ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}

Listing 8. Ciało funkcji inicjalizującej moduł Wi-Fi do pracy w trybie softAP
void app_main(void)
{
//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);

ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
wifi_init_softap();
}

Listing 9. Główna funkcja programu obsługującego tryb softAP

Na rysunku 5 pokazano zrzut ekranu z komunikatami wysyłanymi do terminala przez moduł ESP32 z uruchomionym przykładowym oprogramowaniem. Moduł działa w trybie softAP i tworzy sieć o nazwie „ESP32-softAP” zabezpieczoną hasłem „1234567890ab”. Do sieci podłączona jest jedna stacja, której przydzielono numer IP: 192.168.4.2.

Rysunek 5. Komunikaty wyświetlane w terminalu szeregowym podczas nawiązywania dołączania nowych urządzeń do sieci utworzonej przez moduł ESP32

Przykładowa procedura oparta została na materiale dostępnym tutaj [2].

Ryszard Szymaniak, EP

Odniesienia:

  1. https://medium.com/@fatehsali517/how-to-connect-esp32-to-wifi-using-esp-idf-iot-development-framework-d798dc89f0d6
  2. https://esp32tutorials.com/esp32-access-point-ap-esp-idf/
Artykuł ukazał się w
Elektronika Praktyczna
sierpień 2024
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik grudzień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio listopad - grudzień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje listopad - grudzień 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna grudzień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich grudzień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów