Nodemcu #8

Merhabalar efendim. Bugün telefonumuzdan veya İnternet’e bağlanabilen herhangi bir cihaz üzerinden Nodemcu’ya bağlı olan ledi kontrol edeceğiz.

Haydi başlayalım!

  1. Sistem nasıl çalışıyor?
  2. Çoklu aygıt üzerinden kontrol nasıl sağlanıyor?
  3. Devre şemasının kurulumu
  4. Mobil uygulamayı nasıl yaptım?
  5. Arduino IDE yazılımının anlatımı

1. Sistem nasıl çalışıyor?

İlk önce Arduino kodumuzu Nodemcu’ya yüklüyoruz. Kodumuzu başarıyla yükledikten sonra, seri haberleşme ekranını açıyoruz ve bekliyoruz. Kodumuzda bir sorun yoksa, bir kaç saniye sonra ekrana Nodemcu’ya özel olarak verilen bir IP adresi ekranda yazılacak. Bu IP adresini bir yere not etmenizde fayda var.

Bu IP adresi ile Televizyon, Bilgisayar, Tablet, Cep telefonu veya İnternet’e bağlanan tüm cihazlarla LED’imizi kontrol edebiliriz. Yalnızca İnternet tarayıcısı, erişimi ve aynı ağa bağlı olması gerekiyor. Ben bu işlemin daha kolay olması için MIT App Inventor kullanarak Android telefonlara özel bir uygulama geliştirdim. Bu uygulamanın nasıl yapıldığını ve mantıksal çerçevelerini de birazdan paylaşıyor olacağım.


Örneğin TV üzerinden Nodemcu’ya bağlanmaya çalıştığımızı varsayalım. İlk önce IP adresimizi bilmemiz gerekiyor. Bunun ilk başta nereden geldiğini söylemiştim, o kısma tekrar bakmanızda fayda var. Örneğin elimizdeki IP adresi “192.168.1.55” olsun. Bu IP adresini TV üzerindeki İnternet tarayıcısına girdiğimizde ve yolladığımızda bir şey olmayacak. Çünkü sadece sunucuya bağlanmış olduk, ona bir komut yollamadık.

Bunu yapmak için ise farklı bir parametre kullanacağız. IP adresini yazdıktan sonra yanına ekleyeceğimiz bir değere göre, Nodemcu karar verecek ve bir işlem yapacak.

O da şu şekilde olacak: “192.168.1.55/ledAc” yazdığımda, Nodemcu bunu kendi tarafında alıp belirli kısımlarını kırparak, işimize yarayan “ledAc” kısmını alması ve işlemesi gerekiyor.

Nodemcu’ya gelen veri “192.168.1.55/ledAc” şeklinde olacaktır. Bu bilginin belirli yerlerini kırpıp, “ledAc” şeklinde bir değere dönüşmesini sağlayacağız. Bu değeri bir kontrol ifadesiyle (if, while) kontrol ettikten sonra, Nodemcu istediğimiz işlemi başarıyla yapmaya çalışacaktır.

İşte bu kadar. Sistemin nasıl çalıştığını anladığınızı varsayıyorum.

2. Çoklu aygıt üzerinden kontrol nasıl sağlanıyor?

Herhangi bir aygıt üzerinden bağlantı sağlanabilir. İki şey önemlidir;

  1. Nodemcu’nun İnternet’e bağlanmış ve İnternet erişiminin olması.
  2. Nodemcu’nun bağlandığı İnternet ile erişim sağlanılacak olan aygıtın bağlandığı İnternet’in aynı ağa bağlanmış olması,

Eğer yukarıdakilerden bir tanesi bile sağlanmazsa, maalesef kontrolü sağlayamıyoruz. Peki yurt dışında herhangi bir yerden, Türkiye’deki odamızın ışığının kontrolünü sağlayamayacak mıyız?

Geçen zamanlarda Dünya’nın farklı bir yerinden, farklı bir yerini kontrol etmeye çalışan ve suikaste dayalı bir eylem vardı. Bu eylemin nasıl gerçekleştiğini ve IoT’nin kötü bir hale dönüşmüş versiyonunu da birazdan seyretmiş olacaksınız. M. Serdar Kuzuloğlu anlatıyor, seyrediyoruz.

