STM32 ve ESP8266 ile Web Server

Merhaba arkadaşlar,

Bu konuda STM32 serisi kartları Mbed kullnarak nasıl internete bağlayabilirize değineceğiz. Burada bahsedilen Mbed’ in ne olduğuna ve nasıl kullanıldığına bağlantıdan ulaşabilirsiniz. Bu server uygulaması için bağlantıdaki konuda anlatılan ikinci yöntemi kullanacağız. Bunun sebebi ilk yöntemin pek internet kotası dostu olmaması .. :). Uygulamayı oluştururken herhangi bir kütüphane olmadan daha önceden vermiş olduğumuz Arduino Web Server yapımı konuya benzer bir şekilde doğrudan AT komutları kullanacağız. Bunun sebebi platformio üzerinde henüz Web Server için verimli çalışan bir ESP8266 kütüphanesi bulunmamasıdır.

Yapacağımız uygulamada NUCLEO-L469RG kartını kullanarak ESP8266 yardımı ile bir Web Server oluşturacağız. Bu Web Server üzerinden led yakıp söndürme ve parlaklık değiştirme işlemleri yapacağız. Yazılım, içerisinde kütüphane kullanmamız sebebi ile biraz uzun ancak elimden geldiğince anlaşılır bir şekilde yazmaya çalıştım.

Öncelikle bağlantı şemamızı yapalım. İhtiyacımız olan elemanlar STM32 Nucleo kartı, Esp8266, iki led ve iki direnç. A2′ ye bağlı olan led pwm ile parlaklığı değiştirilecek led, D13′ e bağlı olan led ise yakıp söndürme işlemi için kullanılacak leddir.

Resmi büyültmek için üzerine tıkla

Öncelikle bazı ayarlamalar yapalım. Bu ayarlamalarda Esp8266 ve bilgisayar ile yapacağımız haberleşmenin hızlarını belirleyelim. Bilgisayar için yapılan haberleşme hızı çok önemli değil ancak Esp8266 ile yapılan haberleşme hızının elinizdeki modül ile aynı olmasına dikkat etmelisiniz. Aksi taktirde haberleşme yapamazsınız. Genelde Arduino ile 9600 veya 38400 kullanılır lakin iletişimin daha hızlı ve verilmli olması için ben ben bu hızı tercih ettim.

    pc.baud(115200);               //bilgisayar ile haberleşme hızı
    esp.baud(115200);              //bilgisayar ile haberleşme hızı
    
    esp.attach(&espRxInterrupt, Serial::RxIrq);           //esp veri gelme kesmesi

En alttaki komutta ise Esp8266′ dan veri gelmesi durumunda çalışacak kesme fonksiyonunu ayarladık. Bu yapı iletişimi performansını oldukça arttırmaktadır. Lakin kodda değişiklik yaparken bu yapının asenkron olduğuna dikkat etmelisiniz.

Şimdi sıra geldi ESP8266′ nın ayarlarını yapmaya. Bunları sıralı olarak AT komutları göndererek yapacağız. AT komutlarının ne iş yaptıklarını yanlarında yorum satırı olarak yazılı. Daha detaylı bilgi için buraya bakabilirsiniz. Benim kullandığım Esp8266 içerisinde en yeni firmware yüklüdür. Bu yüzden size de bu yazılımı kullanmak için Esp8266 modülünüzü güncellemenizi tavsiye ederim.

    esp.printf("ATE0\r\n");         //disable ECHO
    while(readEspResponse("OK"));

    esp.printf("AT+CWMODE_CUR=1\r\n");  //only softAp mode
    while(readEspResponse("OK"));
    
    esp.printf("AT+CWLAP\r\n");     //find wifi networks
    while(readEspResponse("OK"));   

    esp.printf("AT+CWJAP_CUR=\"%s\",\"%s\"\r\n", MY_WIFI_SSID, MY_WIFI_PASS);
    while(readEspResponse("OK")); 

    esp.printf("AT+CIPMUX=1\r\n");      //enable multiple connections
    while(readEspResponse("OK"));

    esp.printf("AT+CIPSERVER=1,80\r\n");        //start server at port 80
    while(readEspResponse("OK"));
    
    esp.printf("AT+CIPSTO=10\r\n");     //Server timeout=10 seconds
    while(readEspResponse("OK"));

