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.
Ö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);
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.
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…
Merhaba
Stm32 nucleo l152re kartım var arduino ide si üzerinden programlaya biliyorum arduinoya attığım kodları stm32 attığımda çalışıyor sıkıntı yaşamadım ama esp8266 için yaptığımda çalışmıyor böyle bir durumla karşılaştınız mı?
Not:arduino ile esp8266 ile uygulamalar yaptım
Merhaba, daha önce hiç STM32 serisi kartı Arduino ile programlamadım. Ama ESP8266 ile bir çok uygulama yaptım ve dediğiniz gibi bir sorun ile karşılaşmadım. Bunun sebebi STM32′ nin destekleyip ESP8266′ nın desteklemediği bir şey yapmaya çalışıyor olmanızdandır diye düşünüyorum. Nasıl bir uygulama yapmaya çalışıtğınızı bilmediğim için çok yardımcı olamıyorum. Uygulamanızın da ne olduğunu içeren bir mail gönderirseniz yardımcı olmaya çalışırım. İyi çalışmalar dilerim..
Led ler için kullanacağımız direnç lerin değeri ne olmalı oğuzhan bey?
Merhaba, LED’ ler için resimde verilen değer olan 220 Ohm değerini kullanabilirsiniz. Aslında bu sizin kullandığınız mikrodenetleyicinin verebildiği akım ile alakalı basit bir hesaptır. STM32 mikrodenetleyicilerin GPIO lojik seviyeleri 3.3V ve verebilecekleri akım 20 – 30mA civarıdır. 3.3V / 20mA = 165 ohm direnç çıkar. Elimde 220 olduğu için ben o şekilde kullanmıştım. İyi çalışmalar dilerim…