2019년 5월 26일 일요일

NodeMCU와 구글 스프레드시트 연결

이 글은 NodeMCU ESP8266과 구글 스프레드시트 간의 연결 방법에 대한 글을 소개한다.
튜토리얼 영상

NodeMCU 회로 구성
NodeMCU를 이용해 다음과 같이 회로를 구성한다. 센서 역할을 하는 가변저항을 연결한다. 

스프레드시트 연결
구글 스프레드시트를 만들고, 도구메뉴 스크립트 편집기에서 다음과 같이 스크립트를 추가한다.
function doGet(e) 
{
  var mo = e.parameter.func;
  if(mo == "addData")
  {
    var stat = add_data(e);
    if(stat == 1)
    {
      var result = 
      {
        status : true
      };
      return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
    }
  }
}
function add_data(e)
{
  var sheet = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/182EnOR4vF5eVs4wGD-zOn7pKy_6BMpED8ApjIGh0C9Q/edit#gid=0');
  var lastVal = sheet.getRange("A1:A").getValues();
  var id = lastVal.filter(String).lenght;

  var CurrentDate = new Date();
  var Date_ = Utilities.formatDate(CurrentDate, "IST", "dd/MM/YYYY");
  var Time_ = Utilities.formatDate(CurrentDate, "IST", "HH:mm:ss");

  sheet.appendRow([id, Date_, Time_, e.parameter.val]);
  return 1;
}
게시>웹 앱으로 배포 메뉴를 실행하고, 모두 접근 가능한 권한으로 배포한다.

NodeMCU 코딩
NodeMCU에 다음과 같이 코딩한다. 단, 코드에서 url 은 앞서 배포된 웹 앱 링크 주소로 변경해야 한다.  
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>

const char *ssid = "SERVER NAME"; 
const char *password = "SERVER PASSWORD";  
const char* host = "script.google.com"; 
const char* fingerprint = "89 ff f4 0f 4d 98 09 ed e3 ef 95 f2 8a af af 22 89 08 ac 03";
String url;

void setup() 
{
  Serial.begin(115200);
  delay(100);
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password); 
  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Netmask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
}