Her gönderilen komuttan sonra bir while döngüsü ile “OK” komutunun gelmesini beklememiz gerekiyor. Aksi taktirde önceki işlem bitmeden yeni komut gönderdiğiniz için “bussy p..” hatası alırsınız. Bu kısımdaki while döngüleri ile asenkron olarak çalışan Esp8266′ dan veri okuma işlemi senkron bir hale getirilmiştir. Esp8266′ dan gelen veriyi kesme içerisinde uzun bir diziye kaydettik. Daha sonra ihtiyacımız olan verileri bu diziler içerisinde kesip aldık. Diziye veri atama işlemi şu şekildedir.

 

//esp8266 rx interrupt funciton
void espRxInterrupt(){
    if(esp.readable())
    {
        rxBuff[bufferWritingIndex++]=esp.getc();            //save values to arr
        //pc.printf("%c", rxBuff[bufferWritingIndex - 1]);
        if(bufferWritingIndex>=BUFFER_SIZE)                 //if buffer fill overwrite array from start index
            bufferWritingIndex=0;
    }
}

Ana döngü içerisinde ise bir fonksiyon ile gelen http isteklere göre işlem yapılmasını sağladık. Aradaki 0.1 sn’ lik delay Esp8266′ dan gelen verileri tutan dizinin doldurulması için bekleme işlemidir.

    while(1) {
        // put your main code here, to run repeatedly:
        
        hadleHttpRequests();
        wait(0.1);
    }

Şimdi bu fonksiyonun içerisine bakalım. Yapacağımız işlemler Arduino ile Web Server Kullanımı adlı konudan çok farklı değiller. Sadece bazı fonksiyonlar biraz değişik. Mantık tamamen aynıdır. Gelen request çeşidinin ve request in içeriğini şu şekilde belirleyebiliriz.

//get connection ID, len, request type and request from buffer array
sscanf(ipdBuff + 5, "%c,%d:%s %s", &linkId, &ipdLen, requestType, request);

client-server

Tarayıcıya bağlanacağımız sunucunun yada cihazın web adresini yazınca bir HTTP request oluşur. Basit bir HTTP request içerisinde aşağıdakine benzer bir veri bulunmaktadır. Bizim amacımız ilk satırdaki +IPD, ile başlayan veriyi doğru bir şekilde parsellemektedir.

+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

Request’ i tampon içerisinden belirledikten sonra geriye sadece bir sorgu yardımı ile doğru işlemi gerçekleştirmek kaldı. Eğer gelen request “?led” ise ledin durumu değiştirmek gibi.

if(strcmp(request, "/?led") == 0) //check led request
{
    led1 = !led1;
    sendHomepage(linkId);
}

Parselleme işleminden sonra veri tamponunu temizlemek gelecek sonraki request’ lerde yapılacak işlemleri kolaylaştıracaktır. Tamponu temizleme işlemi basitçe şu şekilde yapılabilir.

//clear rx buffer
void flush_fifo(void) 
{
    while (esp.readable()) {
        (void)esp.getc();
    }
    
    memset(&rxBuff[0], 0, BUFFER_SIZE);
    bufferWritingIndex = 0;
    bufferReadingIndex_IpdSearch = 0;
}

Web sayfamızın son görüntüsü resimdeki gibidir. Bunu siz istediğiniz gibi değiştirebilirsiniz. Ancak statik bir web sayfasında sayfa yenilenmeden sürekli değişken değer gösteremeyeceğinizi unutmamalısınız. Örneğin sürekli değişken bir analog değeri web sayfasında göstermek isterseniz o sayfa ile mutlaka bir soket iletişimi kurmuş olmalısınız. Aksi taktirde verinin değiştiğini ancak sayfa yenilendiğinde görebilirsiniz.

dd

Daha önce de dediğim gibi burada anlatılanlar ile Arduino için anlatılan konu neredeyse aynı olduğu için fazla detaya inmeyeceğim. Ancak burada anlatılanlar için şuna dikkat etmelisiniz. Resmi olarak Esp8266 kullanarak mbed ile bir web server oluşturma uygulaması bulunmamaktadır. Bu yüzden çok stabil çalışan bir örnek bulamadım.  Bir kaç uygulamayı birleştirerek stabil bir web server oluşturmaya çalıştım. Ancak hala birden fazla request’ de server çökmesi gibi sorunlar yaşanmakta. Bunun için özür dilerim. Mbed’ in sayfasında kullanıcılar tarafından oluşturulmuş soket içerikli web server uygulamalarına bağlantıdan ulaşabilirsiniz.

Yazılımın tamamına buradan ulaşabilirsiniz.

Umarım yardımcı olabilmişimdir. İyi çalışmalar dilerim…

4 Comments

Add a Comment

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