'ThingSpeak'에 해당되는 글 3건

  1. 2020.08.11 Software | Blynk 사용해 보기
  2. 2020.03.18 Hardware | CO2 센서인 MH-Z14A 를 활용해 보자 2
  3. 2020.03.15 Software | ThingSpeak 등록하여 IoT 데이터 펼처보기

Software | Blynk 사용해 보기

|

Arduino 나 ESP8266 을 사용하면서, sensor 로부터 받은 데이터를 표현해주는 방법이 몇 가지 있습니다.

일전에는 ThingSpeak 라는 것을 사용해 봤었죠.


* Software | ThingSpeak 등록하여 IoT 데이터 펼처보기

https://chocoball.tistory.com/entry/Software-ThingSpeak-IoT-monitoring


어느 분께서 댓글 달아 주시길, Blynk 도 좋다고 합니다. 사용해 봤습니다.





1. Blynk 란?


Data 는 있지만, 그 값들을 이해하기 쉬운 방법으로 표시해 주고 모니터링 해주는 어플리케이션 이죠.



클라우드 펀딩으로 시작한 솔루션 입니다.


* Blynk - build an app for your Arduino project in 5 minutes

- https://www.kickstarter.com/projects/167134865/blynk-build-an-app-for-your-arduino-project-in-5-m



Arduino project 를 5분만에 시작할 수 있다고 하지만, 숙련된 사람 이야기 이고, 학습하는 시간이 필요합니다.

다만, 각 프로젝트에 따른 예시나 모듈이 잘 되어 있어서, 하다 보면, 아니... 이렇게 쉽게? 라는 생각이 잠시 드는 때도 있습니다.


KickStarater 클라우드 펀딩을 성공적으로 마무리 하고, 아래 사이트에서 정식 런칭하였습니다.


* Blynk Inc

https://blynk.io/





2. Library 설치


저는 Arduino / ESP8266 에서 받은 값을 전달할 목적이므로, Arduino IDE 에서 모듈을 인스톨 합니다.


Tools > Manage Libraries > Blynk


모듈이 인스톨 되면, Arduino > libraries 에 등록 되어 있는 것을 확인 할 수 있습니다.



자동으로 설치해 주는 방법 외에도, 수동으로 파일을 받아서 설치 할 수도 있습니다.


* Blynk Arduino Library

https://github.com/blynkkk/blynk-library/releases/latest





3. App 설치


프로그래밍을 위한 환경이나 라이브러리가 설치되었으면, 실제로 그 값들을 모니터링 하고 확인할 수 있는 인터페이스가 필요합니다.

Blynk 는 모바일 환경에 최적화가 되어 있으므로, 스마트폰에 관련 어플을 설치합니다.


평점이 좋네요.





4. Project 시작하기


모바일앱에서 어플을 시작하면, 등록이 나옵니다.



Facebook 계정 연동으로 시작해도 되나, 저는 그냥 email 로 사용자 등록 하였습니다.



계정을 만들고 로그인 합니다.



New Project 를 선택합니다. My Apps 메뉴를 이용해서, 개인 전용앱 처럼 꾸밀 수도 있다고 합니다.



시작할 새로운 Project 는 주로 어떤 IoT 기기와 연결될 것 인지를 선택합니다.

저는 ESP8266 을 이용하여, WiFi 연결 뿐만 아니라, arduino 처럼 처리도 시킬 것이기 때문에, ESP8266 을 선택 했습니다.



포름알데히드 센서를 이용한 그래프 모니터링용 이니, 그에 맞게 Title / Device / Connection Type 을 선택해 줍니다.

저는 Formaldehyde / ESP8266 / WiFi 를 선택 했습니다.



Create Project 를 최종적으로 누르면, 새로 생성한 project 에 대한 전용 인증 코드가 생성됩니다.

이 코드는 project 마다 유니크 하며, 메일로도 알려 줍니다.



계정 생성시 사용 했던 email 로 관련된 정보가 왔습니다.


Auth Token





5. 소스코드 생성


누가 5분만에 가능하다 했나... 5분은 여기까지 오느라 훨씬 지났습니다.

다만, 코딩을 쉽게 도와주기 위해 "Sketch generator" 라는 메뉴가 준비되어 있어요.


* Sketch generator

https://examples.blynk.cc/


접속하면, 아래처럼 Board (Device) / Connection 방법 / Auth Token 및 예시를 선택하면 소스코드를 만들어 줍니다!



이 페이지에서 만들어준 기본 코드에, 포름알데히드 측정에 사용되었던 코드를 살짝 추가 하였습니다.


Blynk 사용하지 않은 코드


#include "ze08_ch2o.h"
#include "SoftwareSerial.h"
 
// Instantiate a serial port, whatever Stream you have
// SoftwareSerial ch2oSerial(4, SW_SERIAL_UNUSED_PIN); // RX, TX
SoftwareSerial ch2oSerial(14, 14); // RX, TX
 
