Hadi Arduino ile İnternete Bağlanalım

Merhabalar..

Şimdiye kadar bütün projelerimizi local’ de yaptık. Ancak günümüz sistemler artık internete bağlanarak internet üzerinden haberleşerek çalışmakta. Hatta Google nesnelerin interneti projesi kapsamında yeni bir işletim sistemi oluşturup günlük hayatta kullandığımız sistemleri internete bağlamaya çalışmakta. Bu yüzden bende çalışmalarımı internet üzerinden gerçekleştirmeye başladım. Öğrendiklerimi ve edindiğim tecrübelerimi sizinle paylaşmak istedim.

Öncelikle basitten başlayalım. Basitten başlıyacağımız için kullanacağımız platform yine Arduino olacak. Arduino yu Enc28j60 modülü ile internete bağlıyacağız. Bu işlem için Arduino için yazılmış bir kütüphane kullanmamız gerekli. Burada dikkat edilmesi gereken nokta hangi kütüphaneyi kullanmamız gerektiği. Eğer bu örnekte benim de kullandığım gibi harici ethernet modülü (Enc28j60) kullanacaksanız kaynak kodları git-hub da bulunan ethernet-master kütüpnasini kullanacağız. Eğer arduino ethernet shield ini kullanacaksanız Arduino Ide’ si ile gelen Ethernet kütüphanesini kullanabilirsiniz. Kütüphanelerdeki işlemler birbirine yakındır, shield kullanmak isteyenler ufak ayarlamalar ile paylaşacağım kodu Shield ile de kullanabilirler. Bu farklılığın sebebi modüllerdeki entegrelerin farklı olmasındandır. Ethernet Shield W100 entegresi kullanılırken isminden de anlaşılacağı gibi diğer modülde Enc28j60 kullanılır.

Hikaye kısmımız bu kadardı. Öncelikle devre şematiğimizden başlayalım. Arduino enc28j60 ethernet modülü spi haberleşme protokolü ile haberleşir. SPI pinlerinin Arduino modeline göre farklılık gösterdiğine dikkat edilmelidir. Ben burada en çok kullanılan model olan Arduino UNO‘ ya göre çizimi göstereceğim.

ethernetBos 

Çizimde ufak bir hata bulunmaktadır. ENC28j60 modülündeki CS pini Arduino’ da 8 nolu pine bağlanmalıdır.

Arduino Uno üzerinde SPI pinleri şekildeki gibidir. Ethernet kablomuzu bağladıktan sonra Arduino’ muz internete bağlanmaya hazır gelecektir. Burda dikkat edilmesi gereken ethernet modülünün 3.3V pinine bağlanacak olmasıdır. Üzerinde 5V yazıyorsa bile siz 3.3V ile deneyin sağlıklı çalışmazsa 5V çıkarsınız. Benim şimdiye kadar kullandığım tüm modüller 3.3V ile çalışıyordu.

Bağlantımızı yaptık. Şimdi gelelim bizi kuracağımız web server’ a Hello World yazdıran basit Arduino yazılımımıza. Öncelike bağlı olduğumuz modemin bize verdiği IP yi öğrenmemiz gerekli. Bunu öğrenmenin bir kaç yolu var. En basit olanı modeme sormak. Bu sorgu işlemini Arduino ya eklediğimiz kütüphanenin testDHCP isimli sketch’ ini kullanarak yapabiliriz. Bu yazılımı Arduino’ ya attığımız zaman mac adresimiz yardımı ile modemin bize verdiği ip adresini Serial monitör’ den görmüş olacağız. Daha sonra biz web server’ ımızı bu ip üzerine kuracağız. Ben aşağıdaki yazılımda kendi gördüğüm IP adresini kullacağım, siz kendi IP adresi ile değiştirmeyi unutmayın.

#include <EtherCard.h>

//mac ve ip adresleri

//mac adresini modül değişmedikçe değiştirmemeniz tavsiye edilir
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
//Modemin size verdiği IP adresi
static byte myip[] = { 192,168,2,84};

//intenret sayfanız için oluşturduğunuz tampon alan
byte Ethernet::buffer[500];

//bu tampon alana aktarılacak veriler HTML kodlarınız
BufferFiller bfill;


void setup()
{
  Serial.begin(9600);
  //Bağlantı başlatılamamışsa uyarı ver..
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0)
    Serial.println(F("İnternete bağlanılamadı!"));
  
  //serveri statik olarak ip adresimiz üzerine kurduk
  ether.staticSetup(myip);
}

//tampon alana aktaracağımız anasayfamız
//static olarak tanımlanması önemlidir yoksa veri kaybı yaşanır!!
static word homePage()
{
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<html><head><title>Arduino</title>"
    "</head><body><h1>HELLO WORLD!</h1></body></html>");
  return bfill.position();
}


//sonsuz döngüde client' ler ile serveri haberleştirdik
void loop()
{
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  
  if (pos)  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
}

 

