레이블이 esp8266인 게시물을 표시합니다. 모든 게시물 표시
레이블이 esp8266인 게시물을 표시합니다. 모든 게시물 표시

2018년 7월 17일 화요일

ESP32에서 웹소켓 서버 실행 (Websocket server on ESP32)

ESP32에 웹소켓(web socket) 서버를 만들는 방법을 설명하겠다. 이번에 만드는 웹소켓 서버는 가장 단순한 echo 서버로 클라이언트가 보낸 데이터를 그대로 클라이언트에 되돌려 준다.
또한 작성한 웹소켓 서버를 테스트 하기 위해 간단한 파이썬 클라이언트를 작성했다.

ESP32에서 웹소켓을 사용하기 위해 Websocket 라이브러리를 사용하였다. 이 라이브러리는 일반적으로 아두이노에서 TCP 서버를 만드는데 사용되는 WiFiServer 라이브러리 상에서 동작한다.
이 라이브러리는 ESP8266용으로 만들어 져 아직 공식적으로 ESP32를 지원하지는 않지만 약간만 수정하면 ESP32에서도 잘 동작한다.

라이브러리는 https://github.com/morrissinger/ESP8266-Websocket 에서 다운받을 수 있다.


우측 상단의 녹색 (1)번 버튼 (Clone or download) 을 누르면 풀다운 창이 열리고 그곳에서 Download ZIP을 눌러주면 된다. 그러면 ESP8266-Websocket-master.zip 이라는 파일이 다운로드 될 것이다. 이 파일의 압축을 풀면 ESP8266-Websocket-master 이라는 이름의 폴더가 생기게 된다. .


