ESP32 Projeleri
#06İleri

ESPAsyncWebServer ile Bloklamayan Çoklu İstemci REST API

~2 saatTemel HTTP/REST kavramları, GitHub'dan kütüphane kurma deneyimi

Proje Amacı

Birden fazla tarayıcı veya istemcinin aynı anda, birbirini bloklamadan bağlanıp iki rölenin durumunu okuyup değiştirebildiği asenkron (event-driven) bir REST API sunmayı öğretir — akıllı ev panelleri ve endüstriyel kontrol arayüzlerinde tercih edilen mimarinin küçük ölçekli bir örneğidir. ESPAsyncWebServer, gelen her isteği ayrı ayrı bekletmeden (non-blocking) LwIP ağ yığınıyla doğrudan çalışır; bunun için ESP32'nin ikinci çekirdeği ve yeterli RAM'i (520KB SRAM) devreye girer. Bu mimari Arduino Uno'da kurulamaz: WiFi donanımı yoktur; harici bir WiFi shield eklense bile klasik senkron 'WiFiServer' modeli her isteği sırayla işler ve 2KB RAM, birden fazla eşzamanlı bağlantı arabelleğini aynı anda tutmaya yetmez.

Gerekli Malzemeler

  • ESP32 DevKit V1 (38 pin)
  • 2x Röle modülü (5V, optokuplörlü)
  • Breadboard
  • Jumper kablolar
  • Harici 5V güç kaynağı (röle bobinleri için önerilir)

Gerekli Kütüphaneler

