Membuat Relay Berbasis Wifi dengan NodeMCU
Mikrokrontroler NodeMCU dengan dimensi kecil banyak dipakai buat IoT. NodeMCU bisa terhubung dengan 2 cara yaitu dijadikan Hotspot atau terhubung ke hotspot. Biasanya sih agar lebih leluasa yaitu dengan cara terhubung ke jaringan hotspot. Nah NodeMCU bisa kok dijadikan sebuah server layaknya CGI – common gateway interface.
Layaknya webserver yang akan menerima input berupa GET dan POST dari client, maka library yang kita gunakan pun berlaku demikian, bisa menerima input menggunakan 2 method tersebut. Nah agar halaman web dari sisi klien tidak berpindah ketika klik link/tombol maka dibutuhkan AJAX – Asynchronous JavaScript and XML adalah teknik yang digunakan untuk membuat website yang dinamis.
Membuat Relay untuk charger baterai laptop
Contents
Sebenarnya proyek ini sangat sederhana yaitu bagaimana caranya mengatur untuk hidupkan/mematikan charger baterai ketika
- level baterai <=10% maka relay akan ON
- level baterai >=90% maka relay akan OFF
Untuk berkomunikasi dengan nodeMCU menggunakan jaringan WIFI nanti aplikasi bisa diakses via web ataupun menggunakan aplikasi berbasis desktop seperti C# yang mampu secara native mendapatkan informasi level baterai laptop.
Mengapa menggunakan AJAX dan method GET?
Yup karena lebih leluasa nantinya berkirim perintah ke nodeMCU, misalkan saja ini, kita akan membuat project berupa radio dengan TEA5767 tentu ada 2 pengaturan berupa saluran frekuensi dan volume yang digunakan.
Pada proyek yang saya gunakan menggunakan arduino, maka pengaturan volume dan frekuensi menggunakan potensiometer saja sudah lebih dari cukup namun kurang presisi jadi lebih agak lembut cara memutarnya.
ActionPage
Sebuah alamat HTTP akan mempunyai Ip Addres juga action page untuk menangani input dari client, misalkan perhatikan alamat URL berikut http://192.168.4/action_page&volume=50&frekuensi=89.8
merupakan HTTP yang dilengkapi dengan method GET untuk mengirim message ke webserver dengan alamat yang dituju untuk menangani request di sisi server action_page dan variabel yang dikirim berupa volume dan frekuensi.
Tapi bila ingin versi sederhana tanpa mengirimkna nilai tertentu ke sisi server, misalkan untuk menyalakan lampu LED, bisa kok kita buat action_page dengan nama-nama yang berbeda
- LED1ON
- LED1OFF
- LED2ON
- LED2OFF
- LED3ON
- LED3OFF
Kode HTML nya yaitu sederhana saja
<html> <body> <h1> Web Control ESP8266</h1> <p>LED 1 : <a href=\"LED1ON\"\"><button>ON</button></a><a href=\"LED1OFF\"\"><button>OFF</button></a></p><br> <p>LED 2 : <a href=\"LED2ON\"\"><button>ON</button></a><a href=\"LED2OFF\"\"><button>OFF</button></a></p><br> <p>LED 3 : <a href=\"LED3ON\"\"><button>ON</button></a><a href=\"LED3OFF\"\"><button>OFF</button></a></p> </body> </html>
Nah bagaimana memasukan kode HTML tersebut diatas ke NodeMCU? sebenarnya ada 2 cara yaitu
- kode HTML dijadikan sebuah String atau
- dibuat file header misalkan index.h dan nanti di include kan bareng-bareng pada saat compile
Misalkan contoh berikut yang menggunakan point 1 yaitu dengan kode HTML dijadikan sebuah string. Pada Mode ini nodeMCU dijadikan sebuah Access Point dan nanti setelah terhubung ke wifi tersebut buka saja dengan alamat http://192.168.4
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #define LED1 16 #define LED2 5 #define LED3 4 const char* ssid = "bejo"; const char* password = "12345678"; // Password Wifi ESP8266WebServer server(80); String webpage; void setup() { Serial.begin(9600); delay(10); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT); // Connect to WiFi network ------------------------------------------------ Serial.println(); Serial.print("Configuring access point..."); // Mengatur WiFi ---------------------------------------------------------- WiFi.mode(WIFI_AP); // Mode Station WiFi.begin(ssid, password); // Mencocokan SSID dan Password // Print status Connect --------------------------------------------------- Serial.println("IP address: "); Serial.println(WiFi.softAPIP()); // Isi dari Webpage ------------------------------------------------------- webpage+= "<h1> Web Control ESP8266 Warriornux.com</h1>"; webpage+= "<p>LED 1 : "; webpage+= "<a href=\"LED1ON\"\"><button>ON</button></a><a href=\"LED1OFF\"\"><button>OFF</button></a></p><br>"; webpage+= "<p>LED 2 : "; webpage+= "<a href=\"LED2ON\"\"><button>ON</button></a><a href=\"LED2OFF\"\"><button>OFF</button></a></p><br>"; webpage+= "<p>LED 3 : "; webpage+= "<a href=\"LED3ON\"\"><button>ON</button></a><a href=\"LED3OFF\"\"><button>OFF</button></a></p>"; // Membuat tampilan Webpage ----------------------------------------------- server.on("/", []() { server.send(200, "text/html", webpage); }); // Bagian ini untuk merespon perintah yang masuk -------------------------- server.on("/LED1ON", []() { server.send(200, "text/html", webpage); digitalWrite(LED1,HIGH); delay(1000); }); server.on("/LED2ON", []() { server.send(200, "text/html", webpage); digitalWrite(LED2,HIGH); delay(1000); }); server.on("/LED3ON", []() { server.send(200, "text/html", webpage); digitalWrite(LED3,HIGH); delay(1000); }); server.on("/LED1OFF", []() { server.send(200, "text/html", webpage); digitalWrite(LED1,LOW); delay(1000); }); server.on("/LED2OFF", []() { server.send(200, "text/html", webpage); digitalWrite(LED2,LOW); delay(1000); }); server.on("/LED3OFF", []() { server.send(200, "text/html", webpage); digitalWrite(LED3,LOW); delay(1000); }); server.begin(); Serial.println("Webserver dijalankan"); } String req = "10"; void loop() { server.handleClient(); }
Relay – AJAX dan header.h
Cara pertama diatas merupakan tutorial umum yang bisa kalian jumpai untuk mengendalikan ON OFF tapi cara tersebut tidak mengirimkan perintah jika bentuknya nilai/angka, maka dibutuhkan methode lain berupa GET dan sekaligus agar tidak berpindah halaman ketika sebuah FORM di klik, maka kita akan menggunakan ajax saja dan terpisah file HTML nya.
Perhatikan kode HTML berikut yang telah saya lengkapi dengan
- CSS untuk mempercantik tampilan halaman web
- Java script agar menerima input dari sisi client
<html> <head> <style> input[type=text], select, textarea { width: 100%; padding: 12px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-top: 6px; margin-bottom: 16px; resize: vertical } input[type=submit] { background-color: #04AA6D; color: white; padding: 12px 20px; border: none; border-radius: 4px; cursor: pointer; } input[type=submit]:hover { background-color: #45a049; } .container { border-radius: 5px; background-color: #f2f2f2; padding: 20px; } </style> </head> <body onload='change()'> <div class='container'> <h1>Kontrol Volume</h1><br> <label for='fvolume'>Volume</label> <br> <input type='range' min='0' max='100' step='1' value='4' id='volume' name='volume'> <text id='keterangan' style='inline'></text> <br> <input type='submit' value='Kirim' onclick='submitFormAjax()' id='submit'> </div> </body> <script> //untuk mengatur perubahan document.getElementById('volume').oninput = function() { document.getElementById('keterangan').innerHTML = this.value; } //untuk loading pertama kali function change(){ let volume = document.getElementById('volume').value; document.getElementById('keterangan').innerHTML = volume; console.log(volume); } //untuk setting ajax function submitFormAjax() { let xmlhttp= window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.onreadystatechange = function() { //alert(this.status); /* 0: request not initialized 1: server connection established 2: request received 3: processing request 4: request finished and response is ready */ if (this.readyState === 4){ //alert('berhasil'); //console.log(this.status+" berhasil"); }else{ //alert('gagal'); //console.log("gagal"); } //console.log(this.readyState); } let volume = document.getElementById('volume').value; xmlhttp.open('GET','/action_page?&volume=' + volume, true); xmlhttp.send(); } </script> </html>
Jadi ketika user menggeser slider maka keterangnya pun berubah
ketika klik Kirim akan memanggil ajax untuk berkirim pesan ke sisi server xmlhttp.open('GET','/action_page?&volume=' + volume, true);
Membuat Header.H
Karena kode HTML yang teramat panjang, maka kita akan membuat header dengan nama, misalkan saja header.h dengan isinya sebagai berikut yang menggunakan place template R”====”
Kode berikut akan tampil jika kalian telah login
kita buat proyek buat nyalakan / hidupkan relay dengan 2 kondisi yaitu
- mati jika volume <=50
- hidup jika volumen >50
serta mode nodeMCU berupa AP_STA jadi access point serta juga station
#include <ESP8266WiFi.h> #include "index.h" //Our HTML webpage contents #include <ESP8266WebServer.h> #define LED 2 // untuk lampu LED uint8_t RELAY = D1; // Pin D1 sebagai output // SSID dan Password WiFi const char *ssid_wifi = "ZONG MBB-E5573-1D87"; const char *password_wifi = "28041441"; //menjadi hotspot AP acces point const char *ssid_AP = "radiofm"; const char *password_AP = "12345678"; ESP8266WebServer server(80); //Server on port 80 String webpage = MAIN_page; //Read HTML contents void handleRoot() { String s = MAIN_page; //Read HTML contents server.send(200, "text/html", s); //Send web page } void handleForm() { server.send(200, "text/html","sukses"); //Send web page String volume = server.arg("volume"); Serial.println("Volume: "+volume); if (volume.toFloat()<=50){ //mati digitalWrite(LED, HIGH); digitalWrite(RELAY, LOW); }else{ digitalWrite(LED, LOW); digitalWrite(RELAY, HIGH); } } void setup() { Serial.begin(9600); pinMode(RELAY, OUTPUT); //lampu LED pinMode(LED_BUILTIN, OUTPUT); //untuk relay digitalWrite(LED, HIGH); WiFi.mode(WIFI_AP_STA); WiFi.softAP(ssid_AP, password_AP); WiFi.begin(ssid_wifi, password_wifi); Serial.println("Connecting to WiFi .."); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(1000); } Serial.println(""); Serial.print("Local IP: "); Serial.println(WiFi.localIP()); Serial.print("Subnet Mask: " ); Serial.println(WiFi.subnetMask()); Serial.print("Gateway IP: "); Serial.println(WiFi.gatewayIP()); Serial.print("DNS 1: "); Serial.println(WiFi.dnsIP(0)); Serial.print("DNS 2: "); Serial.println(WiFi.dnsIP(1)); server.on("/",handleRoot); server.on("/action_page", handleForm); //form action is handled here server.begin(); } // the loop routine runs over and over again forever: void loop() { server.handleClient(); delay(100); }
HandleRoot dan HandleForm
Perhatikan kode 2 function diatas yaitu
void handleRoot() { String s = MAIN_page; //Read HTML contents server.send(200, "text/html", s); //Send web page } void handleForm() { server.send(200, "text/html","sukses"); //Send web page String volume = server.arg("volume"); Serial.println("Volume: "+volume); if (volume.toFloat()<=50){ //mati digitalWrite(LED, HIGH); digitalWrite(RELAY, LOW); }else{ digitalWrite(LED, LOW); digitalWrite(RELAY, HIGH); } }
handle_root() digunakan untuk menampilkan isi website sedangkan handleForm() digunakan untuk menangani request di sisi server. Untuk incluce header.h caranya mudah kok Sketch -> Add File
Akses mode AP dan STA
karena menggunakan 2 mode berbeda yaitu AP dan STA maka kalian bisa bebas cara mengakses NodeMCU nya nanti. Sebenarnya kalian bisa kok nanti beli di tokopedia casing nya sudah dimodif untuk relay+nodeMCU sehingga lebih praktis. Baca dulu Mengenal Mode Wifi pada Mikrokontroler NodeMCU ESP32
Alat relay dan Aplikasi berbasis Desktop
Berikut alat yang saya buat ala kadarnya saja untuk mematikan / hidupkan charger baterai dengan 2 colokan yang telah dimodif sedemikian rupa. 1 colokan buat sumber daya nodeMCU dan 1 nya lagi buat yang lainnya sebagai objek yang akan dikontrol. Daripada harus beli lagi hee heee…
Berikut tampilan colokan yang digunakan untuk charger baterai laptop.
Berikut aplikasi C# yang saya buat untuk mendapatkan informasi level baterai serta menggunakan timer per 5 detik untuk mengecek kondisi baterai, jika <=10 akan ON relay dan >=90 akan OFF relay. Juga dilengkapi dengan alamat URL ketika mengakses dengan mode berbeda-beda
Jadi menggunakan aplikasi diatas, saya tidak perlu cabut colok baterai ketika sudah mencapai batas tertentu. Tidak perlu kuatir lagi baterai nya cepet rusak mengingat saya tidak punya komputer desktop dan seringkali menggunakan laptop untuk melakukan perhitungan yang sangat rumit seperti deep learning membutuhkan waktu puluhan jam untuk menyelesaikan training nya.
Atapun kadang saya menggunakan relay yang saya buat untuk keperluan yang lain karena bisa diakses via ponsel yang terhubung ke wifi dengan hanya membuka firefox/alat peramban lainnya dengan tampilan seperti berikut
Casing Relay dan NodeMCU
seperti yang sudah saya jelaskan diatas, dipasaran sudah banyak yang jual kok yaitu casing, relay dan nodeMCU jadi satu kesatuan sehingga sangat rapi
Kita bisa menggunakan NodeMCU untuk beragam keperluan
- NodeMCU sebagai kontrol relay dengan 2 mode AP ataupun STA sehingga kita bebas cara aksesnya dengan cara apapun
- Menggunakan Ajax untuk mempermudah berkirim pesan ke server jika klien ingin menggunakan tampilan berbasis Web
- atau menggunakan aplikasi desktop untuk akses nodeMCU secara langsung