이 폴더의 이름을 ESP8266-Websocket (뒷쪽의 "-master' 부분을 제거)로 만들어 준 다음 다시 ZIP 파일로 압축한다

아두이노의 메뉴에서 스케치->라이브러리 포함하기->.ZIP 라이브러리 추가 를 선택 해 준다.



앞축파일을 찾아 선택해서 설치 해 준다.


이제 라이브러리 설치가 완료되었다. 윈도우의 경우 디폴트 위치가 C:\Users\[username]\Documents\Arduino\libraries 가 된다. Mac의 경우/Users/[username]/Docunemts/Arduino/libraries

라이브러리 설치는 끝났지만 그냥 컴파일을 하면 에러가 발생하므로 ESP32에서 사용할 수 있도록 약간의 수정을 해 준다.

라이브러리가 설치된 폴더를 보면 위와 같은 파일이 있는데 그 중 MD5.c, MD5.h 파일을 수정해 줘야 한다.


MD5.c 파일을 오픈 한 화면이다. 파일에서 위의 빨간색 부분 (함수 이름)을 다음과 같이 바꿔주면 된다.


MD5.h 도 유사하게 이름을 바꿔주면 된다.



이제 아두이노 메뉴에서 파일->예제->ESP8266-Websocket->WebsocketClient_Demo 를 열어본다.
예제 파일을 컴파일 해 보면 ESP8266WiFi.h 파일을 찾을 수 없다는 에러가 발생한다. 그러므로 첫번째 줄의 #include <ESP8266WiFi.h> 를 #include <WiFi.h> 로 바꿔줘야 한다.
또한 SSID HERE, PASSWORD HERE 부분에 자신이 사용할 공유기 정보를 넣어줘야 한다.



만일 공유기 ssid가 wifitestap 이고 암호가 ap1234567890 라고 하면 다음과 같이 변경해주면 된다.


샘플코드에서는 analogRead 값을 서버로 보내고 있는데 여기서는 테스트 목적이라 그냥 "Hello" 라는 스트링을 보내도록 수정하였다.


이제 ESP32 보드에 업로드 하고 시리얼 모니터로 결과를 확인할 수 있다.


테스트용 에코서버에 연결되면 반복적으로 "Hello"라는 스트링을 보내고 서버에서 리턴 된 문자를 출력한 것이다.

ESP32용 websocket 라이브러리 설치가 확인되었으면 이제 파이선으로 테스트용 웹소켓 클라이언트를 만들어 보겠다.

여기서는 websocket-client 모듈을 사용한다. 파이선에서 모듈 설치는 pip를 사용해 간단히 해결할 수 있다.

$ pip install websocket-client

모듈을 사용하기 위해 먼저 import 해 줘야 한다.

import websocket
import time

import 한 다음 WebSocket 클래스의 오브젝트를 만들어 준다.

ws = websocket.WebSocket()

이제 만들어 진 오브젝트의 connect() 메소드를 사용해 웹소켓 서버에 쉽게 접속할 수 있다. 메소드를 호출할 때 접속할 서버의 주소를 파라미터로 넘겨주면 되는데 웹소켓을 사용해 접속할 것이기 때문에 주소는 "ws://[server ip]/" 형태로 지정해 줘야 한다. 여기서 server ip는 웹서버가 실행되는 ESP32의 ip 주소를 넣어주면 된다.

테스트 웹소켓 서버로 확인해보고 싶으면 ws://echo.websocket.org/ 를 사용하면 된다.

ws.connect("ws://echo.websocket.org/")

이제 서버에 연결되었기 때문에 send 메소드로 원하는 데이터를 보낼 수 있다.

ws.send("Hello world")

recv 메소드로 서버에서 데이터를 받아 올 수 있다.

result = ws.recv()

서버에 연결을 끊을 때는 close 메소드를 사용하면 된다.

result = ws.close()

간단한 테스트 코드는 아래와 같다.

import websocket
import time

ws = websocket.WebSocket()
ws.connect ("ws://echo.websocket.org/")

i=0
nrOfMsgs = 10

while i<nrOfMsgs:
  ws.send("Msg no. "+str(i))
  result = ws.recv()
  print (result)
  i=i+1
  time.sleep(1)
ws.close()


이제 ESP32에 웹소켓 서버를 만들어 보겠다.
먼저 WebSocketServer.h 를 include 해 줘야 한다.

#include <WiFi.h>
#include <WebSocketServer.h>

다음으로 WiFiServer 클래스 오브젝트 인스턴스로 TCP 서버를 만들어 줘야 한다. 웹소켓 서버는 이 서버 위에서 동작한다. 오브젝트 인스턴스의 파라미터는 옵션으로 서버 포트를 지정하는데 사용한다. 디폴트 값이 80이라 따로 지정하지 않아도 상관없지만 여기서는 명시적으로 80번 포트를 지정해 줬다.

WiFiServer server(80);

그리고 WebSocketServer 클래스의 오브젝트 인스턴스도 만들어 줘야 한다.

WebSocketServer webSocketServer;

마지막으로 공유기 접속을 위한 정보를 지정해 줘야 한다.

const char* ssid = "wifitestap";
const char *password = "ap1234567890";

setup() 함수에서는 우선 무선랩에 접속 후 server 인스턴스의 begin 메소드를 호출해 초기화 해 준다.

void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to the WiFi");
  Serial.println(WiFi.localIP());

  server.begin(80);
  delay(100);
}

loop() 함수에서는 클라이언트와의 접속과 데이터 교환을 처리한다.

먼저 incoming connection이 있는가 확인하기 위해 WiFiServer 오브젝트의 available 메소드를 호출한다. available 메소드는 incoming connection이 있으면 WiFiClient 오브젝트를 리턴한다.

WiFiClient client = server.available();

주의할 점은 아직 웹소켓 클라이언트 레벨이 아니고 TCP 클라이언트 레벨에 있다는 것이다.

TCP 클라이언트가 연결되어 있는지 확인하기 위해 위에서 리턴된 WiFiClient 오브젝트의 connected 메소드를 호출한다. 또한 WebSocketServer 오브젝트에 WiFiClient 오브젝트를 파라미터로 해서 handshake 메소드를 호출해서 프로토콜 핸드쉐이크를 처리하도록 한다.

핸드쉐이크가 성공하면 true를 리턴한다. 이 값이 확인 돼야 클라이언트와 실제 통신을 진행할 수가 있게 된다.


  if (client.connected() && webSocketServer.handshake(client)) {
    // 클라이언트와 통신 코드
  }

