Arduino ile ESP8266 Kullanımı ve Web Server

  

 

 

 

 

 Merhabalar…

 Bu konuda Arduino ile ESP8266 kullanıma değineceğiniz.

 Öncelikle şimdiye kadar ne yaptığımıza ve şimdi ne yapmak istediğimize bakalım. Daha önceki yazılarımızda Arduino ile enc28j60 ile Web Server kurulumunu ve en basit olarak bir Led’ in nasıl yakılacağını anlattık (Buradan). Şimdiki konuda aynı işi wi-fi özelliğine sahip esp8266 modülü ile yapacağız.

 ESP8266 ile kullanacağımız haberleşme 115200 baud rate ile olacağı için Arduino’ da bulunan SoftwareSerial kütüphanesi bu iş için yeterli değildir. (SoftwareSerial max 38400 baud rate’ i destekler.) Haberleşmeyi yüksek hızda kullanmamızın sebebi web sitesi üzerinden yapılan işlem sıklığının artması durumunda oluşabilecek yığılmaları en aza indirmektir. Sizin uygulamanız için düşük baud rate’ de yeterli ise Arduino Uno ile ESP8266 kullanımı yazısındaki adımları takip edebilirsiz. Bu yazıda anlatılanlar Arduino Mega için anlatılmış olup HardwareSerial donanımının Serial3 çıkışları kullanılmıştır.

 Birazda ESP8266 ‘ yı tanıyalım. Basit olarak Seri haberleşme ile kullanılabilen bir wi-fi modülüdür diyebiliriz. Ancak Bunun dışında çok daha fazla amaç için kullanılabilir. Buna en güzel örnek üzerindeki mikrodenetleyici programlanabilirdir. Siz farklı bir mikrodenetleyiciye ihtiyaç daymadan TTL dönüşütürücü kullanarak programlayabilirsiniz. ESP8266 üzerinde 2 adet de GPIO pini bulundur.

 Programlanabilme özelliğinin yanı sıra bir modem gibi DHPC’ ye sahiptir ve kendi ağını kurabilir. İşin güzel kısmı ise bütün ayarları sıra ile AT komutlaru ile yapar. 

 Hangi At komutlarının kullanıldığına buradan bakabilirsiniz.

  Yandaki resimde ESP8266′ ın pin yapısını görmekteyiz. Burada dikkat etmeniz gereken kısım VCC ile belirtilen besleme geriliminin 3.3V olmasıdır. Buna dikkat etmediğiniz taktirde modüle zarar verebilirsiniz. Reset pini Low konumda iken modüle reset atmakta, bu yüzden 10k lık bir direnç ile 5V’ a bağlanması olası sorunları en aza indirgemenize yardımcı olur. Son olarak da CH_PD pinine değinelim. Bu pin modülün hazır konuma geçmesi için anahtar görevi görür. Yani siz her şeyi bağlayıp bu pini boş bırakır yada Low konuma çekerseniz modül size cevap vermeyecektir. Size tavsiyem bu pini 10k ‘ lık bir direnç ile Arduino’ ya bağlamanızdır. Bu sayede pini modülün ne zaman çalışmaya başlayacağına karar verebilirsiniz.

esp8266

 Şimdi bağlantı şemamıza bakalım. Yukarıda da belirttiğim gibi ben Arduino Mega’ nın Serial3 donanımını kullandım. Ancak siz bunu duruma göre değiştirebilirsiniz. 

ESP8266′ yı hazırlamak için gerekli AT komutlarna bakalım.

