Nodemcu #7

Merhaba, bugün Nodemcu ile birlikte Web Server (Sunucu) kurmayı, dosya aktarmayı ve adresimize bağlanmayı anlatacağım.

Başlayalım!

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h> 
#include <WiFiClient.h>
#include <ESP8266mDNS.h>

ESP8266WebServer Sunucu(80);

void Icerik() 
{
  Sunucu.send(200, "text/plain", "Nodemcu #7 - Heey, ben Resul!");
}

void Hata()
{
  Sunucu.send(404, "text/plain", "Hata, boyle bir sayfa yok!");
}

void setup() 
{
  Serial.begin(115200);
  WiFi.disconnect();
  delay(2000);
  WiFi.begin("R2D2", "Tuzen123,");

  while((WiFi.status() != WL_CONNECTED))
  {
    delay(100);
    Serial.print(".");
  }
  
  Sunucu.begin();
  Serial.println("\n\nServer Basladi!");
  
  Serial.print("Internete baglandim ve IP adresim: ");
  Serial.println(WiFi.localIP());
  
  Sunucu.on("/", Icerik);
}
void loop() 
{
  Sunucu.handleClient();
}

Tüm kod satırlarını açıklayalım:

#include <ESP8266WiFi.h>

Nodemcu’ya Wi-Fi özelliğini kazandırmak için <ESP8266WiFi.h> kütüphanesini Nodemcu’ya dahil ediyoruz.


#include <ESP8266WebServer.h>

Nodemcu’ya Server (Sunucu) kurmaya yarayan fonksiyonları çalıştırmak için <ESP8266WebServer.h> kütüphanesini Nodemcu’ya dahil ediyoruz.


#include <WiFiClient.h>

Nodemcu’ya bağlanılacak olan aygıtların (Client = İstemci), sağlıklı bir şekilde bağlanıp ve kontrol edilmesi için <WiFiClient.h> kütüphanesini Nodemcu’ya dahil ediyoruz.


#include <ESP8266mDNS.h>

Açılımı Multicast DNS olup, veri haberleşme metodudur. Bu metodun amacı bir kaynak (Nodemcu) tarafından gönderilen bilgilerin, bir kaç aygıta ulaşmasını sağlamaktır. Bu bilgilerin aygıtlara dağıtımı için <ESP8266mDNS.h> kütüphanesini Nodemcu’ya dahil ediyoruz.


ESP8266WebServer Sunucu(80);

Nodemcu’ya Server (Sunucu) kurmaya yarıyor. Parentez içerisindeki “80” ifadesi ise bağlantı noktası numarasıdır ve genelde “80” bağlantı noktası kullanılır. Amacımız; bir Server (Sunucu) kurup, buna bir bağlantı noktası atamaktır.

Portlar ile alakalı daha fazla bilgiye sahip olmak isterseniz şu bağlantıya tıklamanızda fayda var. Bende, bu kısımdan oldukça fazla yararlandım.


void Icerik() 
{ 
  Sunucu.send(200, "text/plain", "Nodemcu #7 - Heey, ben Resul!"); 
}

Yukarıdaki kodda bir fonksiyon oluşturup, sunucuya bir veri gönderdik. Sırasıyla 200 numaralı durum kodunun, sunucu ile başarılı bir şekilde bağlantı kurulduğunda onay vermek için seçilmiş bir numara olduğunu unutmayalım.

‘200’ numaralı koda “Http Durum Kodu” deniliyor.  1xx ile 5xx arasında numaralandıralan bu kodlar;

1xx – informational (bilgi),

2xx – success (başarı) ,

3xx – redirection (yönlendirme) ,

4xx client error (tarayıcı hatası),

5xx – server error (sunucu hatası) şeklindedir.

İkinci olarak “text/plain” kısmının da “MIME Tipi” olduğunu unutmayalım. Biz metinsel bir ifade yazdıracağımız için “text/plain” kullandık.  MIME Tipleri için şöyle bir kaynağa bakmakta fayda var.