여기서는 간단한 에코서버를 만드는 것이기 때문에 클라이언트에서 받은 데이터를 저장할 버퍼가 필요한데 메소드는 String 타입을 사용한다.

String data;

클라이언트가 아무 때나 접속을 끊을 수 있기 때문에 while 루프를 돌면서 접속이 끊어지지 않았는가 확인해야 한다.

또한 루프의 각 iteration 사이에 약간의 딜레이가 필요하다. 그렇지 않으면 첫번째 몇 바이트를 받은 다음 데이서 수신을 멈출 수 있기 때문에 매우 중요하다.

그러므로 루프의 구조는 다음과 같다.

if (client.connected() && webSocketServer.handshake(client)) {
  String data;
  while (client.connected()) {
    // handle communication
    delay(10);  // delay needed for receiving data correctly
  }
}

이제 while 루프 안에서 webSocketServer 오브젝트의 getData 메소드를 호출해 데이터를 수신한다. 이 메소드는 파라미터가 없고 수신한 데이터를 String 타입으로 리턴한다.

    data = webSocketServer.getData();

데이터를 수신하고 나면 그 내용을 시리얼 포트로 출력하고 클라이언트로 되돌려 보낸다.

클라이언트로 데이터를 보낼 땐 webSocketServer 오브젝트의 sendData 메소드를 호출한다.

클라이언트가 아무 데이터도 보내지 않는 경우도 있을 수 있으므로 데이터 버퍼의 길이를 먼저 확인한다. 그러므로 클라이언트에 데이터를 돌려보내기 위해서는 버퍼에 있는 데이터 길이가 0보다 커야만 한다.

    if (data.length() > 0) {
      Serial.println(data);
      webSocketServer.sendData(data);
    }


위에서 설명하며 작성한 전체 코드는 다음과 같다.

#include <WiFi.h>
#include <WebSocketServer.h>
WiFiServer server(80);
WebSocketServer webSocketServer;
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup()
{
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to the WiFi network");
  Serial.println(WiFi.localIP());
  server.begin()
  delay(1000);
}
void loop()
{
  WiFiClient client = server.available();
  
  if (client.connected() && webSocketServer.handshake(client)) {
    String data;
    while (client.connected()) {
      data = webSocketServer.getData();
      if (data.length() > 0) {
        Serial.println(data);
        webSocketServer.sendData(data);
      }
      delay(10);   // Delay needed for receiving data correctly
    }
    Serial.println("The client disconnected");
    delay(100);
  }
  delay(100);
}

작성한 코드를 테스트 하려면 먼저 ESP32에 업로드 해서 실행시킨다. 그럼 ESP32는 무선랜에 접속하고 local IP를 시리얼 포트로 출력해 준다.


여기서 ESP32의 IP address는 192.168.0.14 이다.
이제 파이썬 코드의 주소 부분을 ESP32의 IP address로 바꿔준다.




주소를 변경했으면 python으로 작성한 클라이언트를 실행시켜 주면 된다.


파이썬 클라이언트(우측 화면)에서 Msg no.x 라는 문자열을 웹소켓을 통해 ESP32로 보내면 ESP32(좌측화면)가 수신한 데이터를 시리얼 포트에 출력하고 그 내용을 클라이언트로 되돌려 보내 준다. 파이썬 클라이언트는 서버에서 받은 데이터 내용을 화면에 출력한 것이다.


2017년 5월 11일 목요일

라즈베리 파이에서 MQTT를 이용해 ESP8266 제어하기

여기서는 라즈베리 파이, ESP8266(또는 와이파이 쉴드를 붙인 아두이노), PC를 MQTT로 연결해 보도록 하겠다.

이번에 하고자 하는 것은 라즈베리파이가 python을 사용해 PC에 있는 MQTT 브로커에 메시지를 보내면 그 메시지가 ESP8266으로 전달되어 거기에 있는 LED를 제어하는 것이다.

MQTT for PC


