Colokan Listrik WiFi


Sekarang lagi trendy banget, semuanya harus bisa dikontrol jarak jauh, nirkabel/wireless. Pada projek ini Keminter coba membuat prototype colokan listrik yang bisa dikontrol lewat wifi/internet.

Stop kontak alias colokan yang menggunakan Wifi ini adalah sebuah sistem yang memungkinkan stop kontak dapat diaktifkan atau dimatikan secara jarak jauh melalui jaringan internet ataupun jaringan lokal melalui perangkat handphone ataupun komputer.

Stop kontak jarak jauh ini berbasiskan modul Wifi berupa ESP8266, modul wifi tersebut dapat berfungsi sebagai wifi hotspot ataupun wifi client. Dikarenakan fungsi modul wifi tersebut yang dapat berfungsi sebagai wifi hotspot ataupun wifi client, maka untuk implementasi di stop kontak wifi ini juga akan terdapat 2 mode pemakaian, berikut kedua mode pemakaian tersebut :

1. Stop kontak sebagai wifi hotspot

Dengan mode stop kontak sebagai wifi hotspot, maka device yang akan terhubung dengan stop kontak wifi ini harus join ke wifi hotspot dari stop kontak wifi ini kemudian dapat mengakses IP address dari wifi hotspot (http://192.168.4.1), setelah mengakses halaman web tersebut, maka akan tampil halaman web sebagai berikut:

Gambar 1. Tampilan web colokan Wifi mode hotspot

Untuk dapat menghidupkan ataupun mematikan stop kontak dilakukan dengan menekan tombol on atau off pada socket #2.

Kelebihan dari penggunaan mode ini adalah :

  • IP Adress Stop kontak (192.168.4.1) akan sama dan tetap untuk semua stop kontak, sehingga tidak perlu dilakukan pencarian ip address untuk stop kontak tersebut.

Sedangkan kekurangan dari penggunaan mode ini adalah :

  • Stop kontak wifi hanya dapat diakses dalam jaringan lokal, dan tidak dapat diakses melalui jaringan internet dikarenakan dalam jaringan wifi tersebut tidak terhubung ke internet

Untuk dapat mengakses stop kontak wifi melalui jaringan internet, dapat dilakukan dengan mode Client

2. Stop Kontak sebagai wifi client

Dengan menggunakan stop kontak wifi sebagai wifi client, berarti stop kontak ini harus di program untuk dapat bergabung kepada wifi hotspot yang akan dipergunakan (wifi hotspot harus memiliki koneksi internet agar stop kontak dapat diakses melalui jaringan internet), setelah stop kontak wifi terhubung ke jaringan hotspot, maka langkah selanjutnya adalah mencari ip address dari stop kontak wifi tersebut dengan cara mencoba untuk mengakses ip address yang berada dalam satu subnet dengan handphone atau komputer yang dipergunakan untuk mengontrol stop kontak, jika ip address sudah ditemukan (misalkan: 192.168.100.22), maka akan tampil halaman web dari stop kontak wifi sebagai berikut :

Gambar 2. Tampilan colokan listrik wifi mode client

Kelebihan dari penggunaan mode ini adalah :

  • Stop kontak wifi dapat diakses melalui jaringan internet dengan menggunakan port forwarding.

Sedangkan kekurangan dari penggunaan mode ini adalah :

  • IP address dari stop kontak wifi kemungkinan bisa berubah – ubah tergantung settingan dari hotspot wifi.
  • Perlu dilakukan pencarian ip address dari stop kontak wifi dalam jaringan hotspot.

 

Peralatan Yang Dibutuhkan  :

  • Stop kontak /  colokan listrik standard pasar

  • Modul Wifi ESP8266

  • Relay DC 5V input, 1A max switching. Relay DC diperlukan untuk melakukan pemutusan ataupun penyambungan arus listrik pada stop kontak.

  • Rangkaian power supply 5V, yang diperlukan untuk menyuplai tegangan yang diperlukan oleh rangkaian. Diambil jadi dari adaptor charger HP yang kecil.

 

  • Dioda 1N4002,  diperlukan untuk menurunkan tegangan dari 5V menjadi tegangan yang diperlukan oleh modul Wifi ESP8266 (3.3V)

 

Skema dan Prinsip Kerja Rangkaian

Modul Wifi ESP8266 akan menjalankan instruksi dari user melalui koneksi wifi, jika instruksi berupa menghidupkan stop kontak, maka GPIO2 akan berlogka 0, ketika GPIO2 berlogikan 0, maka relay akan aktif karena ada beda potensial sebesar 5V di inputnya dan kemudian akan menghidupkan stop kontak. Jika instruksi dari user berupa menonaktifkan wifi maka GPIO2 akan berlogika 1, ketika GPIO2 berlogika 1 relay akan nonaktif dan akan mematikan stop kontak / colokan listrik.

Pemrograman Modul Wifi ESP8266

Modul Wifi ESP8266 dilengkapi dengan mikrokontroler 32 bit RISC CPU dengan internal flash sebesar 36kByte, untuk dapat dipergunakan sebagai stop kontak wifi, maka perlu dilakukan pemrograman pada ESP8266. Untuk penulisan program ke ESP8266 diperlukan rangkaian dengan skema seperti di bawah ini, diperlukan USB to serial untuk komunikasi antara PC dengna ESP8266 untuk penulisan program.

Kompilasi dan Penulisan Program ke modul Wifi ESP8266

Untuk melakukan kompilasi proram dan penulisan program ke modul Wifi ESP8266 menggunakan Arduino IDE, agar arduino IDE dapat support untuk ESP8266, perlu diinstall plugins ESP826 :
Tambahkan setting :
http://arduino.esp8266.com/stable/package_esp8266com_index.json
pada Additional Board Manager URLs pada menu File-Preference-Settings. Search esp8266 pada menu “Tools-Board-Boards Manager…”, kemudian klik install :

  • Pilih menu “Tools-Board-Generic 8266 Module”.
  • Open file source code ( contoh : ESP8266_RemoteLamp.ino )
  • Pilih menu “Sketch-Upload” untuk melakukan penulisan program ke modul Wifi ESP8266.

 

Source Code Program

Di bawah ini adalah source code program.

Untuk menentukan mode dari stop kontak wifi dapat diubah di line 25 :

//Mode program untuk stop kontak wifi (MODE_HOSTPOT atau MODE_CLIENT)

char mode_program = MODE_HOTSPOT;

ubah menjadi MODE_CLIENT untuk merubah mode program menjadi client dan setting WIFI_SSID dan WIFI_PASSWORD sesuai wifi hotspot yang akan dipergunakan, contoh disini sbb :

#define WIFI_SSID “Indihome1”

#define WIFI_PASSWORD “azsxdcfvgb”

SELAMAT MENCOBA, Semoga makin Keminter.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>

#define WIFI_SSID “Indihome1”
#define WIFI_PASSWORD “azsxdcfvgb”
#define COUNTER_WIFI 5
#define EEPROM_MIN_ADDR 0
#define EEPROM_MAX_ADDR 511
#define WIFI_SSID_LEN 20
#define WIFI_PSWD_LEN 8
#define WIFI_SSID_ADDR 0
#define WIFI_PSWD_ADDR (WIFI_SSID_ADDR + WIFI_SSID_LEN)
#define MODE_HOTSPOT 0
#define MODE_CLIENT 1

ESP8266WebServer server(80);
MDNSResponder mdns;
String webPage = “”;
int gpio0_pin = 0;
int gpio2_pin = 2;
//Mode program untuk stop kontak wifi (MODE_HOSTPOT atau MODE_CLIENT)
char mode_program = MODE_HOTSPOT;

void setup() {
unsigned char counterWifi = COUNTER_WIFI;
/*initialize digital esp8266 gpio 2 as an output.*/
pinMode(2, OUTPUT);
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.begin(115200);
delay(100);
Serial.print(“\n”);
#if (mode_program == MODE_CLIENT)
Serial.print(“Trying to connect Wifi Network…\n”);
while(WiFi.status() != WL_CONNECTED && counterWifi– != 0){
delay(1000);
}
if(WiFi.status() == WL_CONNECTED){
Serial.print(“Wifi connected to “);
Serial.print(WIFI_SSID);
Serial.print(“\n”);
}
else
{
Serial.print(“Failed to connect to Wifi “);
#else
{
#endif
Serial.print(WIFI_SSID);
Serial.print(“, activating Wifi hotspot…\n”);
boolean result = WiFi.softAP(“ESPsoftAP_01”, “12345678”);
if(result == true)
{
Serial.println(“Hotspot started : ESPsoftAP_01\n”);
}
else
{
Serial.println(“Hotspot start failed\n”);
}
/*untuk menampilkan jumlah yang connect*/
//Serial.printf(“Stations connected = %d\n”, WiFi.softAPgetStationNum());
}
Serial.print(“===================\n”);
Serial.print(“Remote Lamp Control\n”);
Serial.print(“Keminter Project\n”);
Serial.print(“Version 1.0\n”);

/* Configure web server */
webPage += “<h1>ESP8266 Web Server</h1><p>Socket #1 <a href=\”socket1On\”><button>ON</button></a>&nbsp;<a href=\”socket1Off\”><button>OFF</button></a></p>”;
webPage += “<p>Socket #2 <a href=\”socket2On\”><button>ON</button></a>&nbsp;<a href=\”socket2Off\”><button>OFF</button></a></p>”;

if (mdns.begin(“esp8266”, WiFi.localIP())) {
Serial.println(“MDNS responder started”);
}

server.on(“/”, [](){
server.send(200, “text/html”, webPage);
});
server.on(“/socket1On”, [](){
server.send(200, “text/html”, webPage);
digitalWrite(gpio0_pin, HIGH);
delay(1000);
});
server.on(“/socket1Off”, [](){
server.send(200, “text/html”, webPage);
digitalWrite(gpio0_pin, LOW);
delay(1000);
});
server.on(“/socket2On”, [](){
server.send(200, “text/html”, webPage);
digitalWrite(gpio2_pin, HIGH);
delay(1000);
});
server.on(“/socket2Off”, [](){
server.send(200, “text/html”, webPage);
digitalWrite(gpio2_pin, LOW);
delay(1000);
});
server.begin();
Serial.println(“HTTP server started”);

//WiFiServer server(80);
EEPROM.begin(512);
if (!eeprom_write_string(WIFI_SSID_ADDR, “ABCDEfGHIJ”))
Serial.println(“Error write”);
delay(100);
char ssid[WIFI_SSID_LEN]=”9999999999″;
if (!eeprom_read_string(WIFI_SSID_ADDR, ssid, WIFI_SSID_LEN))
Serial.println(“Error read”);
Serial.println(ssid);
//send http request
checkServerSwitchStatus();
}

// the loop function runs over and over again forever
void loop() {
server.handleClient();
//delay(1000);
//  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
//  delay(1000);              // wait for a second
//  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
//  delay(1000);              // wait for a second
//Serial.printf(“Stations connected = %d\n”, WiFi.softAPgetStationNum());
//Serial.print(WiFi.status());
}

//
// Writes a sequence of bytes to eeprom starting at the specified address.
// Returns true if the whole array is successfully written.
// Returns false if the start or end addresses aren’t between
// the minimum and maximum allowed values.
// When returning false, nothing gets written to eeprom.
//
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
// counter
int i;

// both first byte and last byte addresses must fall within
// the allowed range
if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
return false;
}

for (i = 0; i < numBytes; i++) {
EEPROM.write(startAddr + i, array[i]);
}

return true;
}

