;

Senin, 10 November 2014

Kontrol Lampu via Web (Arduino+EthernetShield)

Senin, 10 November 2014

Kontrol Lampu via Web (Arduino+EthernetShield)

Kontrol lampu via web yang kami buat ini merupakan kontrol jarak jauh dengan menggunakan arduino dan ethernet shield. Untuk hardware arduino di pasaran dijual dengan harga sekitar 250-300 ribu, sedangkan untuk softwarenya bisa didownload diwww.arduino.cc

Butuh beberapa program yang memusingkan bagi saya, program tersebut hanya saya copas tapi tentu dengan melakukan banyak editting juga agar sesuai dengan apa yang saya dan kelompok saya inginkan. Hehehe...

Ini videonya teman.


Yang pertama kali harus disiapkan pastinya alat dan bahannya:
  1. Arduino (hardware maupun software)
  2. XAMPP
  3. Laptop atau PC untuk memprogram
  4. Ethernet Shield
  5. Kabel UTP (Cross dan Straight)
  6. Mikrotik
  7. Switch
  8. LED
  9. Kabel Jumper
  10. Kertas Karton untuk membuat miniatur
Karena kemarin yang kami buat hanya miniatur saja, makanya bahan yang kami butuhkan juga sedikit. Kalo untuk lampu yang menggunakan tegangan AC pastinya butuh rangkaian tambahan untuk menjalankan sistem. Belum juga kalau memang kita ingin membuat yang nyata (pengendali dan yang dikendalikan jauh). Jika sudah mendownload softwarenya, maka library untuk ethernetshield juga harus didownload. Bisa juga didownload pada situs resminya arduino atau cari dari sumber lain.

Langkah kedua adalah menggabungkan arduino dengan ethernetshield:

Langkah ketiga adalah melakukan setting pada mikrotik dan merubah alamat IP PC yang Anda gunakan lalu copas script kode dibawah ini pada software arduino untuk meminta alamat IP yang akan digunakan ethernet shield. Gunakan serial monitor untuk melihat alamat IP, netmask, dsb:

#include <EtherShield.h>

// Silahkan mengubah mymac (alamat MAC). Alamat tersebut harus BEDA
// dengan kelompok lain
static uint8_t mymac[6] = { 0x54,0x55,0x58,0x12,0x34,0x56 };

// Default alamat IP
static uint8_t myip[4] = { 0,0,0,0 };
// Default NetMask
static uint8_t mynetmask[4] = { 0,0,0,0 };
// Default gateway. 
static uint8_t gwip[4] = { 0,0,0,0};
// Default DNS server
static uint8_t dnsip[4] = { 0,0,0,0 };
// Default DHCP server
static uint8_t dhcpsvrip[4] = { 0,0,0,0 };

#define DHCPLED 6

#define BUFFER_SIZE 750
static uint8_t buf[BUFFER_SIZE+1];

EtherShield es=EtherShield();

// Setting delay untuk flashing LED
uint16_t delayRate = 0;

void setup() {

  Serial.begin(9600);
  Serial.println("Uji Coba DHCP Client");
  pinMode( DHCPLED, OUTPUT);
  digitalWrite( DHCPLED, HIGH);    // Matikan LED

  for( int i=0; i<6; i++ ) {
    Serial.print( mymac[i], HEX );
    Serial.print( i < 5 ? ":" : "" );
  }
  Serial.println();
  
  // Menginisialisasi SPI interface
  es.ES_enc28j60SpiInit();

  // Menginisialisasi enc28j60
  Serial.println("Inisialisasi EtherShield - ENC28J60");
  es.ES_enc28j60Init(mymac);

  Serial.println("Inisialisasi Selesai");
  
  Serial.print( "Versi EtherShield - ENC28J60 : " );
  Serial.println( es.ES_enc28j60Revision(), HEX);
  if( es.ES_enc28j60Revision() <= 0 ) {
    Serial.println( "Akses ke EtherShield - ENC28J60 GAGAL");

    while(1);    // Loop
  }
  
  Serial.println("Requesting IP Address");
  // Ambil detail informasi alamat IP
  if( es.allocateIPAddress(buf, BUFFER_SIZE, mymac, 80, myip, mynetmask, gwip, dhcpsvrip, dnsip ) > 0 ) {
    // Menampilkan Hasil
    Serial.print( "Alamat IP: " );
    printIP( myip );
    Serial.println();

    Serial.print( "NetMask Address: " );
    printIP( mynetmask );
    Serial.println();

    Serial.print( "DNS IP: " );
    printIP( dnsip );
    Serial.println();

    Serial.print( "GateWay IP: " );
    printIP( gwip );
    Serial.println();
   
    digitalWrite( DHCPLED, HIGH);
    delayRate = 1000;
    
    // set Alamat IP
    es.ES_init_ip_arp_udp_tcp(mymac,myip,80);
  } else {
    Serial.println("Permintaan alamat IP GAGAL!");
    delayRate = 200;
  }

}