MQTT server(브로커)로 사용할 수 있는 옵션이 몇가지 있다. Amazon의 AWS IoT나 AdafruitIO 같은 서비스들은 클라우드 기반의 브로커이다. 각 서비스는 여러가지 장점이 있다. 프로젝트의 필요성에 따라 클라우드 기반 서비스를 사용할 필요가 있을수도 있다.

Mosquitto


자신의 호스트에 브로커를 실행하고 싶으면 오픈소스인 moqsuitto가 훌륭한 옵션이다. 이 브로커는 MQTT를 완전히 지원할 뿐 아니라 pub/sub를 위한 커맨드라인 유틸리티까지 제공한다.

윈도우를 사용하면 mosquitto.org에서 바이너리 인스톨러를 받을 수 있다. 리눅스의 경우 패키지 매니져에서 'mosquitto' 또는 'mosquitto-mqtt'를 찾으면 된다. 맥에서는 homebrew를 사용해 mosquitto를 설치할 수 있다.

* 맥에서 설치한 경우 '/usr/local/sbin'을 PATH에 넣어줘야 한다.

Running Mosquitto


Mosquitto는 디폴트로 1883번 포트를 사용하고 보안기능은 다 꺼져 있다. 처음 시작할 때는 이것으로 충분하지만 결국에는 보안기능을 추가해 줄 필요가 있다.

Mosquitto를 verbose 모드로 실행하길 권장한다. 그러면 출력을 보고 어떤 일이 일어나는지에 대한 아이디어를 얻을 수 있을 것이다.

MacMan:~ james$ mosquitto -v 
1456272937: mosquitto version 1.4.5 (build date 2015-11-09 14:23:46-0800) starting 1456272937: Using default config. 
1456272937: Opening ipv4 listen socket on port 1883. 
1456272937: Opening ipv6 listen socket on port 1883.

Testing Mosquitto


서버 코드를 verbose 모드에서 실행시키고, 추가로 두개의 명령어 프롬프트를 열어준다. 각각의 명령어 프롬프트에서 메시지 전송 테스트를 위해 mosquitto_pub와 mosquitto_sub를 사용할 것이다.

Subscribing to MQTT Topic with Mosquitto


먼저 클라이언트가"debug"라는 토픽을 subscribe하게 해 준다. 첫번째 명령어 프롬프트에서 아래 명령을 입력해 주면 된다.

$ mosquitto_sub -h 127.0.0.1 -i testSub -t debug

* -h : host flag는 mosquitto가 실행되고 있는 서버를 지정. 여기서는 localhost
* -i : identity flag 는 옵션이다. Client ID가 지정되지 않으면 mosquitto_sub가 임의로 만듬
* -t : topic flag 는 subscribe 하려고 하는 topic을 지정. 여기서는 "debug"

서버에서는 topic을 만들지 않았다는걸 주목해라. Topic은 subscriber나 publisher가 처음 지정할 때 만들어진다.

Publish to MQTT Topic with Mosquitto


이제 topic을 기다리는 클라이언트를 가지고 있으므로, 다른 클라이언트가 그 topic을 publish하게 해 본다.

$ mosquitto_pub -h 127.0.0.1 -i testPublish -t debug -m 'Hello World'


이제 첫번째 명령어 프롬프트 화면을 보면 publish된 메시지가 와 있는것을 확인할 수 있다. mosquitto_pub와 mosquitto_sub 명렁 모두 --help 플래그로 확인 해 봐라. 매우 여러가지 유용한 옵션들을 찾아볼 수 있을 것이다.

이제 mosquitto 브로커가 정상 동작하고 있는것이 확인되었으므로 디바이스와 통신을 하게 해 보자.

MQTT for Raspberry Pi (Python)


라즈베리 파이에서 MQTT 메지시를 보내고 받을 수 있는 옵션으로는 mosquitto를 설치하는 것이다. 그러면 라즈베리 파이에서도 동일하게 mosquitto_pub와 mosquitto_sub 명령어를 사용할 수 있다.

다른 방법으로는 자신이 선호하는 언어용 MQTT 라이브러리를 사용하는 것이다. 여기서는 파이선을 사용한다.