Bu gibi şeylerin olması için ara bağlantının başarılı bir şekilde sağlanması gerekiyor. Nodemcu’nun bir ağa ve ağın da İnternet erişimine başarılı bir şekilde bağlanması gerekiyor. Aynı şekilde karşı tarafında bu kurala uyması gerekiyor ki, bağlantı başarılı bir şekilde gerçekleşsin. Bu arada ara bağlantıdan kastım, sunuculardır. Ama kendi kurduğumuz sunucu değil, bütün Dünya’yı kasıp kavuran ve içinde her şeyi tutan gerçek İnternet’e bağlamamız gerekiyor. Bunun için farklı yöntemler var, fakat en mantıklısı bir web sitesi almak ve buna bir de sunucu kurarak, iletişim kurdurulacak aygıtları buraya bağlamak olacaktır. Diğer türlü gidecek olan veriler yanlış yere yada hiçbir yere gitmeyebilir.

Eğer yukarıdaki şeyler sağlandıysa, IP adresimizi herhangi bir İnternet tarayıcısına yazarak bağlantı kurabiliriz. “192.168.1.55/ledAc” şeklinde bir ifade yazarsak bağlı olan kodumuz çalışacaktır. Ben “192.168.1.55/ON” ve “192.168.1.55/OFF” gibi bir ifade kullanmayı tercih ettim ve buna göre bir yazılım yazdım. Sizler bunu değiştirerek, kendinize özgü bir şey yazabilirsiniz.

192.168.1.55 IP adresi olup, size farklı veya aynı IP adresi gelebilir. Eğer size gelen IP adresi 192.168.1.102 şeklindeyse, İnternet tarayıcısına o IP adresini girmeniz gerekiyor. Eğer başka bir şey girerseniz, hata mesajı verebilir yada IP adresine bağlanmayabilir. İlerleyen zamanlarda IP adresimizi sabitlemeyi de göstereceğim.

Eğer bir kaç tane aygıt ile kontrol etmeye çalışırsanız, en hızlı tepki veren veya komutu ilk önce yollayana göre tepki verecektir.

3. Devre şemasının kurulumu

Nodemcu’nun pinleri sırasıyla şu şekildedir;

Nodemcu kartının pin diyagramı

Yukarıdaki fotoğrafda bizi ilgilendiren kısım, mavi bloklar yani giriş/çıkış pinleri olacak. Yeri geldiğinde 1 tane olan sarı blogu da kullanacağız, fakat şu an yeri ve zamanı değil. Ama o pinin de analog giriş pini olduğunu unutmayalım.

D0 = 16;
D1 = 5;
D2 = 4;
D3 = 0;
D4 = 2;
D5 = 14;
D6 = 12;
D7 = 13;
D8 = 15;
D9 = 3;
D10 = 1;

pinlerine bağlıdır. Ben 13.pini kullanmak istiyorum ve yazılımda bu pinin ayarlamasını yaparak aktif hale getiriyorum. Ama, Nodemcu kartı üzerinde 13 diye bir pin yok. Yukarıdaki yazdığım bilgilere yada pin diyagramına bakacak olursanız, 13 numaralı pinin D7 numaralı bacağa bağlı olduğunu görebiliriz. İstersek 13 yerine, D7 de yazabiliriz. Arduino IDE bunu D7 olarak değil, 13 olarak algılayacaktır.

Nodemcu ile LED bağlantısı

LED’in artı kısmını dijital pine, eksi kısmını ise GND pinine bağlıyoruz. Ben bağlantı tarafında breadboard kullanmak yerine, Nodemcu Shield ile birlikte dişi-dişi kablo kullandım. Daha güzel bir görüntüsü olmakla beraber, daha bir erişme açık olduğunu söyleyebilirim.

4. Mobil uygulamayı nasıl yaptım?

Bu kısma benzeyen bir uygulamayı daha anlaşılır bir şekilde anlattığım bir blog var, ona göz atmak için şuraya tıklayabilirsiniz. Bu da aşağı yukarı aynı bir tasarım da, fakat arka plan kod diyagramı daha farklı olacak.

Telefon uygulamasını Java, Android Studio gibi editörlerde de yapabilirdik, ama MIT App Inventor kullanmamızın sebebi herkesin kolay bir şekilde uygulama yapabilir olmasını sağlamaktır. Arka plan kodları metinsel bir biçimde değil, blok sistemi ile çalıştığı için daha görsel ve anlaşılır bir ifade ile karşınıza çıkmaktadır.

Telefon uygulamasını incelemek için kodu şuradan bilgisayarınıza indirebilirsiniz. “MIT App Inventor / Projects / Import Project (.aia) From My Computer” menüsü üzerinden indirdiğiniz dosyayı bilgisayarınız üzerinden seçtiğinizde, sizde yaptığım projeyi bire bir olarak göreceksiniz.

Tasarım kısmında iki adet buton ve bir adet textbox ekleyerek işe başlıyoruz. Butonların bir tanesi LED’i açma, diğeri ise LED’i kapatma komutunu sağlayacak. Textbox’ı ise kullanıcıdan IP adresini almak için kullanacağız.