// Keluaran alamat ip dari buffer
void printIP( uint8_t *buf ) {
  for( int i = 0; i < 4; i++ ) {
    Serial.print( buf[i], DEC );
    if( i<3 )
      Serial.print( "." );
  }
}

void loop(){
  digitalWrite( DHCPLED, HIGH);
  delay(delayRate);
  digitalWrite(DHCPLED, LOW);
  delay(delayRate);
}

Langkah keempat, jika setting alamat IP pada semua hardware sudah selesai maka test koneksi tersebut. Copas kode berikut ini ke jendela arduino lalu upload. Buka browser kalian dan ketikkan alamat ip ethernet shield untuk menampilkan halaman web yang sudah kita upload ke arduino:

#include "EtherShield.h"

// Rubah MAC dan IP Address agar berbeda dengan kelompok lain
static uint8_t mymac[6] = {
  0x54,0x55,0x58,0x10,0x00,0x25}; 
  
static uint8_t myip[4] = {
  192,168,1,11};       //Alamat IP Ethernet Shield

#define MYWWWPORT 80
#define BUFFER_SIZE 550
static uint8_t buf[BUFFER_SIZE+1];

EtherShield es=EtherShield();

uint16_t http200ok(void)
{
  return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n")));
}

uint16_t print_webpage(uint8_t *buf)
{
  uint16_t plen;
  plen=http200ok();
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<html><head><title>Tes Arduino Shield V1.0</title></head><body>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><h1>Selamat Datang di Arduino Ethernet Shield WEB Server</h1>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr><br><h2><font color=\"blue\">-- Online-kan ARDUINO kamu -- "));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Kontrol keluaran digital"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Baca input digital analog disini"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br></font></h2>") );
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("Versi 0.0 lab KomDat <a href=\"http://www.pmsd.ac.id\"pmsd</a>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</body></html>"));

  return(plen);
}


void setup(){

  es.ES_enc28j60SpiInit();

  es.ES_enc28j60Init(mymac);

  es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT);
}

void loop(){
  uint16_t plen, dat_p;

  while(1) {
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
    if(dat_p==0){
      // tidak ada http request
      continue;
    }
    // tcp port 80 
    if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
      dat_p=http200ok();
      dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>"));
      goto SENDTCP;
    }
     if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
      dat_p=print_webpage(buf);
      goto SENDTCP;
    }
    else{
      dat_p=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
      goto SENDTCP;
    }
SENDTCP:
    es.ES_www_server_reply(buf,dat_p); // kirim data web page
    // akhir tcp port 80

  }
}

Langkah kelima adalah membuat gambar sketsa rumah dan denah elektriknya dan kita masukkan pada folder htdocs pada XAMPP. Nantinya gambar tersebut akan kita panggil dengan kode yang sudah kita gabungkan pada program arduino. Gambar yang kita buat nanti akan tampil pada halaman web, tapi untuk ukuran silahkan disesuaikan sendiri. Contohnya seperti ini, jelek gapapa. Hehehe...

Langkah keenam adalah copas kode berikut ini dan upload ke arduino!

#include <EtherCard.h>

#define LEDAPIN 2
#define LEDBPIN 3
#define LEDCPIN 4
#define LEDDPIN 5
#define LEDEPIN 6