Install MQTT for Python


여기서 사용할 MQTT library는 Paho Python Client이다. 오픈소스로 가장 최신의 MQTT를 지원한다.

설치는 간단하다. 먼저 'pip'를 설치하고 나서 아래 명령을 실행한다.

$ pip install paho-mqtt

* 만일 python3를 사용한다면 'pip' 대신 'pip3'를 사용해야 하는걸 잊지 마라.

Example MQTT Python Code for Raspberry Pi


Paho는 MQTT 서버와 통신을 매우 쉽게 만들어 준다.

import paho.mqtt.publish as publish
import time
print ("Sending 0...")
publish.single("ledStatus", "0", hostname="macman")
time.sleep(1)
print ("Sending 1...")
publish.single("ledStatus", "1", hostname="macman")

진짜 간단하다. 스크립트에 서버가 실행되고 있는 호스트 이름(여기서는 'macman'), Topic (여기서는 'ledStatus'), 메시지(여기서는 '0' 또는 '1')만 알려주면 된다.

이 MQTT 튜토리얼 예제에서는 '0'을 보내고 1초 기다린 후에 '1'을 보낸다. 이 동작은 ESP8266에 있는 LED가 잠깐동안 꺼졌다 다시 켜지게 만든다.


이제 RPi가 MQTT 메시지를 보내게 만들었으니 그 메시지를 받도록 만들어 보자. 다음 섹션은 ESP8266이 topic "ledStatus"의 메시지를 받아 실제로 LED를 깜빡이게 만들 것이다.

MQTT for ESP8266


PubSubClient는 아두이노 기반의 MQTT 클라이언트이다. 단지 몇 줄의 코드만으로 매우 쉽게 topic을 subscribe하거나 새로운 topic을 publish할 수 있다.

여기서는 ESP8266을 프로그래밍 하기 위해 아두이노 IDE를 사용했다.

Installing MQTT for Arduino IDE


아두이노 IDE에 PubSubClient를 설치하는건 간단하다. Github에서 수동으로 설치하거나 또는 Arduino Package Installer를 사용할 수 있다.


Arduino ESP8266 and Uno Note


Ethernet 쉴드가 장착된 Uno와 ESP8266간에 스위칭에는 별도의 추가적인 노력이 필요 없다. 라이브러리는 양쪽 모두 잘 동작한다.

Code Example for Arduino MQTT


PubSubCilent에 포함되어 있는 예제는 매우 훌륭하다. 예제에는 특히 MQTT에 대한 ESP8266 코드도 들어있다. 처음 시작할 때 그것들도 꼭 확인해 보기 바란다.

아래는 WiFi에 연결하고 "ledStatus" topic을 subscribe하는 코드이다. ESP8266이 메시지를 받으면 그에 따라 ledPin을 on/off한다.

#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_INA219.h>

// Connect to the WiFi
const char* ssid = "Dear John";
const char* password = "password123";
const char* mqtt_server = "macman";

WiFiClient espClient;
PubSubClient client(espClient);

const byte ledPin = 0; // Pin with LED on Adafruit Huzzah

void callback(char* topic, byte* payload, unsigned int length) {
 Serial.print("Message arrived [");
 Serial.print(topic);
 Serial.print("] ");
 for (int i=0;i<length;i++) {
  char receivedChar = (char)payload[i];
  Serial.print(receivedChar);
  if (receivedChar == '0')
  // ESP8266 Huzzah outputs are "reversed"
  digitalWrite(ledPin, HIGH);
  if (receivedChar == '1')
   digitalWrite(ledPin, LOW);
  }
  Serial.println();
}


void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
 Serial.print("Attempting MQTT connection...");
 // Attempt to connect
 if (client.connect("ESP8266 Client")) {
  Serial.println("connected");
  // ... and subscribe to topic
  client.subscribe("ledStatus");
 } else {
  Serial.print("failed, rc=");
  Serial.print(client.state());
  Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
  delay(5000);
  }
 }
}

void setup()
{
 Serial.begin(115200);

 client.setServer(mqtt_server, 1883);
 client.setCallback(callback);

 pinMode(ledPin, OUTPUT);
}