//
// Returns true if the address is between the
// minimum and maximum allowed values,
// false otherwise.
//
// This function is used by the other, higher-level functions
// to prevent bugs and runtime errors due to invalid addresses.
//
boolean eeprom_is_addr_ok(int addr) {
return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}

//
// Writes a string starting at the specified address.
// Returns true if the whole string is successfully written.
// Returns false if the address of one or more bytes
// fall outside the allowed range.
// If false is returned, nothing gets written to the eeprom.
//
boolean eeprom_write_string(int addr, char* string) {
// actual number of bytes to be written
int numBytes;

// we’ll need to write the string contents
// plus the string terminator byte (0x00)
numBytes = strlen(string) + 1;

return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}

//
// Reads a string starting from the specified address.
// Returns true if at least one byte (even only the
// string terminator one) is read.
// Returns false if the start address falls outside
// or declare buffer size os zero.
// the allowed range.
// The reading might stop for several reasons:
// – no more space in the provided buffer
// – last eeprom address reached
// – string terminator byte (0x00) encountered.
// The last condition is what should normally occur.
//
boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
// byte read from eeprom
byte ch;

// number of bytes read so far
int bytesRead;

// check start address
if (!eeprom_is_addr_ok(addr)) {
return false;
}

// how can we store bytes in an empty buffer ?
if (bufSize == 0) {
return false;
}

