WiFi dan ESP32 – STA Mode

Pada contoh project, kita akan konfigurasi ESP32 sebagai STA mode dan dihubungkan ke local Wi-Fi network. Aplikasi akan menampilkan content ke serial console berdasarkan GET request dari URL yang telah ditentukan.

Pertama, buat project baru menggunakan PlatformIO, kemudian edit file platformio.ini

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf
monitor_speed = 115200
build_flags =
-DWIFI_SSID=${sysenv.WIFI_SSID}
-DWIFI_PASS=${sysenv.WIFI_PASS}

Ada dua environment variables yang digunakan oleh aplikasi, WIFI_SSID dan WIFI_PASS. Kita dapat spesifikasikan dalam aplikasi, namun itu kurang tepat, karena membuka celah keamanan.

Code

Buka main.c, lalu tambahkan code berikut:

//bagian import library
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "esp_http_client.h"
static EventGroupHandle_t wifi_events;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
#define MAX_RETRY 10
static int retry_cnt = 0;
static const char *TAG = "wifi_app";
static void request_page(void *);
static esp_err_t handle_http_event(esp_http_client_event_t *);
static void handle_wifi_connection(void *, esp_event_base_t, int32_t, void *);

//bagian init wifi
static void init_wifi(void)
{
    if (nvs_flash_init() != ESP_OK)
    {
        nvs_flash_erase();
        nvs_flash_init();
    }
    wifi_events = xEventGroupCreate();
    esp_event_loop_create_default();
    esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &handle_wifi_connection, NULL);
    esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &handle_wifi_connection, NULL);
    wifi_config_t wifi_config = {
        .sta = {
        .ssid = WIFI_SSID,
        .password = WIFI_PASS,
        .threshold.authmode = WIFI_AUTH_WPA2_PSK,
        .pmf_cfg = {
        .capable = true,
        .required = false},
        },
    };
    esp_netif_init();
    esp_netif_create_default_wifi_sta();
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);
    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
    esp_wifi_start();
    EventBits_t bits = xEventGroupWaitBits(wifi_events, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
    if (bits & WIFI_CONNECTED_BIT)
    {
        xTaskCreate(request_page, "http_req", 5 *
        configMINIMAL_STACK_SIZE, NULL, 5, NULL);
    }
    else
    {
        ESP_LOGE(TAG, "failed");
    }
}

//bagian handle wifi conn
static void handle_wifi_connection(void *arg, esp_event_base_t
event_base, int32_t event_id, void *event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
    {
        esp_wifi_connect();
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
    {
        if (retry_cnt++ < MAX_RETRY)
        {
            esp_wifi_connect();
            ESP_LOGI(TAG, "wifi connect retry: %d", retry_cnt);
        }
        else
        {
            xEventGroupSetBits(wifi_events, WIFI_FAIL_BIT);
        }
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
    {
        ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
        ESP_LOGI(TAG, "ip: %d.%d.%d.%d", IP2STR(&event->ip_info.ip));
        retry_cnt = 0;
        xEventGroupSetBits(wifi_events, WIFI_CONNECTED_BIT);
    }
}

//bagain request page
static void request_page(void *arg)
{
    esp_http_client_config_t config = {
    .url = "https://raw.githubusercontent.com/espressif/esp-idf/master/examples/get-started/blink/main/blink_example_main.c",
    .event_handler = handle_http_event,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);
    if (esp_http_client_perform(client) != ESP_OK)
    {
        ESP_LOGE(TAG, "http request failed");
    }
    esp_http_client_cleanup(client);
    vTaskDelete(NULL);
}

//bagian handle http event
static esp_err_t handle_http_event(esp_http_client_event_t *http_event)
{
    switch (http_event->event_id)
    {
        case HTTP_EVENT_ON_DATA:
            printf("%.*s\n", http_event->data_len, (char *)http_event->data);
            break;
        default:
            break;
    }
    return ESP_OK;
}

//bagian main function
void app_main(void)
{
    init_wifi();
}

Penjelasan Code

Bagian Import Library

Pertama kita include file header yang digunakan dalam project. Kemudian kita definisikan global variable, wifi_events, untuk informasi Wi-Fi event.

Bagian Init Wifi

Pertama inisialisasi nvs partition, yang digunakan oleh Wi-Fi library.

Kemudian buat event group dan register event handling function.

Global variable wifi_events digunakan untuk menotifikasi init_wifi mengenai perubahan setelah kita memulai proses Wi-Fi connection.

Selanjutnya, kita buat event loop untuk memonitor perubahan dan register fungsi handle_wifi_connection untuk handle WIFI_EVENT and IP_EVENT.

Definisikan variable wifi_config, untuk menyimpan credentials. Diperlukan sebelum memulai Wi-Fi connection. Kemudian inisialisasi network interface dan Wi-Fi dengan default configuration.

Set Wi-Fi mode ke WIFI_MODE_STA dan spesifikasikan credentials dengan memanggil esp_wifi_set_config.

Terakhir, kita panggil esp_wifi_start. Kemudian kita tunggu success atau fail event pada xEventGroupWaitBits. Jika sukses, kita buat FreeRTOS task untuk mengirim HTTP GET request ker URL.

Bagian handle wifi connection

Fungsi handle_wifi_connection akan memeriksa event Wi-Fi dan IP Event.

Ketika event WIFI_EVENT_STA_START, kita panggil esp_wifi_connect untuk connect ke Wi-Fi network. Event lainnya adalah STA-disconnected.

Jika event WIFI_EVENT_STA_DISCONNECTED, ini berarti koneksi sebelumnya gagal. Kita ulangi sampai MAX_RETRY tercapai. Jika masih gagal setelah MAX_RETRY, kita set bit pada wifi_events.

Jika koneksi berhasil, IP_EVENT_STA_GOT_IP event akan terjadi.

Kita set success pada global wifi_events variable untuk memberitahu fungsi init_wifi
function mengenai perubahan ini, dima akan membuat FreeRTOS task untuk mengirim HTTP GET request ke URL yang dimaksud.

Bagian Request Page

Pertama definsikan HTTP configuration variable, config. Berisi URL info dan handler untuk HTTP events.

Kita tidak perlu me-spesifikasikan HTTP method pada config (default adalah HTTP GET).

Kemudian create HTTP client menggunakan konfigurasi tersebutdan panggil esp_http_client_perform dengan parameter client.

Untuk menutup HTTP session, panggil esp_http_client_cleanup.

Bagian http event handler

Terdapat beberapa HTTP events daam satu session, sepert on-connected, header-sent, dan header-received. Pda fungsi ini kita hanya handle HTTP_EVENT_ON_DATA untuk menampilkan data yang dikembalikan oleh server.

Bagian Main Function

Pada app_main hanya memanggil fungsi init_wifi untuk memulai seluruh proses.

Compile Dan Upload

Untuk compile kita lakukan melalui CLI, jalankan activate.bat, biasanya pada windows disimpan di C:\Users\nama_account\.platformio\penv\Scripts

(penv)$ export WIFI_SSID='\"<your-wifi-ssid>\"'
(penv)$ export WIFI_PASS='\"<your-wifi-password>\"'
(penv)$ pio run
(penv)$ pio run -t erase
(penv)$ pio run -t upload

Sebelum upload aplikasi, pastikan flash dari ESP32 kosong, karena Wi-Fi library menggunakan nvs partition dan harus dalam keadaan bersih agar beroperasi dengan benar.

Setelah aplikasi berjalan, kita akan lihat pada serial monitor, berisi example code dari Espressif yang disimpan di GitHub (lihat url yang digunakna pada config variable).

Sharing is caring:

Leave a Comment