void loop()
{
 if (!client.connected()) {
  reconnect();
 }
 client.loop();
}


모든 마법은 "callback" 함수 안에서 일어난다. 실제 코드에서는 받은 메시지를 처리하는 함수를 작성하고 싶을 것이다. 여기서는 topic에 대해 한글자 메시지만을 보내기 때문에 이 간단한 코드로 충분하다.

Conclusion


이 MQTT 튜토리얼은 매우 기초적이다. 하지만 라즈베리 파이, ESP8266을 MQTT 브로커가 실행되고 있는 PC에 연결하는데 필요한 최소한의 것을 보여준다.

다음에는 MQTT를 통해 어떻게 더 복잡한 메시지를 보낼 수 있는가를 설명하겠다.




2016년 3월 28일 월요일

NodeMCU와 Blynk를 사용한 IoT - (2) 튜토리얼 1

이전 포스트(NodeMCU와 Blynk를 사용한 IoT - (1) 환경설정)에서 환경설정이 끝났으므로 이제 실제로 blnyk를 사용해 원격제어를 해 보겠다.



 Blynk 앱을 실행시키고 로그인을 하면 위와 같은 화면이 나온다. 여기서 'Create New Project'를 클릭한다.



 새로 만들 프로젝트 설정 화면이 나온다.



Project Name 부분에 프로젝트의 이름(여기서는 'Tutorial 1')을 넣고 'Arduino Uno'를 클릭하면 위와 같이 어떤 하드웨어를 사용할 지 선택할 수 있다. 여기서는 NodeMCU를 사용할 것이므로 아래쪽으로 내려가 'NodeMCU'를 선택해 준다.


이제  설정이 끝났으므로 'Create Project' 버튼을 눌러주면 된다. 단 위쪽의 AUTH TOKEN 부분의 파란 글자(여기서는 중간 부분을 일부러 흐리게 한 줄)는 잘 기억하고 있어야 한다. 나중에 NodeMCU에 프로그램을 넣어줄 때 AUTH TOKEN 값을 넣어줘야만 서로 통신이 가능하다.


이제부터 프로젝트 화면을 디자인 할 수 있다.



 화면의 아무 부분이나 터치하면 오른쪽에 위와 같이 위젯을 선택할 수 있는 화면이 열린다.


가장 위에 있는 BUTTON을 선택하면 화면에 버튼 위젯이 생성된다.


생성된 버튼 위젯을 누르면 위와 같이 위젯 설정 화면이 나오게 된다.


 'Button' 부분에 버튼의 이름(여기서는 'Orange')를 넣어주고  'PIN' 부분을 누르면 그 버튼에 연결될 출력핀을 선택할 수 있다.


첫번째 버튼은 Digital - D1 핀을 선택 해 준다.


마지막으로 MODE 부분에서 PUSH와 SWITCH 를 선택할 수 있는데 PUSH인 경우는 누르고 있어야만 on이 되는 타입이고, SWITCH인 경우는 토글 스위치로 동작한다. 여기서는 SWITCH 타입을 사용한다. 설정이 끝났으면 우측 상단의 'OK' 버튼을 눌러준다.


이제 첫번째 버튼 위젯 설정이 끝난 것이다. 버튼 위젯에 방금 넣어준 이름과 핀 번호가 표시된 걸 볼 수 있다.


동일한 방법으로 두개의 버튼을 더 만들어 준다. 각각 이름은 'Blue', 'Yellow'로 하고 핀은 D2, D3을 선택해 주면 된다. 


다시 화면의 빈 부분을 눌러 새 위젯 선택 화면으로 오면 이번엔 'Large Slider'를 선택한다.


Slider 설정화면에서 이름은 'Red Brightness'로 하고 핀은 D4를 선택 해 준다. 핀 번호 옆의 0~255 값은 슬라이더를 이동시켰을 때 변화하는 최소값, 최대값이다.


이제 프로젝트 화면 디자인이 끝났다. 화면 우측 상단의 삼각형 버튼을 누르면 디자인 한 프로젝트 화면을 실행하게 된다.