// Instantiate a sensor connected to the previous port
Ze08CH2O ch2o{&ch2oSerial};
 
void setup() {
    ch2oSerial.begin(9600);
    ch2oSerial.listen();
    Serial.begin(115200); // Serial Monitor
}
 
void loop() {
    Ze08CH2O::concentration_t reading;
     
    if (ch2o.read(reading)) {
        Serial.print("New value: ");
        Serial.println(reading);
    }
}



Blynk 기능을 입힌 코드


#include "ze08_ch2o.h"
#include "SoftwareSerial.h"

SoftwareSerial ch2oSerial(14, 14); // RX, TX
Ze08CH2O ch2o{&ch2oSerial};

int sensorData;

/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial

#include "ESP8266WiFi.h"
#include "BlynkSimpleEsp8266.h"

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXXXXXXXXXX";
char pass[] = "YYYYYYYYYYYYYYYYYYY";

BlynkTimer timer;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
void myTimerEvent() {
	// You can send any value at any time.
	// Please don't send more that 10 values per second.
	
	Ze08CH2O::concentration_t reading;
	if (ch2o.read(reading)) {
		Serial.print("ZE08-CH2O : ");
		Serial.println(reading);
		
		sensorData = reading;
	}
	Blynk.virtualWrite(V5, sensorData);
}

void setup() {
	// Debug console
	Serial.begin(115200);
	
	ch2oSerial.begin(9600);
	ch2oSerial.listen();
	
	Blynk.begin(auth, ssid, pass);
	// You can also specify server:
	//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
	//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
	
	// Setup a function to be called every second
	timer.setInterval(5000L, myTimerEvent);
}

void loop() {
	Blynk.run();
	timer.run(); // Initiates BlynkTimer
}


위의 Before / After 를 비교해 보면, "Sketch generator" 코드에서 자동으로 만들어준 소스에, 원래 소스를 살짝 입히기만 했습니다.

참 쉽죠?! 제가 작업한 것은 다음 세 가지 뿐 입니다.


- 기본 소스 코드 생성 (이것 마저도 인터넷에서 따옴)

- Sketch generator 이용하여 Blynk 연결 소스 만듬

- Auth Token / WiFi 접근 SSID / Password 적용


가장 눈여겨 들여다 봐야 할 부분은 아래 코드 부분입니다.


	Blynk.virtualWrite(V5, sensorData);


Blynk 는 ESP8266 / ESP32 등에서 받는 data 값 들을, 가상의 Pin 으로 보내는 기능이 있습니다.

Analog / Digital 값들이 다양한 Pin 들을 통해 들어온다 하여도, Blynk 로 보낼 때에는 하나의 가상 Pin 으로 고정해서 보낼 수 있습니다.


이렇게 되면, Device 가 변경되더라도 Blynk 앱에서는 변경을 하지 않아도 됩니다. 자세한 내용은 아래 링크를 참고해 보세요.


* What is Virtual Pins

http://help.blynk.cc/en/articles/512061-what-is-virtual-pins


* How to display ANY sensor data in Blynk app

http://help.blynk.cc/en/articles/512056-how-to-display-any-sensor-data-in-blynk-app





6. ESP8266 에서 실행


ESP8266 에 소스를 입히고 실행시키면, 다음과 같은 화면이 Serial Monitor 에 출력 됩니다.


[5220] Connected to WiFi
[5221] IP: 192.168.1.90
[5221] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.6.1 on ESP8266

[5227] Connecting to blynk-cloud.com:80
[5586] Ready (ping: 125ms).
ZE08-CH2O : 66
ZE08-CH2O : 112
ZE08-CH2O : 114
ZE08-CH2O : 117
ZE08-CH2O : 116
ZE08-CH2O : 114
...


ASCII code 를 이용하여 Blynk 문자를 잘 만들었네요 :-)



Library 는 Heartbeat 를 통한 연결상태 확인도 해주는 군요. 잘 만들어져 있습니다.



여기까지 진행하면 ESP8266 에서 할 것은 이제 다 했습니다.




7. Blynk 모바일앱에서 설정


Blynk 로 데이터는 들어오고 있으니, 받을 수 있도록 연동 설정하면 됩니다.

데이터를 표현해주는 방법은 여러 가지가 있으나, 대략 Gauge / SuperChart 로 해결 됩니다.


스마트 폰에서 Create Project 후에 나오는 빈 화면 아무곳을 터치하면, Widget Box 가 아래처럼 뜹니다.

건전지 아이콘에 2000 크레딧이 미리 충전 (무료) 되어 있습니다.

이걸 다 쓰면, 돈을 충전해서 사용해야 합니다. 각 메뉴 추가시 크레딧이 차감되니 신중하게 위젯을 만들어야 합니다.



처음에 멋도 모르고 "Value Display" 를 설정 했더랬습니다. 그냥 조금하게 값만 표시됩니다.