Peki ya bir web server’ dan Arduino’ ya bağlı ledi kontrol etmek istersek ne yapacağız. Artık işlemlerimiz biraz daha karmaşık hale gelecek. Adres çubuğu üzerinden ufak bir haberleşme yapmamız gerekecek. Yani biz bir butona bastığımızda adres çubuğu yardımı ile Arduino’ ya istediğimiz komutu gönderebileceğiz. Burada işin en önemli kısmını BufferFilter nesnesi yapmakta. Bu nesne sayesinde web sitesi üzerinde bir nevi C’ de kullandığımız biçim niteleyicisi yapısını internet sayfamızda kullanabileceğiz. (Format String)

Not: Bu aşamda kullanılan yazılımda üstteki şematiğe ek olarak 4. pine bağlı bir led bulunmaktadır.

buf isimli BufferFiter tipinde bir nesnemiz olsun. Bunun biçim niteleyicileri şu şekildedir:

uint16_t ddd = 123;
double ttt = 1.23;
uint16_t hhh = 0xa4;
long lll = 123456789;
char * sss;
char fff[] PROGMEM = "MyMemory";
sss[0] = 'G';
sss[1] = 'P';
sss[2] = 'L';
sss[3] = 0;
buf.emit_p( PSTR("ddd=$D\n"), ddd );  // "ddd=123\n"
buf.emit_p( PSTR("ttt=$T\n"), ttt );  // "ttt=1.23\n" **TO CHECK**
buf.emit_p( PSTR("hhh=$H\n"), hhh );  // "hhh=a4\n"
buf.emit_p( PSTR("lll=$L\n"), lll );  // "lll=123456789\n"
buf.emit_p( PSTR("sss=$S\n"), sss );  // "sss=GPL\n"
buf.emit_p( PSTR("fff=$F\n"), fff );  // "fff=MyMemory\n"

 

~Alıntıdır~

 Şimdi gelelim Arduino ‘ da adres çubuğundaki veriyi nasıl okuyacağımıza. Web’ de sunucuya bağlanan client’ ler ile haberleşmenin en makul yolu soket oluşturmaktadır. Ancak bu  işlem bu aşamada bizim için biraz karışık. Bizde daha basit olan ve sürekli olarak kullandığımız adres çubuğunu kullanalım. Tarayıcı adres çubuğuna girilen adres gidip, adresteki sunucuya “/” işaretinden sonra gelen veriyi sorgulayacaktır. Bu sorgularda “?” yardımı veri aktarımı yapacağız (Bknz. Querry String). Bizim sunucumuz da Arduino olacağına göre tarayıcının adres çubuğu yardımı ile basit bi iletişim kurabiliriz.  Bunun için basit bir C fonskiyonu kullanacağız, strstr

  if(strstr((char*) Ethernet :: buffer + pos, "GET /?status=ON") != 0)
  {
    Serial.println("LED AC");
    ledStatus = true;
  }

Loop içerisinde bulunan yukarıdaki kodda client’ in adres çubuğu yardımı ile sunucuya gönderdiği veriyi strstr fonksiyonu ile okuduk. Benim BufferFilter içerisinde ayarladığım client’ ın butona bastığında Arduino’ ya göndereceği veri formatı bu şekilde /?status=$S   . Bu yüzden sorgumda gelen veriyi bu şekilde sorguladım.

char *statusLabel;    //labelden gelen verileri diziye atadık
char *buttonLabel;    //butondan gelen verileri diziye atadık

static word homePage()
{
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<html><head><title>Arduino</title></head>" 
    "<body><form>Led Status: $S<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
    "</form></body></html>"), statusLabel, buttonLabel, buttonLabel);
  return bfill.position();
}

 

 Bu kısım yazılımdaki client’ lerin göreceği kısmı. Yani web sayfası kısmı. Burada basit olarak daha önceki örnekte olduğu gibi HTML Header bilgileri web sayfamızın HTML kodları mevcut. HTML kodlarına dikkat ederseniz yukarıda bahsettiğimiz BufferFilter yapısının kullanımı açıkça görülmekte. Burada BufferFilter Arduino(server) ile web sayfasının(client) haberleşmesini sağlayarak Arduino tanımladığımız değişkenlerin değerini web sayfasına(client’ e) yollamamızı sağlıyor.

Peki ya bu veriler ile ledlerimizi nasıl yakıp söndüreceğiz? Çok Basit loop içerisinde okuduğumuz buton verisini kontrol edeceğiz. Butona bastığımızda eğer led kapalı ise ON verisi gönderecek. bizde bunu bi “if” yardımı ile kontrol edeceğiz. 

Kodun tamamına BURADAN ulaşabilirsiniz. Yeterince kod kalabalığı sayfada olduğu için ayrı olarak paylaşmak istedim. Bu sayede değişiklikleri de zamanla aynı link üzerinden görebileceksiniz.

Teşekkürler..

18 Comments

Add a Comment

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