반응형

바로 이전 포스팅에서 ESP32 관련 개발환경 설정 글을 적은 김에 ESP8266에 대한 아두이노IDE 에서의 환경설정에 대해서 적어보려고 한다. 벌써 몇 년 전에 본 블로그의 사물인터넷 카테고리를 통해서 ESP8266 펌웨어를 업그레이드 하고 ESPlorer 라는 IDE 를 이용해서 Lua 언어로 개발하는 방법과 여러가지 예제들을 실행해 보았다. 이번에는 아두이노 IDE와 C언어를 이용해서 개발하는 환경을 만들어 보려고 한다. 결론적으로 말하자면 ESP32 환경설정과 아주 유사하다.

 

Amica 라는 이름의 ESP8266 개발보드이다. 

 

이 보드에 환경을 설정해 보겠다. 만약 PC에서 인식이 되지 않는다면 PC와의 통신을 위하여 CP2102 드라이버가 먼저 설치되어 있어야 한다. http://deneb21.tistory.com/590 글을 참고해서 드라이버를 설치한다. 만약 통신칩이 CP2102가 아니라면 각 칩 개발사의 홈페이지에서 드라이버를 다운로드 받아야 한다.

 

그리고 당연히 아두이노IDE가 설치되어 있어야 한다. arduino.cc 홈페이지에서 최신버전을 다운로드 받아서 설치해 준다. 현재 버전은 1.8.6 이다. 

 

파일->환경설정 을 클릭하면 위와 같은 창이 나온다. 화살표의 버튼을 클릭하면 개발환경을 설치할 수 있는 URL 입력창이 나온다.

 

맨 아랫줄에 다음의 URL을 입력한다. http://arduino.esp8266.com/stable/package_esp8266com_index.json 입력 후 확인 버튼을 눌러서 창을 모두 닫아준다.

 

툴->보드->보드매니저  에 들어가면 맨 아랫쪽에 ESP8266 보드 설치가 뜬다. '설치'를 클릭해서 설치해 준다. 

 

툴->보드 로 들어가서 자신의 제품에 맞는 ESP8266 모듈을 선택한다. 나의 경우엔 ESP-12E 모듈을 선택하니 잘 된다.

 

툴->포트 에서 PC와 연결된 COM 포트를 선택해 준다.

 

모든 설치가 끝났다. 

 

ESP8266 예제에 있는 Blink 예제를 업로드 하고 실행해 본다. Amica 모듈은 기본적으로 하나의 Built in LED를 가지고 있다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
  ESP8266 Blink by Simon Peter
  Blink the blue LED on the ESP-01 module
  This example code is in the public domain
 
  The blue LED on the ESP-01 module is connected to GPIO1
  (which is also the TXD pin; so we cannot use Serial.print() at the same time)
 
  Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}
 
// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}
cs

 

 

https://youtu.be/QC5KKhDo05Y

업로드 잘 되고 Built in LED도 잘 점등이 된다. 이제 ESPlorer와 Lua 언어가 아닌 아두이노 IDE를 통해서 C언어로도 개발이 가능하다.

반응형
반응형

지난 글 에서는 VITCON IoT MODLINK 의 블루투스 링크에 대해서 알아보았다. 기존 아두이노에서 블루투스 사용하는 방법과 별로 다르지 않아 쉽게 블루투스 기능을 이용할 수 있었다. 깔끔하게 플러그인 방식으로 링크를 베이스 보드에 끼우고 스마트폰으로 블루투스를 제어해 보았다. 이번에는 IoT의 핵심이라고 할 수 있는 WIFI Link 를 테스트 해 보려고 한다. VITCON 에서는 와이파이 링크를 위한 전용앱과 전용 IoT 서버도 제공을 한다고 하는데 이것들과 와이파이 링크가 어떻게 연결되고 동작하는지 알아보려고 한다.

 

먼저 와이파이 링크에 대해서 알아보도록 하자

 

와이파이 링크는 위와 같다. ESP8266 칩을 사용 했으며 CFG(Config Mode) / RUN 모드 전환을 위한 스위치와 Reset 스위치가 달려 있다. 

 

매뉴얼에서 발췌한 와이파이 링크의 구성요소이다. 

 

블루투스 링크와 마찬가지로 복잡한 전선의 연결 없이 베이스 보드(아두이노 우노)에 꼽아주면 된다.

 

그 다음 와이파이 링크가 공유기(인터넷)에 연결될 수 있도록 설정을 해 준다. 설정은 VITCON 전용 앱이 있으므로 스마트폰에 앱을 설치해서 간편하게 설정해 줄 수 있다. 

 

VITCON WIFI 로 검색하면 위와 같은 앱을 찾을 수 있으며 설치를 한다. 와이파이 링크 없이 바로 실행하면 에러가 난다. 와이파이 링크를 설정모드로 연결해야 한다.

 

와이파이 링크의 모드전환 스위치를 CFG 에 맞추고 PC에 연결해서 전원을 공급해 준다.

 

스마트폰의 와이파이 연결로 들어가면 와이파이 링크와 다이렉트로 연결되어 설정을 할 수 있도록 와이파이 링크의 AP가 뜬다. 이것을 연결한다. Vitcon_ESP12S 이다.

 

WIFI Connection Manager 앱을 실행한다. 실행하면 아래에 와이파이 리스트가 뜨는데 연결해준다.

 

집의 공유기인 iptime이 잡혔다. 비밀번호를 입력해서 인터넷에 연결해 준다.

 

IoT 서버와의 연결방법은 3가지를 지원하는데 일반적인 TCP 통신, MQTT 프로토콜, MODBUS 를 지원한다. 앱 화면에서 SET HOST 를 누르면 설정화면이 나온다. 위의 사진은 TCP 통신 설정 방법이다. 서버 도메인이나 IP와 포트를 입력하면 된다. 서버주소를 127.0.0.1 (모듈 자신의 IP) 로 설정하면 와이파이 링크는 통신 클라이언트가 아니라 서버로 동작하게 된다.

 

MQTT 서버 설정 화면이다. IoT 프로토콜 중에서 꽤 많이 쓰이고 범용적인 통신이므로 자신이 구축한 MQTT 서버나 그 이외 다양한 MQTT 지원 서버에 연결이 가능하다.

 

MODBUS 에 대해 매뉴얼에는 - Modbus모드는 Modbus RTU프로토콜을 사용하여 자사의 IoT 시스템을 이용하고자 할 때 필요한 설정으로, 자사 IoT서버에 맞게 작동하도록 프로그래밍 되어 있기 때문에 사용을 위해선 반드시 자사 TCP 서버에 연결되어야 합니다 - 라고 쓰여 있다. 그리고 Modbus RTU 프로토콜로 통신하는 어떠한 장비도 와이파이 링크와 직접 통신이 가능하다고 한다.

 

이상으로 와이파이 링크에 인터넷 연결을 설정하고 연결 프로토콜을 설정하는 방법을 알아보았다. 이제 이 중에서 TCP 모드로 연결을 해서 Simple Switch 라는 인터넷으로 릴레이 스위치를 제어할 수 있는 예제를 실행해 보려고 한다.

 

장비 및 프로젝트 등록을 위해서 빛컨의 IoT 지원 사이트인 http://iot.vitcon.co.kr 에 회원가입을 하고 로그인을 해 준다.

 

처음 보이는 리스트에서 '새 장비 추가' 버튼을 클릭해서 장비를 추가해 준다.

 

 

그러면 장비의 ID를 생성해 준다. 이 ID를 이용해서 나의 장비(와이파이 링크)와 빛컨의 서버와 연결을 해 주는 것이다.

 

와이파이 링크와 릴레이 링크의 연결은 매뉴얼에 따라 위와 같이 해 주었다. 

 

아두이노 IDE를 실행하고 스케치 -> 라이브러리 포함하기 -> 라이브러리 관리 로 들어가서 vitcon 으로 검색한 모습이다. VitconCommon 과 VitconIOT 를 설치해 준다.

 

예제 -> Vitcon IOT -> SimpleSwitch 예제를 불러온다.  스케치 중 Device ID 부분에 빛컨 IoT 사이트에서 장비 추가 시 생성된 장비 ID를 카피해서 넣어준다. 그리고 스케치를 업로드를 한다.

 

업로드를 하고 정상적으로 동작한다면 위와 같이 와이파이 링크에 연결 LED가 들어온다. 만약 잘 안된다면 WIFI Connection Manager 과정을 반복.

 

다시 빛컨 IoT 사이트로 돌아와서 접속상태를 본다. 접속상태가 녹색으로 바뀌어 있으면 사이트와 와이파이 링크와 연결이 된 것이다.

 

프로젝트 메뉴로 이동해서 프로젝트를 추가해 준다.

 

위와 같은 방식으로 이름을 입력하고 자주 쓰는 프로젝트에 대해서 미리 정의해 놓은 프로젝트 중에서 simple sw 를 선택해 준다.

 

장비 리스트로 돌아와보면 장비에 프로젝트가 부여된 것을 볼 수 있다.

 

장비 리스트에서 '보기' 버튼을 누르면 위와 같이 스위치 위젯이 하나 뜬다. 

 

https://youtu.be/UzREc-8Ffz4

위젯을 마우스로 클릭해 보니 인터넷을 통해 릴레이가 제어되는 것을 확인했다. 이 릴레이에 전원 제어를 원하는 전기제품을 붙이면 인터넷을 통해서 제어 할 수 있는 것이다.

 

제어는 인터넷 브라우저 뿐만 아니라 'Vitcon IoT Modlink' 라는 앱을 통해서도 제어가 가능하다고 한다. 

 

이상으로 빛컨(Vitcon) 의 모듈식 MCU, IoT 개발도구인 IoT Modlink 에 대해서 3편에 걸쳐서 알아보았다. 관련 매뉴얼과 커뮤니티(네이버 카페) 및 사이트도 잘 되어 있으니 심화학습이 필요한 경우 이용하면 되겠다. 1편의 서두에서 말 했듯이 간편하게 연결이 가능하고 블럭 조립하는 느낌으로 MCU에 대해서 학습하거나 개발을 할 수 있도록 만들어진 꽤 괜찮은 제품 같다. 특히 학습용으로 많이 이용되었으면 한다.

 

 

 

본 리뷰는 (주)빛컨으로부터 제품만을 제공받아 사용 후 작성한 리뷰입니다.

반응형
반응형