// is there is room for the string terminator only,
// no reason to go further
if (bufSize == 1) {
buffer[0] = 0;
return true;
}

// initialize byte counter
bytesRead = 0;

// read next byte from eeprom
ch = EEPROM.read(addr + bytesRead);

// store it into the user buffer
buffer[bytesRead] = ch;

// increment byte counter
bytesRead++;

// stop conditions:
// – the character just read is the string terminator one (0x00)
// – we have filled the user buffer
// – we have reached the last eeprom address
while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
// if no stop condition is met, read the next byte from eeprom
ch = EEPROM.read(addr + bytesRead);

// store it into the user buffer
buffer[bytesRead] = ch;

// increment byte counter
bytesRead++;
}

// make sure the user buffer has a string terminator
// (0x00) as its last byte
if ((ch != 0x00) && (bytesRead >= 1)) {
buffer[bytesRead – 1] = 0;
}

return true;
}
boolean checkServerSwitchStatus(){
#define WHILE_TO 5000 // milliseconds
#define BIAS 1
//String host = “http://www.zalfa-technology.com”;
//char charHost[30] = “zalfa-technology.com”;
const char* host= “zalfa-technology.com”;
unsigned long whileTimeout = 0;
// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
//host.toCharArray(charHost,20);
if (!client.connect(host, httpPort)) {
//    PRINTDEBUG(“connection failed”);
Serial.println(“failed to connect”);
return false;
}
// This will send the request to the server
//  PRINTDEBUG(“Requesting URL: “);
delay(10);
String timeFromReset = String( (int)((millis() / 1000) / 60), DEC);
String url_myState = “/getip.php?abc=ee”;//url + MY_WEB_PWD + “&myState=” + (dude.currentState ? “1” : “0”) + “&lastReset=” + timeFromReset;
//  PRINTDEBUG(url_myState);
delay(10);
client.print(String(“GET “) + url_myState + ” HTTP/1.1\r\n” +
“Host: ” + host + “\r\n” +
“Connection: close\r\n\r\n”);
delay(100);

// Read all the lines of the reply from server and find time
int dataFlag = 0;
int dataFlagCounter = 0;
String line;
while (!dataFlag) {
whileTimeout = millis();
//Serial.println(“looop…”);
while (client.available() &&  ((millis() – whileTimeout) < WHILE_TO) ) {
if (!dataFlag) dataFlag = 1;
line = client.readStringUntil(‘\r’);
//if (line.length() > 4)
//  Serial.println(line);
if (line.length() > 9 + BIAS && line.startsWith(“NextStart:”, BIAS)) {
//        PRINTDEBUG(“Found ON”);
//        dude.getStartTime(line);
}
if (line.length() > 9 + BIAS && line.startsWith(“Next_End_:”, BIAS)) {
//        PRINTDEBUG(“Found OFF”);
//        dude.getEndTime(line);
dataFlag = 2;
}
}
if  (!dataFlag) {
dataFlagCounter++;
if (dataFlagCounter > 20) {
Serial.println(“failed to connect”);
//        PRINTDEBUG(“Connection Failed!”);
client.stop();
//        dude.updateTime(dataFlag);
return false;
}
delay(500);
}else{
Serial.println(line);
}
}
client.flush();
client.stop();
return true;
}

 

Leave a comment

Your email address will not be published. Required fields are marked *