PROGMEM prog_char led_off[]= {
             0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0E,
             0x00, 0x00, 0x00, 0x0E, 0x08, 0x04, 0x00, 0x00, 0x00, 0xB5, 0x41, 0xE5, 0x5A, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47,
             0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, 0x00, 0x02, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x87, 0x8F, 0xCC, 0xBF,
             0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x12, 0x00, 0x00, 0x0B, 0x12, 0x01, 0xD2, 0xDD, 0x7E,
             0xFC, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D, 0x45, 0x07, 0xDC, 0x01, 0x1D, 0x14, 0x21, 0x10, 0xBC, 0x3C, 0xDE, 0x2D,
             0x00, 0x00, 0x00, 0xD2, 0x49, 0x44, 0x41, 0x54, 0x18, 0xD3, 0x75, 0xD0, 0xB1, 0x4A, 0x03, 0x51, 0x10, 0x05, 0xD0, 0xB3,
             0x21, 0x1F, 0x10, 0x04, 0x3B, 0x53, 0x89, 0x5A, 0x09, 0x9B, 0x58, 0xD9, 0x25, 0x5F, 0x60, 0x63, 0x9F, 0x87, 0x5F, 0xE0,
             0x27, 0x6D, 0x7A, 0x5B, 0xC1, 0x6E, 0xF3, 0x01, 0x92, 0x2C, 0x36, 0x56, 0x62, 0x61, 0x23, 0xA4, 0xB1, 0x12, 0xF2, 0x64,
             0xDF, 0x5A, 0xBC, 0x20, 0x5B, 0x98, 0x3B, 0xC5, 0xC0, 0xBD, 0x73, 0xEF, 0x30, 0x53, 0x74, 0x0E, 0x63, 0x48, 0x01, 0xC2,
             0xBD, 0x1B, 0x33, 0xAC, 0x2C, 0xAB, 0x0A, 0x3A, 0x45, 0xA7, 0x10, 0x46, 0xEA, 0x69, 0x39, 0x71, 0x21, 0xD9, 0x78, 0xF5,
             0xD2, 0x98, 0x57, 0x5F, 0x9D, 0x21, 0xA8, 0xEF, 0xCA, 0x53, 0xDF, 0xB6, 0xA2, 0x23, 0xD7, 0xC6, 0xE5, 0x63, 0x6D, 0xC2,
             0x80, 0x10, 0xA6, 0xE5, 0xB9, 0x9D, 0xA4, 0xD5, 0x4A, 0xA2, 0x91, 0xB3, 0x32, 0x04, 0x06, 0x58, 0x5C, 0x89, 0x92, 0x56,
             0xFA, 0xAB, 0x63, 0x16, 0x59, 0x9C, 0x5D, 0xF6, 0xA4, 0xDC, 0x4F, 0x98, 0xC9, 0x3B, 0x33, 0xD5, 0x77, 0x46, 0x64, 0xE7,
             0xAA, 0xE9, 0xD1, 0x79, 0x68, 0xCB, 0x2A, 0x8B, 0xCB, 0x0D, 0xBD, 0xC8, 0x24, 0xF9, 0x60, 0x69, 0x7F, 0xE7, 0xE6, 0xB6,
             0x1C, 0x8B, 0xA2, 0x1F, 0xD1, 0xCE, 0xBB, 0x75, 0x53, 0x4D, 0x3A, 0x03, 0x30, 0x7F, 0x68, 0x9E, 0xBC, 0x29, 0xB4, 0x3E,
             0x3D, 0x5B, 0x37, 0xE6, 0xEC, 0x9D, 0x10, 0x82, 0xC5, 0x3F, 0xEF, 0x3B, 0x8C, 0x5F, 0xC2, 0x84, 0x6A, 0x7B, 0xFB, 0x42,
             0x44, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
             };
             