void loop() 
{
  Serial.print("connecting to ");
  Serial.println(host);
 
  WiFiClientSecure client;

  const int httpPort = 443;
  if (!client.connect(host, httpPort)) 
  {
    Serial.println("connection failed");
    return;
  }

  float t = analogRead(A0);
  
  url = "/macros/s/AKfycbyvGjcryd7c5uNeX6dkleZhmjDKyTrs1L9Lf3kWlPhTZDn9JPrH/exec?func=addData&val="+ String(t);
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");
  delay(500);
  String section="header";
  while(client.available())
  {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println();
  Serial.println("closing connection");
  delay(6000);
}
코드를 업로드하여 실행하면, 약 6초마다 NodeMCU에서 읽은 데이터가 스프레드시트에 업데이트되는 것을 확인할 수 있다.

레퍼런스

2019년 5월 23일 목요일

IoT 커넥션 오픈소스 NODE-RED 사용법 - node-red + NodeMCU + MQTT

이 글은 IoT 장치들간 연결에 사용되는 오픈소스인 노드레드(NODE-RED)를 사용하는 방법을 간단히 나눔한다. 이 글은 IoT 구현을 위해 노드레드, NodeMCU를 사용한다.

노드레드는 IBM에서 IoT 시스템 개발 지원하는 오픈소스 플랫폼이다. 노드레드를 이용하면, 코딩할 필요없이 다양한 IoT 프로토콜, 입출력 연결을 손쉽게 처리할 수 있다. 노드레드는 아파치 라이센스 2.0을 지원하기 때문에 라이센스 규약만 지키면 상용 패키지를 개발하는 데 큰 문제가 없다.

이 글은 노드레드를 이용해 다음과 같이 IoT 장치와 MQTT방식으로 데이터 교환을 하는 간단한 IoT 시작품 만드는 방법을 보여준다.
노드레드로 만든 간단한 IoT 데쉬보드 테스트
nodered.org 소개

노드레드 설치
설치는 간단하다.

1. Node.js 설치
노드 레드는 노드JS를 사용한다. 우선 아래 링크에서 Node.js LTS 버전을 다운로드 받아 설치한다.

2. Node.js 명령 콘솔 실행 및 버전 확인
다음과 같이 설치된 메뉴 중에 command prompt 메뉴를 실행한다.
실행 후, 다음 명령어로 노드JS 설치 버전을 확인한다.
node --version; npm --version

3. node-red 및 데쉬보드 설치
다음 명령어로 node-red와 데쉬보드를 설치한다. 참고로, node-red는 데쉬보드와 같이 다양한 추가 플러그인을 지원한다.
npm install -g node-red
npm i node-red-dashboard

4. node-red 실행
다음 명령으로 node-red를 실행한다. 만약, network security error (PPSecurityException)발생하면 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned 명령을 터미널에서 실행한다.
node-red

5. node-red 웹브라우저 실행
크롬을 실행한 후 http://127.0.0.1:1880/ 에 접속하면, node-red GUI를 확인할 수 있다. 

노드레드 사용
IoT 시스템 디자인
우리는 MQTT란 IoT 표준 프로토콜을 이용해, NodeMCU 에서 얻은 센서값을 노드레드에 전달해 줄 것이다. 이를 위해, MQTT 데이터를 저장하고 있어야 할 MQTT 브로커가 있어야 한다. 브로커는 http://test.mosquitto.org 란 오픈소스 서버를 사용하기로 한다. 이 서버는 공개이며 무료로 사용할 수 있다.

아울러, 노드레드에서 NodeMCU로 MQTT 데이터를 전달하는 예제도 구현할 것이다. NodeMCU에 전달할 데이터는 단순히 NodeMCU에 연결된 LED를 켜고 끄는 데 사용한다. 

참고로, 센서값과 LED ON/OFF는 노드레드에서 제공하는 데쉬보드를 이용해 GUI를 쉽게 구현할 수 있다. 

NodeMCU 회로 구성 및 코딩
1. 회로구성
다음과 같이 NodeMCU 회로를 구성한다.


   D4 PIN = LED +
   GND PIN = LED -
   GND PIN = 10K 저항 끝단
   A0 PIN = 10K 저항 반대 끝단
   A0 PIN = 조도센서 끝단
   3.3V PIN = 조도센서 반대 끝단

참고로, NodeMCU 핀번호는 다음과 같다. 

2. 코딩
컴퓨터와 NodeMCU를 USB케이블로 연결한다. 그리고, 아두이노 IDE를 실행하고, 툴>보드 메뉴에서 NodeMCU 1.0을 선택하고, 툴>포트 메뉴에서 NodeMCU와 연결된 포트를 선택한다.

다음 코드를 붙여넣고, 코드에서 WiFi ssid와 pwd를 수정한 후, NodeMCU 보드에 업로드한다.

 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
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* mqtt_server="test.mosquitto.org";
WiFiClient espclient;

void callback(char* topic,byte* payload,unsigned int length1){    
  Serial.print("message arrived[");
  Serial.print(topic);
  Serial.println("]");
  
  String data = "";
  for(int i=0;i<length1;i++)
    data = data + payload[i];     
  Serial.println(data);
  Serial.println(payload[0]);

  if(payload[0] == 48)      // if(data == "48")
  {
    digitalWrite(D4, LOW);  //ASCII VALUE OF '0' IS 48
    Serial.println("off");
  }
  else if(payload[0] == 49) // else if(data == "49")
  {
    digitalWrite(D4, HIGH);   //ASCII VALUE OF '1' IS 49
    Serial.println("on");
  }
}

PubSubClient client(mqtt_server,1883,callback,espclient);

void setup() {
  pinMode(D2,OUTPUT);
  Serial.begin(115200);
  Serial.print("connecting");
  WiFi.begin("ssid","pwd");         //SSID,PASSWORD 
  while(WiFi.status()!=WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  digitalWrite(LED_BUILTIN, HIGH); 
  
  reconnect();
}

void reconnect(){
  while(WiFi.status()!=WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }
  while(!client.connected()){
    if(client.connect("ESP8266Client123456789")){
      Serial.println("connected");
      client.subscribe("ledcontrol");
    }
    else{
      Serial.print("failed,rc=");
      Serial.println(client.state());
      delay(500);
    }
  } 
}

int now = 0;
int lastMeasure = 0;

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

  // Timer variable with current time
  now = millis();
  if (now - lastMeasure > 3000) {
    lastMeasure = now;
    int value = analogRead(A0);
    String data = String(value);
    client.publish("sensor/light", data.c_str());  
  }
}

노드레드 디자인
1. MQTT 노드 설정과 LED ON/OFF 버튼 생성
우선, 노드레드의 입력>mqtt 를 Drag&drop으로 생성한다. 생성된 mqtt노드를 더블클릭해, 다음과 같은 속성창에서 http://test.mosquitto.org 서버(포트 = 1883) 추가하고, 토픽명은 ledcontrol, QoS=0 으로 설정한다.

버튼을 2개 추가하고, 속성을 다음과 같이 각각 설정한다. 참고로, Group에 설정된 값은 데쉬보드에 함께 표시되는 그룹을 결정한다.
LED ON 버튼 설정

LED OFF 버튼 설정

방금 만든 MQTT와 버튼 2개를 다음과 같이 연결한다.

2. 조도센서 MQTT 노드 생성과 데이터 확인용 debug 생성
MQTT노드를 하나 더 추가하고, 아래와 같이 토픽=sensor/light 로 설정한다. 

데쉬보드에서 debug를 만들고, mqtt와 서로 연결한다.

debug의 속성은 다음과 같이 설정한다.

3. 조도센서 MQTT 노드 생성과 데이터 확인용 guage 생성
방금 만든 mqtt (sensor/light)를 복사해 붙여넣어 하나 더 만든다. 
그리고, 데쉬보드에서 다음과 같이 gauge를 만든 후 서로 연결한다.

gauge의 속성은 다음과 같이 설정한다.

이렇게까지 하면, 다음과 같이 노드레드가 구성되었을 것이다. 

데쉬보드 Layout 탭을 선택해 다음과 같이 탭, 그룹을 디자인한다. 다음과 같이 on, off, gauge를 정의한다.

4. 노드레드 설정 배포 및 데쉬보드 확인
이제 배포하기를 클릭한다. 그리고 디버그 탭을 선택한다. 다음과 같이 NodeMCU에서 MQTT로 전달받은 데이터가 로그로 출력되고 있을 것이다. 

Layout 탭의 화살표 아이콘을 클릭하면 데쉬보드가 다음과 같이 실행된다. 

ON/OFF 버튼을 클릭해 보자. 몇초후에 NodeMCU 에 연결된 LED가 동작할 것이다.

차트도 다음과 같이 추가해 mqtt와 연결해 보자. 

다시 배포한 후 데쉬보드를 확인하면, 다음과 같이 차트가 추가된 것을 확인할 수 있다.
노드레드 데쉬보드 결과

만약 좀 더 좋은 사용자 인터페이스가 필요하다면 그라파나(grafana)를 사용할 수도 있다. 참고로, 그라파나는 코딩하지 않고 데이터 소스를 연결해 시각화하는 모니터링 도구로 아파치 라이센스 2.0을 준수하고 있다.

마무리
앞에서 IoT 데이터를 NodeMCU로 부터 MQTT 프로토콜로 받아 데쉬보드로 확인하는 것까지 해 보았다. 노드레드로 하지 않았다면, MQTT 코딩부터 데쉬보드 구현까지 많은 시간이 걸렸을 것이다. 이 과정은 코딩이 불필요하며, 익숙해 지면 몇십분만에 끝낼 수 있다.

노드레드는 오픈소스로 자기 컴퓨터를 서버로 운영하여 데이터를 저장할 수 있으고, 메일, 트위터, MQTT 등 다양한 입출력 유형을 제공하여 가성비가 매우 좋다. 데쉬보드는 N-screen을 지원하여, 크롬, 스마트폰 등을 모두 지원한다.

레퍼런스

2019년 5월 18일 토요일

구글 코랩(Colab)으로 쉽게 딥러닝 해 보기

딥러닝할때 많은 사람들이 환경 설정으로 애를 먹는다(환경 설정이 50%). 딥러닝 환경을 구축은 여러가지 방법이 있다.

1. 우분투 기반
2. 아나콘다 기반
3. 도커 이미지 기반
4. 아마존 웹 서비스 기반 (링크 참고)

물론, 아래로 갈수록 설치할 필요가 없고 쉬워진다. 다만, 정해진 용량 이상 사용하면 과금이 발생한다. 물론, 직접 딥러닝 서버와 데이터센터를 구축하고 싶은 사람들은 1, 2 옵션을 좋아할 것이다.

본인이 진행한 핸즈온은 도커로 미리 준비된 keras-full 로 진행한 것이었는 데, 회사 공식 컴퓨터 실임에도 불구하고 사내 방화벽, 열악한 인터넷 환경이 문제를 일으켰다. 도커부터 이미지 설치까지 미리 공지했었으나, 열정만 갖고 오신 분들도 계셔서 직접 체험하지 못한 분들이 있었다(이분들에게 본의아니게 시켜 좌절 경험시켜 드려 마음 한켠 짐이 생겨 버림. 이런 말도 안되는 환경에서 설치한다는 것은 네트워크 전문가 십만명이 와도 불가능한 것이다).

잠깐 머리에 스쳐간 4번 카드는 제일 편하지만, 개인적으로 AWS 옵션이 켜져 몇 달동안 계속 돌아가는 바람에 계정에 락이 걸려 버렸다(아마존 나쁘다).

그래서, 구글신에게 물어보기로 함.

공짜로 딥러닝 라이브러리 설치 않하고 사용할 수 있는 방법은 없나요?

구글신이 말씀하시길 코랩이 공짜고 AWS보다 좋다 하여, 당장 시작해보았다.

코랩은 colaboratory의 약자로 구글에서 제공하는 클라우드 기반 개발 도구이다. 쥬피터 노트북과 매우 비슷하다. 아래 링크를 클릭하면 바로 경험해 볼 수 있다.


여기서 나타나는 창의 메뉴 중 새 PYTHON 3 노트 메뉴를 클릭해 소스파일을 하나 생성해 본다.

모든 라이브러리가 설치되어 있지 않겠지 싶어, 그리 기대하지 않고 LSTM 코드(링크) 입력하고 돌렸음. 너무 과했나 싶었는 데, 어~ 잘 돌아가네.
아무 문제 없이 돌아간 LSTM

구글 드라이브와 연동되는 코랩

게다가 구글 드라이브와 연동되어 소스코드도 자동 저장해 준다. 클라우드 서버 랩 12기가, 디스크 50기가도 공짜다 (감동의 물결 T.T~).

물론, 이 공간도 다 차면 AWS처럼 돈 달라 하겠지만, 일단 딥러닝 핸즈온 강의할 때 환경 설정 개고생 안해도 된다. 참고로, 코랩은 미리 만들어 놓은 개발 튜토리얼과 영상을 제공한다(정말 인자하시다).

여기서 제공하는 튜토링얼 중에 CNN 모델 기본 예제인 MNIST 를 실행해 보았다(링크). 아래와 같이 98.5%의 정확도로 학습된다.
이 모델에서 잘 못 예측한 사례를 보면 다음과 같다(사람도 헤깔리는 글씨체).

오픈된 이미지 데이터인 CIFAR10으로 테스트해보았다.

CNN모델은 Google에서 제공해 주는 것을 활용했다(여기 클릭). 큰 문제 없이 학습이 된다.

데이터셋 각 세대별 CNN 모델 훈련 모습

VGG 모델도 실행해 보자(여기 링크). 이 링크 예제를 실행하기 전에 COLAB 클라우드 저장소에 아래 코드로 door1.jpg 이름의 3차원 건축 모델을 업로드해야 한다.
from google.colab import files
uploaded = files.upload()
코드를 COLAB으로 붙여넣기하고, 실행하면 다음과 같이 건축 객체를 인식하는 것을 확인할 수 있다.

참고로, 이 예제를 실행할 때, 미리 딥러닝 환경과 패키지를 설치하는 개노다가는 전혀 하지 않았다.

사람이란 간사하다. 얼마전까지 내 PC에서 딥러닝 환경 만들어야 그것들(G사, A사 포함)에 종속되지 않는다고 떠들어 댔건만.. 구글신 고마워요.

참고 - 아마존 클라우드 EC2 Deep Learning Instance 사용하기
아마존 클라우드에서 Deep Learning 사용은 매우 쉽다. AWS 콘솔에 로긴한 후 EC2 클라우드 서비스를 실행하고, 미리 만들어 놓은 Deep Learning 이미지 인스턴스를 실행하면 된다. 인스턴스는 도커 같은 컨테이너에서 실행된다. 이미지는 기본적으로 keras, tensorflow 등 많이 사용되는 패키지를 설치해 놓았으며, NVIDIA, CUDA등 설치가 번거로운 드라이버들을 미리 설정해 놓았기 때문에 그냥 사용만 하면 된다. 보안 등 기본적인 서버 관리는 아마존이 해 준다.
다만, 인스턴스 리소스(네트워크, CPU사용시간, 저장소 사용용량 등)에 따라 기본용량을 넘거가면 과금된다.

자세한 내용은 AWS Deep Learning Instance 사용 링크를 참고하길 바란다.

레퍼런스
  1. 강태욱, 2017, 텐서플로우 MNIST 딥러닝 및 텐서보드 그래프 가시화
  2. 강태욱, 2018, 케라스 기반 이미지 인식 딥러닝 모델 구현
  3. Sebastian Norena, 2018, How to get Images from ImageNet with Python in Google Colaboratory
  4. Google, MNIST handwritten digits classification with CNNs
  5. Google, Cifar10 Keras with Colab
  6. Ricardo's Place, 2019, Direct access to your webcam and microphone inside Google Colab notebook
  7. DLology, 2018, How to run Object Detection and Segmentation on a Video Fast for Free
  8. Chibuk, Tutorial to Build a Convolutional Neural Network for Images with keras+google drive and google colaboratory (exploring Google's colab tool)
  9. Google Colab (Jupyter) notebook to retrain Object Detection Tensorflow model with custom dataset.
  10. Object Detection in Google Colab with Custom Dataset
  11. Train a model in tf.keras with Colab, and run it in the browser with TensorFlow.js
  12. Mask R-CNN with OpenCV
  13. Autonomous driving - Car detection
  14. CNN Part 1: Understanding the working of Convolutional Neural Network