“AT+RST” ESP8266′ nın reset atmasını sağlar. Gücü Arduino’ ya ilk verdiğinizde pinlere voltaj yeni gideceğinden bu komutu kullanmanıza gerek yoktur. Ancak öncdene güç verdiğiniz bir Arduino’ yu sürekli programlıyorsanız bu komutu kullanmanız gereklidir.

 “AT+CWMODE”  ESP8266′ nın wi-fi çalışma modunu ayarlar. AT+CWMODE=1 bütün modlar için ESP8266′ yı aktifleştirir. Bu modu 2 yapmanız halinde ESP8266 wi-fi özelliğini kullanmayacaktır. Siz wi-fi leri görüntülemeye çalışsanızda ESP8266′ hata mesajı verecektir.

 “AT+CWLAP” ESP8266′ nın bağlanabileceği wi-fi bağlantı noktalarını gösterir. (En yakında kablosuz modemleri)

 “AT+CWJAP” ESP8266′ nın wi-fi ye bağlanmasını sağlar. iki parametre alır ve kullanımı  AT+CWJAP=”SSID”,”Password” şeklindedir. Burada dikkat etmeniz gereken nokta herhangi bir ağa bağlanmaya çalışmadan önce, ağ bağlantılarını taramış olmanız gerekir.(AT+CWLAP daha önce kullanılmalıdır.)

 “AT+CIFSR ESP8266′ nın sahip olduğu IP’ leri igösterir. Kullandığınız moda göre 2 farklı ip gösterecektir. Bir tanesi kendi oluşturduğu ağdaki statik IP, diğeri ise eğer wi-fi ye bağlanmışsa ağdan aldığı statik IP’ dir.

 “AT+CIPMUX” ESP8266 ‘nın TCP bağlantı şeklini belirler. AT+CIPMUX=1 çoklu bağlantı kurmanızı sağlar.

 “AT+CIPSERVER” İki parametre alır. ESP8266′ nın açık ya da kapalı olma durumunu, ve bağlantı portunu belirler.  AT+CIPSERVER=1,3000 ,bağlantı açık ve 3000 portu kullanılacak anlamına gelir.

 Şimdi web server’ ımızı oluşturmaya bakalım. Üstte ESP8266 için ayarlamaları yaptık . Web Server oluşturmaya çalışırken Enc28j60 modülü ile kullanımında olduğu gibi verileri internete bir tampon üzerinden yazacağız ve bu tampon üzerinden okuyacağız. Tek seferde okunacak tampon boyutunu basit olarak şu şekilde belirleyebiliriz.

#define BUFFER_SIZE 128   //Tampon boyutunu belirler
char buffer[BUFFER_SIZE];  //Tamponu oluşturduk

Tampondaki verileri okumak için bu fonksiyonu kullanacağız. Oluşturduğumuz Web Server’ a bağlanmaya çalışıtığımızda HTTP GET motedu çağrılmış olur. Bu medtod kaynaktan data isteyen metodtur. Yani Bu istek oluşmuşsa Server bize web sayfasını göndermesi gerekir.

Serial3.readBytesUntil('\n', buffer, BUFFER_SIZE);   //Tampondaki verileri okuduk

Tampondan veriler okuduk ancak /GET metodunun istendiğine emin olmamız lazım. Aksi taktirde Server gerksiz işlemler yapacak, hatta çökmeye sebep olacaktır. (Serial monitöre gelen bussy p hatası çökme olmuş demektir.) Öncelikle biz Ip’ ye bağlandığımızda nasıl bir data gelecek ona bakalım.

+IPD,0,436:GET /?led HTTP/1.1
8,en-US;q=0.6,en;q=0.4
eWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36

client-server Tamponda gelen verilerin başındaki +IPD ifadesi ESP8266′ nın data almaya başladığını gösterir. Sonraki sıfır ch_id olarak tanımlayacağımız, bağlantıyı başlatanın id’ sidir. Bu id’ den kime ne göndermemiz gerektiğini belirleyebiliriz. Sonraki 436 ise tamponda bize gelen verinin boyutudur. Bunların dışında “GET /?led” ifadesi bulunmakta. Bu yapı Adres çubuğunun sonuna eklenir, sayfalar arasında ve server ile haberleşme için kullanılır. Bunun anlamı kullanıcı server’ dan /?led isimli istekte bulunuyor. Biz bunu server tarafında işleyerek istediğimiz gibi kullanabiliriz. (Örneğin led yakmak için)