지난 글 (http://deneb21.tistory.com/550) 에서는 IoT-MODLINK 에 대해서 개괄적인 내용을 알아보았다. 지난 글 에서도 말했지만 내가 가지고 있는 무선관련 링크는 2개 인데 블루투스 링크와 와이파이 링크를 가지고 있다. 먼저 블루투스 링크를 연결하여 사용하는 방법에 대해서 알아보려고 한다. 다들 알다시피 블루투스 통신은 2.4Ghz 대역의 주파수로 통신을 하며 주로 10미터 이내의 근거리 통신에 이용 된다. 간혹 안테나 등을 개조해서 수 백 미터 거리의 통신을 하는 경우도 있기는 하지만... 아무튼 블루투스는 근거리 무선통신으로 각종 사물의 제어를 하는데 유용하다. 그리고 스마트폰과도 블루투스를 이용해서 쉽게 연결이 가능하므로 전용 앱을 이용하면 손 쉽게 사물의 제어가 가능하다. 이번 글에서는 스마트폰과 IoT-MODLINK (+블루투스 링크, LED 링크) 를 연결해서 어떻게 사물을 제어할 수 있는지 알아보려고 한다.

 


블루투스 링크이다. CSR BC417 (블루투스 V2.0) 칩을 이용했으며 Reset 스위치가 달려 있다.

 


매뉴얼에 나오는 블루투스 링크 구성도이다. 그냥 아두이노에 연결한다면 핀배열, 연결, 전원까지 신경을 써야 하겠지만 IoT-MODLINK 에서는 베이스 보드에 그냥 꼽으면 된다. 좋은 점이다.

 


위와 같은 위치에 링크를 꼽아 주었다. LED 링크는 D4, D5 핀을 이용하고 블루투스 링크는 D2, D3 핀을 이용 한다. 물론 링크는 자신이 원하는 곳에 꼽으면 된다.

 

예전에 썼던 블루투스 모듈 관련 글인 http://deneb21.tistory.com/267 를 참고하면 손쉽게 블루투스 링크의 설정이 가능하지만 다시 한 번 적어본다. 블루투스 기기는 각각의 고유한 이름과 접속을 위한 비밀번호를 가지고 있다. 이를 초기 상태에서 사용자가 원하는대로 설정할 필요성이 있다.

 

■블루투스 링크 설정 (AT Command)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <SoftwareSerial.h> //시리얼통신 라이브러리 호출
 
int blueTx=2;   //Tx (보내는핀 설정)at
int blueRx=3;   //Rx (받는핀 설정)
SoftwareSerial mySerial(blueTx, blueRx);  //시리얼 통신을 위한 객체선언
 
void setup() 
{
  Serial.begin(9600);   //시리얼모니터
  mySerial.begin(9600); //블루투스 시리얼
}
void loop()
{
  if (mySerial.available()) {       
    Serial.write(mySerial.read());  //블루투스측 내용을 시리얼모니터에 출력
  }
  if (Serial.available()) {         
    mySerial.write(Serial.read());  //시리얼 모니터 내용을 블루추스 측에 WRITE
  }
}
cs

위의 소스를 업로드 한다. 
업로드 후 시리얼 모니터를 연다.

 


전송칸에 AT 라고 입력하고 엔터를 누르면 시리얼 모니터에 OK 라고 나온다. 블루투스와 시리얼 모니터가 제대로 통신하고 있다는 뜻이다. 

 


블루투스 링크에 이름을 부여한다. AT+NAMEIOT-BTL 으로 했다. OKsetname 이라고 나오면서 이름이 정해졌다. AT+NAME 다음에 바로 세팅할 이름을 붙여 쓰면 된다. 즉, 이 블루투스 링크의 이름은 IOT-BTL 이 된다.

 


아무나 링크에 접속할 수 없도록 PIN (비밀번호)를 정해준다. NAME 세팅과 비슷하게 AT+PIN 뒤에 설정할 PIN을 적어주면 된다. 1234로 설정했다.

 

혹시 위의 설명이 이해가 안간다면 더 자세한 설명은 http://deneb21.tistory.com/267 에 있다.

 

이제 블루투스 링크에 새 이름도 생겼고 보안을 위한 비밀번호도 생겼다. 제어를 위한 어떠한 스케치도 없지만 한 번 무작정 스마트폰에서 연결을 해 본다. 설정한 이름과 핀으로 등록이 될 것이다. 블루투스 앱 이용을 위해서라도 한 번은 스마트폰에 블루투스 링크를 등록해 주어야 한다.

 

이제 스마트폰에 블루투스 앱을 설치해서 LED 링크의 LED를 블루투스 링크를 통해서 무선으로 ON/OFF 하는 예제를 하나 만들어 보려고 한다.

 

■ 스마트폰

스마트폰에서는 'Bluetooth Controller' 라는 앱을 설치했다. 이 앱이 아니라도 블루투스 링크로 문자열을 보낼 수 있는 어떠한 앱이라도 가능하다.

 

구글 플레이에서 위의 앱을 검색해서 설치했다. 버튼들의 이름과 속성값을 마음대로 설정할 수 있고 복잡하지 않아서 애용한다.

 

버튼들의 설정은 위와 같이 했다. 좌측은 보여지는 버튼의 이름이고 오른쪽은 눌렀을때 블루투스 링크로 전송하는 문자열이다.  이 문자열을 아두이노에서 받아서 LED를 제어한다.

 

설정이 완료된 버튼들의 모습이다. 말 그대로 LED 링크의 2개의 LED를 켜거나 끌 수 있도록 설정하였다.

 

 

■ 소스

소스는 간단하다. 스마트폰 블루투스 앱에서 블루투스 링크로 보내는 문자열을 판단하여 LED 링크의 LED1 또는 LED2를 켜거나 끄는 것이다. 간단한 예제이지만 이것을 기반으로 응용하면 전자제품 등의 제어도 쉽게 할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <SoftwareSerial.h> //시리얼 통신 라이브러리 호출
 
int blueTx=2;   //Tx (보내는핀 설정)
int blueRx=3;   //Rx (받는핀 설정)
SoftwareSerial mySerial(blueTx, blueRx);  //시리얼 통신을 위한 객체선언
String myString=""//받는 문자열
 
void setup() {
  Serial.begin(9600);   //시리얼모니터 
  mySerial.begin(9600); //블루투스 시리얼 개방
  pinMode(4, OUTPUT);  //D4을 OUTPUT으로 설정 (LED ON/OFF)
  pinMode(5, OUTPUT);  //D5을 OUTPUT으로 설정 (LED ON/OFF)
}
 
void loop() {
  while(mySerial.available())  //mySerial (블루투스 수신 문자열) 값이 있으면
  {
    char myChar = (char)mySerial.read();  //mySerial int형식의 값을 char형식으로 변환
    myString+=myChar;   //수신되는 문자열을 myString에 모두 붙임 (1바이트씩 전송되는 것을 모두 붙임)
    delay(5);           //수신 문자열 끊김 방지
  }
  
  if(!myString.equals(""))  //myString 값이 있다면
  {
    Serial.println("input value: "+myString); //시리얼모니터에 myString값 출력
      if(myString=="d4on") {
        digitalWrite(4, HIGH); //D4 LED ON
      } else if(myString=="d4off") {
        digitalWrite(4, LOW);  //D4 LED OFF
      } else if(myString=="d5on") {
        digitalWrite(5, HIGH);  //D5 LED ON
      } else if(myString=="d5off") {
        digitalWrite(5, LOW);  //D5 LED OFF
      } else {
        
      }            
    myString="";  //myString 변수값 초기화
  }
}
cs

 

 

https://youtu.be/FsBeO0OLGu0

결과 동영상이다. 스마트폰과 페어링이 되면 블루투스 링크의 LED가 깜빡이지 않게 되고 문자열 수신을 받을 수 있는 상태가 된다. 각 버튼을 누를때마다 LED 링크에 있는 2개의 LED가 켜지거나 꺼지는 것을 확인할 수 있다.

 

 

본 리뷰는 (주)빛컨으로부터 제품만을 제공받아 사용 후 작성한 리뷰입니다.

반응형
반응형

가끔 아두이노나 ESP8266 등을 이용해서 무언가를 만들고 있을때 드는 생각이 있다.  복잡한 케이블 연결 없이 좀 더 쉽고 빠르게 원하는 모듈끼리 센서끼리 연결할 수 있는 방법은 없을까? 하는 생각이다. 그렇게 되면 개발에 들어가는 시간을 아낄 수 있을 것이고 아낀 시간은 소프트웨어 개발에 더욱 집중할 수 있을것이기 때문이다. 우리나라 기업인 빛컨(VITCON)에서 이런 사람들을 위해 아두이노 기반의 조립형 개발보드인 IoT-Modlink 라는 제품을 내 놓았다. 아두이노 기반의 베이스 보드와 Link 로 칭하는 각종 모듈들을 조립식으로 구성해서 코딩교육에 이용하거나 개발을 간편하게 할 수 있도록 한 제품이다. 

 

이번글은 1편으로 IoT-Modlink 의 베이스 보드와 각 Link에 대해서 개괄적으로 알아보려고 한다. 다음편에서는 Base보드에 각각의 Link 들을 조합해서 기능들을 살펴볼 예정이다. 또한 빛컨에서 자체적으로 운영하는 IoT Service 에 연결도 해 보려고 한다.

 

포장 상자이다. 파란색 예쁜 상자에 흰색 V 자가 선명하다. 나는 이런 미니멀한 디자인이 좋다. ^^ 상자를 열어서 구성품들을 살펴본다.

 

베이스 보드에 PC USB 시리얼 연결을 위한 Upload Link 와 아두이노 우노와 호환되는 Uno Link가 꼽혀 있다. 당연한 얘기지만 아두이노 IDE를 사용해서 개발할 수 있다. Upload Link는 FT232 칩을 이용했으므로 드라이버를 설치해 주어야 한다. 각 Link를 꼽을 수 있는 단자들은 아두이노 우노의 단자들을 쪼개어 놓은 것이다. 물론 각 모듈별로 전원공급 및 SDA, SCL, MISO, MOSI... 등의 단자들은 공통적으로 사용할 수 있도록 구성이 되어 있다.

 

■ FT232 드라이버 다운로드

http://www.ftdichip.com/Drivers/VCP.htm 

또는 빛컨 자료실에서도 다운로드 받을 수 있다. 

http://www.vitconshop.com/board/?id=download

 

 

Uno Link는 ATMega328P 칩을 기반으로 한다. 일반적인 아두이노 우노와 같다. 아두이노 메가 이용자들을 위한 Mega Link 도 있다고 한다.

 

베이스 보드의 뒷면이다. 뒷면에도 핀 단자의 이름이 빼곡하고 친절하게 쓰여 있다.

 

베이스 보드에 직접 전원을 연결할 수 있는 5V 1A 어댑터와 PC와의 연결을 위한 USB 케이블이 동봉되어 있다. 따로 구입하지 않아도 되서 마음에 든다. ^^

 

인터넷 연결을 위한 WiFi Link 이다. 나에게도 친숙한 ESP8266 기반의 ESP-12S로 구성되어 있다.

 

WiFi Link 의 뒷 모습.

 

2채널의 Relay Link 이다. SSR(Solid State Relay) 2개가 달려 있으므로 두 개의 전원을 ON/OFF 할 수 있다.

 

5A 250VAC 용량이므로 가정용 전원으로 사용하는 일반적인 전기기구에 사용이 가능하다.

 

근거리에서 여러가지 사물을 무선으로 제어할 수 있는 Bluetooth Link 이다.

 

블루투스 링크의 뒷모습이다.

 

그 이외 Link 들이다. 좌측 상단에서 우측으로 가변저항 2개를 달아 놓은 Volume Link, ON/OFF 스위치 2개로 구성된 Select Link, Tact 스위치 2개로 구성된 Tact Link, LED 2개로 구성된 LED Link, 자신이 가진 센서나 부품 등을 만능기판식으로 부착해서 사용할 수 있는 Proto Link, 온도를 측정할 수 있는 NTC Link 로 구성이 되어 있다. 

 

내가 가진 IoT Modlink 패키지 구성품은 이상이다. 하지만 이외에도 많은 Link 들이 존재하므로 원하는 대로 구입해서 적용하면 깔끔하게 개발을 할 수 있을 것이다. 

 

iot_modlink_led.ino
다운로드

IoT Modlink를 첫 개시하는 기분으로 베이스 보드에 LED Link를 연결하고 아두이노 IDE에서 Blink 프로그램을 작성해서 업로드 해 보았다.

 

https://youtu.be/j8sbR2fXK4U

LED Link 의 LED가 깜빡이면서 잘 작동한다.

 

이 제품을 살펴보니 쉽게 모듈(Link)을 꼽아서 사용할 수 있어서 코딩 교육용으로 매우 좋을 것으로 생각된다. 실제로 아두이노 개발 시 듀폰 케이블이 10개가 넘어가면 좀 어지럽고 보기가 좋지 않고 헷갈리기 쉽다. 또한 빠른 개발을 원하는 임베디드 개발자 한테도 도움이 될 수 있는 유용한 보드 같다. 더군다나 홈페이지를 들어가보니 AVR 이외에도 다른 다양한 MCU 들에 대해서도 비슷한 성격의 보드 개발이 진행중이라고 하니 기대가 된다.

 

다음편에서는 좀 더 상세하게 IoT Modlink에 대해서 알아보려고 한다. IoT Modlink 관련 링크 및 자료를 소개하면서 이 글을 마친다.

 

 

 

본 리뷰는 (주)빛컨으로부터 제품만을 제공받아 사용 후 작성한 리뷰입니다.

반응형
반응형

ESP8266 에 손을 놓고 있다가 진짜 오랜만에 애용하던 무료 IoT 클라우드인 ThingSpeak.com 에 들어가 보았다. 홈페이지 상단에 How To Buy 라는 메뉴가 눈에 띤다. 유료화가 되었다. 물론 상업적 목적 이외의 경우에는 제한적인 조건으로 무료로 사용할 수 있도록 여지를 남겨 두었다. 아무튼 잘 사용하긴 했지만 조금 더 좋은 조건으로 무료로 사용할 수 있는 다른 IoT 클라우드 서비스를 찾아 보았다. 물론 이도 저도 싫으면 MQTT 같은 IoT 프로토콜 사용법을 익혀서 자신만의 IoT 클라우드 서버를 구축할 수도 있겠지만 돈이 든다. 그리고 본격적으로 IoT 에 뛰어들기 전에는 별로 필요성을 못 느낀다.


[https://thingspeak.com/prices]

ThingSpeak 의 무료 조건이다. 간단하게 하루 8200개 이하의 데이터만 저장이 가능하다고 생각하면 된다. 사실 생각해보면 테스트나 연구용으로 사용하기에는 특수한 경우를 제외하고는 그다지 나쁜 조건은 아닌 것 같다. 22초 간격으로 두 개의 디바이스(채널)가 공짜다. 물론 시간을 늘리면 디바이스를 더 추가할 수 있다. 그 반대의 경우도 마찬가지이다.



[https://ubidots.com/pricing]

ubidots 의 조건이다. 디바이스는 20개 이하로 지원되고 메시지는 60초 간격 업로드로 제한이 되어 있다. 업로드 시간은 좀 그렇지만 디바이스가 20개나 지원이 된다는 것이 좋은 점 같다. 그러므로 하루에 28800개의 데이터 저장이 가능하다. 이벤트 엔진을 통해서 SMS, Email, 텔레그램 등으로 메시징도 가능하다.


[ThingSpeak의 그래프]

데이터 저장소로서의 IoT 클라우드 역할도 있지만 두 서비스 모두 데이터를 비주얼화 해서 보여주는 기능이 있다. ThingSpeak 의 경우 데이터를 여러가지 형태의 그래프로 표현해서 보여줄 수 있고 수치해석 프로그램인 MATLAB 과의 연동도 가능하다.


[ubidots의 라이브 대시보드]

ubidots는 대시보드 서비스로 여러 데이터들의 상황을 한 눈에 볼 수 있는 서비스(Live Dashboards)를 제공한다.


이상 간단하게 두 IoT 클라우드 서비스의 무료 버전을 비교해 보았다. 장단점이 있으니 원하는 서비스를 이용하면 된다. 나의 개인적인 의견이지만 개인 연구/학습용, 취미용으로는 ThingSpeak.  좀 더 심화되거나 나중에 산업용으로 확장을 원한다면 ubidots가 더 좋아 보인다.



덧붙임) 이 서비스들 이외에도 괜찮은 IoT 클라우드 있으면 추천 바랍니다

반응형
반응형

유난히도 더웠던 여름이었다. 이제 내일부터는 기온이 떨어지면서 폭염이 사라진다고 한다. 나는 지난 8월4일 부터 현재까지 NodeMCU 펌웨어가 설치된 ESP8266 하드웨어에 온도센서인 LM35를 부착하여 1분에 한 번씩 방안의 온도를 측정하여 IoT 클라우드 서비스인 ThingSpeak.com 에 데이터를 업로드 하였다. 20일 정도 기록을 하였는데 3만개 정도의 데이터가 쌓였다. 그래서 그 데이터를 다운로드 받아서 분석해 보고자 한다. 의미 있는 작업인지 아닌지 모르겠지만 올해 여름이 역대급 폭염이었기 때문에 기록으로 남겨 두려고 한다. 일단 센서는 방안 창문 옆에 두었고 창문은 항상 열려있었고 그늘이기 때문에 아마도 기록된 온도는 바깥의 온도보다는 1~2도 정도는 낮게 측정이 되었을 것이다.


우선 ThingSpeak.com 에 접속해서 나의 채널로 이동한 다음 Data Import/Export 탭에서 Download 버튼을 눌러서 지금까지 업로드된 데이터를 다운로드 받아야 한다. 데이터는 XML, JSON, CSV 형식으로 받을 수 있는데 엑셀에서 열기 위해 CSV 형식으로 데이터를 받았다.


▶ 다운로드 받은 데이터 파일

feeds.csv



엑셀 (정확히는 리브레 오피스의 스프레드 시트)로 CSV 파일을 열어 보았다. 위와 같이 엑셀과 비슷하게 열린다. 함수도 호환이 되어서 MAX, MIN, AVERAGE 함수를 이용해서 최고기온, 최저기온, 평균온도를 표시해 보았다. 평균온도가 30도에 육박하니 정말 덥긴 더웠다보다. 참고로 측정일자는 UTC 기준이다. 그러므로 우리나라의 시간으로 고치려면 +9 시간을 해야 한다.


날짜 별로 가장 더웠던 날은 위에 주황색으로 표시한 35도로 측정된 날짜이다. 각각 UTC+9 를 하면 8월5일 13시 35분, 8월 6일 14시 21분, 8월 11일 14시경이 가장 높았던 온도로 기록 되었다. 하지만 그 밑으로 34도 짜리 기록이 엄청나게 많았다. 34 이상의 기록을 살펴보면 역시나 13시 ~ 15시 사이에 측정된 기록이 대부분 이어서 역시 상식과 같이 하루 중 가장 더운 시간은 오후 13시~15시로 생각이 된다. 

 

이번에는 가장 낮았던 기록을 찾아 보았다. 가장 낮았던 기록은 24.7도로 8월 12일 3시 40분 ~ 5시경, 그리고 8월 15일 6시경이다. 그러고보니 하루 이틀 정도는 새벽에 좀 시원했던 기억이 있긴하다.


이렇듯 데이터를 IoT 클라우드에 올려 놓으니 이렇게 분석도 할 수 있고 좋은 것 같다. 물론 이런 데이터를 이용한다면 아래와 같이 그래프를 그릴 수도 있을 것이다. 이 그래프는 ThingSpeak 위젯앱인 'IoT ThingSpeak Monitor Widget' 을 이용해서 그렸다.



내년 여름은 안 더웠으면 좋겠다.

반응형
반응형

NodeMCU 펌웨어에는 많은 모듈들이 포함되어 있다. 하지만 사용하지 않을 모듈을 포함하는 것은 용량상으로나 기능적으로 낭비가 아닐 수 없다. 이럴 경우 사용을 원하는 모듈만 포함시켜서 펌웨어를 생성할 수 있는 사이트가 있어서 소개한다. 바로 NodeMCU Build 라는 사이트 이다.  NodeMCU 모듈에 대한 설명은 NodeMCU Documentation 사이트인https://nodemcu.readthedocs.io/en/dev/ 사이트에서 볼 수 있다.




NodeMCU Custom Build 사이트 

https://nodemcu-build.com



https://nodemcu-build.com 사이트로 이동하면... 


이메일로 빌드된 펌웨어 링크를 보내주므로 이메일을 적어준다. 확인을 위해서 두 번 적어준다.


master 와 dev 중에 빌드 브랜치를 고를 수 있다. 특이사항이 없다면 master를 선택해 준다.


여기가 중요하다. 포함하기를 원하는 모듈을 고를 수 있다. 필요한 모듈을 모두 체크해 준다. 가장 기본적인 모듈은 미리 체크가 되어 있으므로 웬만하면 포함하도록 하자


SSL 지원기능을 사용하는지? 디버그 모드를 ON 할 것인지 선택한다.


모든 사항을 입력했으면 맨 아래의 Start your build 를 클릭한다.


위의 화면이 나오면 펌웨어의 빌드가 시작된 것이다. 이제 메일이 오기를 기다리면 된다. 경우에 따라 다르겠지만 나 같은 경우는 메일이 오는데 10분 정도 걸린 것 같다. 네이버 메일 등을 이용할 경우 스팸메일함에 들어가 있을 확율이 높으므로 스팸메일함도 확인을 해 보자


위와 같이 빌드 시작되었다는 메일과 약 2분 후 빌드가 완료 되었다는 메일이 도착했다.


빌드완료 메일을 클릭하면 위와 같이 빌드가 완료된 펌웨어를 다운로드 받을 수 있는 링크를 보내준다. float, integer 버전 중 원하는 것을 다운로드 받아서 ESP8266 하드웨어에 펌웨어를 올리면 된다.


다운로드 받은 펌웨어를 하드웨어에 올리는 방법 및 Esplorer 개발환경 설치에 대해서는 아래의 링크를 참고하면 된다.

ESP8266 기반 NodeMCU 개발보드에 개발환경 설치

http://deneb21.tistory.com/399


반응형
반응형

NodeMCU 에서도 서보 모터를 제어할 수 있다. 바로 PWM (Pulse Width Modulation, 펄스 폭 변조) 신호를 이용해서 제어가 가능한데 NodeMCU 에서는 pwm 이라는 모듈을 기본으로 제공하고 있기 때문에 이를 이용해서 서보를 제어할 수 있다. 응용한다면 인터넷으로 열고 닫을 수 있는 도어락 같은 것을 만들 수도 있을 것이다. 


PWM 은 간단하게 설명하자면 5V 와 0V 의 신호가 번갈아 반복되는 것인데 이것의 반복되는 사이클을 조절해서 신호를 주는 것이다.


이미지 : https://www.arduino.cc/en/Tutorial/PWM

위의 그래프와 같이 5V 와 0V 가 반복 되는 시간을 변환해서 서보에 신호를 전달하는 것이다.


PWM에 대해서 좀 더 자세한 설명은 아래의 링크를 참고하면 된다.


제어할 모터는 가장 대중적으로 많이 사용되는 SG90 서보 모터를 NodeMCU 펌웨어가 올라간 ESP8266 보드에 연결해서 제어해 보았다.


SG90 서보의 모습이다. 갈색, 빨간색, 노란색의 3가닥의 연결선이 있으며 갈색은 GND, 빨간색은 5V, 노란색은 PWM 신호를 받는 선이다.  


아래와 같이 ESP8266 과 연결하였다. 

 ESP8266

 SG90 (Servo)

 GND

 Brown

 5V

 Red

 D4

 Yellow


내가 연결한 ESP8266 개발 보드인 Wemos D1 mini 보드에는 5V 출력이 있어서 거기에 서보를 연결하면 되지만 3.3V 출력 밖에 없는 보드도 있다. 테스트 삼아 3.3V 에 연결해 보았는데 별 차이 없이 동작하긴 했지만 4.8V 이상에서 동작하는 SG90의 특성 상 5V에 연결해 주는 것이 좋다. 이럴 경우 외부전원(5V)을 서보에 연결해주고 외부전원의 마이너스를 ESP8266의 GND와 서보의 GND에 같이 연결해 주어서 전원을 보강해 주는 것이 좋다.


■ 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
local pin4 = 4
 
-- set pin index 1 as pwm output, frequency is 50Hz, 
print("0")
pwm.setup(pin4, 501024*0.075)
 
-- Position 0
-- 20ms cycle, High duration is 20ms * 7.5= 1.5ms
print("1")
pwm.setduty(pin4, 1024*0.075)
pwm.start(pin4)
tmr.delay(5000000)
pwm.stop(pin4)
 
-- Posigion 90
-- 20ms cycle, High duration is 20ms * 10= 2.0ms
print("2")
pwm.setduty(pin4, 1024*0.1)
pwm.start(pin4)
tmr.delay(5000000)
pwm.stop(pin4)
 
-- Posigion -90
-- 20ms cycle, High duration is 20ms * 5= 1.0ms
print("3")
pwm.setduty(pin4, 1024*0.05)
pwm.start(pin4)
tmr.delay(5000000)
pwm.stop(pin4)
 
-- Position 0
-- 20ms cycle, High duration is 20ms * 7.5= 1.5ms
print("4")
pwm.setduty(pin4, 1024*0.075)
pwm.start(pin4)
tmr.delay(5000000)
pwm.stop(pin4)
 
cs


소스는 NodeMCU 의 pwm 모듈을 이용해서 동작한다. high 상태의 duration 을 이용해서 서보를 제어한다. 아래의 SG90 pdf 문서를 보면 pwm 신호를 어떻게 주면 서보의 움직이는 각도를 조절할 수 있는지 알 수 있을 것이다.

SG90Servo.pdf



NodeMCU PWM 모듈에 대해서는 아래의 링크를 참고하면 된다.


https://nodemcu.readthedocs.io/en/dev/en/modules/pwm/




반응형
반응형

아두이노나 ESP8266 관련 프로그래밍을 하다가 보면 가끔 현재 시간 정보가 필요한 경우가 있다. 이럴 경우 쉽게 사용할 수 있는 방법은 예전에 소개한 바 있는 RTC 모듈(Real Time Clock)이라는 장치를 이용하는 것이다. 하지만 장치가 인터넷에 연결되어 있다면 RTC가 필요 없다. 간단하게 현재의 시각을 알 수 있는 방법이 따로 있기 때문이다. 바로 웹서버에 요청(Request)해서 응답(Response)이 오는 HTTP 헤더 정보에 바로 Date, Time 정보가 있는 것이다. 이 정보를 파싱해서 자신의 코드에 삽입해서 이용하면 된다. 


 

그럼 HTTP 헤더란? 


우리가 사용하는 인터넷은 HTTP (Hyper Text Transfer Protocol) 라는 규약(프로토콜)을 이용해서 서버와 브라우저간에 통신을 하게 되고 정보를 교환하게 되는데 이 때 서버에서 브라우저 쪽으로 덧붙여서 보내주는 정보라고 보면 된다. 이 정보 안에는 Date/Time 정보가 있어서 이 것을 이용하면 현재의 시간을 구할 수 있는 것이다. 실제로 구글 크롬에서 F12 버튼을 누르면 HTTP 헤더 정보를 볼 수 있다.


Chrome 에서 F12 를 눌러서 개발자 도구에서 HTTP 헤더를 보는 모습


ESP8266 을 이용해서 서버에 빈(Empty) 요청을 날리면 위와 같이 웹서버에서 Date 라는 Name 으로 날짜, 시간 정보를 준다. 기준은 그리니치 표준시 기준인 GMT 기준으로 제공하기 때문에 우리나라 시간으로 변환을 원한다면 GMT+9시간을 해야한다.


■ 소스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-- retrieve the current time from Google
 
function queryTime()
  conn=net.createConnection(net.TCP, 0
 
  conn:on("connection",function(conn, payload)
    conn:send("HEAD / HTTP/1.1\r\n".. 
               "Host: google.com\r\n"..
               "Accept: */*\r\n"..
               "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)"..
               "\r\n\r\n"
                end)
            
  conn:on("receive", function(conn, payload)
    print('Retrieved in '..((tmr.now()-t)/1000)..' milliseconds.')
    print('Google says it is '..string.sub(payload,string.find(payload,"Date: ")
           +6,string.find(payload,"Date: ")+35))
    conn:close()
    end
  t = tmr.now()    
  conn:connect(80,'google.com')
end
 
tmr.alarm(010 * 10001, function() queryTime() end )
 
print("Queries every 10 sec the time from Google server")
print("Stop this by tmr.stop(0)")
cs


소스는 간단하다. google.com 으로 요청을 날리고 응답받은 HTTP 헤더 정보인 payload 에서 Date 부분을 추출해서 표시해주는 소스이다. 여기서는 google 에 요청했지만 다른 웹서버 URL 을 사용해도 상관이 없다.

 

 

실행결과는 위와 같다. 10초 마다 google 서버의 시간을 받아와서 print 해 주고 있다.


이 정보는 HTTP 헤더 정보인 payload 변수에 담겨져 있는 내용인데 payload 정보도 print 해 보았다. 위와 같이 payload 의 마지막 부분에 Date 가 있는 것을 알 수 있다.


소스에 GMT+9 를 하고 적절한 디스플레이를 연결하면 정확한 시간을 보여줄 수 있는 인터넷 시계도 만들 수 있을 것 같다.

반응형
반응형

'NodeMCU Lua 사용해보기 #12 - 인터넷을 통한 릴레이 제어 #1' 글에서는 어떻게 인터넷을 통해서 릴레이(Relay)를 제어할 수 있는지 알아보았다. 그런데 사용을 하다보면 원격지에서 어떤 릴레이가 현재 ON 상태이고 OFF 상태인지 알 수 있는 방법이 없다. 만약 릴레이에 선풍기를 연결해 두었으면 현재 꺼진 상태인지 켜진 상태인지 알 수가 없는 것이다. 그래서 이번에는 NodeMCU 의 gpio 모듈을 이용해서 현재 릴레이의 상태를 알 수 있도록 소스를 수정해서 개선해 보았다. 이전 글에서 모든 연결과 조건은 동일하며 internet_relay.lua 의 소스만 수정하면 된다.

 

■ NodeMCU gpio Module Documentation

https://nodemcu.readthedocs.io/en/dev/en/modules/gpio/

 

위의 NodeMCU Documentation 사이트에 들어가면 gpio 모듈에 대한 설명이 나온다. 이 중에서 gpio.read() 를 이용해서 현재 릴레이의 상태를 알 수 있다.

 

위의 사이트에 들어가면 나오는 gpio.read() 의 사용설명이다. gpio.read(핀번호) 로 현재 해당 gpio 단자의 상태를 알 수 있다. 0 이면 Low, 1 이면 High 의 상태인 것이다. 릴레이에서는 High가 OFF, Low 가 ON 상태 이므로 릴레이 제어에 사용하는 4개의 gpio 핀의 상태를 읽어서 HTML 에서 출력해 주도록 internet_relay.lua 소스를 수정하면 될 것이다. 

 

■ 소스

인터넷 연결을 위한 credentials.lua 와 init.lua 의 소스는 이전 1편의 글과 동일하다.  internet_relay.lua 소스만 수정이 되었다. 그래도 모든 소스를 다시 올려 본다.

 

credentials.lua

1
2
3
4
-- WiFi Connect information
SSID = "WiFi Name(SSID)"
PASSWORD = "WiFi Password"
 
cs

 

init.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-- http://deneb21.tistory.com/
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("WiFi Connected...")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        --dofile("webserver.lua")
        dofile("internet_relay.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs

 

internet_relay.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
--http://deneb21.tistory.com/
--Configure relay ouutput pins, pins are floating and relay opto needs ground to be activated. So pins are kept high on startup.
Relay1 = 1
Relay2 = 2
Relay3 = 3
Relay4 = 4
 
gpio.mode(Relay1, gpio.OUTPUT)
gpio.write(Relay1, gpio.HIGH);
gpio.mode(Relay2, gpio.OUTPUT)
gpio.write(Relay2, gpio.HIGH);
gpio.mode(Relay3, gpio.OUTPUT)
gpio.write(Relay3, gpio.HIGH);
gpio.mode(Relay4, gpio.OUTPUT)
gpio.write(Relay4, gpio.HIGH);
 
print("internet relay standby...")
 
--Create server and send html data, process request from html for relay on/off.
srv=net.createServer(net.TCP)
srv:listen(8080,function(conn) --change port number if required. Provides flexibility when controlling through internet.
    conn:on("receive", function(client,request)
        local html_buffer = "";
        local html_buffer1 = "";
        local html_buffer2 = "";
        local gpio1, gpio2, gpio3, gpio4
        
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local _GET = {}
        if (vars ~= nil)then
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*"do
                _GET[k] = v
            end
        end
 
        html_buffer = html_buffer.."<html><head><meta http-equiv=\"Content-Language\" content=\"en-us\"><meta http-equiv=\"Content-Type\" content=\"text/html;\">";
        html_buffer = html_buffer.."</head><body><font size=5>Internet Relay1 Control (NodeMCU/Lua, ESP8266)</font></br>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON1\"><button style=\"width:300\">Relay1 ON</button></a><a href=\"?pin=OFF1\"><button style=\"width:300\">Relay1 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON2\"><button style=\"width:300\">Relay2 ON</button></a><a href=\"?pin=OFF2\"><button style=\"width:300\">Relay2 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON3\"><button style=\"width:300\">Relay3 ON</button></a><a href=\"?pin=OFF3\"><button style=\"width:300\">Relay3 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON4\"><button style=\"width:300\">Relay4 ON</button></a><a href=\"?pin=OFF4\"><button style=\"width:300\">Relay4 OFF</button></a><br/>";
    
    
        local _on,_off = "",""
        if(_GET.pin == "ON1")then
              gpio.write(Relay1, gpio.LOW);
        elseif(_GET.pin == "OFF1")then
              gpio.write(Relay1, gpio.HIGH);
        elseif(_GET.pin == "ON2")then
              gpio.write(Relay2, gpio.LOW);
        elseif(_GET.pin == "OFF2")then
              gpio.write(Relay2, gpio.HIGH);
        elseif(_GET.pin == "ON3")then
              gpio.write(Relay3, gpio.LOW);
        elseif(_GET.pin == "OFF3")then
              gpio.write(Relay3, gpio.HIGH);
        elseif(_GET.pin == "ON4")then
              gpio.write(Relay4, gpio.LOW);
        elseif(_GET.pin == "OFF4")then
              gpio.write(Relay4, gpio.HIGH);                            
        end
 
        -- Relay Status Read
        if(gpio.read(1)==0) then gpio1 = "ON" else gpio1 = "OFF" end
        if(gpio.read(2)==0) then gpio2 = "ON" else gpio2 = "OFF" end
        if(gpio.read(3)==0) then gpio3 = "ON" else gpio3 = "OFF" end
        if(gpio.read(4)==0) then gpio4 = "ON" else gpio4 = "OFF" end
 
        -- Relay Status print
        print("gpio1:"..gpio1)
        print("gpio2:"..gpio2)
        print("gpio3:"..gpio3)
        print("gpio4:"..gpio4)
 
        -- Relay Status print html
        html_buffer2 = html_buffer2.."<br/>Relay1 : "..gpio1;
        html_buffer2 = html_buffer2.."<br/>Relay2 : "..gpio2;
        html_buffer2 = html_buffer2.."<br/>Relay3 : "..gpio3;
        html_buffer2 = html_buffer2.."<br/>Relay4 : "..gpio4;
        html_buffer2 = html_buffer2.."</body></html>";
        
        --Buffer is sent in smaller chunks as due to limited memory ESP8266 cannot handle more than 1460 bytes of data.
        client:send(html_buffer);
        client:send(html_buffer1);
        client:send(html_buffer2);        
        client:close();
        collectgarbage();
    end)
end)
 
cs

 

internet_relay.lua 소스를 보면 65행 에서부터 gpio.read() 모듈을 사용해서 해당 릴레이의 상태값을 얻어온다. 얻어온 값 (0 은 ON, 1 은 OFF) 에 따라 'ON' 또는 'OFF' 문자열을 할당한다. 그리고 html_buffer2 에 릴레이 상태 표시를 위한 HTML 을 만들어 준다. 기존의 html_buffer 와 html_buffer1 에 html_buffer2 를 붙여서 클라이언트(브라우저) 요청 시 HTML 을 출력해 준다.

 

 

https://youtu.be/oa-s8caFprI 

동작 화면을 캡처해 보았다. 릴레이가 동작하는 장면도 같이 찍고 싶었지만 손이 3개면 가능하겠는데 2개라 찍지 못했다. 아무튼 잘 작동한다. 브라우저를 닫았다가 다시 열어도 잘 작동한다.

 

이것을 조금 더 발전시킨다면 인터넷으로 켜고 끌 수 있는 멀티콘센트도 충분히 만들 수 있을 것 같다. 물론 샤오미를 비롯해서 이미 많은 기업에서 Smart Plug 또는 WiFi Plug 라는 이름으로 이미 나와 있지만 말이다.

 

Xiaomi Smart Plug

 

 

 

▶추가사항(2016.09.30) : 위의 소스를 작성하면서 참고한 소스와 사이트를 정리해 본다.

http://www.instructables.com/id/WiFi-Internet-Controlled-Relays-using-ESP8266-Quic/

http://robokits.co.in/download/init.zip

init.zip
다운로드

반응형
반응형

이번에는 NodeMCU, Lua, ESP8266 (Amica Board) 를 가지고 인터넷을 통하여 릴레이(Relay) 를 제어해 보려고 한다. 릴레이에 대해서는 이 블로그에서 많이 다루었지만 인터넷으로 릴레이를 제어하는 것은 처음인 듯 하다. 릴레이를 인터넷을 통하여 제어할 수 있다는 의미는 세계 어디서든 인터넷에만 연결되어 있으면 집안 또는 원격지의 전기, 전자기구 들을 제어할 수 있다는 말과 같다. 활용하기에 따라 요즘 IoT 광고에 나오는 기능들을 충분히 DIY로 구현해 볼 수 있다고 생각한다.


릴레이는 예전에 테스트 해 보았던 4채널 릴레이 모듈을 이용했다. 4개의 릴레이가 붙어 있어서 4개의 전원을 ON/OFF 할 수 있다. VCC, GND 와 제어를 위한 IN1 ~ IN4 단자가 달려 있다.


ESP8266 보드는 이제껏 계속 사용해 왔던 위와 같은 Amica 라는 이름의 ESP8266 개발보드를 이용했다. 펌웨어는 'NodeMCU_float_0.9.6-dev_20150704' 버전을 이용했다. 


그런데 문제가 발생했다. 위의 개발보드의 단자를 보면 3.3V 출력 밖에 없다. 하지만 릴레이 모듈은 5V 에서 동작한다. 외부전원을 사용해 볼까? 생각하다가 그냥 보드의 3.3V 에 연결해서 테스트해 보기로 했다. 연결해보니 정상적으로 동작하긴 한다. 그러나 5V 로 동작할 때 보다 뭔가 릴레이의 접점이 붙는 소리가 힘이 없다. 테스트용으로는 상관이 없겠지만 신뢰성 있는 장치를 만들 경우에는 릴레이에 정격의 전압을 반드시 사용해야 할 듯 하다.


 ESP8266

 Relay (4 Channel)

 3.3V

 VCC

 GND

 GND

 D1

 IN1

 D2

 IN2

 D3

 IN3

 D4

 IN4


연결은 위의 표와 같이 해 주었다.


■ 소스

internet_relay.lua 소스는 http://www.robokits.co.in 의 소스를 참고하여 수정하였다. 원래는 2채널용 소스였고 잡다한 HTML 태그가 달려 있었는데 정리해 주고, 인터넷 연결 부분의 소스를 분리해 주었다.


credentials.lua

1
2
3
-- WiFi Connect information
SSID = "와이파이 이름"
PASSWORD = "와이파이 패스워드"
cs


init.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("WiFi Connected...")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        --dofile("webserver.lua")
        dofile("internet_relay.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs


internet_relay.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
--Configure relay ouutput pins, pins are floating and relay opto needs ground to be activated. So pins are kept high on startup.
Relay1 = 1
Relay2 = 2
Relay3 = 3
Relay4 = 4
 
gpio.mode(Relay1, gpio.OUTPUT)
gpio.write(Relay1, gpio.HIGH);
gpio.mode(Relay2, gpio.OUTPUT)
gpio.write(Relay2, gpio.HIGH);
gpio.mode(Relay3, gpio.OUTPUT)
gpio.write(Relay3, gpio.HIGH);
gpio.mode(Relay4, gpio.OUTPUT)
gpio.write(Relay4, gpio.HIGH);
 
--Create server and send html data, process request from html for relay on/off.
srv=net.createServer(net.TCP)
srv:listen(8080,function(conn) --change port number if required. Provides flexibility when controlling through internet.
    conn:on("receive", function(client,request)
        local html_buffer = "";
        local html_buffer1 = "";
        
        
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local _GET = {}
        if (vars ~= nil)then
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*"do
                _GET[k] = v
            end
        end
 
        html_buffer = html_buffer.."<html><head><meta http-equiv=\"Content-Language\" content=\"en-us\"><meta http-equiv=\"Content-Type\" content=\"text/html;\">";
        html_buffer = html_buffer.."</head><body><font size=5>Internet Relay Control (NodeMCU/Lua, ESP8266)</font></br>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON1\"><button style=\"width:300\">Relay1 ON</button></a><a href=\"?pin=OFF1\"><button style=\"width:300\">Relay1 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON2\"><button style=\"width:300\">Relay2 ON</button></a><a href=\"?pin=OFF2\"><button style=\"width:300\">Relay2 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON3\"><button style=\"width:300\">Relay3 ON</button></a><a href=\"?pin=OFF3\"><button style=\"width:300\">Relay3 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."<a href=\"?pin=ON4\"><button style=\"width:300\">Relay4 ON</button></a><a href=\"?pin=OFF4\"><button style=\"width:300\">Relay4 OFF</button></a><br/>";
        html_buffer1 = html_buffer1.."</body></html>";
    
    
        local _on,_off = "",""
        if(_GET.pin == "ON1")then
              gpio.write(Relay1, gpio.LOW);
        elseif(_GET.pin == "OFF1")then
              gpio.write(Relay1, gpio.HIGH);
        elseif(_GET.pin == "ON2")then
              gpio.write(Relay2, gpio.LOW);
        elseif(_GET.pin == "OFF2")then
              gpio.write(Relay2, gpio.HIGH);
        elseif(_GET.pin == "ON3")then
              gpio.write(Relay3, gpio.LOW);
        elseif(_GET.pin == "OFF3")then
              gpio.write(Relay3, gpio.HIGH);
        elseif(_GET.pin == "ON4")then
              gpio.write(Relay4, gpio.LOW);
        elseif(_GET.pin == "OFF4")then
              gpio.write(Relay4, gpio.HIGH);                            
        end
        --Buffer is sent in smaller chunks as due to limited memory ESP8266 cannot handle more than 1460 bytes of data.
        client:send(html_buffer);
        client:send(html_buffer1);
        client:close();
        collectgarbage();
    end)
end)
 
cs


internet_relay.lua 소스를 보면 ESP8266 이 웹서버로 동작한다. 8080 포트로 클라이언트의 요청을 기다리고 있다가 클라이언트(브라우저)의 요청이 있을 경우 html_buffer 의 내용을 브라우저로 보내준다. HTML 의 내용에는 각 릴레이에 해당되는 버튼에 링크태그를 걸어서 버튼 클릭 시 pin 이라는 name 으로 릴레이의 ON/OFF value 를 보내준다. 이 값을 가지고 if 문을 이용하여 각각의 릴레이를 ON/OFF 하도록 제어하는 것이다.




위의 소스를 보드에 업로드 하고 브라우저에서 ESP8266에 할당된 IP + 설정한 포트번호를 치고 들어가면 위와 같이 버튼 8개가 나열된다. 각 버튼 클릭 시 릴레이 1 ~ 4 가 제대로 제어가 됨을 확인 하였다.



물론 위와 같이 공유기의 내부IP를 이용한 접속은 말 그대로 내부IP(사설IP)이기 때문에 집에서 밖에 콘트롤 할 수 없으며 별 의미가 없다.  이럴 경우는 공유기의 DDNS, 포트포워딩 설정을 이용하면 외부에서도 접근이 가능하다. 이에 대해서는 예전 글 "외부에서 NodeMCU 웹서버 접속하기" 를 참고하면 된다.



▶추가사항 (2016.07.29) : http://deneb21.tistory.com/427 에 조금 더 업그레이드 된 소스를 올려 놓았다. (릴레이 현재상태를 알 수 있도록 함.)

반응형
반응형

NodeMCU Lua 사용해보기 지난 10편에서는 ThingSpeak 에 ESP8266 보드를 이용해서 DHT11 의 데이터를 업로드 해 보았다.  이번에는 비슷한 서비스인 dweet.io 라는 IoT 클라우드 서비스를 이용해 보려고 한다. ThingSpeak 는 회원가입이 필요 했는데 dweet 은 회원가입이 필요 없고 Things 의 이름을 Key 로 사용한다. 고유한 이름으로 Thing 의 이름을 지정해주고 자신의 IoT 데이터를 업로드 하면 되는 것이다.


dweet.io 사이트에서 어떠한 오퍼레이션 없이 유니크한 Thing Name 을 가지고 dweet 으로 데이터를 보내면 dweet.io 에서 데이터를 받아서 저장하기 때문에 바로 데이터 업로드를 위한 하드웨어 및 소스를 준비하면 된다.  ESP8266 보드인 Amica 에 DHT11 온습도 센서를 아래와 같이 연결을 하였다.


 ESP8266 (Amica Board)

 DHT11

 D5

 Signal

 3.3V

 VCC (+)

 GND

 GND


■ 소스


credentials.lua

1
2
3
4
-- WiFi Connect information
SSID = "Your WiFi SSID"
PASSWORD = "Your WiFi Password"
 
cs


init.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("WiFi Connected...")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        --dofile("webserver.lua")
        dofile("dht11_dweet.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs


dht11_dweet.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
DHT_PIN = 5 -- defined by DHT shield (D5)
HOST    = "dweet.io"
THING_NAME   = "Your Thing Name"
 
function read_DHT()
  status,temp,humi,temp_decimial,humi_decimial = dht.read(DHT_PIN)
  if( status == dht.OK ) then
    print("DHT Temperature = "..temp.." grdC  ".."Humidity = "..humi.." %")
  elseif( status == dht.ERROR_CHECKSUM ) then
    print"DHT Checksum error." );
  elseif( status == dht.ERROR_TIMEOUT ) then
    print"DHT Time out." );
  end
end
 
function dweet()
  read_DHT()
  conn=net.createConnection(net.TCP,0
  conn:on("receive", function(conn, pl) print("response: ",pl) end)
  conn:on("connection", function(conn, payload) 
          print("connected"
          conn:send("POST /dweet/for/"..THING_NAME.."?"
          .. "temp=" .. temp 
          .. "&humi=" .. humi 
          .. " HTTP/1.1\r\n"
          .. "Host: " .. HOST .. "\r\n"
          .. "Connection: close\r\n"
          .. "Accept: */*\r\n\r\n"end)
  conn:on("disconnection", function(conn, payload)
          print("disconnected"end)
  conn:connect(80, HOST)
end
 
dweet()
 
-- dweets every 60 sec.
tmr.alarm(010 * 10001, function() dweet() end )
 
print("Dweets every 60 sec DHT11 data to dweet.io")
print("Stop this by tmr.stop(0)")
cs


credentials.lua 와 init.lua 에서 ESP8266 보드를 와이파이에 연결시키고 dht11_dweet.lua 에서 dweet.io 로 DHT11의 온습도 데이터를 업로드 한다. 위의 3가지 lua 파일을 ESP8266 보드에 업로드 하고 실행하면 되는 것이다. dweet.io 사이트에서는 아무것도 설정해 주지 않아도 된다. 다만 위의 소스에서 THING_NAME 의 값은 유니트한 값이어야 한다.


ESPlorer 에서 위와 같이 데이터를 업로드하고 실행하면 dweet.io 에서 데이터가 잘 전송되었다는 리턴값을 보내 준다.


소스를 수정 후 업데이트 할 경우에는 위에 사용된 타이머 0번을 Stop 시키고 업로드 해야 한다. tmr.stop(0) 명령어를 이용해서 타이머를 멈추고 업로드 하면 된다.



이제 dweet.io 사이트에 들어가 본다.


■ dweet.io

https://dweet.io/ 

 

dweet.io 사이트에서 상단의 Play 를 클릭하면 아래와 같이 API 설정 목록이 뜬다.


Play 메뉴에서 여러가지 API 에 대한 설명을 볼 수 있고 자신의 Thing 에 대한 설정을 할 수 있다. 둘러보면 모두 이해할 수 있는 내용이다. 이 API 들을 이용해서 데이터를 끌어와 관련 웹이나 스마트폰 앱 또는 또 다른 Thing 을 만들 수 있을 것이다.


위의 소스를 이용해서 데이터를 업로드한 dweet 의 THING NAME 은 'deneb_nodemcu_dht11_01' 이다. http://dweet.io/follow/deneb_nodemcu_dht11_01 (이 URL 은 언제든지 내가 ESP8266의 전원을 끊으면 동작하지 않을 수 있음) 를 클릭해서 들어가보면 데이터가 잘 업로드 되고 있는 것을 알 수 있다.



위의 화면에서 'Create a Custom Dashboard' 를 클릭하면 freeboard.io 사이트로 이동을 하는데 Things의 데이터를 비주얼하게 표현해 주는 사이트이다. 


사이트에 가입하면 위와 같이 게이지 같은 위젯도 추가가 가능하다. 


dweet.io 를 사용해본 소감은 ThingSpeak 보다 간단해서인지 왠지 적응이 잘 안된다. 너무 오픈되어 있어서 그런가? 좀 혼란스럽다. 아직까지는 ThingSpeak 가 더 마음에 든다. 앞으로 dweet 에 대해 새로운 사항을 알게되면 이 포스팅에 내용을 추가할 생각이다.

반응형
반응형
이번에는 사물인터넷에서 각광 받고 있는 메시지 전송 프로토콜인 MQTT (Message Queue Telemetry Transport) 에 대해서 알아보겠습니다. MQTT 는 IBM 에 의해서 개발되었고 2014년 국제 민간 표준기구인 오아시스에 의해서 표준으로 제정되었습니다. 이 프로토콜이 사물인터넷의 통신규약으로 각광 받고 있는 이유는 경량화가 가능해서 통신 대역폭이 제한적인 사물인터넷에 적합하기 때문 입니다. 현재 페이스북도 회원들간의 메시지 전송에 MQTT 프로토콜을 이용하고 있다고 합니다.

https://sakshambhatla.wordpress.com

위의 그림을 보면 가운데 MQTT Broker 라는 것이 있고 Publish 와 Subscribe 가 있습니다. Publisher 가 Hi 라는 메시지를 보내면 Subscribe 가 Broker 를 통해서 메시지를 받는 것 입니다. 구독하지 않은 토픽과 Subscriber 는 메시지를 받을 수 없습니다. 

IoT MQTT 활용 예 (http://www.eurotech.com/en/)


이러한 MQTT 오픈소스로 각광을 받고 있는 Mosquitto 를 설치해 보고 테스트를 한 번 해 볼까 합니다. 이 서비스를 설치한 필자의 컴퓨터는 윈7 32비트 입니다.

mosquitto 를 설치 실행하려면 먼저 openSSL 소프트웨어가 설치되어 있어야 합니다. 다음의 URL 에 들어가서 자신의 OS 에 맞는 버전의 OpenSSL 을 다운받아 설치 합니다. 설치 시 DLL 파일을 찾아야 하므로 아래와 같이 설치 옵션을 지정 합니다. 버전은 Light 버전을 설치해 주었습니다.


 
mosquitto 홈페이지에 들어가서 윈도우용 설치 파일을 다운로드 하고 설치 합니다.

아래의 FTP 에 가서 pthreadVC2.dll 파일을 다운로드 해서 mosquitto 설치 폴더에 복사해 줍니다.

OpenSSL 설치폴더 하위의 Bin 폴더에서 libeay32.dll, ssleay32.dll 두 개의 DLL 파일을 복사해서 mosquitto 설치 폴더에 넣습니다.


혹시 mosquitto.exe 는 실행이 되는데 mosquitto_sub, mosquitto_pub 가 아래와 같은 에러가 나면서 실행이 안된다면 다음의 프로그램을 설치해 보세요.

■ Visual C++ 2010 SP1 Redistributable Package


 

■ 설치한 파일들 모음

mosquitto 설치파일들.zip


mosquitto 설치가 끝났습니다. 윈도우 커맨드창으로 들어가서 mosquitto 설치 폴더로 이동하여 다음을 입력하면 mosquitto broker 가 실행 됩니다. 기본 포트는 1883 이며 변경을 원하면 conf 파일에서 설정 가능 합니다.

■ mosquitto broker 실행

mosquitto -v

-v 옵션은 모든 통신과정을 보여주는 옵션 입니다.

실행이 되었습니다. 1883 포트로 실행이 됩니다. 기존의 ipv4 뿐만 아니라 ipv6 으로도 Listen 하고 있습니다. 



■ mosquitto subscriber , publisher 실행

mosquitto_sub -h 호스트 -t 토픽명 
(ex: mosquitto_sub -h 192.168.0.12 -t /deneb)

mosquitto_pub -h 호스트 -t 토픽명 -m 메시지
(ex: mosquitto_pub -h 192.168.0.12 -t /deneb -m "Hello World!!")


좌측 위 publisher, 좌측 아래 subscriber, 오른쪽 mosquitto Broker 입니다. pub 에서 메시지를 발행하면 broker 에서 받아서 해당 토픽을 subscribe 한 subscriber 들에게 보냅니다. subscriber 인 왼쪽 아래의 창에 전송된 메시지가 표시됨을 볼 수 있습니다.


구글 플레이스토어에서 MQTT Client 라는 앱을 다운로드 받아서 테스트해 보았습니다. MQTT Broker 인 192.168.0.12 의 /deneb 토픽을 subscribe 해 보았습니다. 위와 같이 publisher 의 메시지가 잘 보입니다.


MQTT Client 앱은 subscriber 와 publisher 를 모두 지원 합니다. 이번에는 publisher 로 'hello i am smart phone' 이라는 메시지를 보내 보았습니다.


좌측 하단의 Subscriber 에 hello i am smart phone 이라는 메시지가 표시 됩니다.


앞으로 NodeMCU Lua 를 이용해서 위와 같은 MQTT 서비스를 적용해볼 생각 입니다.


반응형
반응형

NodeMCU 관련 연재글은 한 타임 쉬고 이제껏 모은 ESP8266 보드를 정리해보고 용도에 따른 선택기준 및 사용하면서 느낀 점을 적어보려고 합니다. 현재 저는 ESP-01, ESP-12E, Wemos D1 Mini, Amica 보드 총 4개의 ESP8266 보드를 가지고 있습니다. 각각의 보드들을 사용해보고 리뷰를 적어보겠습니다.


왼쪽부터 제일 처음 국내 인터넷 쇼핑몰을 통해 구입했던 ESP-01 입니다. 그리고 그 뒤에 알리에서 주문한 보드들 입니다. 좌측부터 각각 가격은 대략 5000원, 2달러, 3달러, 3.5달러 정도 입니다. 가격차이는 많이 날 것 같지만 거기서 거기 입니다. 


먼저 ESP-01 입니다. 이 보드는 가장 기본적인 ESP8266 보드 입니다. GPIO0, GPIO2 두 개의 GPIO 핀과 3.3V 전원입력, 통신을 위한 Tx, Rx 핀 등 8개의 핀만 제공합니다. ESP8266 의 기능을 극히 제한하고 테스트용으로 적합한 보드 입니다. 솔직한 생각으로는 이 보드는 공부용 으로도 사지 않는 것이 좋습니다. 활용성이 매우 떨어 집니다. 가격도 이 보드에 1달러 정도만 더 주면 ESP8266 의 훨씬 많은 기능을 이용할 수 있는 보드를 살 수 있습니다. 크기가 작다는 장점이 있기는한데 훨씬 기능이 많은 ESP-12E 와 비교시 그다지 큰 차이가 나지도 않습니다. 가격차이도 별로 없습니다. 게다가 PC와 연결해서 개발용으로 쓰려면 추가로 아두이노나 시리얼 통신을 위한 USB UART 보드가 필요 합니다. 


ESP-12E 보드 입니다. 크기는 ESP-01 과 비슷합니다. Rx, Tx 등 통신을 위한 핀들은 당연히 있고 GPIO 단자가 9개 제공되고 ADC 단자가 1개 전원입력 VCC, GND 그리고 Reset 을 위한 단자가 제공 됩니다. ESP-01 과 비교하면 훨씬 많은 기능이 제공 됩니다. 칩 자체도 금속커버로 덮여 있어서 칩의 쿨링도 잘 될 것 같습니다. ESP-01 과 같이 PC에 연결해서 코딩하려면 아두이노나 USB UART 보드가 필요 합니다. ESP8266 자체 모듈만 필요한 분들은 ESP-01을 사느니 이것을 사는게 훨씬 좋습니다. 그러나 이 보드도 단점이 있습니다. 핀을 연결하는 저 구멍의 간격이 좁아서 일반적인 핀은 꼽을 수 없습니다. 핀 자체도 들어가지 않습니다. 구멍이 좁거든요. 그래서 이 보드를 사용할 경우에는 아래와 같은 어댑터 보드를 추가로 구입하면 편리하게 쓸 수 있습니다.

Adapter Plate 라고 하는데 이런 부품을 추가로 구입해서 납땜해주면 좀 더 편하게 이용할 수 있습니다. 1달러 미만으로 구입이 가능 합니다. 실제로 사용할 IoT 제품을 구현할 분들은 이 모듈을 사는 것이 좋습니다. 소형화가 가능하고 기능도 많고 구동에 필요 없는 부품들(USB 시리얼 통신칩, 레귤레이터 등)도 달려있지 않거든요.


이것은 ESP8266 개발을 위한 Wemos D1 Mini 라는 보드 입니다. (사진의 것은 복제품 입니다. 하지만 구조와 기능은 동일 합니다. 정품은 Wemos 라고 쓰여 있으며 1달러 정도 더 비쌉니다)  보드 위에 탑재된 ESP-12E 모듈을 기반으로 하며 핀의 기능은 같습니다. 거기에 추가로 USB Serial 통신칩이 달려 있어서 마이크로 USB 케이블을 연결하면 바로 PC에 연결이 되서 편리하게 개발이 가능 합니다. 레귤레이터도 달려 있어서 3.3V, 5V 도 출력이 가능 합니다. 리셋 스위치도 달려 있어서 하드 리셋이 가능 합니다. 개발 연습용으로 매우 편리하며 좋습니다. 하지만 이 보드도 단점이 있습니다. USB Serial 칩으로 사용된 CH340G 라는 칩이 전력을 많이 먹는 것 같습니다. 비교적 전류가 약한 데스크탑 전면부의 USB 단자에 연결하면 보드가 인식이 되지 않습니다. 장치관리자에서 생겼다가 없어졌다가를 반복하네요. 충분한 전력을 공급하는 메인보드 자체 USB 포트에 연결하면 바로 인식이 됩니다. 아무튼 그 점만 빼면 개발용으로 매우 좋은 보드 입니다. 하지만 아래의 제품이 더욱 좋습니다.


바로 위의 D1 Mini 보다 0.5 달러 정도 비싼 Amica 라는 이름의 보드 입니다. 그야말로 본격적인 ESP8266 개발용 보드라고 생각 됩니다.  총 30개의 핀이 달려 있으며 ESP8266의 모든 기능을 이용할 수 있습니다. USB Serial 칩도 CH340G 보다 고급칩인 CP2102 칩을 사용해서 그런지 D1 Mini 의 전력문제 같은것 없이 노트북이건, 데스크탑 전면 포트건 어떤 PC의 USB 포트에 꼽아도 바로 동작 합니다. 마이크로 USB 포트가 달려 있어서 케이블로 바로 PC와 연결해서 개발이 가능 합니다. 하드 Reset, Flash 스위치를 제공 합니다. 알리를 뒤져보면 이것과 비슷한 모양의 보드인데 가격이 더 싼 것도 있습니다. 하지만 자세히보면 시리얼 통신칩으로 CH340G 를 이용하는 것들 입니다. 개발을 위해서 구입한다면 몇 백원 더 주고 이 보드를 구입하는게 좋다고 생각 합니다. 검색어는 'esp8266 development board' 라고 입력하면 이런 것들이 많이 나옵니다.


정리해 보자면 개발을 위해서는 Amica 보드, 실생활에 직접적인 활용을 위해서는 ESP-12E 보드(필요에 따라 Adapter 보드도 추가)를 구입하는 것이 바람직 하다고 생각됩니다.


이상으로 ESP8266 보드들에 대한 리뷰를 적어 봤습니다. 저는 위의 제품 제조사와 아무런 관련이 없습니다. 직접 구입해서 써보면서 느낀 점을 솔직하게 써 봤습니다.. ^^



▶추가사항 (2016.07.26) : 블로그 광고에 언젠가부터 ESP8266 국내총판 이라는 광고가 눈에 들어왔다. http://idktech.co.kr/ 라는 회사인데 사이트에 들어가보니 네이버에 Espressif (ESP8266 개발사) 개발자 모임 이라는 카페가 개설되어 있다. 이런 카페가 있을 줄은 몰랐다. 가입자 현재 39명으로 아주 미미한 카페이지만 관련 정보를 찾거나 제품정보를 얻는데 조금은 도움이 될 것 같아 가입을 했다. 카페 주소는 http://cafe.naver.com/espressif 이다.

반응형
반응형

예전에 IoT 클라우드 서비스인 ThingSpeak.com 에 대해서 알아보고 실제로 ESP8266 모듈인 ESP-01과 아두이노를 이용해서 DHT22 의 온도, 습도 데이터를 ThingSpeak 에 올려본 적이 있습니다. 하지만 AT Command 기반 이었고 ESP-01 은 아두이노에서 읽은 센서 데이터를 받아서 인터넷에 올려주는 역할만을 했습니다. 이번에는 NodeMCU 를 이용해서 DHT11 센서의 온도와 습도 데이터를 ThingSpeak 에 올려보도록 하겠습니다. 지난 글에서 구현 했던 DHT11 센서의 데이터를 읽어서 온도, 습도를 알려주는 웹서버는 인터넷을 통해서 들어오는 요청에 대해서 응답을 줬었지만 ThingSpeak 연동은 센서 데이터를 ESP8266을 통해서 보내는 것이므로 반대의 개념이 되겠습니다. ThingSpeak 서비스에 대해서는 예전에 자세하게 다룬 적이 있어서 링크로 대신 합니다. 



ThingSpeak 서비스 개념도 입니다. 센서로 부터 데이터를 받은 ESP8266 보드가 데이터를 ThingSpeak 서버에 업로드하고 그 데이터를 스마트폰, PC, 아두이노, 또 다른 ESP8266 등 n개의 장치로 보내서 활용이 가능 합니다. 물론 받은 데이터로 또 다른 장치를 제어할 수도 있습니다. 활용하기 나름이죠.


ESP8266 보드는 여전히 ESP-12E 기반의 Amica 보드를 이용 합니다. 센서는 DHT11 온도 습도 센서를 이용합니다. 센서와 ESP8266 개발보드와의 연결은 아래의 이전 글 을 참고해서 연결하면 됩니다. 똑같습니다. 다시 말하자면 센서의 전원은 Amica 보드의 3.3V 에 연결하고 Signal 은 D5에 연결했습니다.


이제 ESPlorer를 열고 ESP8266 Amica 보드를 연결하고 코딩을 합니다. credentials.lua 와 init.lua 는 NodeMCU 웹서버 만들기 글에서 사용한 것과 동일 합니다. 대신 dht11_thingspeak.lua 를 init.lua 에서 call 해 줍니다.


■ 소스 #1 (credentials.lua)

1
2
3
4
-- WiFi Connect information
SSID = "your wifi name"
PASSWORD = "your wifi password"
 
cs



■ 소스 #2 (init.lua)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("WiFi Connected...")
        file.close("init.lua")
        dofile("dht11_thingspeak.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs


■ 소스 #3 (dht11_thingspeak.lua)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
pin = 5 -- dht11 signal pin
temp = 0
humi = 0
writekey = "your thinkspeak channel write api key"
 
tmr.alarm(1,15000,1,function()readDHT()sendData(temp,humi)end)
 
--read DHT11 temp, humi data function
function readDHT()
    status, temp, humi = dht.read(pin)
    if status == dht.OK then
        temp = math.floor(temp)
        humi = math.floor(humi)
    elseif status == dht.ERROR_CHECKSUM then
        print"DHT Checksum error." )
    elseif status == dht.ERROR_TIMEOUT then
        print"DHT timed out." )
    end
    dht = nil
end
 
--send data to thingspeak
function sendData(temp,humi)
    -- conection to thingspeak.com
    print("Sending data to thingspeak.com")
    conn=net.createConnection(net.TCP, 0
    conn:on("receive", function(conn, payload) print(payload) end)
    
    -- api.thingspeak.com 184.106.153.149
    conn:connect(80,'184.106.153.149'
    conn:send("GET /update?key="..writekey.."&field1="..temp.."&field2="..humi.." HTTP/1.1\r\n"
    conn:send("Host: api.thingspeak.com\r\n"
    conn:send("Accept: */*\r\n"
    conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n")
    conn:send("\r\n")
    conn:on("sent",function(conn)
    print("Closing connection")
    conn:close()
    end)
    conn:on("disconnection", function(conn)
    print("Got disconnection...")
  end)
end
 
cs


인터넷을 통해서 thingspeak에 dht11 의 온도, 습도 데이터를 업로드 하는 소스 입니다. 4번째 줄 writekey 부분에 자신의 thingspeak 채널의 Write API Key 를 입력해야 합니다.


물론 thingspeak 채널에는 온도, 습도를 받을 수 있는 2개의 field 가 등록되어 있어야 합니다. 위의 링크의 thingspeak 글을 참고하면 쉽게 만들 수 있습니다.



소스를 모두 업로드 하고 장치를 Soft Reset 하면 위와 같이 데이터를 ThinsSpeak 에 업로드 하기 시작 합니다.


ThingSpeak.com 에 접속해서 데이터를 업로드 하고 있는 채널에 들어가면 위와 같이 우리집 온도와 습도가 그래프로 표시 됩니다. 물론 스마트폰 웹브라우저로도 볼 수 있으며 데이터를 csv, json, xml 형식으로 다운로드 받을 수도 있습니다. 



위의 링크를 참조하면 자신의 스마트폰에 위젯앱을 추가하여 데이터를 실시간으로 모니터링 할 수 있으며 입계값을 설정하여 경고가 울릴 수 있게 할 수도 있습니다. 예를 들어 온도가 30도가 넘으면 경고 알람을 울리게 설정할수도 있는 것이죠.


스마트폰에서 ThingSpeak 위젯앱 'IoT ThingSpeak Monitor Widget' 을 설치하고 설정한 모습 입니다.

반응형
반응형

지난 글들에서 NodeMCU Lua 를 이용해서 간단한 웹서버를 만들어 보았고 공유기 설정을 통하여 NodeMCU ESP8266 웹서버를 외부에서도 접속이 가능하도록 만들어 보았습니다. 하지만 브라우저로 웹서버에 접속해도 Hello NodeMCU 라는 글자만 출력되었었죠. 아무런 정보도 표시되지 않는다면 IoT 로서의 의미가 없습니다. 이번에는 온습도 센서인 DHT11 을 ESP8266 개발보드인 Amica 에 연결해서 웹서버에 접속하면 온도와 습도가 표시되도록 해 보겠습니다. 어디든 인터넷만 연결이 되면 스마트폰, PC 등에서 현재 집의 온도와 습도를 알 수 있는 것이죠.


제가 가지고 있는 DHT11 센서 입니다. 저항이 달려 있는 모듈형태로 되어 있어서 보드와 연결 시 따로 저항을 연결하지 않아도 됩니다. 모듈형태가 아니라 위의 파란부분의 핀 4개짜리 센서만 가지고 있다면 5K 정도의 저항을 Signal 과 VCC 사이에 달아 주어야 합니다. DHT11 에 대한 자세한 사용법은 [여기] 를 참고 하시면 됩니다.


그리고 Amica  ESP8266 개발 보드 입니다. DHT11 이 3V~5.5V를 지원하므로 전원은 3.3V 핀을 이용하면 됩니다. 연결은 아래의 표를 참조해서 연결하면 됩니다.


 DHT 11

 ESP8266 (Amica)

 Signal

 D5

 VCC

 3.3V

 GND

 GND


연결이 되었으면 이제 소스를 코딩하면 됩니다. 소스는 이전 글에서 해 보았던 웹서버 만들기의 credentials.lua, init.lua, webserver.lua 를 변형해서 사용할 것 입니다.


■ credentials.lua

와이파이 연결정보를 가지고 있는 파일 입니다.


1
2
3
4
-- WiFi Connect information
SSID = "와이파이이름"
PASSWORD = "와이파이패스워드"
 
cs



■ init.lua

와이파이에 연결해 주는 기능을 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("WiFi Connected...")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        dofile("webserver.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs




■ webserver.lua

웹서버를 실행하고 DHT11 센서의 값을 읽어서 웹에서 요청이 들어오면 준비된 HTML (온도 및 습도값 포함) 을 전송하는 기능을 합니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pin = 5 -- dht11 signal pin
srv = net.createServer(net.TCP)
srv:listen(8080, function(conn)
 
    status, temp, humi, temp_dec, humi_dec = dht.read(pin)
    if status == dht.OK then
        temp_1 = math.floor(temp)
        humi_1 = math.floor(humi)
    elseif status == dht.ERROR_CHECKSUM then
        print"DHT Checksum error." )
    elseif status == dht.ERROR_TIMEOUT then
        print"DHT timed out." )
    end
    tmr.delay(1000000)
    conn:on("receive", function(sck, payload)
        print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>My House Temperature & Humidity<br/></h1>" .. "<br/><h1>Temperature = " .. temp .. "C</hr>" .. "<br/><h1>Humidity = " .. humi .. "%</hr>")
    end)
    conn:on("sent", function(sck) sck:close() end)
end)
print("webserver ready...")
cs


위의 소스를 보면 이전 글에서 작성 했던 웹서버 코드를 기반으로 DHT11 값을 추가해서 HTML 을 리턴 할 수 있도록 수정해 주었습니다.


DHT11 의 경우 초기의 NodeMCU 같은 경우는 별도의 라이브러리를 사용해야 코드가 단순화 되었었는데 지금은 위와 같이 간단하게 읽어오는 것이 가능 합니다. 아마도 펌웨어 자체에 라이브러리가 포함이 된 듯 합니다.



위의 3개의 소스를 ESPlorer 를 통해서 ESP8266 개발보드에 'Save to ESP' 해서 업로드 해 줍니다. init.lua 는 맨 마지막에 업로드 해 주는 것이 좋습니다.


소스를 모두 업로드 하고 Reset 을 눌러서 Soft Reset 을 한 번 해 줍니다. 시리얼 창에 'webserver ready...' 라는 메시지가 나오면 준비가 완료된 것 입니다.


이제 브라우저를 열고 저의 공유기에서 ESP8266 웹서버에 할당된 IP 인 192.168.0.18 로 접속해서 온도와 습도가 잘 나오는지 확인해 봅니다. 포트는 8080 을 이용했으므로 다음과 같이 브라우저의 주소창에 입력하면 됩니다. http://192.168.0.18:8080/



이번에는 외부에서 스마트폰 LTE 연결로 확인을 해 보겠습니다. 물론 이것을 가능하게 하려면 [여기] 를 참고 하셔서 공유기의 DDNS, 포트 포워드 를 설정해서 외부에서도 ESP8266 웹서버에 접속 가능하도록 만들어 주어야 합니다.


위와 같이 스마트폰으로 외부에서도 DDNS에서 만들어준 URL을 입력하면 DHT11 센서가 측정한 값을 실시간으로 볼 수 있습니다. 이를 응용하면 가스누출, 조명 밝기, 침입자 탐지 등도 원격지에서 모니터링 할 수도 있을 것 같습니다.



▶ 추가사항 (2016.07.08) : 위의 webserver.lua 소스가 작동에는 지장이 없으나 좀 지저분하여 소스를 수정하고 주석도 좀 추가해 보았습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
pin = 5 -- dht11 signal pin
temp = 0 -- initialize temperature
humi = 0 -- initialize humidity
port = 8080 -- web port
 
srv = net.createServer(net.TCP)
srv:listen(port, function(conn)
    ReadDHT()   -- dht read function call
    tmr.delay(1000000)
    conn:on("receive", function(sck, payload)
        print(payload)
        --// response html
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>My House Temperature & Humidity<br/></h1>" .. "<br/><h1>Temperature = " .. temp .. "C</hr>" .. "<br/><h1>Humidity = " .. humi .. "%</hr>")
    end)
    -- response
    conn:on("sent", function(sck) sck:close() end)
end)
print("webserver listening..."
 
 
function ReadDHT()
    status, temp, humi = dht.read(pin)
    if status == dht.OK then
        temp = math.floor(temp)
        humi = math.floor(humi)
    elseif status == dht.ERROR_CHECKSUM then
        print"DHT Checksum error." )
    elseif status == dht.ERROR_TIMEOUT then
        print"DHT timed out." )
    end
    dht = nil   --release dht module
end
 
cs


반응형
반응형

지난 NodeMCU 관련 글 7편 에서 ESP8266 보드(Amica Board)에 간단한 웹서버를 만들어 보았습니다. 하지만 공유기의 내부 IP 를 통해서만 접속이 가능 했습니다. IoT 의 개념이 외부에서도 집안의 장치에 마음대로 접근해서 컨트롤 하는 것이 목표이기 때문에 외부에서 접속이 안된다면 별 의미가 없습니다. 공유기의 DDNS 서비스와 포트포워딩 기능을 이용하여 지난번 구현 하였던 웹서버를 외부에서도 접속할 수 있도록 해 보겠습니다. 사실 이 글은 NodeMCU 글이라기 보다는 공유기 설정 관련 글이지만 어차피 NodeMCU 시리즈를 엮는데 필요할 것 같아서 8편 글로 올립니다.


이 글에서 사용한 공유기는 ipTime 유무선 공유기 입니다. 하지만 다른 회사의 공유기를 사용하고 있는 분들이라도 DDNS나 포트포워딩의 개념은 같으므로 적용하는데 별 어려움은 없을 것 입니다.



■ DDNS 서비스란?

먼저 DDNS는 Dynamic DNS 의 약자 입니다. 동적 DNS 라고 하는데 먼저 DNS의 개념을 알아야 합니다.  DNS는 도메인 네임을 IP로 바꿔주어서 인터넷에 연결할 수 있도록 합니다.  모든 인터넷 서버는 IP를 가지고 있으니까요. 우리가 www.naver.com 이라는 도메임을 주소창에 치면 DNS 서버가 이것을 받아서 해당되는 IP를 가지고 있는 서버로 연결해 주는 것이죠. 그런데 Naver 같은 회사는 고정 IP 를 서버에 사용 합니다. 그래서 IP가 변할 일이 없습니다. 반면 가정의 인터넷은 IP가 변합니다.(물론 고정 IP서비스도 있긴 함) 동적 IP를 할당하는 것이죠. IP는 한정된 자원이기 때문에 하나의 IP를 여러사람이 돌아가면서 쓰도록 해 놓은 것 입니다. 고로 기존의 DNS 서비스에는 등록이 불가능 합니다. 이럴 경우 DDNS 라는 서비스를 사용하게 됩니다. 


ipTime 같은 경우는 iptime.org 라는 DDNS 서비스를 자사의 공유기 사용자들에게 무료로 사용하도록 해 주고 있습니다. 서비스에 가입을 하면 공유기가 공인IP를 모니터링 하게 되고 IP가 변경될 경우 이 공인 IP를 DDNS 서비스에 등록해서 계속 갱신하도록 해 줍니다. 고로 xxxxxx.iptime.org 라는 자신만의 도메인으로 가정의 웹서버에 접속 할 수 있도록 해 주는 원리 입니다.


하지만 ipTime 같은 경우는 자체의 DDNS 서비스를 구현하고 공유기 구매자들에게 무료로 제공하고 있지만 그렇지 않은 경우도 많습니다. 그러므로 DDNS 기능을 사용하기 위해서는 공유기 구입 전 공유기가 DDNS 서비스를 지원하는지 알아봐야 합니다. 만약 DDNS 서비스가 지원되지 않는다면 자신의 공인 IP를 알아내서 연결하는 방법을 쓸 수 있습니다. 자신의 공인 IP를 알아내는 방법은 [여기] 를 클릭하면 알 수 있습니다.

 


■ 포트포워딩 이란?

포트포워딩이랑 공유기에서 DDNS 등을 통해 외부에서 요청이 들어올 경우 설정해 놓은 웹서버로 연결해주는 기능 입니다. 예를 들어 xxxxxx.iptime.org:8080 이라고 외부에서 브라우저에 주소를 쳐서 연결을 요청하는 경우 먼저 DDNS 서비스가 이를 공인 IP로 변경해 줍니다. xxxxxx.iptime.org:8080 -> 218.237.234.156:8080 이런 식으로 변경이 됩니다. 그러면 218.237.234.156 IP를 쓰고 있는 공유기를 찾아서 요청 정보를 공유기가 받습니다. 공유기에서는 포트포워딩 목록을 보고 내부 IP 인 192.168.0.18:8080 을 사용하는 NodeMCU 웹서버로 요청을 보내 줍니다. 그럼 NodeMCU 에서는 준비된 응답(HTML)을 보내주게되는 것입니다.


이제 공유기를 실제로 설정해 보겠습니다.


ipTime 공유기의 관리자에 들어 갑니다. 접속 IP 는 192.168.0.1 입니다. 관리화면으로 이동 합니다.


ipTime 공유기의 DDNS 설정 입니다. 고급설정 -> 특수기능 하위에 있습니다. 저의 경우 이미 만들어 놓은 DDNS 도메인이 있어서 저렇게 나옵니다. 추가 버튼을 눌러서 서비스에 가입을 해 주면 됩니다. 접속 도메인에 사용할 자신만의 호스트이름과 이메일, 비밀번호 등을 설정하면 쉽게 추가할 수 있습니다.


 DDNS설정이 끝났으면 포트포워딩을 설정 합니다. 고급설정 -> NAT/라우터관리 하위에 있습니다. 아랫 부분에 새로운 포트포워딩 규칙을 적는 곳이 있습니다. 적절한 이름을 적어주고 프로토콜은 http, tcp 를 선택합니다. 포트는 저 같은 경우는 8080을 할당해 주었습니다. 이렇게 하게되면 지난 NodeMCU 7편에서 설정했던 webserver.lua 의 소스의 포트 설정 부분을 80 에서 8080으로 바꾸어서 다시 업로드 해 주어야 합니다. 그리고 NodeMCU 에 할당된 내부 IP를 적어 줍니다. 모든 것을 이상없이 적었으면 '적용' 버튼을 누르면 됩니다. 


새 포트포워드 규칙이 생성되었습니다. 맨위 오른쪽의 저장 버튼을 눌러서 전체 설정을 한 번 더 저장해 줍니다.


이제 테스트를 하면 됩니다. 테스트 전 [NodeMCU Lua 사용해보기 #7 - 간단한 웹서버 만들어보기] 에서 만들었던 NodeMCU 는 전원이 꼭 들어가 있어야 합니다. 그리고 위에서 말 했지만 다시 말하자면 webserver.lua 의 포트를 아래와 같이 수정해서 다시 업로드 해 주어야 합니다.


1
2
3
4
5
6
7
8
9
-- a simple HTTP server
srv = net.createServer(net.TCP)
srv:listen(8080, function(conn) -- 서비스 포트 수정
    conn:on("receive", function(sck, payload)
        print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>")
    end)
    conn:on("sent", function(sck) sck:close() end)
end)
cs


3번째 줄의 포트번호 설정이 80 -> 8080 으로 변경 되었습니다. 나머지는 같습니다.


이제 외부에서 NodeMCU 웹서버가 제대로 응답을 해 주는지 확인을 해 봐야 합니다. 직접 확인을 하기 위해 근처의 PC방이나 친구집에 가서 테스트 할 수도 있겠지만 제일 쉬운 방법은 스마트폰의 와이파이를 끄고 LTE 나 3G로 연결해서 스마트폰의 브라우저로 확인해 보는 것입니다.


저의 스마트폰 브라우저에서 DDNS에서 설정한 호스트명으로 연결한 모습 입니다. (저의 호스트명은 지웠습니다. 개인적으로 사용하고 있는 DDNS 서비스라서요.) 외부에서도 연결이 잘 됩니다. 이제 나만의 NodeMCU 웹서버는 인터넷 연결만 가능하면 미국이건 중국이건 아프리카건 어디에서든 연결이 가능한 서버가 된 것입니다.

반응형
반응형

이번에는 NodeMCU Lua 를 사용해서 간단한 웹서버를 만들어보고 브라우저로 웹서버로 접속해서 응답을 얻어보겠습니다. 웹서버를 만들기 위해서는 'NodeMCU Lua 사용해보기 #5 - 인터넷에 연결해보기' 를 먼저 공부해야 합니다. 인터넷에 연결이 되어 있어야 웹서버가 동작 하니까요. 일단 간단하게 브라우저에서 ESP8266 장치로 요청을 보내면 장치가 준비된 HTML 을 브라우저로 응답을 보내주는 형식 입니다.


NodeMCU 펌웨어가 설치된 ESP8266 장치를 PC에 연결 하고 ESPlorer 를 실행 합니다. Open 을 눌러서 PC와 통신 가능 상태로 만들어 줍니다.


웹서버 기능은 총 3개의 Lua 파일로 만들었습니다. 와이파이 연결 정보를 담고 있는 credentials.lua, 인터넷 연결을 해 주는 init.lua, 그리고 웹서버의 역할을 해 주는 webserver.lua 의 3개 파일로 구현 할 수 있습니다.


■ credentials.lua


1
2
3
4
-- WiFi Connect information
SSID = "와이파이 이름"
PASSWORD = "와이파이 패스워드"
 
cs


위와 같이 와이파이 연결 정보를 SSID, PASSWORD 변수에 담아 두는 소스 입니다.


■ init.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("Running")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        dofile("webserver.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
 
cs


init.lua 파일은 ESP8266 이 부팅 시 가장 먼저 실행하는 파일 입니다. 이 파일에 인터넷 연결 소스를 작성 합니다. 와이파이 연결에 credentials.lua 의 내용을 dofile("credentials.lua")  부분을 통해서 참조하게 되고 와이파이에 연결 합니다. 와이파이 연결 후 startup() function을 call 하고 startup() 은 실행 후 dofile("webserver.lua") 을 통해서 webserver.lua 파일을 실행하게 됩니다. 


■ webserver.lua

1
2
3
4
5
6
7
8
9
10
-- a simple HTTP server
srv = net.createServer(net.TCP)
srv:listen(80, function(conn)
    conn:on("receive", function(sck, payload)
        print(payload)
        sck:send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>")
    end)
    conn:on("sent", function(sck) sck:close() end)
end)
 
cs


웹서버로 브라우저의 요청이 오면 가지고 있던 HTML 을 응답으로 내어주는 가장 간단한 형태의 웹서버 구현 입니다. 


HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1> Hello, NodeMCU.</h1>


위의 HTML 코드를 브라우저로 보내 줍니다. 그리고 브라우저에서는 웹서버에서 응답받은 내용을 브라우저에 표시해 주겠죠. 그리고 위의 소스를 보면 srv:listen(80, function(conn)  부분이 있습니다. 


여기에서 80은 웹서버의 서비스 포트 입니다. 80은 기본 웹서비스 포트로서 브라우저 URL 입력창에 포트 번호를 붙이지 않아도 됩니다. 만약 포트를 80이 아니라 8080 같은 포트로 설정하면 URL 마지막에 포트 번호를 표기 해야 합니다. 예를 들면 http://192.168.0.18:8080 이런 식으로 주소를 적어야 합니다. 혹시나 가정용 인터넷을 이용할 경우에는 80포트를 인터넷 회사에서 사용하지 못하도록 막아 놓는 경우도 있기 때문에 8080, 8088... 등 다른 포트를 이용해서 외부에서 연결을 설정 하기도 합니다. 



위와 같이 3개의 소스 파일을 ESPlorer 에서 작성하고 Save to ESP 버튼을 눌러서 ESP8266 보드에 업로드 해 줍니다. 업로드 순서는 init.lua 파일을 가장 나중에 업로드 해 주시면 됩니다. 왜냐하면 업로드 후 자동으로 실행이 되는데 나머지 2개의 파일을 찾지 못하면 에러를 내기 때문에 그렇습니다. 업로드 후 Reset 버튼을 눌러서 Soft Reset 해 봅니다. 보드가 다시 시작 하면서 init.lua 를 자동으로 실행하게 되고 위와 같이 192.168.0.18 이라는 IP를 잡고 웹서버가 실행이 됩니다. 고로 웹서버의 IP 가 접속주소가 됩니다.


브라우저를 하나 열고 제대로 ESP8266에서 작동 중인 웹서버가 제대로 응답을 주는지 확인해 봅니다.


PC의 브라우저를 열고 웹서버 주소인 192.168.0.18 로 연결해 보았습니다. 응답을 잘 주고 있습니다.


PC뿐 안니라 스마트폰의 브라우저 에서도 웹서버 연결이 잘 됩니다.


이상으로 NodeMCU Lua를 이용해서 ESP8266 보드에서 간단한 웹서버를 구현해 보았습니다.  간단하지만 센서값을 인터넷을 통해 보여주거나 반대로 외부에서 ESP8266에 연결된 장치 들을 콘트롤 할 수 있는 기초가 마련된 것 입니다.




▶ 추가사항 (2016.07.25) : http://orasman.tistory.com/358 여기에 위의 소스의 개선점을 트랙백으로 올려 주셨네요. 서버가 닫히지 않았을 경우 닫아주는 소스가 추가 되었습니다.

반응형
반응형

지난 글에서 NodeMCU 를 이용해서 ESP8266을 인터넷에 연결해 보았습니다. 그런데 ESPlorer 라는 다소 생소한 이름의 개발툴에 대해서는 그다지 자세하게 알아보지 못했네요. 이번 글에서는 ESPlorer 에 대해서 알아 보겠습니다. ESPlorer 는 러시아 개발자가 만든 소프트웨어 입니다. 그래서 홈페이지에 들어가보면 ESPlorer 메뉴는 영어로 나오지만 다른 메뉴는 러시아어로 나옵니다. 아무튼 이런 프로그램이 없었다면 Putty 같은 터미널 프로그램으로 한 줄 한 줄 정성스럽게(?) 코딩을 했을텐데 매우 편리하게 개발을 할 수가 있습니다. ESPlorer는 JAVA 언어로 만들어져 있습니다. 그래서 어떤 OS 가 됐든지 JAVA SDK 만 설치되어 있다면 하나의 소스로 변경 없이 실행이 가능 합니다.


처음 실행했을 때의 화면 입니다. ESPlorer 는 크게 두 부분으로 구분할 수 있는데 왼쪽은 소스 편집 업로드 등을 할 수 있는 창이고 오른쪽은 시리얼 통신 내용을 보여주는 시리얼 창 입니다. 왼쪽의 소스창 부터 보겠습니다.

  • 빨간색 부분은 소스편집기의 부가 기능 입니다. open, save, copy, paste 등의 일반적인 편집 메뉴와 다르지 않습니다.

  • 파란색 영역은 실제 소스편집이 이루어지는 창 입니다. New 라고 탭이 하나 열려 있는데 여러개의 파일을 열어서 탭으로 이동하면서 소스편집이 가능 합니다.

  • 녹색 영역은 소스 작성 후 ESP8266 에 Send, Save, Upload 기능을 하는 버튼들이 모여 있습니다. 기능에 따라서 여러가지 버튼이 존재 합니다.


이제 오른쪽 시리얼창을 보겠습니다.


  • 노란색 부분은 장치에 연결을 위한 버튼들이 있습니다. 기본적으로 PC에 ESP8266을 연결하고 Open 버튼을 누르면 연결이 됩니다. 

  • 노란색 부분 아래는 실제 시리얼 통신 내용을 보여주는 창 입니다. 

  • 갈색 부분은 Snippet 기능입니다. 자주 사용하는 명령어나 소스를 Snippet 에 저장해 놓고 단추만 누르면 매크로 처럼 자동으로 실행이 되는 기능 입니다. 이 기능은 아래쪽에서 좀 더 자세히 알아보겠습니다.

  • 핑크색 부분은 Heap 메모리, Chip Info 등의 ESP8266 장치의 각종 정보를 보는 기능과 Soft Reset 버튼이 위치하고 있습니다. 그리고 핑크색 아래에 희미하게 창이 또 있는데 여기는 자주 사용하는 명령어 들을 모아놓아서 사용하기 쉽게 만들어 놓은 기능 입니다. 예를 들어 여기에서 file.remove("") 를 선택하면 파일명만 적어서 Send 버튼을 누르면 실행이 되는 기능 입니다.

  • 그리고 제일 오른쪽에 3개의 버튼이 있습니다. Format, FS info, Reload 가 있는데 Format 은 말 그대로 장치에 탑재된 프로그램을 싹 다 지우는 역할을 합니다. FS info 는 장치의 프로그래밍 가능 공간에 대한 정보 입니다. 총용량, 사용된 용량, 남은 용량으로 표시 합니다. Reload 는 FS info 의 상세정보 입니다. 프로그래밍 가능 공간에 대한 정보뿐 아니라 탑재된 프로그램 파일들에 대한 정보도 보여 줍니다.


왼쪽 소스창의 Command 탭 입니다. NodeMCU 에서 자주 사용하는 명령어들이 모여 있습니다. 장치를 Restart 하거나 칩이나 Heap 메모리 정보를 봅니다. List Files 는 장치에 업로드된 파일들을 표시해 줍니다. 위에서 알아보았던 Reload 버튼과 같은 기능 입니다. tmr.stop 은 지금 실행되고 있는 timer 모듈의 실행을 멈춰 줍니다. 오른쪽에서 해당 timer 의 ID 를 선택하고 tmr.stop 버튼을 누르면 해당 timer 가 정지 됩니다. timer 모듈에 의해서 무한루프를 돌고 있을 때 사용하면 됩니다. 그리고 아래쪽으로 WiFi 연결을 쉽게 해 주는 기능이 있습니다.


이번에는 Snippets 탭에 들어가 봅니다. 총 16개의 Snippet 을 설정할 수 있습니다. 빨간 영역의 Edit Snippet 버튼을 누르고 Snippet 편집창에 자주 사용하는 코드를 넣어 주고 Save 버튼을 눌러서 저장해 줍니다. 그리고 오른쪽 시리얼 창의 노란색 영역의 Snippet0 ~ Snippet15 까지의 버튼이 있는데 저장한 Snippet 버튼을 눌러주면 입력한 소스를 실행해 주는 기능 입니다. 일종의 매크로 기능이라고 보시면 됩니다.


Snippet0 에 WiFi AP 리스트를 보여주는 소스를 저장하고 시리얼 창의 Snippet0 버튼을 클릭해서 실행한 모습 입니다. 시리얼 창에 WiFi 리스트가 쫙 뜹니다.


Settings 탭 입니다. ESPlorer 의 환경설정을 위한 기능들 입니다. NodeMCU 와 MicroPython 중 사용하고자 하는 펌웨어를 고를 수 있고 통신을 위한 설정들... 그리고 코딩을 하고 소스 저장 시 자동으로 ESP8266에도 Save 되도록 ESPlorer 실행 시 Default 로 잡혀 있는데 'AutoSave file to ESP after save to disk' 옵션을 Uncheck 해 주면 소스를 저장해도 자동으로 장치에 업로드 되지 않습니다. 따로 Save to ESP 버튼을 클릭해야만 소스가 장치에 업로드 됩니다. 


ESPlorer 는 AT Command 기반의 개발도 지원을 합니다. AT-based 탭에 들어가면 각종 AT Command 를 쉽게 사용할 수 있도록 많은 버튼들이 마련되어 있습니다.


끝으로 무료 소프트웨어 이나 마음에 들면 러시아 개발자에게 Donation 할 수 있습니다. 시리얼 창의 Donate 버튼을 누르면 paypal 로 이동해서 기부할 수도 있네요. ^^

반응형
반응형

이제 드디어 NodeMCU 개발 보드인 ESP8266(ESP-12E) 기반의 아미카(Amica) 를 인터넷에 연결해 보겠습니다. '드디어' 라는 말을 쓴 이유는 ESP8266 보드는 IoT(Internet of Things) 구현을 위한 보드인데 인터넷에 연결이 되지 않으면 아무런 의미가 없기 때문에 인터넷 연결을 시작으로 본격적인 개발을 할 수 있다는 의미에서 사용해 보았습니다.  이 글에서는 인터넷 Wi-Fi 에 보드를 연결해보고 통신이 되는지 확인해 보도록 하겠습니다. 시작하기 전에 예전에 올렸던 Amica 보드의 모습을 다시 보도록 하겠습니다.


보드는 위와 같이 생겼습니다. ESP8266 이라고 쓴 부분이 와이파이를 통해서 인터넷에 연결하고 각종 제어를 담당하는 핵심 부품인 MCU 부분 입니다. ESP8266 이라는 칩 입니다. 그리고 칩은 Wi-Fi 안테나와 연결이 되어서 무선 인터넷에 연결할 수 있도록 해 줍니다. 예전에 했던 말이지만 개발환경만 갖춘다면 꼭 위와 같은 보드가 아니더라도 ESP8266 칩을 사용한 어떠한 보드 모듈이라도 인터넷에 연결 할 수 있습니다. 다만 저의 경우는 ESP-01과 USB UART 로 NodeMCU 펌웨어와 ESPlorer  를 이용해서 개발을 시도해 봤지만 너무 불안정해서 이 보드를 사용할 뿐 입니다.


이번에는 저의 맥북을 사용해서 ESPlorer 를 통해서 보드에 연결을 해 보았습니다. 맥에서도 개발환경을 갖추기 위해서는 윈도우와 다를 바가 없습니다. Mac에  Mac OS X 용  CP2102 드라이버를 설치하고 ESPlorer 실행, 연결해서 Open 후 사용하면 됩니다.  다만 ESPlorer Open 시 윈도우에서는 COM1, COM2 등으로 포트를 지정했는데 맥에서는 '/dev/cu.SLAB_USBtoUART' 로 시리얼 통신 장치를 지정해 주면 됩니다.


자, 이제 준비는 끝났습니다. NodeMCU를 통해서 ESP8266을 인터넷에 연결해 봅시다.


■ credentials.lua 파일 생성

연결하려는 와이파이의 연결 정보를 담고 있는 파일 입니다. 그냥 코드에 적어 주어도 되지만 이런 정보는 파일을 분리해 주는 것이 좋습니다.


1
2
3
-- WiFi Connect information
SSID = "와이파이 이름"
PASSWORD = "와이파이 패스워드"
cs


ESPlorer 에서 File -> New 를 선택해서 새 파일을 생성해서 credentials.lua 라고 저장해 주면 됩니다. 물론 SSID (와이파이 이름), Password 는 자신이 연결하려는 와이파이 연결 정보를 입력해야 합니다. 이름은 꼭 credentials 가 아니어도 됩니다. 다만 파일을 로드 할 때는 그 이름을 사용해야 하겠죠. 위의 코드는 연결하려는 와이파이의 SSID, Password 를 설정하는 코드 입니다.



위와 같이 디스크에 저장 시 보드에 자동으로 업로드가 됩니다.



■ init.lua 파일 생성

init.lua 파일은 예전에 설명했던 바와 같이 NodeMCU가 처음으로 부팅될 때 기본으로 실행되는 파일 입니다. 이 파일에 인터넷 연결을 설정해 두면 보드에 전원이 공급될 시 자동으로 인터넷에 연결이 되는 것 입니다. 그러므로 인터넷 연결이 필수인 NodeMCU 에서는 init.lua 에 인터넷 연결 정보를 담아 놓으면 개발 시 편리하겠죠. 그 이외 보드 부팅 시 기본적인 Loading 이 필요한 사항을 담아 놓기도 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
 
function startup()
    if file.open("init.lua"== nil then
        print("init.lua deleted or renamed")
    else
        print("Running")
        file.close("init.lua")
        -- the actual application is stored in 'application.lua'
        -- dofile("application.lua")
    end
end
 
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(110001, function()
    if wifi.sta.getip() == nil then
        print("Waiting for IP address...")
    else
        tmr.stop(1)
        print("WiFi connection established, IP address: " .. wifi.sta.getip())
        print("You have 3 seconds to abort")
        print("Waiting...")
        tmr.alarm(030000, startup)
    end
end)
cs


init.lua 도 credentials.lua 와 마찬가지로 새파일을 만들고 위의 코드를 써서 저장을 해 줍니다. 맨 첫줄에 보면 credentials.lua 파일을 loading 하고 있습니다. 그리고 와이파이 연결 시까지 timer 모듈을 통해서 반복해서 연결이 시도되고 연결이 완료되면 startup function 을 call 합니다. 그리고 init.lua 를 닫아주고 프로그램이 실행될 실제 코드가 있는 application.lua (주석처리 되어 있음) 를 열어주게 됩니다. 인터넷 연결을 이용해서 실행될 실질적인 코드는 application.lua 에 위치하게 되는 것 입니다. 


위와 같이 credentials.lua 에 설정한 와이파이 연결 정보로 192.168.0.18 의 IP가 할당이 되고 인터넷에 연결이 되었습니다. 인터넷 연결이 되었으니 이 상태에서 본격적인 다음의 코드를 작업하면 되는 것 입니다. 이제 Amica 보드(ESP8266)에 전원이 들어오면 맨 먼저 위에서 설정한 인터넷에 연결을 시도할 것 입니다.


만약 잘 안된다면 credentials.lua 의 정보를 한 번 더 확인하고 두 파일을 모두 'Save to ESP' 버튼을 눌러서 개발보드(ESP8266)에 업로드 해 줍니다.



네트워크에 잘 연결이 되었는지 확인해 보기 위해서 위의 IP 로 ping 을 해 보았습니다.


통신이 잘 됩니다.


이상으로 ESP8266을 NodeMCU를 사용해서 인터넷에 연결해 보았습니다. 이제 이 작은 모듈이 인터넷이라는 거대한 네트워크에 연결이 되었으니 이를 무궁무진하게 활용하는 일만 남았네요. 상상력이 필요 합니다.


※ 참고 사이트 : https://nodemcu.readthedocs.io/en/dev/

반응형

+ Recent posts