Esp32 İle Asenkron Olarak Çalışan Web Server Projesi

AsenkronServer

Esp32 Kartının Kurulumu

Bilgisayarınızda halihazırda kurulu bir Arduino IDE’si olduğunu varsayıyorum. Ancak projede kullanacağımız ESP32, IDE’nin standart kurulumunda gelmiyor o yüzden bazı ek işlemler yapmamız gerekecek.

Arduino IDE’sini açıp Dosya>Tercihler menüsünden Ek Devre Kartları Yöneticisi URL’leri kısmına aşağıdaki adresi ekleyelim: https://dl.espressif.com/dl/package_esp32_index.json

Daha sonra Araçlar>Kart>Kart Yöneticisi kısmından Esp32 kartını bulup kuralım.

Kart Yöneticisi Penceresi


Projeye Giriş

Asenkron Server

Projeye başlamadan önce senkron, asenkron gibi kavramları websocket’in ne olduğundan bahsetmek istiyorum.

Senkron Nedir ?
Kelime anlamı eşzamanlı olan senkron kelimesi yazılımda birtakım işlemlerin sıra ile yapılmasıdır.Basit bir analoji yapmak gerekirse bir fatura ödeme merkezindesiniz ve faturanızı ödemek için kuyruğa girdiniz. Sizin önünüzde fatura ödemek isteyen kişilerin faturaları ödenmeden sizin faturanız ödenmez. İşte bu şekilde işlemleri sıralı bir şekilde yapılmasına senkron programlama denir.

Asenkron Nedir ?
Kelime anlamı “Aynı zamanda veya birlikte meydana gelmeyen” olan asenkron kelimesi yazılımda yürütülen işlemlerin uzun sürmesinden dolayı yürütülmesi gereken diğer işlemlerin beklemeden çalışmasına devam edebilmesini sağlar. Senkronu açıklarken yaptığım gibi basit bir analoji yapmam gerekirse mutfakta iki çeşit yemek pişiriyorsunuz ve birini yapmaya başladınız. Elinizdeki yemek kaynarken diğer yemeğe başlamak için elinizdeki yemeğin bitmesini beklemezsiniz. İşte bu duruma asenkron programlama denir.

Websocket Nedir ?
WebSocket, tek bir TCP bağlantısı üzerinden tam çift yönlü iletişim kanalı sağlayan bir bilgisayar iletişim protokolüdür. WebSocket protokolü, sunucuya ve sunucudan gerçek zamanlı veri aktarımını sağlayarak, tarayıcı ile web sunucusu arasında etkileşimi sağlamaktadır. Bu, sunucunun istemci istemeden tarayıcıya içerik gönderebileceği ve bağlantıyı açık tutarak istediği zaman mesaj alabilmesini veya gönderebilmesini sağlayan standart bir yöntem ile sağlanmaktadır.Bizim bu projemizde ise web sayfası yenilenmeden kart üzerindeki ledi açıp kapatabilmemizi sağlanıyor.
Neden Websocket ?
Yeni bir istek HTTP protokolündeki kuralların tekrar edilmesine ve fazla trafik kullanımına neden olur.Trafik kullanımı ve HTTP protokolüyle gerçek zamanlı uygulamaların yönetilmesi maliyetli ve zor olduğundan dolayı websocket kullanılır.


Proje içerisinde kullanacağımız kütüphaneler Esp32 kartımızın ağa bağlanmasını ve üzerinde bir web sayfasını asenkron çalıştırmasını sağlayacak.

  #include <WiFi.h>
  #include <AsyncTCP.h>
  #include <ESPAsyncWebServer.h>

Proje içerisinde kullanılan kütüphanelerin linkleri:


    const char* ssid = "Ag Adi";
    const char* password = "Ag Parolasi";
    const int led = 2;

Ssid ve password kısmına bulunduğunuz ortamdaki ağın adını ve parolasını giriniz. Esp32 üzerindeki led GPIO2 pinine bağlı olduğu için led isminde değişkeni bu pine atadık.


    const char index_html[] PROGMEM = 

Progmem anahtar sözcüğü normalde Esp32’nin Sram’ine kaydetmesi gerekirken Flash hafızasına kaydetmesini sağlar. Esp32’nin Flash hafızası 4MB’dır.


    void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Sayfa Bulunamdadi");
}

NotFound fonksiyonu sayfa bulunamadığında 404 hata kodunu ve sayfa bulunamadı mesajını gönderecek.


    AsyncWebServer server(80);

AsyncWebServer sınıfından server adlı bir nesne oluşturduk ve parametre olarak 80 verdik. Girilen parametre portu temsil ediyor.


  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Wifi agina Baglanmadi!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());

Bu kod bloğunda sırasıyla;


  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);

Led adlı değişkenin bulunduğu pine(GPIO2) çıkış verdik ve başlangıçtaki durumunu kapalı olarak belirledik.


server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

Gelen isteğe karşılık web sayfasını istemciye gönderir.


server.on("/ac", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, "text/plain", "ac sinyali gonderildi.");
  });

Gelen “/ac” isteğine karşılık ledi açık konuma getirir ve istemciye “ac sinyali gonderildi.” mesajını iletir.


server.on("/kapat", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, LOW);
    request->send(200, "text/plain", "kapat sinyali gönderildi.");
  });

Gelen “/kapat” isteğine karşılık ledi kapalı konuma getirir ve istemciye “kapat sinyali gonderildi.” mesajını iletir.


server.onNotFound(notFound);
server.begin();

Bu kod bloğunda sırasıyla:


#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>


const char* ssid = "Ag Adi";
const char* password = "Ag Parolasi";

const int led = 2;

const char index_html[] PROGMEM = R"rawliteral(<!DOCTYPE Html>

<head>
    <meta charset="utf-8">
    <title> Web Sayfasi </title>
    <style>
        body {
            margin: 0;
            text-align: center;
        }
        
        button {
            width: 200px;
            height: 100px;
            border-radius: 3px;
        }
    </style>
</head>

<body>
    <h2>Esp32 İle Asenkron Web Server</h2>
    <br>
    <button style="background-color: #77d772;" id="ac" onclick="myfunction('ac')"><b>Aç</b></button>
    <button style="background-color: red;" id="kapat" onclick="myfunction('kapat')"><b>Kapat</b></button>
    <h4>Led Durum:
        <h4 id="leddurum">Led Kapalı</h4>
    </h4>
    <script>
        function myfunction(value) {
            var xhr = new XMLHttpRequest();
            if (value == 'ac') {
                document.getElementById("leddurum").innerHTML = "Led Açık";
                xhr.open("GET", "/ac", true);
                xhr.send();
            } else {
                document.getElementById("leddurum").innerHTML = "Led Kapalı";
                xhr.open("GET", "/kapat", true);
                xhr.send();
            }
        }
    </script>
</body>

</Html>)rawliteral";



void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Sayfa Bulunamdadi");
}

AsyncWebServer server(80);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Wifi agina Baglanmadi!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());
  
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
  });

  
  server.on("/ac", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, HIGH);
    request->send(200, "text/plain", "ac sinyali gonderildi.");
  });

  
  server.on("/kapat", HTTP_GET, [] (AsyncWebServerRequest *request) {
    digitalWrite(output, LOW);
    request->send(200, "text/plain", "kapat sinyali gönderildi.");
  });
  
  server.onNotFound(notFound);
  server.begin();
}

void loop() {
 
}
· Esp32, Asenkron, Web Server