Üçüncü kısımda ise yollanacak olan değerimizi gireceğiz. Ben bu kısma “Nodemcu #7 – Heey, ben Resul!” adlı metni yazdırmayı tercih ettim. Durumu özetlemek gerekirse; kısacası bir fonksiyon oluşturup, sunucuya “Nodemcu #7 – Heey, ben Resul!” adlı metni yolladık.

“Fonksiyon da nedir?” dediğinizi duyar gibiyim. Fonksiyonların amacı; tekrar tekrar yazılacak olan kodları tek satırda çağırmak ve çalıştırmaktır.

Örneğin;

void Ekrana_Yaz() 
{ 
  Serial.println("Birinci Mesaj");
  Serial.println("İkinci Mesaj");
  Serial.println("Üçüncü Mesaj");
}

İçerisinde üç satır kod olan bir kodu, alt alta üç defa yazdığımızda dokuz satır kod tutar değil mi? Bu da bize göz karmaşıklığı ve yavaşlılık verecektir.

Serial.println("Birinci Satır");
Serial.println("İkinci Satır");
Serial.println("Üçüncü Satır");
Serial.println("Dördüncü Satır"); 
Serial.println("Beşinci Satır"); 
Serial.println("Altıncı Satır");
Serial.println("Yedinci Satır"); 
Serial.println("Sekizinci Satır"); 
Serial.println("Dokuzuncu Satır");

Evet, gördüğünüz gibi dokuz adet kod satırı tuttu. Bunu engellemek için fonksiyon kullanabiliriz. Fonksiyon kullandığımızda, kodları sürekli yazmak yerine, fonksiyon ismini çağırmamız yeterli olacaktır.

void Ekrana_Yaz() 
{ 
  Serial.println("Birinci Mesaj"); 
  Serial.println("İkinci Mesaj"); 
  Serial.println("Üçüncü Mesaj"); 
}

Ekrana_Yaz();
Ekrana_Yaz();
Ekrana_Yaz();

Evet, gördüğünüz gibi toplam üç adet fonksiyonu çağırdığımızda, aslında dokuz satır kodu çağırmış oluyoruz. Fonksiyonu her bir kere çağırdığımızda, -aksi belirtilmedikçe- içerisindeki kodlar bir defaya mahsus çalışır. Bu çalışma sonucu, toplam dokuz satır kodu, yine eskisi gibi ve kolay bir şekilde elde edebiliriz.


void Hata() 
{ 
  Sunucu.send(404, "text/plain", "Hata, boyle bir sayfa yok!");
}

Yukarıdaki kodda “Hata” adlı bir fonksiyon oluşturup, Sunucu’ya herhangi bir hata sonucunda; “Hata, boyle bir sayfa yok!” adlı metni yolladık.

404 numaralı durum kodunun, tarayıcı hatası için seçilmiş bir numara olduğunu unutmayalım.

“text/plain” kısmının da “MIME Tipi” olduğunu unutmamakta fayda var. Biz metinsel bir ifade yazdıracağımız için “text/plain” kullandık.  MIME Tipleri için şöyle bir kaynağa bakmakta fayda var.

Üçüncü kısımda ise hata sonucunda ekrana çıkan metni gireceğiz. Bu kısma hata mesajını ifade eden bir metin yazdıracağız. Ben bu kısma “Hata, boyle bir sayfa yok!” adlı metni yazdırmayı tercih ettim.

‘404’ numaralı koda “Http Durum Kodu” deniliyor.  1xx ile 5xx arasında numaralandıralan bu kodlar;

1xx – informational (bilgi),

2xx – success (başarı) ,

3xx – redirection (yönlendirme) ,

4xx client error (tarayıcı hatası),

5xx – server error (sunucu hatası) şeklindedir.


Serial.begin(115200);

IP adresimizi, sunucu bilgilerini öğrenmek için seri haberleşmeyi başlatmak gerekiyor. Ben genelde “115200 baud” hızını kullanıyorum.


WiFi.disconnect();

