위모스(Wemos) D1 활용

위모스(Wemos) D1 ESP8266 아두이노 호환보드를 활용하여 인터넷 전등제어

Posted by 최일규 on 2017. 12. 29

위모스(Wemos) D1 ESP8266 아두이노 호환보드를 활용하여 인터넷 전등제어

아두이노 와이파이 통합 호환보드 Wemos D1가지고 와이파이로 전등을 제어해 보았습니다.

이전 포스트에서 인터넷으로 전원을 제어하는 주제로 실습을 해보았는데요. 일부 복잡한 구성 (라즈베리파이와 아두이노를 조합)을 해야한다는 문제가 있더군요..

좀더 간단한 구성으로 전원을 제어하는 방법을 찾다가 WeMos(아두이노 + 와이파이 통합보드)만 가지고 직접 간단한 웹서버를 구축하고 제어하는 방법을 연구해 보았습니다.

WeMos D1 (ESP8266-12E 와이파이 통합보드)은 가격도 저렴하고 ESP-01 시리얼와이파이 모듈과 같이 펌웨어 업데이트 문제가 없어 개발에 집중할수 있습니다.

아두이노 호환보드로  CH34X칩을 위한 드라이버를 설치해야만 포트를 인식시킬수 있어, 맥OS기준으로 다음 사이트에서 드라이버를 다운받아 .pkg를 설치합니다.

http://www.wch.cn/download/CH341SER_MAC_ZIP.html

설치후 포트정보에서 "/dev/cu.wchusbserial1410" 이 보이지 않는다면, 다운받은 드라이버 메뉴얼(PDF)을 참고하시어, 맥OS의 보안설정을 진행하세요.

 

WeMos D1을 사용하려면, 추가적인 보드매니저를 추가해야 되는데요 

다음과 같이 추가적인 보드매니저 URL을 추가하시고, http://arduino.esp8266.com/stable/package_esp8266com_index.json 

esp8266 by ESP8266 Community를 설치하시면,  "툴 - 보드"에서 WeMos D1 R2 & mini를 선택할수 있습니다.

ESP8266 와이파이모듈은 크게 AP모드와 Client모드를 지원하는데요

아래 소스는 WIFI_AP모드로, WeMos D1 디바이스가 공유기가 되서 스마트폰으로 WeMos를 제어하는 로직입니다.

단지 인터넷은 되지 않는 사설네트워크 이므로 예를 들어 192.168.4.1 과 같이 접속을 해볼수가 있어요.

저는 아래와 같은 코드로 릴레이를 통해 전원을 ON/OFF하는 작업을 진행해 봤는데요. 원격에서 제어하려면 항상 공유기 AP를 찾아 접속해야하는 복잡한 단계가 있네요 ㅠ

#include <ESP8266WiFi.h>

WiFiServer server(80); //Initialize the server on Port 80

int LED_PIN = 14;

void setup() {

  WiFi.mode(WIFI_AP); //Our ESP8266-12E is an AccessPoint 
  WiFi.softAP("Hello_IoT", "12345678"); // Provide the (SSID, password);
  server.begin(); // Start the HTTP Server
  
  Serial.begin(115200); //Start communication between the ESP8266-12E and the monitor window
  IPAddress HTTPS_ServerIP= WiFi.softAPIP(); // Obtain the IP of the Server 
  Serial.print("Server IP is: "); // Print the IP to the monitor window 
  Serial.println(HTTPS_ServerIP);
  
  pinMode(LED_PIN, OUTPUT); //GPIO14 is an OUTPUT pin;
  digitalWrite(LED_PIN, LOW); //Initial state is OFF

}

void loop() { 
  WiFiClient client = server.available();
  if (!client) { 
    return; 
  } 
  //Looking under the hood 
  Serial.println("Somebody has connected :)");


  //Read what the browser has sent into a String class and print the request to the monitor
  String request = client.readStringUntil('\r'); 
  //Looking under the hood 
  Serial.println(request);

  if (request.indexOf("/OFF") != -1){ 
    digitalWrite(LED_PIN, LOW);
    Serial.println("POWER OFF"); 
  } else if (request.indexOf("/ON") != -1){ 
    digitalWrite(LED_PIN, HIGH);
    Serial.println("POWER ON");
  }

  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html>\r\n";
  s += "<head><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\"></head>";
  s += "<body>";
  s += "<br><input type=\"button\" name=\"b1\" value=\"POWER ON\" onclick=\"location.href='/ON'\">";
  s += "<br><br><br>";
  s += "<input type=\"button\" name=\"b1\" value=\"POWER OFF\" onclick=\"location.href='/OFF'\">";
  s += "</body>";
  s += "</html>\n";

  client.flush(); //clear previous info in the stream
  client.print(s); // Send the response to the client
  delay(1);
  Serial.println("Client disonnected"); //Looking under the hood
}

참고 URL) http://www.makewith.co/page/project/1004/story/2480

참고소스) 스케치 - 파일 - 예제 - ESP8266Wifi - WifiClient

그래서 WeMos D1을 기존 iptime과 같은 공유기에 접속하고, 저는 스마트폰으로 iptime을 접속해서 WeMos를 제어하는 방법이 좋을거 같다고 생각했습니다.

그래서 위 소스와 WifiClient 소스를 응용해서 다음과 같이 프로그램을 수정했습니다.

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

const char* ssid = "iptime";
const char* password = "비밀번호";

ESP8266WebServer server(80);

const int LED_PIN = 14;

String s = "<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\"></head><body><br><input type=\"button\" name=\"b1\" value=\"ON\" onclick=\"location.href='/on'\" style=\"width:100%;height:70px;font-weight:bold;font-size:1em\"><br/><input type=\"button\" name=\"b1\" value=\"OFF\" onclick=\"location.href='/off'\" style=\"width:100%;height:80px;font-weight:bold;font-size:1em\"></body></html>";


void handleRoot() {
  //digitalWrite(led, 1);
  server.send(200, "text/html", s);
  //digitalWrite(led, 0);
}

void handleNotFound(){
  //digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/html", message);
  //digitalWrite(led, 0);
}

void setup(void){
  //pinMode(led, OUTPUT);
  //digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  //on
  server.on("/on", [](){    
    digitalWrite(LED_PIN, LOW);
    Serial.println("POWER ON");
    server.send(200, "text/html", s);
  });

  //off
  server.on("/off", [](){
    digitalWrite(LED_PIN, HIGH);
    Serial.println("POWER OFF");
    server.send(200, "text/html", s);
  });

  server.onNotFound(handleNotFound);

  server.begin();
  Serial.println("HTTP server started");

  pinMode(LED_PIN, OUTPUT); //GPIO14 is an OUTPUT pin;
  digitalWrite(LED_PIN, HIGH); //Initial state is OFF

}

void loop(void){
  server.handleClient();  
}

일단, 잘 되네요~

코드가 지저분하지만, 리펙토링은 추후에 진행하는걸로 하고 구현을 목표로 진행해 보았습니다.

결과는 유투브 동영상으로 올려봤습니다.

이제 집에 있는 공유기만 접속하면 WeMos에 접속해서 전등을 ON/OFF 할 수 있겠군요.

감사합니다.