역시 데이터 값 표현은 차트죠. SuperChart 만들어 봅니다.

PIN 정보는 항상 "Virtual 5 PIN" 으로 했습니다만, 다른 Pin 들도 다이렉트로 사용할 수 있나 봅니다.



만들어진 위젯에 손가락을 잠깐 동안 올려 놓으면, 위치를 이동 시킬 수 있습니다.



이제 센서 값들의 모니터링은 일상으로 사용하는 스마트폰에서 바로바로 확인이 가능하게 됩니다.

웹페이지를 띄울 필요도 없고, 인증을 걸 필요도 없이, 하나의 앱 처럼 사용할 수 있어서 편하긴 합니다.




FIN


And

Hardware | CO2 센서인 MH-Z14A 를 활용해 보자

|

1. 이산화탄소


이산화탄소는 지구로 들어 왔다가 빠져나가는 태양광 복사열을 차폐하여 온실효과를 내는 주범 입니다.

매년 기온이 상승하고 있습니다. 기온 상승으로 인하여 지구에서는 지금까지 겪지 못했던 일들이 일어나고 있죠.


전 지구적으로 본다면, 과거로부터 CO2 의 농도 변화는 일정한 주기를 가져 왔습니다.



하지만, 현재의 CO2 농도는 과거의 주기적인 범위에서 한참을 벗어나 있습니다.

측정 데이터를 가지고 본다면, 산업혁명 이후 꾸준히 증가 중 이라는 것을 알 수 있습니다.



산업혁명 이전은 280 ppm 이하였고, 그 이후 약 300년 사이에 140 ppm 정도 늘었습니다.

옛날과 비교하면 150% 가 되어있는 셈 입니다. 수백만년동안 일정한 주기를 가지던 패턴이 300년 동안 완전히 붕괴된 것이죠.


예전 개그 프로에서 봤던, 공기좋은 알프스에서 채집한 공기를 깡통에 넣어 팔아도 되는 시대가 올지도 모르겠습니다.



참고로, 현재 우리가 살고 있는 "요즈음" 은, 410 ppm 정도가 일반적인 수치임을 위의 그래프를 통해 알 수 있습니다.




2. MH-Z14A


생활 공간의 쾌적한 조성은, 삶에 있어서 행복감을 줄 수 있는 요소 중 하나 입니다.


이를 위해, 산소 발생기를 만들어 볼 생각이 났습니다.

다만, 산소 발생기를 만들더라도, 현재의 상황 - 농도 - 를 알고 있어야 조정이 가능하니, CO2 측정 방법을 찾아 봅니다.


CO2 센서로는 몇 가지가 존재하나, MH-Z14A 라는 것이 심심치 않게 사용되고 있네요.

거의 2만원이 넘는 가격이지만, 구입합니다. 기체 포집 센서들은 꽤나 가격이 높게 형성되어 있습니다.


* Free shipping NDIR CO2 SENSOR MH-Z14A infrared carbon dioxide sensor module,serial port, PWM, analog output with cable MH-Z14

https://www.aliexpress.com/item/Free-shipping-NDIR-CO2-SENSOR-MH-Z14A-infrared-carbon-dioxide-sensor-module-serial-port-PWM-analog/32617820781.html



센서의 스펙은 다음과 같습니다.


Product Name: MH-Z14A infrared type, carbon dioxide detection sensor
1. the working voltage: DC 4.5-5.5V
2. Working current: Mean < 60mA; peak 150mA
3. the detection range: 0-5000ppm
4. the detection accuracy: ± (50ppm + 3% reading value)
5. Warm-up time: 3min
6. the output signal:
   1) analog output voltage: (D1 port 0V-2.5V) (D2 port 0.4-2V) linear output
   2) serial port (UART) (TTL level)
   3) PWM
7. response time: T90 < 120s
8. the working temperature: 0-50C
9. Humidity: 0-95% RH
10. life: 5 years
11. size: 57mm X 35mm X 15mm
12. weight size: 17g

Package Including: 1pcs X CO2 sensors



3. 도착


도착샷은 예의.



평범하게 배달.



리본 케이블이 딸려 있습니다만, pin hole 로도 연결이 가능합니다.



뒷면은 레귤레이터와 신호 처리 chip 이 달려 있습니다. 그리고 방수 코팅도 되어 있네요.





4. 통신 과 연결 방법


메뉴얼과 스펙 문서를 첨부합니다.


mh-z14a_co2-manual-v1_01.pdf

mh-z14_co2.pdf


문서를 보니, 이 센서와 통신할 수 있는 방법은 3가지가 됩니다. 각각의 사용법은 밑에서 다뤄 보겠습니다.


Analog

PWM

UART (RX/TX)


Pin header 정보 입니다.



리본 케이블을 사용할 경우, 각 선의 의미는 아래 그림과 같습니다.



새로 납땜해야 하는 pin header 말고, 리본 케이블을 사용하여 깔끔하게 연결해 보도록 하겠습니다.



5. 리본 케이블용 커넥터


리본 케이블을 이용하여 예쁘게 연결하고 싶으니, 리본 케이블 커넥터나 연장을 생각해 봅니다.

일단 측정해 봅니다. 대략 1mm 정도 되겠네요. 아래 규격일 듯 합니다.


* JST SH 1.0mm

- http://www.jst-mfg.com/product/detail_e.php?series=231



알리에서 검색해 보니, 아래 제품이 맞을 듯.

* 10 sets 1.0mm 1.25mm 1.5mm 2.0 2.54mm 2PIN /3/4/5/6/12P Pin Male & Female PCB Connector SH JST ZH PH XH 2 Pin
    - https://www.aliexpress.com/item/32733307616.html



잘 도착 했습니다.



커넥터의 female / male 이 짝으로 도착했습니다.



도착한 커넥터와 센서에 딸려 나온 커넥터를 비교해 보니... 덴장.

기존 커넥터의 pin 피치를 비교해 보면, 좀더 조밀합니다.



빵판이나 일반적인 연결 용도로 사용되는 (2.54mm) Pin connector 도 주문 했더랬습니다.

빵판에 prototype 회로를 만드려면, pin 이 필요하니까요.


* 100PCS 2.54mm Dupont Jumper Wire Cable Housing Female/Male Pin Connector Terminal Kit
    - https://www.aliexpress.com/item/32908083223.html



암수 모양 한세트를 주문 했습니다.



이걸 제대로 사용하기 위해선는 찝는 툴이 필요하다는 것을, 물건 받아보고 나서야 깨닫습니다.



한가지 아쉬운건, 캐스팅 된 핀이 아니라, 프레스된 철판을 구부려서 만든 모양 입니다.



프레스로 된 pin 은 잘 구부러질 뿐만 아니라, 빵판 안에서 부러져 버리면 꺼낼 수가 없어, 죽은 소켓이 되어버리기 때문입니다.
(그래 뽰자 큰 영향은 없지만...)




6. 연결은 결국...


결국 빵판에 연결 방법으로는, 선 끝을 자르고, 기존 pin 을 이식하는 것으로 정했습니다.



Female 소켓에서 한 땀 한 땀 분리합니다.



혹시? 하고 이것 그대로 직접 연결하면 어떨까 하여 연결해 보니, 진동에 의한 결선 이탈이 쉽게 일어나므로 포기.



원래 생각했던 대로, pin 달린 jumper 에서 pin 만을 잘라 이식합니다.



선을 서로 꼬아준 다음, 납땜해 주고, 수축튜브 이용하여 마무리 했습니다. (완벽)



드디어 arduino 와 연결하여 측정이 가능하게 되었습니다.




7. UART


우선 아래 blog 를 많이 참고했습니다.


* Dr. Monk's DIY Electronics Blog

- http://www.doctormonk.com/2018/03/review-and-test-of-mh-z14a-ndir-co2.html


다만, 위의 링크에서 제시한 UART (Software Serial) 포트를 Arduino 의 digital pin 로 측정하는 것은 잘못된 방법입니다.

Analog pin 에 RX/TX 를 접속 시켜야 하며, PWM / Analog 입력을 동시에 받으면, 모든 값이 뒤틀립니다.

그래서 UART 따로, PWM / Analog 를 따로 측정해 봤습니다. (많은 삽질의 결과)


우선 UART. 센서에 3.3V 를 먹이고, TX/RX 를 analog pin 에 연결하여 데이터를 받습니다.



처음으로 센서를 동작시켜본 기념으로 동영상을 올립니다.

센서 가동중에는 네 귀퉁이에 어렴풋이 불이 켜졌다가 꺼지기를 반복합니다.


참고로, TX / RX 에 접속시킨 채로 sketch 를 upload 하면 error 가 나는군요.


#include "SoftwareSerial.h"

const long samplePeriod = 10000L;

SoftwareSerial sensor(A2, A3); // RX, TX
const byte requestReading[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
byte result[9];
long lastSampleTime = 0;

void setup() {
  Serial.begin(9600);
  sensor.begin(9600);
}

void loop() {
  long now = millis();
  if (now > lastSampleTime + samplePeriod) {
    lastSampleTime = now;
    int ppmS = readPPMSerial();
    Serial.println(ppmS);
  }
}

int readPPMSerial() {
  sensor.flush();
  for (int i = 0; i < 9; i++) {
    sensor.write(requestReading[i]); 
  }
  
  while (sensor.available() < 9) {}; // wait for response
  for (int i = 0; i < 9; i++) {
    result[i] = sensor.read(); 
  }
  int high = result[2];
  int low = result[3];
  return high * 256 + low;
}


결과 입니다. UART 는 값 보정이 필요해 보입니다.


보정을 위해서는 기준값을 알아야 하는데, 기준값을 도출하기 위해서는 정확히 조성된 환경에서 보정작업이 이루어져야 합니다.

저는 그런 환경이나 챔버가 없으므로, calibration 은 무시.





8. Analog / PWM


그나마 현실적인 값을 도출하는 Analog 와 PWM 값 확인 입니다.


#include "SoftwareSerial.h"

const int analogPin = A0; // analog pin
const int pwmPin = 6; // digital pin

const long samplePeriod = 10000L;

long lastSampleTime = 0;

void setup() {
  Serial.begin(9600);
  pinMode(pwmPin, INPUT_PULLUP);
}

void loop() {
  long now = millis();
  if (now > lastSampleTime + samplePeriod) {
    lastSampleTime = now;
    int ppmV = readPPMV();
    int ppmPWM = readPPMPWM();
    Serial.print(ppmV); 
    Serial.print("\t"); 
    Serial.println(ppmPWM); 
    }
}

int readPPMV() {
  float v = analogRead(analogPin) * 5.0 / 1023.0;
  int ppm = int((v - 0.4) * 3125.0);
  return ppm;
}

int readPPMPWM() {
  while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high
  long t0 = millis();
  while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
  long t1 = millis();
  while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high again
  long t2 = millis();
  long th = t1-t0;
  long tl = t2-t1;
  long ppm = 5000L * (th - 2) / (th + tl - 4);
  while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
  delay(10); // allow output to settle.
  return int(ppm);
}


결과값은 다음과 같습니다. 왼쪽이 Analog 값, 오른쪽이 PWM 입니다.



위에서 알 수 있듯, 값의 변화나 지구의 CO2 농도를 참고했을 때, PWM 이 좀더 현실적인 값이 아닌가 합니다.




9. WiFi 연결


일반적으로 센서를 가지고 변화 추이를 확인하려면, 상당히 긴 시간동안의 데이터를 수집해야 합니다.

지금까지는 PC를 켜 놓고 Arduino IDE 의 Serial Monitor 를 사용하여 측정 했었습니다.


Cloud 시대인 만큼, 이번에는 WiFi 를 이용하여 ThingSpeak 에 측정 데이터를 보내주기로 합니다.

ThingSpeak 등록 및 기본 사용법은 아래 포스트에서 다뤘습니다.


* Software | ThingSpeak 등록하여 IoT 데이터 펼처보기
    - https://chocoball.tistory.com/entry/Software-ThingSpeak-IoT-monitoring


힘들었던 것은, ESP-01 의 WiFi command 를 이용하여, 필요한 command 를 하나씩 확인하는 작업이었습니다.



위 스샷은 "AT+CIPMUX" 를 통하여 single channel / multi channel 통신을 정의하는 것 입니다.

값에 "0" 을 정의하면 single 이고, 1~4 숫자면 multi channel 입니다.


참조한 블로그 처럼, Multi Channel 을 이용하면 좋을 듯 하지만,

다른 명령어에서 channel 번호를 명시해야 하는 등 번거로워서 Single Channel 설정으로 "AT+CIPMUX=0" 이용.


이외 명령어들은, 연결할 호스트 정의 및 HTTP data 전송에 관련한 부분입니다.


AT+CIPMUX=0
AT+CIPSTART="TCP","api.thingspeak.com",80
AT+CIPSEND=49
GET /update?api_key=XXXXXXXXXXXXXXXX?field1=351
AT+CIPCLOSE


- AT+CIPMUX=0 > Single Channel 로 통신 시작

- AT+CIPSTART="TCP","api.thingspeak.com",80 > 연결할 host 명과 port 정의
- AT+CIPSEND=49 > 전송할 데이터 사이즈를 미리 정의
- GET /update?api_key=XXXXXXXXXXXXXXX?field1=351 > HTTP GET request
- AT+CIPCLOSE > session close



위는 FTDI 를 이용하여, 직접 Serial Monitor 를 이용하여 WiFi 통신"만" 테스트해 보는 스샷입니다.

FTDI 를 이용한 자세한 활용 방법은 아래 글에서 다뤘습니다.


* Hardware | ESP-01 or ESP8266 사용기 - 2
    - https://chocoball.tistory.com/entry/Hardware-ESP01-or-ESP8266-using-2


참고한 blog 의 소스에는 ">" 캐릭터가 나오면 send 명령어를 실행하게끔 되어 있습니다만, 실패가 계속 나더군요.

테스트 해본 결과, 제가 가지고 있는 ESP-01 모듈은 ">" 이 나오기 전, "OK" 가 먼저 뜨므로, 기준을 "OK" 문자로 해야 합니다.


이렇듯, 소스를 하나하나 검증하면서 제대로 동작하는 command 들을 끼워 맞추기까지 오래 걸렸습니다.

없는 시간 쪼개어 가며 테스트하고 삽질하였더니만 2개월 정도 걸린 듯 합니다.




10. 최종 버전


아래는 arduino / MH-Z14A / ESP-01 간의 pin 연결표 입니다.


 MH-Z14A | Arduino Nano
------------------------
   PWM   |     D6
   GND   |     GND
   VCC   |     5V
------------------------


  ESP-01 | Arduino Nano
------------------------
   TX    |     D10
   RX    |     D11
   VCC   |     3.3V
   GND   |     GND
  CHPD   |     3.3V
------------------------


아래는 layout 입니다. 추가 전원을 위해 MB102 도 사용했습니다.



아래는 실제로 연결한 arduino nano / MH-Z14A / ESP-01 / MB102 입니다.



지금까지 확인한 내용이 모두 담긴 소스 입니다.


#include "SoftwareSerial.h"

// HM-Z14A
const int pwmPin = 6; // digital pin

// ESP-01
#define RX 10
#define TX 11
SoftwareSerial AT(RX, TX);

// WiFi
String ssid = "XXXXXXXXX"; //Wifi SSID
String password = "XXXXXXXXX"; //WiFi Pass
String apiKeyIn = "XXXXXXXXX"; // API Key
const unsigned int writeInterval = 25000; // write interval (in ms)

// ThingSpeak
String host = "api.thingspeak.com"; // API host name
String port = "80"; // port

int AT_cmd_time;
boolean AT_cmd_result = false; 

void setup() {
  Serial.begin(9600);
  pinMode(pwmPin, INPUT_PULLUP);
  
  // WiFi status
  Serial.println("---------- Program Start");
  AT.begin(115200);
  Serial.println("Initiate AT commands with ESP8266 ");
  sendATcmd("AT",5,"OK");
  sendATcmd("AT+CWMODE=1",5,"OK");
  Serial.print("Connecting to WiFi:");
  Serial.println(ssid);
  sendATcmd("AT+CWJAP=\""+ ssid +"\",\""+ password +"\"",20,"OK");
}

void loop() {
  // get CO2 data
  int ppmPWM = readPPMPWM();
  
  // Create the URL for the request
  String url = "GET /update?api_key=";
  url += apiKeyIn;
  url += "&field1=";
  url += ppmPWM;
  url += "\r\n";
  Serial.println("---------- Open TCP connection");
  sendATcmd("AT+CIPMUX=0", 10, "OK");
  sendATcmd("AT+CIPSTART=\"TCP\",\"" + host +"\"," + port, 20, "OK");
  sendATcmd("AT+CIPSEND=" + String(url.length()), 10, "OK");
  
  Serial.print("---------- requesting URL: ");
  Serial.println(url);
  AT.println(url);
  delay(2000);
  sendATcmd("AT+CIPCLOSE", 10, "OK");
  
  Serial.println("---------- Close TCP Connection ");
  Serial.println("");
  
  delay(writeInterval); // delay
}

// PWM function
int readPPMPWM() {
  while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high
  long t0 = millis();
  while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
  long t1 = millis();
  while (digitalRead(pwmPin) == LOW) {}; // wait for pulse to go high again
  long t2 = millis();
  long th = t1-t0;
  long tl = t2-t1;
  long ppm = 5000L * (th - 2) / (th + tl - 4);
  while (digitalRead(pwmPin) == HIGH) {}; // wait for pulse to go low
  delay(10); // allow output to settle
  return int(ppm);
}

// sendATcmd
void sendATcmd(String AT_cmd, int AT_cmd_maxTime, char readReplay[]) {
  Serial.print("AT command:");
  Serial.println(AT_cmd);
  
  while(AT_cmd_time < (AT_cmd_maxTime)) {
    AT.println(AT_cmd);
    if(AT.find(readReplay)) {
      AT_cmd_result = true;
      break;
    }
    
    AT_cmd_time++;
  }
  
  Serial.print("...Result:");
  if(AT_cmd_result == true) {
    Serial.println("DONE");
    AT_cmd_time = 0;
  }
  
  if(AT_cmd_result == false) {
    Serial.println("FAILED");
    AT_cmd_time = 0;
  }
  
  AT_cmd_result = false;
}


참조한 blog 에서는, URL 을 만들 때, 단순히 4 bytes 를 추가한 size 를 CIPSEND 하라고 했지만, 제대로 동작하지 않습니다.

Line feed / carriage return 을 GET method 뒤에 추가되어야 정상 동작 합니다. (아래 소스의 제일 마지막 줄)


...
  String url = "GET /update?api_key=";
  url += apiKeyIn;
  url += "&field1=";
  url += ppmPWM;
  url += "\r\n";
...

성공한 결과물을 Serial Monitor 로 확인해 보면 다음과 같습니다.

WiFi 연결 및 HTTP Get method 로 REST API 동작을 확인 할 수 있어요.





11. 결과


ThingSpeak 사이트에서 확인한 결과 입니다.



거실에 설치 후, 외출하면서 CO2 농도가 떨어짐.

외출에서 귀가하면서 농도가 한번 급등하고, 그 후에 지속적으로 오름.

취침시간을 기점으로 점점 떨어지다가 기상과 더불어 다시 올라가는 그래프를 보여 줬습니다.


우리 집은 CO2 농도가 꽤나 높은 것으로 나오네요.




12. Update - 20200328


약 10일간 측정한 데이터 입니다.


feeds.csv



잘못 들어간 쓰레기 값들을 조금 조정했습니다. 전원 문제도 있고, 빵판의 접점 문제 등으로 가끔 쓰레기값이 나오는 듯 해요.



5일 그래프를 겹쳐 봤습니다.

1000 ppm 이상의 값에 대해 비정상임을 의심해 봤으나, 전체적으로 보면 정상 수치임을 알 수 있습니다.

저녁에 가족 4명이 거실에 있으면, 대략 1300대의 값을 보여 줬습니다. 모두 잠든 새벽에는 400 언저리 수치를 보여줘, 전 지구의 값과 동일하다는 것을 확인 할 수 있었어요.


요일별로 늦게 일어나는 주말에는 점심 언저리부터 값이 증가하고, 외출해 있을 때에는 거의 값의 변화가 없었으며, 저녁 12시 취침시간을 기점으로 아침 기상까지 수치가 떨어지는 그래프를 보여 줬습니다.


산소 발생기와 연동한다면, 새벽 외에는 하루 종일 틀어놔야 겠군요. 물론, 400 수치로 돌아오면 멈추는 루틴이 필요하겠지만.



And

Software | ThingSpeak 등록하여 IoT 데이터 펼처보기

|

Arduino 를 통해 센서값을 확인 할 때, Arduino IDE 의 Serial Monitor 를 사용하게 되면 PC 를 계속 켜놔야 합니다.

PC 를 리부팅 하거나 다른 용도로 사용하게 되면, 측정을 중단해야 하므로 적절한 활용 방법이 아닙니다.




1. ThingSpeak


이런 불편을 없애려면 cloud 시스템에 internet 을 통해 올리면 됩니다.

그렇지만, 이걸 혼자서 하려면 다음과 같은 작업들이 필요합니다.


- 서버 설치

- OS 설치

- Apache 등 HTTP 서버 어플 설치

- DB 설치 및 설정

- API 설정

- 인터넷 설정

- 보안 설정

- 등등


유지 보수까지 생각하면 끝이 없는 작업입니다.

IoT 하나 하려다가 힘 다 빠지겠습니다. 그래서 나온 cloud 형 서비스가 몇 가지 있습니다.


* ThingSpeak for IoT Projects

https://thingspeak.com/





2. ThingSpeak 등록


사이트 가서 등록 고고.



개인 email 이면 됩니다.



비번도 등록하고.



대학 email account 를 가지고 있으면, 대학에서 보유한 Matlab 계정을 자동 연동하여 사용할 수 있습니다.

그렇게 되면, 대학교에서 구매한 Matlab 을 사용하게 되므로, 대학교 구매부서와 확인해 봐야 합니다. (무단 사용이 될 수 있슴)



아직 대학교 email account 도 가지고 있지만, 개인 account 를 사용했습니다.



계정 등록이 끝나면, 최종 verify 메일이 옵니다.



계정 인증 후, 비번 완료하면 끝납니다.





3. MathWorks


ThingSpeak 는 Matlab 을 개발한 MathWorks 에서 제공하는 서비스 입니다.

그래서인지, MathWorks 에서 제공하는 툴이나 Knowledge 를 사용할 수 있습니다.



제가 요츰 필요한 지식은 Arduino > ESP8266 > ThingSpeak 연동 방법도 나와 있습니다.

만, 최신 ESP 모듈을 기준으로 설명되어 있어서, 별 도움은 못 되었네요. 다른 글에서 이 부분은 집중적으로 다뤄 보도록 하겠습니다.



무료 사용자는, 하루 8,219 개를 사용할 수 있습니다.

하루 24시간 동안, 1초마다 값을 보내게 되면, "86,400" 개 이므로, 이의 1/10 보다 조금 더 적게 값을 보내야 합니다.

대략 15초에 1번 정도로 값을 보내면, 한 개의 sensor 값 읽어 들이는 것에 활용할 수 있겠네요.





4. API Key


HTTP GET/POST 를 이용하여 값을 보내는 RESTful API 를 사용할 때, API Key 가 할당 됩니다.



API Key 사용법은, 위의 스샷 오른쪽 밑에 보이듯이, "api_key=" 로 시작하는 GET URL 의 string 으로 넣어 사용할 수 있습니다.



실제로 값을 API 를 통해 cloud 에 올릴 경우는 아래와 같이 API 키를 넣어주면 됩니다.



전체 HTTP URL 로 만들면 다음과 같이 됩니다.


Write a Channel Feed
https://api.thingspeak.com/update?api_key=[Write_Key]&field1=[value]




5. Channels


계정과 API Key 가 있다 하더라도, 나만의 장소를 만들어야 합니다. 이게 Channels 이 됩니다.



이번에 CO2 취집 센서인 MH-Z14A 를 가지고 CO2 값을 취합하고 싶으니, 아래와 같은 채널을 만들었습니다.

Field1 은 CO2 값이 넣어지도록 하였습니다.



저의 Home Environment 채널이 만들어 졌습니다.

나중에 CO2 뿐만 아니라, 다른 기체 값들도 추가로 입력 받을 수도 있겠네요.





6. HTTP headers


Arduino / ESP-01 을 통해서 값을 입력받은게 아니지만, 브라우저를 사용하여 직접 REST API 를 통해서 값을 전송해 봤습니다.


리턴값으로 "1" 이 표시됩니다. 값들이 쌓여 가면, 이 숫자 카운트가 올라갑니다.

먹고사는 직업이 이쪽인지라, 직업병 발휘해 봅니다.


HTTP Request / Response 는 다음과 같습니다.



아래는 HTTP Request 만 뽑아 봤습니다.

브라우저가 아니고 command line 으로 ESP-01 을 컨트롤 할 때, 필요할 듯 하여 여기에 기록해 봅니다.


Host: api.thingspeak.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: s_fid=18DA4B3665F95BB2-21E82C5CDD94C74E; _ga=GA1.2.1025526633.1578383783; s_cc=true
Upgrade-Insecure-Requests: 1


아래는 HTTP Response 입니다.


HTTP/2 200 OK
date: Mon, 20 Jan 2020 05:03:40 GMT
content-type: text/plain; charset=utf-8
content-length: 1
status: 200 OK
x-frame-options: SAMEORIGIN
access-control-allow-origin: *
access-control-allow-methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
access-control-allow-headers: origin, content-type, X-Requested-With
access-control-max-age: 1800
etag: W/"4e07408562bedb8b60ce05c1decfe3ad"
cache-control: max-age=0, private, must-revalidate
x-request-id: e0fa0bd9-fc3a-4e9a-a09e-efb6326dcd6c
x-runtime: 0.022047
x-powered-by: Phusion Passenger 4.0.57
server: nginx/1.9.3 + Phusion Passenger 4.0.57
X-Firefox-Spdy: h2




7. Read a Channel Feed


API Key 를 통하여 Channel 값을 읽을 경우는 다음과 같이 API 를 날리면 됩니다. 아래는 JSON 방식의 값 추출 입니다.


Read a Channel Feed
https://api.thingspeak.com/channels/[Channel_ID]/feeds.json?api_key=[Read_Key]&results=2
{"channel":{"id":Channel_ID,"name":"Home Environment","description":"gathering values from IoT sensors","latitude":"0.0","longitude":"0.0","field1":"CO2","created_at":"2020-01-10T09:36:21Z","updated_at":"2020-01-10T09:37:06Z","last_entry_id":3},"feeds":[{"created_at":"2020-01-20T04:53:28Z","entry_id":2,"field1":"40"},{"created_at":"2020-01-20T05:03:40Z","entry_id":3,"field1":"39"}]}


인터넷 브라우저를 사용하면 아래처럼 정렬된 값을 확인할 수 있습니다.



값이 쌓여 가면서 그래프를 그려 줍니다.


참고로, 이번에 MH-Z14A 를 이용해서 측정했던 결과 입니다.

PC 없이도 값들을 바로바로 올릴 수 있고, 그래프 조정도 할 수 있어, 왜 이제 했나 싶을 정도 입니다.


* Hardware | CO2 센서인 MH-Z14A 를 활용해 보자
    - https://chocoball.tistory.com/entry/Hardware-CO2-sensor-MH-Z14A





8. 그 외


잘못된 값들이 전체 그래프의 통일성을 외곡시키므로 조금 다듬을 경우는 Timescale 값을 조정하면 됩니다.
10 으로 하면, 10개 값을 하나로 보여주어, 이빨 빠지는 구간 - 잘못된 값 - 들을 날려버릴 수 있습니다.


과거 값들이 불편할 경우는, Channels > Channel Settings > Clear Channel 을 이용하여 지울 수 있습니다.





9. FIN


이젠 PC 를 항상 켜놔야 하는 것으로 부터 해방입니다!




10. Update - 20200328


ThingSpeak 에서 그래프가 보이는 화면에서 data 를 export 하면, 거의 하루치 밖에 받을 수 없습니다.




측정된 값 전체를 받기 위해서는, My Channels > Data Import / Export > Export Download 에서 CVS 로 받을 수 있습니다.




EXCEL 로 그린 위의 그래프들은 이 메뉴에서 다운로드 받은 CVS 를 가지고 만들었습니다.




And
prev | 1 | next