Bağlanılan kablosuz ağ ile arasındaki bağlantıyı sonlandırır. Bağlanılacak olan ağa bağlanmadan önce, diğer bağlantıların koparılması ve birden fazla bağlantı yapmamaktır. Amaç tedbir alıp, önceki bağlantıları koparıp, yeni bir bağlantıya açık olmaktır.


delay(2000);

2 sn geciktirme işlemi yapıyoruz. Bu sayede kodu yüklediğimiz zaman, seri haberleşme ekranını açana bilgilerin iki sn kadar gecikmesini sağlıyoruz.


WiFi.begin("Wi-Fi_Adı","Wi-Fi_Sifresi");

İçerisine yazdığımız bilgiler (Wi-Fi Adı ve Şifresi) ile bir ağa bağlanmaya çalışacaktır.


while((!(WiFi.status() == WL_CONNECTED))) 
{ 
  delay(100); 
  Serial.print("."); 
}

while((!(WiFi.status() == WL_CONNECTED)))  ile while(WiFi.status() != WL_CONNECTED) komutları birbirini aynısıdır.

Ağa bağlanma süreci bir kaç saniye sürecektir. Bu sebeple anında bağlanamayacağı için bağlantı durumunu sürekli kontrol etmesini ve bize bilgi vermesini istiyoruz. WiFi.status()  komutu bu işe yarıyor. Bu komut bize Wi-Fi bağlantı durumunu kontrol edip, bize bilgi veriyor. Bağlandıysa WL_CONNECTED değerini, bağlanmadıysa hiçbir değeri vermiyor.

Bu aşamadan sonra yapacağımız şey sürekli (bağlanana kadar) bunun kontrolünü sağlamaktır. Bunu ise while() döngüsü ile yapacağız.

while((!(WiFi.status() == WL_CONNECTED))) )  ile de Wi-Fi bağlantısı kurulmamışsa, yani Wi-Fi bağlantısı WL_CONNECTED değerine eşit değilse, döngünün içerisinde dönüp duracak ve loop() döngüsüne gitmemiş olacak.

Eğer bu döngüyü eklemezsek, void setup()  fonksiyonunda işlem bittikten hemen sonra, ağa bağlanma durumu gözetmeksizin void loop() döngüsüne geçecek ve haliyle hata yada eksik bilgiler alacağız. Çünkü ağa bağlanıp, bağlanmadığını bilmiyoruz. Döngü içerisinde biraz geciktirme ve nokta işareti ekleyerek görsellik sağladım. Her döngü içerisine girdiği zaman, biraz geciktirme ve bir adet nokta ekleyerek devam edecek. Tıpkı bir “loading ekranı” gibi olacak.


Sunucu.begin(); 
Serial.println("\n\nServer Basladi!"); 

Serial.print("Internete baglandim ve IP adresim: "); 
Serial.println(WiFi.localIP());

Birinci satırda Sunucu’yu başlatıyoruz. İkinci satırda iki adet boş satır ekleyip, ardından “Server Basladi!” adlı bir metinsel ifade yazdırıyoruz. Üçüncü satırda “Internete baglandim. IP adresim: ” yazdırıyoruz. Dördüncü satırda ise “Internete baglandim. IP adresim: ” kısmının yanına gelecek değeri (Local IP / Yerel IP / Alan Adresi) yazdırıyoruz..

Web sitelerindeki aynı mantıkla çalışmaktadır. Yani, Web sitelerinde alan adına benzeyen kısım; WiFi.localIP() , sunucuya benzeyen kısım ise Sunucu.begin(); kısmıdır.


