1. #!trpst#trp-gettext data-...
  2. #!trpst#trp-gettext data-...
  3. ESP-IDF / ESP32
  4. Giriş
  5. ESP-IDF ile Wi-Fi Ağına Bağlanmak ve Event Loop Yönetimi

ESP-IDF ile Wi-Fi Ağına Bağlanmak ve Event Loop Yönetimi

Print

GPIO kesmeleri ve FreeRTOS görevlerinden sonra, ESP32’yi gerçek bir nesnelerin interneti (IoT) cihazı yapan en önemli özelliğe geldik: Wi-Fi Bağlantısı.

ESP-IDF mimarisinde Wi-Fi işlemleri, Arduino’daki gibi tek satırlık WiFi.begin() fonksiyonundan biraz daha detaylıdır. ESP-IDF, asenkron ve profesyonel bir yapı olan Event Loop (Olay Döngüsü) mimarisini kullanır. Bu sayede cihaz internete bağlanırken, koparken veya IP adresi alırken işlemci kilitlenmez, arka planda olaylar tetiklenir.

1. Wi-Fi Ön Gereksinimleri (NVS ve LwIP)

Wi-Fi ağını başlatmadan önce iki temel yapıyı ayağa kaldırmamız gerekir:

  • NVS (Non-Volatile Storage): ESP32’nin Wi-Fi sürücüsü, radyo kalibrasyon verilerini cihazın flash belleğinde (NVS bölümünde) saklar. Bu yüzden önce NVS başlatılmalıdır.
  • LwIP (esp_netif): TCP/IP yığınını (stack) yöneten ağ arayüzüdür. IP adresi alma, DHCP istemcisi gibi işlemler burada yürütülür.

2. Event Loop Nedir?

ESP32’de Wi-Fi sürücüsü arka planda çalışır. “Bağlantı koptu”, “IP adresi alındı” veya “Şifre yanlış” gibi durumlar oluştuğunda sisteme bir “Event” (Olay) fırlatır. Biz de bir Event Handler (Olay İşleyici) fonksiyonu yazarak bu olayları yakalar ve cihazın ne tepki vereceğini belirleriz.

3. Örnek Senaryo: Station (İstemci) Modunda Wi-Fi’ye Bağlanma

Aşağıdaki kod, ESP32’yi Station (STA) modunda başlatır, belirttiğiniz ağa bağlanır ve koptuğunda otomatik olarak 5 kez yeniden bağlanmayı dener.

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#define WIFI_SSID      "Agin_Adi"
#define WIFI_PASS      "Sifre1234"
#define MAXIMUM_RETRY  5

static const char *TAG = "WIFI_TEST";
static int s_retry_num = 0;

// Olay isleyici (Event Handler) fonksiyonu
static void event_handler(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) {
        // Wi-Fi basladiginda baglanmayi tetikle
        esp_wifi_connect();
        ESP_LOGI(TAG, "Wi-Fi basladi, baglaniliyor...");
    } 
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        // Baglanti koptugunda veya basarisiz oldugunda yeniden dene
        if (s_retry_num < MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGW(TAG, "Baglanti koptu, tekrar deneniyor (%d/%d)...", s_retry_num, MAXIMUM_RETRY);
        } else {
            ESP_LOGE(TAG, "Wi-Fi agina baglanilamadi!");
        }
    } 
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        // IP adresi basariyla alindiginda
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "Baglanti basarili! IP Adresi: " IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0; // Hata sayacini sifirla
    }
}

void wifi_init_sta(void) {
    // 1. Ag arayuzunu (LwIP) baslat
    ESP_ERROR_CHECK(esp_netif_init());
    
    // 2. Varsayilan olay dongusunu (Event Loop) olustur
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    // 3. Wi-Fi donanimini varsayilan ayarlarla baslat
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 4. Olay isleyiciyi sisteme kaydet (WIFI ve IP olaylarini dinle)
    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_got_ip;
    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));

    // 5. Wi-Fi yapilandirmasi (SSID ve Sifre)
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = WIFI_SSID,
            .password = WIFI_PASS,
            .threshold.authmode = WIFI_AUTH_WPA2_PSK, // Guvenlik protokolu
        },
    };
    
    // Modu Station (Istemci) olarak ayarla ve yapilandirmayi yukle
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    
    // 6. Wi-Fi'yi baslat
    ESP_ERROR_CHECK(esp_wifi_start());
}

void app_main(void) {
    // Wi-Fi surucusu kalibrasyon verileri icin NVS'yi baslat
    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, "Wi-Fi kurulumu basliyor...");
    wifi_init_sta();
}

4. Dikkat Edilmesi Gereken Kritik Noktalar

  • ESP_ERROR_CHECK Kullanımı: ESP-IDF’te her fonksiyon esp_err_t türünde bir dönüş değeri (örn: ESP_OK) verir. ESP_ERROR_CHECK makrosu, işler ters gittiğinde hatanın hangi satırda olduğunu konsola yazdırıp sistemi durdurarak hata ayıklamayı (debugging) çok kolaylaştırır.
  • Kimlik Bilgilerinin Güvenliği: Örnekte SSID ve şifre koda doğrudan (hardcoded) yazılmıştır. Profesyonel projelerde bu bilgileri Kconfig (Menuconfig) üzerinden veya Bluetooth (BLE) üzerinden telefondan alarak NVS’ye kaydetmek çok daha güvenli bir yaklaşımdır.
  • Asenkron Yapı: esp_wifi_start() fonksiyonu çağrıldığında kod alt satıra geçmeye devam eder, Wi-Fi’nin bağlanmasını beklemez. Bağlantı sürecini takip etmek istiyorsanız, bir önceki yazımızdaki gibi EventGroup veya FreeRTOS Queue yapılarını kullanmanız gerekir.
Tags , , , , ,

How can we help?