Textbox’u eklemeseydik, yani arka planda normal bir şekilde IP adresi girseydik, uygulamayı telefonumuza yüklediğimizde ve çalıştırdığımızda o IP adresi dışında bir IP adresine bağlanma gibi bir özellik olmayacaktı. İstediğimiz IP adresine veri yollamamız için bir adet textbox’ı tasarıma dahil edip, istediğimiz IP adresine göre veri iletişimini yapmasını sağladık.

Arka plan kodlarında ise, ne zaman LED’i aktif hale getirmek için oluşturulan butona tıklanmışsa içerisindeki kodlar çalışacaktır. İlk komutu incelediğimiz zaman, tasarım ekranında eklediğimiz Web komponenti üzerinden Web sitesine bilgi yollayabileceğiz, fakat hangi bilginin gideceğini ve nereye gideceğini yazmalıyız. İlk başta yaptığım şey de “http://” değerini web adresine yaz, devamına ise kullanıcının girdiği IP adresini (sayısal değeri) metinsel değere dönüştürüp, “http://” ifadesi ile birleştir ve en son kalan kısmına ise “/ON” ifadesini birleştirip, bu komutu yolla diyoruz. En son gidecek olan veri “http://192.168.1.55/ON” şeklinde olacaktır.

İnternet tarayıcısına bilgileri gizli bir şekilde (POST metodu ile) değil, bilgilerin görünmesini istediğimiz için GET metodunu kullandık. Çünkü bilgiler görünmezse, karşı taraf bu bilgiyi İnternet adresi satırından alamayacağı için, herhangi bir işlem yapamayacaktır. İlerleyen zamanlarda POST metodunu kullandığımız bir blog da gelecek, merak etmeyin 🙂

Eğer çok bunaldıysanız, biraz ara vermenizi tavsiye ederim. Yoksa uçuşa geçiyoruz!

İkinci komutta ise, birinci yaptığım mantık da “http://” değerini web adresine yaz, devamına ise kullanıcının girdiği IP adresini (sayısal değeri) metinsel değere dönüştürüp, “http://” ifadesi ile birleştir ve en son kalan kısmına ise “/OFF” ifadesini birleştirip, bu komutu yolla diyoruz. En son gidecek olan veri “http://192.168.1.55/OFF” şeklinde olacaktır.

Telefon uygulama kısmı ise bu kadardı. Eğer anlamadığınız bir yer olursa, mutlaka yorum kısmından sorunuzu sormayı unutmayınız.

5. Arduino IDE yazılımının anlatımı

Galiba en zevkli ve karışık kısma geldik 🙂

#include <ESP8266WiFi.h>
WiFiServer server(80);

void setup()
{  
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  WiFi.disconnect();
  delay(2000);
  WiFi.begin("Wi-Fi Adı", "Wi-Fi Şifresi");
  
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    Serial.print(".");
  }
  
  Serial.print("\nInternete baglandim ve IP adresim: ");
  Serial.println(WiFi.localIP());
  Serial.print("\n");
  server.begin();
}

void loop()
{
    WiFiClient client = server.available();
    
    if (!client) 
    {
      return; 
    }
    
    while(!client.available())
    {  
      delay(1); 
    }
    
    String veri = client.readStringUntil('\r');
    veri.remove(0, 5);
    veri.remove(veri.length()-9,9);
    
    if (veri == "ON") 
    {
      digitalWrite(13, HIGH);
      Serial.println("Led Yaniyor!");
      
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("");
      client.println("<!DOCTYPE HTML>");
      client.println("<html> LED Acik </html>");
      client.stop();
      delay(1);
    }
    
    else if (veri == "OFF") 
    {
      digitalWrite(13, LOW);
      Serial.println("Led Sondu!");
      
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("");
      client.println("<!DOCTYPE HTML>");
      client.println("<html> LED Kapali </html>");
      client.stop();
      delay(1);
    }
}

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.