Sunucu.on("/", Icerik

Önceden başlatılan sunucuyu, çalıştırıyoruz. İlk kısımda bulunan “/”, sunucumuzdaki bilgilerin “text/plain”e gönderimi ve gösterimi sağlıyor. Eğer bu parantezi (/) kaldırırsak, ekranda “not found” yazacaktır. Bunun sebebi uyumsuz olması ve parantezi arayarak, dizin oluşturup, bilgi gösterimini sağlamaktır. İkinci kısımda ise “Icerik” adlı fonksiyonumuzdaki bilgileri çağırıyoruz. Bu çağırma sonucunda; sunucu “text/plain” mantığında çalışıp, “Icerik” adlı bir fonksiyon olacak ve “Icerik” adlı fonksiyonun içerisindeki bilgileri göstermesini sağlayacaktır.


Sunucu.handleClient();

Http sunucularını oluşturup, gerekli gösterimleri ve işleyişleri yapan ana kod parçasıdır. Bu kod olmazsa, olmazdır. Detaylı bilgi için şu kaynağa bakmanızda fayda var.


 

Evet, bunların sonucunda sizlerde aşağıdaki gibi IP adresini görmüş, sunucuyu kurmuş, başlatmış ve siteye bağlanmaya hazır hale geldiğini görmüş olacaksınız.

Yukarıda gördüğünüz adresi, herhangi bir internet tarayıcısına yazarsak alttaki gibi bir ekranla karşılaşmış olacağız;

 


Bu arada Nodemcu’ya ana kodu yüklediğiniz zaman, bilgilerin yalnızca bir defaya mahsus çalıştığını göreceksiniz. Bunun sebebi kodları void setup() kısmına yazmış olmamızdır. Eğer kodları void loop() kısmına yazarsak; ekrandaki bilgilerin sürekli tazelendiğini görebilirsiniz.

Kodu yükledikten sonra Seri Haberleşme Ekranını açıp, ardından kapatıp ve tekrar açmaya çalıştığınızda ekrana bir şeyler gelmeyebilir. Bunun sebebi kodlar yüklendikten sonra, ilk önce void setup() kısmına, ardından void loop() kısmına geçecektir. Sizler kodu yüklediğiniz ve  Seri Haberleşme Ekranını açtığınızda yüksek bir ihtimalle kod satırı void setup() kısmında olacağı için kodları bir defaya mahsus görebilirsiniz. Fakat Seri Haberleşme Ekranını tekrar kapatıp, açtığınızda ise kod satırı yüksek bir ihtimalle void loop() kısmına geçmiş olacak ve orada dönüp duracağı için, ekrana bir şeyler gelmeyecektir. Bu sorunu çözmek için ya ana kodları void loop() kısmına atabilirsiniz. Ya da Nodemcu üzerinde bulunan “RST” butonuna basıp Nodemcu’yu resetleyebilirsiniz.

Bunları yaptığınızda bilgilerin sürekli tazelendiğini ve bir defaya mahsus çalışmadığını görebilirsiniz.

 

Bir sonraki blog’da görüşmek üzere, sevgilerimle.

You May Also Like

Comments

Onur

Merhaba, öncelikle hazırladığın yazılar çok açıklayıcı ve faydalı bu yüzden teşekkür ederim. Nodemcu ile bir proje yapmaktayım cihaz ip alıyor bu ip adresini tarayıcıya yazıp buton ile evde ki bir röleyi kontrol ediyorum. Ama sabit İP olmadığı için cihaz açılıp kapanınca ya da belirli aralıklarla İP adresi değişiyor. Bu sorun nasıl çözülebilir. Bir fikriniz var mı?

    Resul Tüzen

    Merhaba, rica ederim.

    “https://forum.arduino.cc/index.php?topic=460595.0” bu sayfada sabit IP ayarlama ayarları mevcut, bunları koda ekleyebilirsiniz. Bu kısımlara ilerleyen zamanlarda değineceğim. Eğer bu kısımdaki adımları ve kodları uygularsanız sorun çözülecektir. Her şey bittikten sonra ise “begin()” komutundan sonra, “config()” komutunu çalıştırmanız, derlemeniz gerekiyor. Bunun sırasına dikkat etmezseniz mantıksal hata alabilirsiniz.

    Eğer bir sorun olursa bana ulaşabilirsiniz, sevgilerimle.

Leave a Comment

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>