PROGMEM prog_char led_on[]= {
             0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0E,
             0x00, 0x00, 0x00, 0x0E, 0x04, 0x03, 0x00, 0x00, 0x00, 0xED, 0x66, 0x30, 0xE2, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47,
             0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4C, 0x54, 0x45, 0x00, 0x00, 0x00, 0xFF, 0xCC, 0x00,
             0xCC, 0x66, 0x00, 0xFF, 0xFF, 0x33, 0xFF, 0x99, 0x00, 0xFF, 0xCC, 0x33, 0xCC, 0x99, 0x66, 0xFF, 0xFF, 0x99, 0xCC, 0x99,
             0x33, 0xCC, 0x99, 0x00, 0xFF, 0xCC, 0x66, 0x99, 0x66, 0x00, 0xFF, 0xCC, 0x99, 0x4A, 0x4E, 0xC9, 0x79, 0x00, 0x00, 0x00,
             0x01, 0x74, 0x52, 0x4E, 0x53, 0x00, 0x40, 0xE6, 0xD8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4B, 0x47, 0x44, 0x00, 0x88,
             0x05, 0x1D, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x12, 0x00, 0x00, 0x0B, 0x12, 0x01,
             0xD2, 0xDD, 0x7E, 0xFC, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4D, 0x45, 0x07, 0xDC, 0x01, 0x1D, 0x14, 0x23, 0x1C, 0x87,
             0xBC, 0xF0, 0x84, 0x00, 0x00, 0x00, 0x48, 0x49, 0x44, 0x41, 0x54, 0x08, 0xD7, 0x63, 0x60, 0x80, 0x03, 0x26, 0x25, 0x05,
             0x30, 0x95, 0x55, 0x3E, 0x0D, 0xC4, 0xD0, 0x31, 0x16, 0x14, 0x6C, 0x02, 0xD2, 0xC9, 0x86, 0x82, 0x82, 0xD2, 0x40, 0xE1,
             0xC5, 0x40, 0x3A, 0x44, 0x81, 0x81, 0xA9, 0x18, 0x46, 0x0B, 0x0A, 0x8A, 0xBA, 0x00, 0xE9, 0x60, 0x08, 0xCD, 0x90, 0x0C,
             0xA4, 0x9D, 0x80, 0xEA, 0x35, 0x80, 0xD2, 0x20, 0x9A, 0xA9, 0x53, 0xD0, 0x49, 0x01, 0xC9, 0x5C, 0x08, 0x00, 0x00, 0x9A,
             0x56, 0x0B, 0x58, 0x9D, 0x6A, 0x76, 0x99, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
             };

static byte mymac[] = {0x54,0x55,0x58,0x10,0x00,0x25};
static byte myip[] = {192,168,1,11};                            //Alamat IP EthernetShield
byte Ethernet::buffer[700];

boolean led0Status;
boolean led1Status;
boolean led2Status;
boolean led3Status;
boolean led4Status;

void setup () {

  Serial.begin(9600);
  Serial.println("Kendali Lampu Rumah via Web");

  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed");
 else
   Serial.println("Initialyzing");

  if (!ether.staticSetup(myip))
    Serial.println("Setting IP address GAGAL");

  Serial.println();
  
  pinMode(LEDAPIN, OUTPUT);
  pinMode(LEDBPIN, OUTPUT);
  pinMode(LEDCPIN, OUTPUT);
  pinMode(LEDDPIN, OUTPUT);
  pinMode(LEDEPIN, OUTPUT);
  off ();
  led0Status = true;
  led1Status = true;
  led2Status = true;
  led3Status = true;
  led4Status = true;
}
  
void loop() {

  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);
  
  if(pos) {
    
      if(strstr((char *)Ethernet::buffer + pos, "GET /?LED0") != 0) {
        led0Status = !led0Status;
        off();
        Teras();
        
  
      }
      if(strstr((char *)Ethernet::buffer + pos, "GET /?LED1") != 0) {
        led1Status = !led1Status;
        off();
       R_Klg();
       
      }
      
      if(strstr((char *)Ethernet::buffer + pos, "GET /?LED2") != 0) {
        led2Status = !led2Status;
        off();
       K_Tidur();
     
      }
      if(strstr((char *)Ethernet::buffer + pos, "GET /?LED3") != 0) {
        led3Status = !led3Status;
        off();
        Dapur();
        
      }
      if(strstr((char *)Ethernet::buffer + pos, "GET /?LED4") != 0) {
        led4Status = !led4Status;
        off();
        Toilet();
      }
    
    
      BufferFiller bfill = ether.tcpOffset();
      bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
        "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
        "<Style>"
        "Body {"
          "background-image: url(\"http://192.168.1.12/rumah.jpg\");"
          "background-repeat: no-repeat;"
        "}"
        "</style>"
        "<html><head><title>Web Lamp</title></head><body>"
        "STATUS LAMPU: <br><br>"));
       
      if(led0Status) bfill.emit_p(PSTR("Lampu Teras:<a href=\"/?LED0\"><input type=\"button\"value=\"OFF\"></a>"));
      else bfill.emit_p(PSTR("Lampu Teras:<a href=\"/?LED0\"><input type=\"button\"value=\"ON\"></a>"));
      bfill.emit_p(PSTR("<br>"));
      
      if(led1Status) bfill.emit_p(PSTR("Lampu R.Keluarga:<a href=\"/?LED1\"><input type=\"button\"value=\"OFF\"></a>"));
      else bfill.emit_p(PSTR("Lampu R.Keluarga:<a href=\"/?LED1\"><input type=\"button\"value=\"ON\"></a>"));
      bfill.emit_p(PSTR("<br>"));
      
      if(led2Status) bfill.emit_p(PSTR("Lampu K.Tidur:<a href=\"/?LED2\"><input type=\"button\"value=\"OFF\"></a>"));
      else bfill.emit_p(PSTR("Lampu K.Tidur:<a href=\"/?LED2\"><input type=\"button\"value=\"ON\"></a>"));
      bfill.emit_p(PSTR("<br>"));
              
      if(led3Status) bfill.emit_p(PSTR("Lampu Dapur:<a href=\"/?LED3\"><input type=\"button\"value=\"OFF\"></a>"));
      else bfill.emit_p(PSTR("Lampu Dapur:<a href=\"/?LED3\"><input type=\"button\"value=\"ON\"></a>"));
      bfill.emit_p(PSTR("<br>"));
            
      if(led4Status) bfill.emit_p(PSTR("Lampu Toilet:<a href=\"/?LED4\"><input type=\"button\"value=\"OFF\"></a>"));
      else bfill.emit_p(PSTR("Lampu Toilet:<a href=\"/?LED4\"><input type=\"button\"value=\"ON\"></a>"));
                  
      bfill.emit_p(PSTR("</body></html>"));
      ether.httpServerReply(bfill.position());

  }
}