프로젝트를 실행시켰지만 아직 이 프로젝트에 연결된 하드웨어가 없기 때문에 'NodeMCU is offline'이라는 메시지가 나오게 된다. 

이제 프로젝트에 연동되는 하드웨어를 만들어 준다. 이번에 사용할 회로는 다음과 같다.

4개의 LED를 NodeMCU의 D1, D2, D3, D4에 각각 연결해 주면 된다. 여기서는 D1/2/3에 연결된 LED는 on/off로 제어하고 D4에 연결된 LED는 PWM을 사용해 밝기를 제어해 보도록 한다.

여기에 사용할 코드는 다음과 같다.

#define BLYNK_PRINT Serial   
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
 

char auth[] = ".......";   // AUTH TOKEN
void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, "....", "....");   // SSID & PASSWORD
}

void loop()
{
  Blynk.run();

}


아두이노 IDE에서 위와 같이 프로그램 코드를 넣어주면 된다. 소스코드에서 빨간색 '....' 부분은 각각 첫번째부터 Blynk 앱에서 프로젝트를 만들때 자동으로 생성된 AUTH TOKEN 값, 두번째는 자신의 공유기 SSID, 세번째는 공유기 암호로 바꿔 프로그램을 NodeMCU에 업로드 해 주면 된다.

프로그램 업로드가 끝나고 NodeMCU에서 실행되면 이제 다시 스마트폰의 앱으로 돌아와 버튼을 눌러보거나 슬라이더를 움직이면서 보드에 연결된 LED의 동작을 확인해 보면 된다.

NodeMCU의 경우 각 핀에 대해 별도의 설정이나 제어 코드가 하나도 없는데도 Blynk를 사용하는 것 만으로 쉽게 원격에서 제어가 가능해진다.

여기서는 단순히 LED를 연결했지만 LED 대신 릴레이를 연결해 주면 곧바로 가전제품을 원격제어 하는 식의 스마트 홈을 구축할 수 있게 된다. 아래의 경우 SSR(Solid State Relay)를 사용해 전원 스위치 역할을 하게 한 것이다.



(단 220V 교류를 제어하는건 최소한의 전기적인 기본 지식이 필요하다. 기본적인 지식도 없이 시도하다 보면 감전 및 화재등의 사고가 발생할 수 있으니 주의하기 바란다.)



2016년 3월 23일 수요일

NodeMCU와 Blynk를 사용한 IoT - (1) 환경 설정

Blynk를 사용해 IoT 시스템을 구축하는데 가장 쉽고 저렴하게 사용할 수 있는 것이 ESP8266이다. 다만 ESP8266 모듈을 그냥 사용하려면 약간의 추가 회로를 붙여줘야 하는데 그런거 신경 쓸 필요 없이 바로 사용할 수 있는 것이 NodeMCU 이다.

 

 Aliexpress에서 대략 개당 $4~5 정도에 구입할 수 있다. USB-to-Serial, 플래쉬 라이팅에 필요한 버튼들까지 다 들어있어 컴퓨터에 USB 케이블로 연결만 해 주면 바로 사용할 수 있다. 또한 핀헤더도 표준 2.54mm 간격이라 매우 편리하다.


다만 한가지 단점은 보드이 폭이 약간 넓어 일반적인 브레드보드에 꼽으면 점퍼선을 연결할 수가 없다.


그래서 쉽게 사용하기 위해 만능기판에 2열 핀헤더를 이용해 베이스 보드를 만들어 줬다.

ESP8266은 기본적으로 LUA 언어를 사용할 수 있도록 인터프리터가 들어있는데 그보다는 아두이노 IDE를 사용하는 것이 더 편리하고 다양한 라이브러리를 활용할 수 있어 유용하다.

