Tuesday, August 9, 2016

Nodemcu ve Arduino IDE ile Yerel Ağ Üzerinden Elektrikli Su Isıtıcısı Kontrolü

Facebook üzerinden ilgi gösteren ve güzel mizah yapan arkadaşlara teşekkür ederim. Yorumlarda güzel muhabbet döndü, güldük eğlendik.



Hemen konuya girelim ve malzemeleri kısa açıklamalarla sayalım.





    • Nodemcu: Nodemcu ESP8266 denen arduino benzeri bir programlama kartı, siz nasıl diyor "PIC". Bunun arduinodan farklı tarafı üzerindeki dahili wifi bağlantısı, bu aleti "repeater" olarak kullandığını iddia edenler bile var.







    • Röle: Röle gavurca "relay" diye tabir edilen şey bilindiği gibi 5V gerilim ile mekanik olarak ayrı bir bağlantıyı açıp kapamaya yarıyor. Aklınıza gelebilecek her türlü ev aletini hatta evin sigortasını bile röleye bağlayıp bir tuşla şlak şlak diye açıp kapatabilirsiniz.







    • Termistör: Termistor dediğimiz şey direncin yandan yemişi, ısıya göre direnci değişiyor biz de bu sayede sıcaklıkla ilgili fikir sahibi oluyoruz. Sağolsun.










    • Direnç: Bildiğimiz normal sıradan direnç. Tabii direnç var direnç var kaç ohm olacak, falan onları bilmiyorum. Benim elimde 150 ohm vardı onu kullandım iş gördü. Tabi burada kullandığınız termistöre de bağlı biraz. Nodemcu'nun AO pini 0-2V aralığında okuyormuş. Ama direk 3.3V verince de bişey olmuyor.










    • Elektrikli Isıtıcı: Bildiğiniz 5 liralık suya direkt elektrik veren ısıtıcı, ya da akıllı olmayan herhangi bir ketıl olabilir. Sanırım resimdeki elektrikli cezve olarak geçiyor. Türk kahvesi nasıl olur acaba bunda?










    • 220V/AC-5V/DC Adaptör: Yani kısaca herhangi bir telefon şarj aleti ya da eski nokia şarj aletleri falan.



    .

    .

    .

    .

    .

    .

    Kodun Tamamı Şöyle

    #include <ESP8266WiFi.h>
    #include <stdint.h>
    
      IPAddress ip(192,168,1,25);  //Node static IP
      IPAddress gateway(192,168,168,168);
      IPAddress subnet(255,255,255,0);
    
    const char* ssid = "SUPERONLINE_WiFi_8674";
    const char* password = "******";
    const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
    int sensorValue = 0;  
    int outputValue = 0;
    int timeVal = 0;
     
    int RelayPin = 05; // GPIO13 (D1 on Nodemcu)
    int connectionLed = 04; //D2
    
    WiFiServer server(80);
    
    void WIFI_connect(){
      WiFi.begin(ssid, password);
      WiFi.config(ip, gateway, subnet);
      while (WiFi.status() != WL_CONNECTED) {
        digitalWrite(connectionLed, HIGH);
        delay(50);
        digitalWrite(connectionLed, LOW);
        Serial.print(".");
        delay(50);
      }
      if(WiFi.status() == WL_CONNECTED){
        digitalWrite(connectionLed, HIGH);
      }
    
      Serial.println("");
      Serial.println("WiFi connected");
     
      }
    
    void setup() {
      
      Serial.begin(115200);
      delay(10);
     
      pinMode(RelayPin, OUTPUT);
      pinMode(connectionLed, OUTPUT);
      digitalWrite(RelayPin, LOW);
      digitalWrite(connectionLed, LOW);
     
      // Connect to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);
     
      
      // Start the server
      server.begin();
      Serial.println("Server started");
     
      // Print the IP address
      Serial.print("Use this URL to connect: ");
      Serial.print("http://");
      Serial.print(WiFi.localIP());
      Serial.println("/");
     WIFI_connect();
    }
     
    void loop() {
      
       if(WiFi.status() != WL_CONNECTED){  
        WIFI_connect();
      
      }
      delay(1);
    
       // read the analog in value:
      sensorValue = analogRead(analogInPin);
      // map it to the range of the analog out:
      outputValue = map(sensorValue, 0, 1023, 0, 255);
        sensorValue = sensorValue*1.6;
       if(sensorValue >= 100){
        digitalWrite(RelayPin, LOW); 
        int value = LOW;
       }
    
      delay(1);
      // Check if a client has connected
      WiFiClient client = server.available();
      if (client == 0) {
        delay(1);
        return;
      }
     
      // Wait until the client sends some data
      Serial.println("new client");
      while(!client.available()){
        delay(1);
      }
     
      // Read the first line of the request
      String request = client.readStringUntil('\r');
      Serial.println(request);
      client.flush();
      client.println("HTTP/1.1 200 OK");
      // Match the request
        if (request.indexOf("/LED=SENSORVAL") != -1)  {
      
       client.println("Content-Type: text");
       client.println(""); //  do not forget this one
       client.println(sensorValue);
      }
      
      if (request.indexOf("/LED=ON") != -1)  {
       
        digitalWrite(RelayPin, HIGH);
        value = HIGH;
      }
      if (request.indexOf("/LED=OFF") != -1)  {
    
        digitalWrite(RelayPin, LOW);
        value = LOW;
      }
    // Set RelayPin according to the request
    //digitalWrite(RelayPin, value);
     
      // Return the response
    
      if(request.indexOf("/LED=") == -1 && request.indexOf("/favicon.ico") == -1){
      client.println("Content-Type: text/html");
      client.println(""); //  do not forget this one
     client.println(" <!DOCTYPE HTML>        ");                                                                                   
    client.println(" <html> ");
    client.println(" <style> body{ ");
    client.println(" height: 100%;  ");
    client.println(" background-color: cornflowerblue;"); 
    client.println(" display: flex;  ");
    client.println(" align-items: center;");   
    client.println(" justify-content: center;");
    client.println("transition: background-color 2s;} ");
      client.println("  #wrap{transform: scale(2);");
       client.println(" }");
    client.println(" </style>");
    client.println("<div id='wrap'>");
    client.println(" <svg viewBox='0 0 286 398'");
    client.println("  xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve'");
    client.println("  x='0px' y='0px' width='286px' height='398px'");
    client.println(" >");
    client.println("  <g id='Layer%201'>");
    client.println("    <path d='M 50 343 L 231 343 L 221 307 L 62 307 L 50 343 Z' stroke='#000000' stroke-width='4' fill='#8c4600'/>");
    client.println("    <path d='M 62 307 C 62 307 66 188 60 178 C 54 168 41 141 41 141 L 178 141
     L 234 141 L 234 156.6667 L 178 161.6667 L 178 307 L 62 307 Z' stroke='#000000' 
    stroke-width='4' fill='#db9c64'/>");
    client.println("    <path d='M 178 202.5 L 173.493 202.5 L 167.493 199.5 L 161.4931 202.5 
    L 155.4932 199.5 L 149.4936 202.5 L 143.4941 199.5 L 137.4941 202.5 L 131.4949 199.5 
    L 125.4955 202.5 L 119.4958 199.5 L 113.496 202.5 L 107.4967 199.5 L 101.4969 202.5 
    L 95.4974 199.5 L 89.4975 202.5 L 83.4979 199.5 L 77.4989 202.5 L 71.4996 199.5 
    L 65.4999 202.5 L 62.85 202.5 C 64.2466 240.2103 63 307 63 307 L 178 307 L 178 202.5 Z' 
    stroke='#000000' stroke-width='4' fill='#99e5ff'/>");
    client.println("    <path d='M 190 307 C 190 307 216.6351 272.3889 216 240 C 215.3333 
    206 201 159 201 159 L 231 157 C 231 157 246.6667 209 246 240 C 245.3333 271 221 307 221 
    307 L 190 307 Z' stroke='#000000' stroke-width='4' fill='#8c4600'/>");
    client.println("    <path id='Ellipse' d='M 103 324 C 103 314.611 110.611 307 120 307 
    C 129.389 307 137 314.611 137 324 C 137 333.389 129.389 341 120 341 C 110.611 341 103
     333.389 103 324 Z' stroke='#000000' stroke-width='4' fill='#d90000'/>");
    client.println("    <path id='wire' d='M 79 307 L 79 271 L 85 284 L 92 273 L 99 284 L 106 
    272 L 112 284 L 119 272 L 124 283 L 132 271 L 138 282 L 144 270.6667 L 151 284 L 158 270 
    L 158 305 ' stroke='#000000' stroke-width='4' fill='none'/>");
    client.println("  </g>");
    client.println(" </svg>");
    client.println(" <div style= 'font-size: x-large;margin-top: -175px;margin-left: 80px;'>
    <span id='val'>30.00</span><span>C</span></div></div>");
    client.println(" <script>");
    client.println("var bulb = document.getElementsByTagName('svg')[0];");
    client.println("var bulbElipse = document.getElementsByTagName('svg')[0].getElementById('Ellipse');");
    client.println("var wire = document.getElementsByTagName('svg')[0].getElementById('wire');");
    client.println("var onOff = 'off';");
    client.println("var readyToReceive= true;");
    client.println(" bulb.onclick = function(){");
    client.println("var xhttp = new XMLHttpRequest();");
    client.println("     xhttp.onreadystatechange = function(e) {");
    client.println("      if (xhttp.readyState == 4 && xhttp.status == 200) {");
    client.println("readyToReceive = true;");
    client.println("        if(onOff == 'off'){onOff = 'on';      ");
    client.println("        bulbElipse.style.fill = 'yellow';          ");
    client.println("        wire.style.stroke = 'orange';          ");
    client.println("document.body.style.backgroundColor = 'coral';}");
    client.println("        else if(onOff == 'on'){onOff = 'off';   ");
    client.println("        bulbElipse.style.fill = 'red';      ");
    client.println("        wire.style.stroke = 'black'; ");
    client.println("document.body.style.backgroundColor = 'cornflowerblue';}");
    client.println("        }");
    client.println("    };");
    client.println("     var link;");
    client.println("         if(onOff == 'off'){link = '/LED=ON';}");
    client.println("         else if(onOff =='on'){link = '/LED=OFF';}");
    client.println("  if(readyToReceive){readyToReceive = false;");
    client.println(" xhttp.open('GET', link, true);");
    client.println("    xhttp.send();}");
    client.println(" }");
    client.println(" function getSensorVal(){");
    client.println(" var xhttp = new XMLHttpRequest();");
    client.println(" xhttp.onreadystatechange = function(e) {");
    client.println("      if (xhttp.readyState == 4 && xhttp.status == 200) {");
    client.println("      document.getElementById('val').innerHTML =xhttp.responseText;");
    client.println("if(+document.getElementById('val').innerHTML == 100){ onOff = 'off'; 
    bulbElipse.style.fill = 'red'; wire.style.stroke = 'black'; 
    document.body.style.backgroundColor = 'cornflowerblue';}");
    client.println("     } }");
    client.println("      xhttp.open('GET', 'LED=SENSORVAL', true);");
    client.println("    xhttp.send();");
    client.println(" }");
    client.println("      setInterval(getSensorVal, 3000);");
    client.println("  </script>");
    client.println(" </html>");
    
      }
      delay(1);
      Serial.println("Client disonnected");
      Serial.println("");
     
    }

    Şimdi Yapım

    Şimdi bunu yaparken beyler bir sürü ayrıntı sayabilirim. Ama bazı şeyleri bildiğinizi varsayıyorum. Önce tabiki aletimizi "breadboard"a yatırıyoruz ben ortadan ikiye kesilmiş "breadboard" kullanıyorum çünkü nodemcu genişliği pis öyle bütün "breadboard"u kaplıyor. Sonra sırayla rölemizi
    termistörümüzü takıp açıp kapatma falan yapıyoruz.



    Nodemcu denen aletin pinleri arduino IDE'de GPIO'lar gibi olmadığı için hangi numaranın kimi kontrol ettiğini şu resme bakarak çözdüm.
     Yani o meşhur "blink" örneğinde mesela 13 yazıyor, buna atıyorsun D7 yazan yer "blink" yapıyor.

    Bir de bu alet 3.3V ile çalışıyor ve VCC yazan yere de 5V vermek gerekiyor en çok. Ama ben 16V verdim bişey olmadı kendini kapattı.







    Aşağıdaki resimde bağlantıların nereden nereye çekildiğini görüyoruz, bunlardan D1, D2 olanların yerleri opsiyoneldir. Ama A0, yani analog pini sadece 1 tanedir.



    Ben bunu yaparken önce röleyi güzel bir yere yapıştırdım. Bolca sıcak silikon kullandım. Sıcak silikon aletin ısınmasıyla yumuşuyor ama tam bir akma durumu olmuyor.

    Öte yandan termistör dediğimiz sıcaklık ölçen parçanın kafasını aletin dibinde kenarına patex ile yapıştırdım. Patex yani japon gibi olan ve aktivatör spreyli yapıştırıcı. Lakin çok iyi bir sonuç aldım diyemem, ölçümleri neredeyse 20 saniye gecikme ile alıyorum çünkü sıcak su yukarı doğru hareket ediyor ve koyduğum noktanın ısınması geç oluyor. Sizlere tavsiyem bir şekilde suya daha yakın bir yere ya da yandan daha yukarı bu parçayı monte etmenizdir. Hatta suyun içine bile sallandırabilirsiniz.

    Daha sonra elektrikli cezvenin fişinden alete yakın bir noktayı yarım kesip açtım. buradaki kablolardan sadece birini keserek 2 uç haline getirdim. Röle üzerindeki 3 girişten NO, yani "normally open" normal halde açık yazılı 2 girişe takıp vidalarını sıktım.

     Nodemcu aletini bilgisayara takabileceğim şekilde röle ve termistöre şekilde görüldüğü gibi bağladım. aletin fişni de içine su koyup prize taktım. Bilgisayardan programı attıktan sonra adrese girip açmakla uğraşmadım rölenin D1'e bağlanan kablosunu 3.3V veren yere bağlayarak ısıtmayı başlattım.

    Sonra arduino IDE'de open serial monitor dediğimiz yeri açtım. Oradan sıcaklık ile sensör değerindeki değişimi takip etmek istiyordum. Ama sanırım yukarıdaki kodda o satırı çıkardım.

    "if (request.indexOf("/LED=SENSORVAL") != -1)  {" yazan yerin hemen altına şu ifadeyi eklerseniz serialden takip sağlayabilirsiniz: Serial.println(sensorValue);

    Burada az suyla ve çok suyla 1-2 defa suyu kaynatıp tam fokur fokur kaynadığı zaman hangi değeri okuduğumu gördüm. Bu değeri 100 kabul ettim ve 100'ü o değere bölerek bir katsayı çıkardım.
    Örneğin kaynama sırasında 56 okuyorsam 100/56=1.78. Örnek kodda 1.6*sensörValue yazan yer bu mantıkla yazılmıştır. Tabii ki bu santigrat derece bakımından doğru bir ölçüm yapmaya yaramaz ama önemli olan suyun kaynadığını anlamak.

    Sonra ikiye kesilmiş bir mini breadboard'un yarısını da "patex" yardımıyla rölenin hemen üzerine yapıştırdım. Gerekli bağlantıları yaptıktan sonra elektrikli cezvenin kablosunu yine alete yakın bir yerden tam kestim. Soydum ve açtım sonra kutusunu kırıp fiş kısmını attığım bir 5V şarj aletinin kartını aldım. Bu aletin içinde fiş bağlantılarının olduğu ve ayan beyan göreceğiniz 2 büyük bağlantı noktası var. Bunlara hem prizin fişte kalan 2 ucunu hem de aletten gelen 2 ucunu bağladım ve kutunun içine koyarak tekrar kapattım. Şimdi aleti prize taktığımızda şarj aleti 5V üretip Nodemcu'yu beslemeye başlayabilir. Şarj aletinden USB için çıkan 5V artı ve eksi kablolarının uçlarına "header" dediğimiz metal çubuklardan lehimleyip artı ucunu Vin yazan yere eksi ucunu GND yazan yere taktım.

    Yapılış hakkında sormak istediğiniz başka bir şey olursa yorum yazıp sorabilirsiniz.

    Program Uyarlama


    Şimdi programın neresi ne işe yarıyor ona bakalım. Ben de bu kodu aslında başka bir yerden kopyalamıştım çok eskiden. Kendisine kredi veremiyorum çünkü hatırlamıyorum. Ama zaten o kod ledi aç kapa yapınca sayfayı tekrar yüklüyordu ve benim için çirkin ve kullanışsızdı. Biraz da web sitesi yapmayla uğraştığımdan dedim ki bu AJAX dedikleri şeyle çalışsın sayfa yenilemesiyle uğraşmasın.

    Yani şöyle oluyor. Oradaki html kodunda "<a href="/led=on" /> yazdığınızda düğmeye basınca siz servera "/led=on" sayfası için istek göndermiş oluyorsunuz. Ama bunu sayfayı yenilemeden yapmak isterseniz javascript ile şunu yazmanız gerekiyor:

     dugme.onclick = function(){
                                var xhttp = new XMLHttpRequest();
                                xhttp.onreadystatechange = function(){
                                          if(xhttp.readyState == 4 && xhttp.status == 200){
                                           var gelencevap = xhttp.responseText;                                                                                         }
                                            }
                                    xhttp.open(GET, 'link', true);
                                    xhttp.send();
                                    }


    Şimdi bu yukarıdaki gördüğünüz bir standart AJAX fonksiyonudur. Burada olan şey şudur, normalde bir linke tıkladığınızda sayfa gelir ve olduğunuz sayfa gider. Burada 'link' yazan yere o adresi açtığınızda hangi sayfa gelecekse o sayfa xhttp.responseText isimsi değişkenin içine tanımlanır. Onu oradan alıp sayfaya yükleyebilirsiniz sayfa yenileme yapmadan. Ayrıca kırmızı renkli yazılı kısımdaki fonksiyon server cevap verdiğinde çalışır. Yani mesela örneğimizde resime tıklandığında kafadan ısıtıcının reng değişmez, server cevap verdiği zaman değişir. Yani örneğin server kapatılırsa tıklandığında renk hiç değişmez çünkü serverdan cevap gelmeyecektir.

    Tabi burada yazılanlar servis edilen HMTL web sayfasının içindeki bir <script> tagına yazılmış javascript kısımlarıdır. Ben bunları önce notepad++'da yazdım. sicaksu.html olarak kaydedip nasıl göründüğüne baktım. Üzerindeki düzenlemeleri bitirdiğimde de başka bir yere atıp ALT+SHIFT+AŞAĞI TUŞU kombinasyonuyla bütün satır başlarını seçtim.
    Sonra satır başlarına: client.println("
    ve satır sonlarına da: "); karakterlerini yerleştirdim.

    Esasen ilk boş istekte serverın verdiği cevap ile tarayıcıya yüklenen sayfanın kodu aşağıdadır:

    <!DOCTYPE HTML>  
    
    <html>
    
    <style> body{
    
    height: 100%; 
    
    background-color: cornflowerblue;
    
    display: flex; 
    
    align-items: center;  
    
    justify-content: center;
    
        overflow: hidden;
    
     transition: background-color 2s;}
    
      #wrap{transform: scale(2);
    
      }
    
    </style>
    
    <div id='wrap'>
    
    <svg viewBox='0 0 286 398'
    
     xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' xml:space='preserve'
    
     x='0px' y='0px' width='286px' height='398px'
    
    >
    
     <g id='Layer%201'>
    
      <path d='M 50 343 L 231 343 L 221 307 L 62 307 L 50 343 Z' stroke='#000000' stroke-width='4' fill='#8c4600'/>
    
      <path d='M 62 307 C 62 307 66 188 60 178 C 54 168 41 141 41 141 L 178 141 L 234 141 L 234 
    156.6667 L 178 161.6667 L 178 307 L 62 307 Z' stroke='#000000' stroke-width='4' 
    fill='#db9c64'/>
    
      <path d='M 178 202.5 L 173.493 202.5 L 167.493 199.5 L 161.4931 202.5 L 155.4932 199.5 
    L 149.4936 202.5 L 143.4941 199.5 L 137.4941 202.5 L 131.4949 199.5 L 125.4955 202.5 
    L 119.4958 199.5 L 113.496 202.5 L 107.4967 199.5 L 101.4969 202.5 L 95.4974 199.5 
    L 89.4975 202.5 L 83.4979 199.5 L 77.4989 202.5 L 71.4996 199.5 L 65.4999 202.5 L 62.85 202.5
     C 64.2466 240.2103 63 307 63 307 L 178 307 L 178 202.5 Z' stroke='#000000' stroke-width='4' 
    fill='#99e5ff'/>
    
      <path d='M 190 307 C 190 307 216.6351 272.3889 216 240 C 215.3333 206 201 159 201 159 
    L 231 157 C 231 157 246.6667 209 246 240 C 245.3333 271 221 307 221 307 L 190 307 Z' 
    stroke='#000000' stroke-width='4' fill='#8c4600'/>
    
      <path id='Ellipse' d='M 103 324 C 103 314.611 110.611 307 120 307 C 129.389 307 137 314.611 
    137 324 C 137 333.389 129.389 341 120 341 C 110.611 341 103 333.389 103 324 Z' 
    stroke='#000000' stroke-width='4' fill='#d90000'/>
    
      <path id='wire' d='M 79 307 L 79 271 L 85 284 L 92 273 L 99 284 L 106 272 L 112 284 
    L 119 272 L 124 283 L 132 271 L 138 282 L 144 270.6667 L 151 284 L 158 270 L 158 305 ' 
    stroke='#000000' stroke-width='4' fill='none'/>
    
     </g>
    
    </svg>
    
    <div style= 'font-size: x-large;margin-top: -175px;margin-left: 85px;'><span  
    id='val'>35.00</span><span>C</span></div></div>
    
    <script>
    
        var bulb = document.getElementsByTagName('svg')[0];
    
        var bulbElipse = document.getElementsByTagName('svg')[0].getElementById('Ellipse');
    
        var wire = document.getElementsByTagName('svg')[0].getElementById('wire');
    
        var onOff = 'off';
    
     var readyToReceive= true;
    
    bulb.onclick = function(){
    
        var xhttp = new XMLHttpRequest();
    
        xhttp.onreadystatechange = function(e) {
    
       if (xhttp.readyState == 4 && xhttp.status == 200) {
    
        readyToReceive = true;
    
        if(onOff == 'off'){onOff = 'on';
    
        bulbElipse.style.fill = 'yellow';
    
        wire.style.stroke = 'orange';
    
        document.body.style.backgroundColor = 'coral';}
    
        else if(onOff == 'on'){onOff = 'off';
    
        bulbElipse.style.fill = 'red';
    
        wire.style.stroke = 'black';
    
        document.body.style.backgroundColor = 'cornflowerblue';}
    
        }
    
      };
    
        var link;
    
            if(onOff == 'off' ){link = 'LED=ON.php';}
    
            else if(onOff =='on' ){link = 'LED=OFF.php';}
    
      if(readyToReceive){readyToReceive = false;
    
      xhttp.open('GET', link, true);
    
      xhttp.send();}
    
    }
    
    function getSensorVal(){
    
    var xhttp = new XMLHttpRequest();
    
    xhttp.onreadystatechange = function(e) {
    
       if (xhttp.readyState == 4 && xhttp.status == 200) {
    
       document.getElementById('val').innerHTML = xhttp.responseText;
    
       if(+document.getElementById('val').innerHTML == 100){
    
       onOff = 'off'; bulbElipse.style.fill = 'red'; wire.style.stroke = 'black';
    
       document.body.style.backgroundColor = 'cornflowerblue';}
    
       }
    
       xhttp.open('GET', 'LED=SENSORVAL.php', true);
    
       xhttp.send();
    
     }
    
    }
    
     setInterval(getSensorVal, 3000);
    
     getSensorVal();
    
     </script>
    
    </html>


    Şimdi burada bildiğiniz gibi arduino IDE'de yazılım şöyle çalışır. Önce kütüphaneleri

    #include <ESP8266WiFi.h>

    şeklinde programa eklenir. Bu kütüphanelerdeki önceden tanımlanmış fonksiyonlar yazdığımız programda kullanılır hale gelir.

    Şunu da bildiğinizi varsaydım ama bilmeyenler için buraya koyayım. ESP8266 modülünü arduino IDE'de programlamak için "preferences" kısmında additional boards manager URLs kısmında şu linki yapıştırarak gerekli kütüphanelerin githubdan otomatik eklenmesi sağlanır: http://arduino.esp8266.com/stable/package_esp8266com_index.json

    Kütüphaneler eklendikten sonra program önce global değişkenleri hafızaya atar, örneğin
    int sensorValue =0;
    gibi deklarasyonlar değişkenlerin en üst "scope"da tanımlanmasını sağlar. Bu sayede daha sonra bunlara her yerden erişiriz.

    Bundan sonra global fonskiyonları hafızaya atar, bu programda örnek olarak WIFI_connect() bir global fonksiyon olarak tanımlanmıştır. Bunu global olarak tanımlamamın sebebi hem
    setup() içinde hem de bağlantı kopması halinde loop() içinde kullanacak olmamdır.

    Global fonksiyonlardan sonra bildiğiniz gibi yeni proje açtığınızda kendinden yazılı gördüğünüz void setup() ve void loop() fonksiyonları vardır. Bu fonksiyonların özellikleri setup program başladığında 1 kere loop ise sürekli tekrar ederek içindeki komutları uygular. Örneğin önceki kendi tanımladığımız global fonksiyonlar uygulanmaz sadece hafızaya atılır, setup() ya da loop() içinde çağırmadığınız sürece uygulanmaz.

    void setup() dediğimiz gibi başlangıçta herşeyden önce uygulanacak komutların yazıldığı fonksiyondur. Yani örneğin bazı şeyler loop başlamadan ayarlanmış olması gerekiyorsa oraya yazılır. En çok bildiğimiz Serial.begin(115200) fonksiyonudur herhalde, bu fonksiyon bir kütüphaneden çağırılıp çalışmaya başlar ve usb üzerinden veri akışını başlatır.

    Bunu yaptıktan sonra sürekli durmadan çalışacak fonksiyonumuz ve genel olarak kodu yazdığımız yer void loop() fonksiyonudur. Örneğin void loop() fonksiyonunda şöyle bir şey yaparsanız:
    if(elma == elma){
    return;
    }
    Buradaki return ifadesi loop fonksiyonunun "return"den sonraki satırları uygulamaya koymadan fonksiyona son vermesine sebep olur. Ancak loop fonksiyonu sürekli tekrar edeceği için sürekli gelip elma == elma ifadesinin doğruluğunu test edecektir. İfade doğru olduğu sürece sürekli burası kontrol edilip fonksiyon orada çalışmayı bırakacaktır. Dolayısıyla bu durumda hangi satırları önce hangilerini sonra yazdığımızın biraz önemi vardır.

    ------------

    Şimdi cihaza elektrik geldi program başladı, burada ilk olarak değişkenleri tanımlayacak ve bir kere "void setup" fonksiyonunu yürütecek.
    Koddaki "void setup" fonksiyonuna bakarsanız sırayla şunları yapıyor.

    Serial.begin(115200) // "serial"i başlatıyor. Bunu usbden olup biteni görmek için yapıyoruz.

    Serial.print 'lerin hepsi tercihe bağlı. Usb'den bağlanınca bazı değerleri okumak istemiyorsanız silebilirsiniz.

    server.begin() //Server'ı başlatıyor. Bu fonksiyon include ettiğimiz kütüphaneden geliyor.

    WIFI_connect() // Bu fonksiyonu yukarıda biz tanımladık. Onun içinde ne varsa burada onlar yürütülecek.


    ... devamını yazacağım.


    Sunday, August 7, 2016

    Local Server controlling a Light with Nodemcu


    Info About Author

    Hello, all my electronics knowledge is based on li-ion charging, arduino programming and front-end web developing. And none of them is my profession. So, my apologies if I wont be able to use some terms when it needs to be used.

    Purpose of This Reading

    If you are familiar with arduino, and maybe you did thought an arduino with wifi is very cool. And you bought something called Nodemcu. In this post you will find some code to control a GPIO pin or light a led over your local network, and it is fuc-king asynchronous.

    What is NodeMcu?

    Nodemcu is a wifi enabled prototyping board, I mean it is something actually extended board. Actual brain of this card is called ESP8266 and it is literally mounted on the board. What rest of board does is enables you to program with usb connection and regulates some voltages.

    This is how a Nodemcu looks like:

    That metallic part with wifi logo on it is ESP8266 module I have mentioned. Anyways you dont need to know none of these. There is one more module I want mention and it has the same properties with Nodemcu and its called Wemos, it is very compact and cute I will buy one when I have money:

    Normally Nodemcu is made for using with an IDE called ESPlorer, and it can be programmed with a programming language called Lua, it is a Javascript like language, but interface and settings are not convenient for me. Although I have those installed, this project is programmed using Arduino IDE.

    Just Copy Paste the Code We'll Talk Later

    #include <ESP8266WiFi.h> const char* ssid = "WRITE YOUR ROUTER NAME HERE"; const char* password = "WRITE YOUR WIFI PASS HERE"; int ledPin = 13; // GPIO13 (D7 on Nodemcu) WiFiServer server(80); void setup() {   Serial.begin(115200);   delay(10);   pinMode(ledPin, OUTPUT);   digitalWrite(ledPin, LOW);   // Connect to WiFi network   Serial.println();   Serial.println();   Serial.print("Connecting to ");   Serial.println(ssid);   WiFi.begin(ssid, password);   while (WiFi.status() != WL_CONNECTED) {     delay(500);     Serial.print(".");   }   Serial.println("");   Serial.println("WiFi connected");   // Start the server   server.begin();   Serial.println("Server started");   // Print the IP address   Serial.print("Use this URL to connect: ");   Serial.print("http://");   Serial.print(WiFi.localIP());   Serial.println("/"); } void loop() {   // Check if a client has connected   WiFiClient client = server.available();   if (!client) {     return;   }   // Wait until the client sends some data   Serial.println("new client");   while(!client.available()){     delay(1);   }   // Read the first line of the request   String request = client.readStringUntil('\r');   Serial.println(request);   client.flush();   // Match the request   int value = LOW;   if (request.indexOf("/LED=ON") != -1)  {     client.println("HTTP/1.1 200 OK");     digitalWrite(ledPin, HIGH);     value = HIGH;   }   if (request.indexOf("/LED=OFF") != -1)  {     client.println("HTTP/1.1 200 OK");     digitalWrite(ledPin, LOW);     value = LOW;   } // Set ledPin according to the request //digitalWrite(ledPin, value);   // Return the response   if(request.indexOf("/LED=") == -1){client.println("HTTP/1.1 200 OK");   client.println("Content-Type: text/html");   client.println(""); //  do not forget this one   client.println("<!DOCTYPE HTML>");  client.println("<html>");  client.println("<style> html{");  client.println("height: 100%;");  client.println("background-color: #ff9d79;");  client.println("display: flex;");  client.println("align-items: center;");  client.println("justify-content: center;}");  client.println("</style>");  client.println("<svg viewBox='0 0 286 398'");  client.println(" xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
    xml:space='preserve'  ");  client.println(" x='0px' y='0px' width='286px' height='398px'");  client.println(">");  client.println(" <g id='Layer%201'>");  client.println("   <path id='Ellipse' d='M 95.2857 282.7273 C 93.8259 205.9716 33 200.9362 33
    142.8182 C 33 84.7002 86.1001 34 142 34 C 197.8999 34 251 84.7002 251 142.8182 C 251 200.9362
    188.3161 205.9716 188.7143 282.7273 L 95.2857 282.7273 Z' stroke='#ffffff' stroke-width='15'
    fill='#aaaaaa'/> ");  client.println("   <path d='M 95.2857 282.7273 L 95.2857 344.9091 L 142 376 L 188.7143
    344.9091 L 188.7143 282.7273 L 95.2857 282.7273 Z' stroke='#000000' stroke-width='15'
    fill='#aaaaaa'/>");  client.println("   <path id='wire' d='M 110.8571 271.1818 L 110.8571 142.8182
    L 126.4286 189.4545 L 142 142.8182 L 157.5714 189.4545 L 173.1429 142.8182 L 173.1429
    271.1818 ' stroke='#555555' stroke-width='11' fill='none'/>");  client.println("   <path id='Line' d='M 103.5 350 L 187.5 311 ' stroke='#000000'
    stroke-width='15' fill='none'/>");  client.println("   <path id='Line2' d='M 98 323.5 L 179 285.5 ' stroke='#000000'
    stroke-width='15' fill='none'/>");  client.println(" </g>");  client.println("</svg>");  client.println("<script>");  client.println("   document.onreadystatechange = function(){ ");
     client.println(" if(document.readyState == 'complete'){");
    client.println(" var bulb = document.getElementsByTagName('svg')[0];");  client.println("var bulbElipse = document.getElementsByTagName('svg')[0].getElementById('Ellipse');");  client.println("    var wire = document.getElementsByTagName('svg')[0].getElementById('wire');");  client.println("    var onOff = 'off';");  client.println("bulb.onclick = function(){");  client.println("    var xhttp = new XMLHttpRequest();");  client.println("    xhttp.onreadystatechange = function(e) {");  client.println("     if (xhttp.readyState == 4 && xhttp.status == 200) {");    client.println("       if(onOff == 'off'){onOff = 'on';");  client.println("       bulbElipse.style.fill = 'yellow';");  client.println("       wire.style.stroke = 'orange';}");  client.println("       else if(onOff == 'on'){onOff = 'off';");  client.println("       bulbElipse.style.fill = '#aaaaaa';");  client.println("       wire.style.stroke = '#555555';}");  client.println("       }");  client.println("   };");  client.println("    var link;");  client.println("        if(onOff == 'off'){link = '/LED=ON';}");  client.println("        else if(onOff == 'on'){link = '/LED=OFF';}");  client.println("xhttp.open('GET', link, true);");  client.println("   xhttp.send();");  client.println("} }}");  client.println(" </script>");  client.println("</html>");   }   delay(1);   Serial.println("Client disonnected");   Serial.println(""); }