void send_png_image(PGM_P png_image, unsigned int image_size) {
  
  BufferFiller bfill = ether.tcpOffset();
  bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
    "Content-Type: image/png\r\n\r\n"));
  bfill.emit_raw_p(png_image, image_size);
  ether.httpServerReply(bfill.position());
}
void Teras (){
  digitalWrite(LEDAPIN, led0Status);
  digitalWrite(LEDBPIN, led1Status);
  digitalWrite(LEDCPIN, led2Status);
  digitalWrite(LEDDPIN, led3Status);
  digitalWrite(LEDEPIN, led4Status);
}

void R_Klg(){
  digitalWrite(LEDAPIN, led0Status);
  digitalWrite(LEDBPIN, led1Status);
  digitalWrite(LEDCPIN, led2Status);
  digitalWrite(LEDDPIN, led3Status);
  digitalWrite(LEDEPIN, led4Status);
}

void K_Tidur (){
  digitalWrite(LEDAPIN, led0Status);
  digitalWrite(LEDBPIN, led1Status);
  digitalWrite(LEDCPIN, led2Status);
  digitalWrite(LEDDPIN, led3Status);
  digitalWrite(LEDEPIN, led4Status);
}

void Dapur(){
  digitalWrite(LEDAPIN, led0Status);
  digitalWrite(LEDBPIN, led1Status);
  digitalWrite(LEDCPIN, led2Status);
  digitalWrite(LEDDPIN, led3Status);
  digitalWrite(LEDEPIN, led4Status);
}

void Toilet(){
  digitalWrite(LEDAPIN, led0Status);
  digitalWrite(LEDBPIN, led1Status);
  digitalWrite(LEDCPIN, led2Status);
  digitalWrite(LEDDPIN, led3Status);
  digitalWrite(LEDEPIN, led4Status);
}

void off(){
  delay(200);
  digitalWrite(LEDAPIN, HIGH);
  digitalWrite(LEDBPIN, HIGH);
  digitalWrite(LEDCPIN, HIGH);
  digitalWrite(LEDDPIN, HIGH);
  digitalWrite(LEDEPIN, HIGH);
}


Kode yang merah merupakan kode untuk memanggil gambar dengan XAMPP. Jika program sudah terupload maka halaman web yang tampak akan seperti penampakan berikut ini:


Nah, jika button OFF pada halaman tersebut kita klik maka lampu yang kita letakkan pada miniatur bagian teras akan menyala dan button menjadi ON sebagai indikator di webnya. Begitu pula dengan button dan LED yang lainnya.

Sementara hanya ini dulu yang bisa saya bagikan, mungkin memang membingungkan. Boleh bertanya biar gak membingungkan. Hahaha...

Sekian posting kali ini, jika ada yang tidak berkenan mohon dimaafkan dan semoga bisa membantu teman-teman dalam berkarya. AMDG.
Description: Kontrol Lampu via Web (Arduino+EthernetShield) Rating: 4.5 Reviewer: Alvianno Wijaya - ItemReviewed: Kontrol Lampu via Web (Arduino+EthernetShield)

Silahkan Baca Artikel Lain yang tidak Kalah menariknya.

Ilmu Komputer 95 - 07.32
Comments
0 Comments

0 komentar:

Posting Komentar