ESPAsyncWebServer (me-no-dev, GitHub'dan zip olarak kurulmalı — Library Manager'da yok) + AsyncTCP (me-no-dev, aynı şekilde GitHub'dan). ArduinoJson (>= 6.x) JSON yanıtları için.

Pin Bağlantıları

Bileşen PiniBağlantı
Röle-1 IN
GPIO4
Röle-2 IN
GPIO16
Röle VCC
5V (VIN, harici kaynak önerilir)
Röle GND
GND

Devre Şeması

ESP32 Kodu

esp32-06-espasyncwebserver-ile-bloklamayan-coklu-istemci-rest-api.ino
1#include <WiFi.h>
2#include <ESPAsyncWebServer.h>
3#include <ArduinoJson.h>
4
5const char* ssid = "WIFI_ADINIZ";
6const char* password = "WIFI_SIFRENIZ";
7const int ROLE1 = 4, ROLE2 = 16;
8
9bool role1Durum = false, role2Durum = false;
10
11AsyncWebServer server(80);
12
13void jsonDurumGonder(AsyncWebServerRequest* istek) {
14 StaticJsonDocument<128> doc;
15 doc["role1"] = role1Durum;
16 doc["role2"] = role2Durum;
17 String cikti;
18 serializeJson(doc, cikti);
19 istek->send(200, "application/json", cikti);
20}
21
22void setup() {
23 Serial.begin(115200);
24 pinMode(ROLE1, OUTPUT);
25 pinMode(ROLE2, OUTPUT);
26 digitalWrite(ROLE1, LOW);
27 digitalWrite(ROLE2, LOW);
28
29 WiFi.begin(ssid, password);
30 while (WiFi.status() != WL_CONNECTED) { delay(400); Serial.print("."); }
31 Serial.println("\nBağlandı: " + WiFi.localIP().toString());
32
33 // GET /durum -> mevcut röle durumlarını JSON olarak döner
34 server.on("/durum", HTTP_GET, [](AsyncWebServerRequest* istek) {
35 jsonDurumGonder(istek);
36 });
37
38 // POST /role/<no>/<on|off> -> ilgili röleyi anında değiştirir, bloklamaz
39 server.on("^\\/role\\/([1-2])\\/(on|off)$", HTTP_POST, [](AsyncWebServerRequest* istek) {
40 int roleNo = istek->pathArg(0).toInt();
41 bool acik = istek->pathArg(1) == "on";
42 if (roleNo == 1) { role1Durum = acik; digitalWrite(ROLE1, acik ? HIGH : LOW); }
43 else { role2Durum = acik; digitalWrite(ROLE2, acik ? HIGH : LOW); }
44 jsonDurumGonder(istek);
45 });
46
47 server.onNotFound([](AsyncWebServerRequest* istek) {
48 istek->send(404, "application/json", "{\"hata\":\"bulunamadi\"}");
49 });
50
51 server.begin(); // async sunucu ayrı bir görevde çalışır, loop()'u BLOKLAMAZ
52}
53
54void loop() {
55 // ESPAsyncWebServer kendi görevinde çalıştığı için loop() tamamen boş
56 // kalabilir veya başka işler (sensör okuma vb.) için kullanılabilir.
57 delay(1000);
58}

Çalışma Açıklaması

ESPAsyncWebServer callback'leri kendi async görev bağlamında çalışır — bu fonksiyonlar içinde delay() kullanmak asenkron modelin tüm amacını bozar ve kesinlikle kullanılmamalıdır. pathArg() ile regex tabanlı route (^\\/role\\/([1-2])\\/(on|off)$) kullanılmıştır; kütüphane sürümüne göre regex desteği farklılık gösterebilir, uyumsuzluk yaşanırsa iki ayrı sabit route (/role/1/on, /role/1/off vb.) tanımlamak daha güvenilir bir yoldur.

Test Bilgisi

Kodu yükleyin, Seri Monitör'den IP adresini alın. Aynı anda 2-3 farklı sekmeden veya cihazdan curl ya da tarayıcıyla 'curl -X POST http://<IP>/role/1/on' ve 'curl http://<IP>/durum' isteklerini art arda gönderin; hiçbiri diğerini beklemeden anında yanıt vermeli — senkron bir sunucuda bu istekler sıraya girip gözle görülür şekilde gecikirdi, bu farkı iki mimariyi ayrı ayrı deneyerek gözlemleyebilirsiniz.

Olası Sorunlar ve Çözümleri

Derleme hatası 'AsyncWebServer.h bulunamadı' alıyorsanız: bu kütüphane Arduino Library Manager'da bulunmaz, GitHub'dan (ESP32Async/ESPAsyncWebServer ve ESP32Async/AsyncTCP) zip indirip 'Include Library > Add .ZIP Library' yoluyla kurmalısınız. Röleler rastgele tetikleniyorsa: harici 5V kaynağın GND'sinin ESP32 GND'siyle ortak olduğundan emin olun, ortak toprak (common ground) bu tür karma güç kaynaklı devrelerde şarttır. Bellek zamanla azalıp cihaz donuyorsa (memory leak): her AsyncWebServerRequest callback'inde mutlaka istek->send() çağrıldığından emin olun, yanıt göndermeyen bir route zamanla bellek sızıntısına yol açar.

Alternatif Çözümler

JSON gövdeli POST istekleri (body) almak için AsyncCallbackJsonWebHandler eklenebilir, böylece query/path parametreleri yerine gerçek bir REST body kullanılır — daha standart ve genişletilebilir bir API tasarımı sağlar. Kimlik doğrulama için server.on() içine Basic Auth (istek->authenticate()) eklenerek yetkisiz erişim engellenebilir. WebSocket (AsyncWebSocket, proje #19'daki gibi) eklenerek durum değişikliklerinin istemcilere anlık push edilmesi sağlanabilir, böylece istemcilerin periyodik olarak /durum'u sorgulaması (polling) gerekmez.

Bu projenin kodunu AI ile özelleştir

Farklı pin, ek özellik ya da başka bir sensör mü istiyorsun?

Benzer Projeler

İleri

Şifreli BLE ile Kimlik Doğrulamalı Akıllı Kilit

BLE (Bluetooth Low Energy) bonding/pairing ile bir telefonun kimliğini bir kez eşleştirip, sonraki bağlantılarda ESP32'nin donanımsal AES şifrelemesiyle korunan bir kanaldan 'kilidi aç' komutunu doğrulamayı ve bir servo ile fiziksel kilidi açmayı öğretir. ESP32'nin dahili BLE radyosu, Secure Connections (LE Secure Connections) ile şifreli eşleştirme yapabilecek donanımsal kripto desteğine sahiptir. Bu güvenlik düzeyi Arduino Uno'da kurulamaz: kart hiçbir Bluetooth radyosu (Classic veya BLE) içermez ve kripto hızlandırma donanımı da yoktur; harici bir BLE modülü (HM-10 gibi) eklense bile bu modüller genelde bonding/güvenli eşleştirmeyi tam desteklemez.

Orta

Fauxmo ile Alexa/Google Home Sesli Kontrol Entegrasyonu

ESP32'yi, Amazon Alexa veya Google Home'un zaten tanıdığı bir Philips Hue/Belkin Wemo akıllı priz gibi taklit ederek (fauxmoESP kütüphanesiyle UPnP/SSDP protokolü üzerinden), herhangi bir bulut hesabı veya geliştirici kaydı olmadan 'Alexa, lambayı aç' gibi sesli komutlarla röle kontrolü yapmayı öğretir. ESP32'nin WiFi ağ yığını, UDP multicast (SSDP keşif) ve yerel bir HTTP sunucusunu aynı anda çalıştırabilecek yeterli RAM ve ağ desteğine sahiptir. Bu senaryo Arduino Uno'da kurulamaz: WiFi donanımı olmadığından ne UDP multicast dinleyebilir ne de Alexa'nın yerel ağ taramasına yanıt verebilecek bir HTTP sunucusu çalıştırabilir.

İleri

ESP32-CAM ile Edge AI Yüz/Nesne Tanıma (ESP-WHO)

Kameradan alınan görüntü üzerinde, veriyi buluta göndermeden doğrudan cihaz üzerinde (edge AI) yüz tespiti yapmayı öğretir; Espressif'in ESP-WHO/esp-dl çerçevesi, kamera modülünün PSRAM'ini kullanarak görüntü karelerini tamponlayıp önceden eğitilmiş küçük bir sinir ağı modelini gerçek zamanlı çalıştırır. ESP32-CAM'in özel kamera arayüzü (DVP) ve harici PSRAM çipi, görüntü karelerini ve model ağırlıklarını aynı anda bellekte tutabilecek kapasiteyi sağlar. Bu tür bir işlem Arduino Uno'da gerçekleştirilemez: kamera bağlamak için gereken paralel DVP arayüzü hiç yoktur, PSRAM'i yoktur ve 2KB dahili RAM'i tek bir düşük çözünürlüklü görüntü karesini bile tutmaya yetmez — bir yapay sinir ağı modelini çalıştırmak ise bambaşka bir kapasite gerektirir.