먼저 아두이노(http://www.arduino.cc)를 다운받아 설치해 준다.  버젼 1.6.5를 추천한다.

 http://www.arduino.cc 로 접속해 상단 메뉴바의 'Download'를 선택한다.

 Download 화면에서 바로 다운로드 하지 말고 우측 하단에서 'previous version of the current release'를 클릭한다.

버젼 1.6.5를 다운받아 설치해 주면 된다.

바로 다운로드가 시작되지 않고 아두이노 지원을 부탁하는 화면이 나온다. 기부를 원하면 액수를 지정하고 'Contribute & Download'를 누르면 되고, 기부 없이 바로 다운로드 받으려면 'Just Download'를 선택하면 된다.


아두이노가 설치되면 esp8266을 위한 추가 패키지를 설치해 줘야만 한다.


먼저 아두이노를 실행한다.



상단의 메뉴바에서 '파일'->'환경설정'을 선택한다.


'Additional Boards Manager URLs' 필드에 'http://arduino.esp8266.com/stable/package_esp8266com_index.json'를 입력해 준다.


위와 같이 입력했으면 '확인' 버튼을 눌러준다.


만일 아두이노를 이전부터 사용하고 있어 'Additional Boards Manager URLs' 필드에 위와 같이 다른 주소가 들어있는 경우라면 기존의 주소 뒤에 콤마(,)를 넣고 주소를 추가해 주거나 아니면 오른쪽의 아이콘(위의 스크린샷에서 오른쪽의 아이콘)을 눌러준다.


그러면 새 창이 열리는데 여기에서 한 줄에 하나씩 주소를 넣어주고 '확인'을 눌러줘도 된다.

이제 URL 추가가 끝났으면 실제 보드 패키지를 설치해야 한다.


'도구'->'보드'->'Boards Manager...' 를 선택한다.


보드 매니져 창이 열리고 추가할 수 있는 보드 패키지 목록이 보인다.


아래쪽으로 스크롤 해 보면 esp8266 항목이 보인다. 이 항목을 선택하면 우측 하단에 'Install' 버튼이 생긴다. 이 버튼을 눌러주면 아두이노에서 사용하는 ESP8266 패키지가 설치된다.

버튼을 누르면 바로 설치가 진행되는데 약간의 시간이 걸린다. 설치가 끝나면 '닫기' 버튼을 눌러 Boards Manager를 닫아준다.


 이제 '도구'->'보드'를 보면 이전에는 보이지 않았던 ESP8266 모듈을 사용한 보드들 항목이 보이게 된다. 자신이 사용하고자 하는 보드를 선택해주면 된다. 여기서는 NodeMCU 0.9를 선택했다.


NodeMCU로 보드를 선택하고 '파일'->'예제'로 가서 아래쪽으로 내려가 보면 ESP8266 예제코드들을 볼 수 있다.

이제 실제로 동작을 확인하기 위해 프로그램을 입력해 본다.

먼저 아두이노에서 아래의 코드를 입력해 준다.

void setup()
{
  pinMode(1, OUTPUT);
}

void loop()
{
  digitalWrite(1, HIGH);
  delay(500);
  digitalWrite(1, LOW);
  delay(500);
}



위의 사진에서 표시된 부분이 1번 핀에 연결되어 있는 LED이다. 위의 코드가 실행되면 이 LED가 깜빡이게 된다.

이제 프로그램을 보드로 업로드 해 보겠다.








아두이노에서는 다른 보드와 동일하게 상단의 'Upload' 버튼을 눌러주면 된다.


다만 NodeMCU의 경우 아두이노 보드처럼 'Upload' 버튼만 누르면 되는게 아니고, 보드가 flash download 모드로 들어가도록 해 줘야만 한다. 위에 두개의 버튼이 있는데 먼저 '1'번 버튼을 누르고 있는 상태에서 '2'번 버튼을 눌렀다 뗀다. 그리고 '1'번 버튼을 떼 주면 된다. 


정상적으로 업로드가 진행되면 위와 같이 진행된다. 프로그램 업로드가 끝나면 LED가 반짝이게 된다.

* NodeMCU 보드를 컴퓨터에 연결했을 때 디바이스 드라이버를 찾지 못하면 구글에서 CH340G driver 로 검색해 드라이버를 설치해 주면 된다. 


NodeMCU와 Blynk를 사용한 IoT - (2) 튜토리얼 1