WiFiServer server(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.


const int LED = 13;

Nodemcu’ya bağlanılacak olan LED’in pin numarası program çalıştığı süre zarfında sabit olacağı için, LED adlı değişkenimizi const (sabit) tipinde, integer (tamsayı) veri tipinde oluşturup, 13 numara’ya atadık.


pinMode(LED, OUTPUT);

Nodemcu’ya bağlanılacak olan LED değişkenini (13 numaralı pini) çıkış pini olarak kullanacağımızı belirttik.


Serial.begin(115200);

IP adresimizi ve İnternet üzerinden alınan verileri ekrana yazdıracağız. Bu ekrana yazdırma işlemi için seri haberleşme ekranını kullanıyoruz. Seri haberleşme ekranını kullanmamız için ise başlatmamız gerektiğinden dolayı, bu komut seri haberleşme ekranını başlatmış oluyor.


WiFi.disconnect();

Bağlanılan kablosuz ağ ile arasındaki bağlantıyı sonlandırır. Amacımız, tedbir almak ve ö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 Şifresi");

İç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.


Serial.print("\nInternete baglandim ve IP adresim: ");
Serial.println(WiFi.localIP());
Serial.print("\n");
Sunucu.begin();

Birinci satırda ilk başta boş bir satır ekleyerek, hemen yanına “Internete baglandim ve IP adresim: ” şeklinde bir ifade yazıyoruz. Eğer boş bir satır eklemezsek, İnternet’e bağlanma sırasında ekrana yazdırılan noktalar ile karışık bir yapıya bürünecek. Bu ifadenin hemen yanına IP adresimizi yazıyoruz. Bu komutun peşine bir adet yeni boş satır ekleyerek, sunucuyu başlatıyoruz.


WiFiClient client = Sunucu.available();

Sunucu’ya bağlanılacak olan istemciyi oluşturmak için bu komutu kullandık. Yalnızca istemciyi oluşturmak değil, sunucunun kullanım durumunda olup, olmadığını belirten “available()” fonksiyonunu da bu oluşturduğumuz değişkene aktardık.

Sunucu ve istemciler arasındaki farkları, detayları anlatan bir kaynak için şuraya bakabilirsiniz.


if (!client) 
{
  return; 
}

Bu kod bloğunda eğer “client” ismindeki değişkenimiz, yani istemcimiz kurulu durumda değilse yada kurulmamışsa geri dön diyoruz. Geri döndüğünde tekrar kontrol ediyor ve eğer şart sağlanmazsa, yani yine istemcimiz kurulu durumda değilse yada kurulmamışsa, tekrar geri dönüyor. Eğer istemcimiz kurulu durumda ise, bu sefer şart sağlanmadığından dolayı o kod bloğunu atlayarak bir sonraki aşamaya geçiyor.

Bu kod bloğunu bir şey de daha kullanabiliriz. Seri haberleşme ekranını açana kadar eklediğimiz geciktirme süresini kaldırıp, bu kod bloğunun aynısını da setup kısmına eklersek ve “client” yazan kısmı da “Serial” yazarsak, çok işimize yarayacaktır.

Bu kod sayesinde, program seri haberleşme ekranını ekranına açana kadar beklemiş olacaktır.


while(!client.available())
{  
  delay(1); 
}

Bu kod bloğunda eğer “client” ismindeki değişkenimiz, yani istemcimiz kullanılabilir bir durumda değilse 1 ms geciktirme süresi ekliyor. Durum her seferinde tekrar kontrol ediyor ve eğer şart sağlanmazsa, yani yine istemcimiz kullanılabilir bir durumda değilse, tekrar 1 ms geciktirme süresi ekliyor. Eğer istemcimiz kullanılabilir bir durumda ise, bu sefer şart sağlanmadığından dolayı, o kod bloğunu atlayarak bir sonraki aşamaya geçiyor.


String veri = client.readStringUntil('\r');
veri.remove(0, 5);
veri.remove(veri.length()-9,9);

Yukarıdaki kodu anlamadan önce, alttaki koda bakmamız daha mantıklı olacak. Amacım, sizlere detaylı ve kuvvetli bilgileri açıklamaktır. Bu yüzden, işin en önemli kısmını bir çırpıda anlatıp geçemem.


String veri = client.readString();
Serial.println(veri);

Yukarıdaki kod parçasını bir üst kod parçasıyla değiştirdiğinizde, bir veri almaya çalıştığınızda alttaki verilerle karşılaşacaksınız. ON, OFF veya bize yarayan komutları nasıl alacağız?

Zira almazsak, alttaki ekran görüntüsünde olduğu gibi, bir mesaj geldiği zaman 8 satır kod bizi bekliyor demektir. Bir şeyiniz kaybolduğunda nasıl didik didik arıyorsanız, bu kod parçasında da size yardımcı olacak yerleri almalı, geri kalan yerleri çöpe tıkmalısınız. Yoksa aşağıdaki ekran görüntüsünde olduğu gibi yığın bir bilgi karmaşıklığıyla karşılaşırsınız.

Yukarıdaki bordo kısımlarla boyanan yerler, bir bilgi geldiğinde gelen verilerin hepsini gösteriyor. Gördüğünüz üzere oldukça karışık bir yapıdalar. Bu gelen veriler içerisindeki asıl verimiz ilk baştaki veridir. Yani “GET /” ile başlayan kısımdır. Ondan sonraki kısımlar gelen veriden daha çok, nasıl ve nereye geldiği ile alakalı kısımlardır. Bu kısımlara takılmadan hemen “GET /” ile başlayan yere geçelim.

Evet, gelen verinin ilk satırda olduğunu bulduk. Bu satırdan sonraki satırlar bizi pek ilgilendirmediği ve işimize yaramadıkları için onları silmeliyiz. Peki nasıl?

Aslında bir kaç satır üstte cevabını verdim. İlk satırdan sonrası silinmeyecek mi? O zaman ilk satır başını gördüğü zaman, sonrasını dahil etmeden, önceki satırı alıp bir değişkene kaydedelim ve işimizin bir kısmını bitirelim 🙂

Bunun için satır başı ifadesini ve “ReadStringUntil()” komutunu bilmemiz gerekiyor. Bu komut, ifadeleri belirli bir sıraya göre ayıklamaya yarar. Boşluklara, virgüllere, noktalara, satır başlarına veya harflerin aritmetikselliğine göre ayırım yapabiliyor.

Mesela, “ResulTuzen,1234,Mesaj” ifadesi üzerinden gidelim. Burada sizce nasıl bir ayrım yapılabilir? Ortak ifadeye bakıldığında “virgül (,)” ile ayırım yapmak mantıklı olacak. O zaman ifade şöyle olabilir;

String veri = readStringUntil(',');

Bu ifadede virgül gördüğü yerleri parça parça ayıracak. Biz de bu parçaları alıp, işleyeceğiz. Seri haberleşme ekranına yazacağımız ifadeler metinsel olacağından dolayı, ‘veri’ değişkenini String olarak tanımladım. Eğer bir sayı girmeye çalışırsanız, kodunuzda hata almazsınız, fakat mantıksal bir hata olur. Çünkü 5 yazdığımızda bunu 5 olarak değil, “5” olarak görecektir. Bu da girilen ifadenin sayı değil, tırnak işaretinden dolayı metinsel olduğunun kanıtıdır. Bunu çözmek oldukça basit. Eğer sayısal bir ifade girildiyse ve metinsel olarak baz alınacağından dolayı, bunu int (integer – tamsayı) tipine çevirip bu şekilde işlem yapabiliriz. Bu durumda metinsel olarak girilen sayılar, int (integer – tamsayı) tipine dönüşecek ve sayı gibi de kullanabileceğiz.


İlk gelen ifadeyi satır başı komutuyla ayrışdıracağımız için, “\r” komutunu kullanacağız. Kaçış komutları hakkında daha fazla bilgi alabilirsiniz.

En son komutumuz şu şekilde olacak;

String veri = readStringUntil('\r');

“readStringUntil()” fonksiyonunu kullanırken, readStringUntil(‘\r’) yerine readStringUntil(“\r”) tarzında bir kod oluşturursanız, hata alırsınız. Bu hatanın sebebi, fonksiyonun char veritipinde değerleri alıp, ayıklamasıdır. Eğer siz çift tırnak (“) kullanıyorsanız, bu ifadeye metinsel bir değerin girileceğini kabul etmiş olursunuz, bu yüzden yazılımsal bir hata alırsınız. Eğer ifadedeki çift tırnakları (“) tek tırnağa dönüştürüp yazarsanız, hatanız büyük ihtimalle gidecektir.


Bu komutu başarılı bir şekilde yazdıktan sonra, gelen verimize bakalım. Nasıl bir değişiklik olmuş, daha doğrusu istediğimiz ve anlattığım gibi mi oldu?

Bize lazım olan bilgileri aldık ve diğer satırları hiç işe bulaştırmadan, başarılı bir şekilde verileri aldık. Bu veriler halen bize lazım olan şeyler değil, bunları birazcık daha kırpmamız lazım. Bize lazım olan şey ilk satırdaki bazı bilgilerdir. İlk satırdaki bilgileri aldığımıza göre sonraki aşamaya geçebiliriz.

Bu aşamada ise “GET” metodu ile İnternet tarayıcısından okuduğumuz bilgileri almayı göstereceğim. Ben İnternet tarayıcısına “ResulTuzen,1234,Mesaj” ifadesini girmeyi tercih ettim. Siz ne girerseniz girin, gelen ifade “GET /gelenMesaj HTTP/1.1” şeklinde olacaktır. Bize sadece “/gelenMesaj” işe yarayacağından dolayı başındaki ve sonundaki ifadeleri de silersek, salt bilgiyi elde etmiş olacağız.

En baştan “GET /” ifadesini silmek için şu komutu kullanacağız;

veri.remove(0, 5);

Veriyi sil demektir, fakat belirli bir şeye göre silecek. O sınırlarımız ise, başlama noktası (indis) anlamını yaratan (0) parametresi, kaç karakter sileceğimizi söyleyen (5) parametresini girmemiz gerekiyor. Biz 0 numaralı indis’den, yani en baştan başla ve beş karakter kadar sil diyeceğiz. Bu yüzden yukarıdaki gibi bir komut yazdık. Bu komut sıfırıncı indis’den (en baştan) başla ve 5 karakter sil demektir.

Beş karakter silindiğinde ifade şu şekilde olacak;

Son olarak sonundaki ” HTTP/1.1″ verisini de silelim ve elimize salt bilgi gelmiş olsun 🙂

veri.remove(veri.length()-9,9);

Şimdi, “length()” komutu nereden çıktı diyeceksiniz? Hemen açıklayayım. “length()” komutu verinin uzunluğunu verecek. Peki bu bizim ne işimize yaracak?

En baştan başla ve şu kadar git diyebiliriz, ama fonksiyonel olmaz. Her gelen veri için uyumlu olmaz. En baştan başla ve 10 karakter kadar git dediğimizde, 10 karakterlik bir veriye göre çok güzel bir iş çıkarsa da, 20 karakterlik bir verinin yarısını kaybetme durumuyla karşı karşıya kalacağız. Bunun için verinin uzunluğunu bilmemiz gerekiyor. Bu veri uzunluğunu bildikten sonra, bundan 9 karakter (” HTTP/1.1″ değeri uzunluğu kadar) çıkartıyoruz. Dokuz karakterin sayısal değerinin sebebi ” HTTP/1.1″ den kaynaklanıyor. ” HTTP/1.1″ ifadesi 9 karakter olacağından dolayı, 9 karakter çıkarıyoruz. Bunun sonucunda indis noktamızın başlangıcını bilineceğinden dolayı, daha mantıklı bir işlem yapmış olacağız.

Verimiz en son şu şekildeydi: “ResulTuzen,1234,Mesaj HTTP/1.1” Bu değerin uzunluğu 30 karakter. 30 – 9 = 21.indisten silmeye başlayıp, 9 karakter silecek. Bu durumda ise en son verimiz şu şekilde olacak;

Evet, bu kısım da burada bitmiş bulunmakta. Şimdi bir sonraki kod parçasına geçelim.


Bizim amacımız led yakıp, söndürmek olacağından dolayı. ON veya OFF komutlarının gelmesi yeterliydi. İlerleyen bloglarda çoklu veri yönetiminin sıralı ve mantıksal alımını ve işlenmesini göstereceğim. Bu kadar detaylı bilginin de, şu anlık yeterli olacağını düşünüyorum.

Bize İnternet tarayıcısı ve GET metodu ile gelen bilgi: “GET /ON HTTP/1.1” ve “GET /OFF HTTP/1.1” olacaktır. Yukarıdaki anlatımda bunların nasıl kırpılacağını söylemiştim. Bu sefer kırpılan ve gelen ifade “ON” veya “OFF” ifadesi olacağından dolayı, bunu kontrol edip LED’i yakıp/söndürmek kalıyor. Siz isterseniz mobil uygulama kısmında “ON” veya “OFF” komutu yollamak yerine, farklı ve Türkçe karakter içermeyen komutları gönderebilirsiniz. Eğer bunu yaptıysanız, Arduino IDE kısmında ON ve OFF komutlarını güncellemeniz gerekiyor.


Fark ettiyseniz kurduğum cümle arasında “kontrol etmekten” bahsettim. Bunu if ve else ile yapacağız.

İlk önce eğer gelen komut “ON” değerine eşitse, yani LED’i yak komutu geldiyse diyelim.

if (veri == "ON") 
    {

    }

Sonra gelen komut “OFF” değerine eşitse, yani LED’i söndür komutu geldiyse diyelim.

else if (veri == "OFF") 
    {

    }

İlk önce gelen verinin “ON” komutuna eşit olduğu şartın içerisindeki komutları düzenleyelim. En son kısımda ise “OFF” komutunu düzenleyeceğiz.

else if (veri == "ON") 
    {
      digitalWrite(LED, HIGH);
      Serial.println("Led Yaniyor!");
      
      client.println("HTTP/1.1 200 OK");
      client.println("Content-Type: text/html");
      client.println("");
      client.println("<!DOCTYPE HTML>");
      client.println("<html> LED Acik </html>");
      client.stop();
    }

digitalWrite(LED, HIGH);
Serial.println("Led Yaniyor!");

LED’i yakıyoruz ve seri haberleşme ekranına da “Led Yaniyor!” diye bir mesaj yolluyoruz.


client.println("HTTP/1.1 200 OK");

Sunucu’da tırnak işaretleri arasındaki bilgileri gösterecek. Hangi bilgileri gösterecek ve bu bilgiler nelerdir?

HTTP 1.1, İnternet kurallarının en gelişmiş versiyonudur. Bu versiyonların sebebi ise güvenlik ve özellikten dolayıdır. Biz gelişmiş olan HTTP 1.1 kuralını kullanarak, bilginin başarıyla alındığını söyleyen durumu kodunu kullanacağız. Yani “200” numaralı durum kodunu da yanına ekliyoruz. Yanındaki “OK” kelimesi de karşı tarafa, sunucudan bir sinyal geldiğini ve bu sinyalin olumlu bir şekilde dönüt aldığını belirten parametredir. Bu yazılan komutların hepsi “IP adresine bağlı” sunucuda gösterileceği (print edileceği) için “sayfa bulunamıyor” gibi bir hata almazsınız.

Durum kodları ve HTTP hakkında daha fazla bilgi alabilirsiniz.


client.println("Content-Type: text/html");

Sunucu’da tırnak işaretleri arasındaki bilgileri gösterecek. İçerik tipinin “text/html” olacağını belirttim. “text/html” olarak belirtilen ifadenin, bir MIME tipi olduğunu bilmekte fayda var. MIME tipi kullanmazsak, sunucu’da gösterilen şeylerin html değil, sadece bir metin olduğunu söylemiş oluruz. Bu yüzden MIME tipi kullanarak, sunucuda gösterilecek olan bilgilerin html kodu olacağını belirttim.

MIME tipleri hakkında daha fazla bilgi alabilirsiniz.


client.println("");

Gösterilecek olan bilgilerin arasında, bir adet boşluk bırakıyor ve devam ediyorum.


client.println("<!DOCTYPE HTML>");

Gösterilecek olan bilgilerin her İnternet tarayıcısında farklı farklı görünmesini istemiyorsak, “<!DOCTYPE HTML>” kodunu kullanmamız gerekiyor. İnternet Explorer, Opera veya Safari gibi İnternet tarayıcılarında uygulama farklılıklarından dolayı görüntülerde farklılıklar olacağı için, bunun önüne geçmemiz için bu kodu kullanacağız. Bu kodu kullanmamız için “<html> </html>” kodları üstüne yazmamız gerekiyor, aksi takdirde maalesef çalışmayacaktır. Yani bu kodu, her İnternet tarayıcısına uyumluluk sağlasın diye kullanıyorum.

DOCTYPE kodu hakkında daha fazla bilgi alabilirsiniz.


client.println("<html> LED Acik </html>");

Sunucu üzerinde “<html> </html>” parametrelerini kullanarak, HTML sayfası biçiminde ana gövdeye “LED Acik yazıyoruz.” Bu şekilde alt alta istediğimiz şeyleri yazdırabiliriz, fakat Türkçe karakter kullanmamız gerekiyor. Eğer Türkçe karakter kullanacaksak, Türkçe karakter ifadesini destekleyecek kod parçasını da kullanmamız gerekiyor. O da <meta charset=”UTF-8″> olacaktır. Eğer bunu kullanırsak, Türkçe karakterleri başarılı bir şekilde sunucumuzda gösterebiliriz.

HTML nedir ve nasıl yazılmalıdır? ” hakkında daha fazla bilgi alabilirsiniz.


client.stop();

Sunucumuzu en son işimiz bittikten sonra kapatıyoruz / durduruyoruz. Eğer durdurmazsak, çalışmaya devam edecektir.


delay(1);

1 ms geciktirme süresi ekliyoruz. Bu gecikme süresinin sebebi, sunucuda gereksiz bir şekilde kalabalık yapmamanın önüne geçmektir. Sürekli komut alıp / gönderme işi yüzünden ani duraklamalar meydana gelebilir.


If komutu ile işimiz bitti. Şimdi ise “OFF” değerine eşitse, yani LED’i yak söndür komutu geldiyse diyelim ve kodlarımızı yazalım. Kodların bütün hali, en yukarıdaki kısımda bulunuyor, oradan tekrar bakabilirsiniz.

digitalWrite(LED, LOW);
Serial.println("Led Sondu!");

LED’i söndürüyoruz ve seri haberleşme ekranına da “Led Sondu!” diye bir mesaj yolluyoruz.


client.println("HTTP/1.1 200 OK");

Sunucu’da tırnak işaretleri arasındaki bilgileri gösterecek. Hangi bilgileri gösterecek ve bu bilgiler nelerdir?

HTTP 1.1, İnternet kurallarının en gelişmiş versiyonudur. Bu versiyonların sebebi ise güvenlik ve özellikten dolayıdır. Biz gelişmiş olan HTTP 1.1 kuralını kullanarak, bilginin başarıyla alındığını söyleyen durumu kodunu kullanacağız. Yani “200” numaralı durum kodunu da yanına ekliyoruz. Yanındaki “OK” kelimesi de karşı tarafa, sunucudan bir sinyal geldiğini ve bu sinyalin olumlu bir şekilde dönüt aldığını belirten parametredir. Bu yazılan komutların hepsi “IP adresine bağlı” sunucuda gösterileceği (print edileceği) için “sayfa bulunamıyor” gibi bir hata almazsınız.

Durum kodları ve HTTP hakkında daha fazla bilgi alabilirsiniz.


client.println("Content-Type: text/html");

Sunucu’da tırnak işaretleri arasındaki bilgileri gösterecek. İçerik tipinin “text/html” olacağını belirttim. “text/html” olarak belirtilen ifadenin, bir MIME tipi olduğunu bilmekte fayda var. MIME tipi kullanmazsak, sunucu’da gösterilen şeylerin html değil, sadece bir metin olduğunu söylemiş oluruz. Bu yüzden MIME tipi kullanarak, sunucuda gösterilecek olan bilgilerin html kodu olacağını belirttim.

MIME tipleri hakkında daha fazla bilgi alabilirsiniz.


client.println("");

Gösterilecek olan bilgilerin arasında, bir adet boşluk bırakıyor ve devam ediyorum.


client.println("<!DOCTYPE HTML>");

Gösterilecek olan bilgilerin her İnternet tarayıcısında farklı farklı görünmesini istemiyorsak, “<!DOCTYPE HTML>” kodunu kullanmamız gerekiyor. İnternet Explorer, Opera veya Safari gibi İnternet tarayıcılarında uygulama farklılıklarından dolayı görüntülerde farklılıklar olacağı için, bunun önüne geçmemiz için bu kodu kullanacağız. Bu kodu kullanmamız için “<html> </html>” kodları üstüne yazmamız gerekiyor, aksi takdirde maalesef çalışmayacaktır. Yani bu kodu, her İnternet tarayıcısına uyumluluk sağlasın diye kullanıyorum.

DOCTYPE kodu hakkında daha fazla bilgi alabilirsiniz.


client.println("<html> LED Kapali </html>");

Sunucu üzerinde “<html> </html>” parametrelerini kullanarak, HTML sayfası biçiminde ana gövdeye “LED Kapali yazıyoruz.” Bu şekilde alt alta istediğimiz şeyleri yazdırabiliriz, fakat Türkçe karakter kullanmamız gerekiyor. Eğer Türkçe karakter kullanacaksak, Türkçe karakter ifadesini destekleyecek kod parçasını da kullanmamız gerekiyor. O da <meta charset=”UTF-8″> olacaktır. Eğer bunu kullanırsak, Türkçe karakterleri başarılı bir şekilde sunucumuzda gösterebiliriz.

HTML nedir ve nasıl yazılmalıdır? ” hakkında daha fazla bilgi alabilirsiniz.


Evet, kodlarımız bitti. Şimdi deneyelim ve nasıl çalıştığını görelim.

İlk önce kodumuzu Nodemcu’ya yüklüyoruz.


Kodumuz yükleniyor.


Kodumuz yüklendiğine göre, IP adresimizi öğrenelim.


Devremizi kuralım.


Mobil uygulamamızı açıp, IP adresimizi girelim.


LED’imizi Mobil Uygulama veya İnternet üzerinden yakalım.


LED’imizi Mobil Uygulama veya İnternet söndürelim.


Blog burada bitti, o zaman alkış zamanı!

You May Also Like

Comments

Ebubekir

Süper 👍

    Resul Tüzen

    Çok teşekkürler 🙂

osman culaz

Bir şeyi bilmek başka, anlatabilmek başka şey. Gerçekten teşekkür ederim bu anlaşılır yazı dizisi için. Bu alandaki ilk adımı sayenizde atmış oldum. Ledi yaktım. Eksik olmayınız:)

    Resul Tüzen

    Estağfurullah. Kıymetli vaktinizi ayırıp okuduğunuz ve ürettiğiniz için asıl ben teşekkür ederim 🙂

Osondi

Resul bey tebrik ederim çok güzel anlatım, sunum. İngilizcem iyi seviyede çok nadir Türkçe araştırıyorum fakat içeriğinizi yabancı kaynaklardan daha kaliteli buldum. Sorularım var ama önce bir hakkınızı teslim etmek gerekli. Elinize sağlık.

    Resul Tüzen

    Estağfurullah, çok teşekkür ederim. Tabii, sorularınızı merakla bekliyorum.

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>