Kullanıcının server’ dan istediği ifadeleri iyice anlamlandırmak gerekir. Yani +IPD ve GET / ifadesinin geldiğinden emin olamak gerekir. Bunun için bazı fonksiyonlar kullanacağız.

strncmp(buffer, "+IPD,", 5) == 0

Burada kullanılan strncmp fonksiyonu parametre olarak aldığı string ifadeleri son parametre olarak gelen değer boyunca kıyaslar. (Yani buffer’ ın ilk beş değeri “+IPD,” ‘mü diye bakar.) Eğer eşit ise sıfır döndürür.

sscanf(buffer + 5, "%d,%d", &ch_id, &packet_len);

Bu fonksiyon C programlamada kullandığımız scanf’ in string ‘den okuyan çeşidir. Scanf ile aynı işi yapar.

strncmp(pb, "GET /?led", 8) == 0

Bu fonksiyonda ise yukarıda bahsettiğimiz kullanıcının server’ dan hangi bilgiyi istediğini sorguladığımız kısım. Siz bunu kendinize göre değiştirebilirsiniz.

Server ile iletişimin doğru olabilmesi için tampondaki fazla verileri mutlaka temizlenmelidir. Bunun için şu şekilde bir yapı kullanabilirsiniz. Bu fonksiyonu ihtiyacının olduğu yerde çağırarak tamponu boşaltabilirsiniz.

void clearSerialBuffer(void) {
  while ( Serial3.available() > 0 ) {
    Serial3.read();
  }
}

Bunun dışında AT komutlarını ESP8266′ ya göndermek için sendData isimli bir fonksiyonu kullandım. Bu sayede hem işlemlere timeOut verdim hemde geribesleme istediğim yerlerden alabildim.

String sendData(String command, const int timeout, boolean debug)
{
  String response = "";     //server' ın bize vereceği cevap

  Serial3.print(command); // server a gönderdiğimiz komut

  long int time = millis();     //timeout ın ilk değeri

  while ( (time + timeout) > millis())
  {
    while (Serial3.available())   
    {

      // The esp has data so display its output to the serial window
      char c = Serial3.read(); // read the next character.
      response += c;
    }
  }

  if (debug)      //geribesleme istiyorsak görüntüledik
  {
    Serial.print(response);
  }

  return response;    //cevabı geri döndürdük
}

 Son olarak bizden istenen isteğe göre sayfayı gönderdiğimiz fonksiyonumuzu verip yazıyı sonlandıralım. Burada HTTP header zorunludur. Nasıl değiştirileceğini bilmiyorsanız değiştirmemenizi tavsiye ederim. Bağlantının başarılı şekilde gerçekleştiğini tarayıcıya belirtmek gerekir. Bunun dışında içeriği kendi isteğinize göre değiştirebilirsiniz.

void homepage(int ch_id) {
  String Header;        //Http header' ı oluşturduk

  Header =  "HTTP/1.1 200 OK\r\n";
  Header += "Content-Type: text/html\r\n";
  Header += "Connection: close\r\n";
  //Header += "Refresh: 5\r\n";

  String Content;     //Sayfamızın içeriği
  Content = "<center><h1>Hello World!</h1></center><hr><center><h2>Oğuzhan Başer</h2></center><hr>Led State: D";
  Content += String(ledState);
  Content += "<br><a href=\"/?led\"><input type=\"button\" value=\"Led Durum\"></a>";

  Header += "Content-Length: ";
  Header += (int)(Content.length());
  Header += "\r\n\r\n";


  Serial3.print("AT+CIPSEND=");   //Sayfayı belirttiğimiz AT komutu CH_ID ve içerik uzunluğu
  Serial3.print(ch_id);
  Serial3.print(",");
  Serial3.println(Header.length() + Content.length());
  delay(10);

  //içeriği gönderdik
  if (Serial3.find(">")) {
    Serial3.print(Header);
    Serial3.print(Content);
    delay(10);
  }
}

Kodun tamamına gitHub linkinden ulaşabilirsiniz.

Octocat

 

Teşekkürler…

44 Comments

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir