재료

  • USB 케이블 1개
  • LED 3개
  • 브래드 보드 1개
  • 저항 3개
  • 아두이노 우노 1개
  • esp8266 1개
  • 점프 와이어 13개

    드디어 이번 프로젝트의 목표였던 사물 인터넷(IoT)를 구현해보는 시간이 되었네요. 이번 프로젝트에서는 지난 프로젝트에서 온도 센서 값을 ThingSpeak의 채널에 보냈던 것을 다시 받아와 온도에 따라서 다른 LED가 켜지도록 구현해봅시다. 지난번 프로젝트의 연장선이라고 할 수 있겠네요. 지난번 프로젝트를 완성하지 못하였다면 <ThingSpeak을 이용하여 온도센서 값 읽어오기>로 가셔서 온도 센서 값을 채널에 올려놓고 이번 프로젝트를 진행하도록 합시다.




STEP1. 준비물

    이번 프로젝트는 지난 프로젝트에 이어서 진행하는 것이므로, 지난 프로젝트에서 추가로 필요한 준비물에 대해서만 소개하도록 하겠습니다.


아두이노 보드, 브래드 보드, USB 케이블, ESP8266, LED 3개, 저항 3개, 점프 와이어 13개


    USB 케이블로도 전원이 연결되지만 무선으로도 연결되는 것을 확인하고 싶으시다면 AC 어댑터도 준비해주세요.


STEP2. 회로도




STEP3. 연결 과정 및 코드 업로드

    코드를 업로드 하시기 전에 이 ESP8266은 기존에 쓰던 것과는 다른 새 것이어서 아두이노에 적합하도록 펌웨어 업데이트가 필요합니다. <ESP8266 사용을 위한 펌웨어 업데이트하기> 의 글로 가셔서 펌웨어 업데이트를 완료하신 뒤에 아래의 코드를 아두이노에 업로드해주세요.


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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <SoftwareSerial.h>
#include <ESP8266wifi.h>
#include <stdlib.h>
#define DEBUG true
 
int led1Pin=13//RED
int led2Pin=11//YELLOW
int led3Pin=9;  //GREEN
//자신의 thingspeak 채널의 Read API key 입력
String apiKey="Read API key";
 
SoftwareSerial esp8266(2,3); //TX/RX 설정, esp8266 객체생성
 
void setup() {
  // put your setup code here, to run once:
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(led3Pin, OUTPUT);
 
  /*시리얼 통신 속도 9600보드레이트 설정*/
  Serial.begin(9600);
  /*소프트웨어 시리얼 시작*/
  esp8266.begin(9600);
   /*AT Command 이용*/
  sendData("AT+RST\r\n"2000, DEBUG); //reset module
  sendData("AT+CWMODE=1\r\n"1000, DEBUG); //dual mode로 설정
  sendData("AT+CWJAP=\"MakeWith1(2.5G)\",\"mw06010601\"\r\n"5000, DEBUG); //사용할 공유기 설정
}
 
void loop() {
  // put your main code here, to run repeatedly:
  // TCP 연결
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += "184.106.153.149"// api.thingspeak.com 접속 IP
  cmd += "\",80";           // api.thingspeak.com 접속 포트, 80
  esp8266.println(cmd);
 
  if(esp8266.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }
 
  //GET 방식으로 받기 위한 설정
  String getStr="GET /channels/";
  getStr+="215132"; //채널ID
  getStr+="/fields/1/last.txt?key=";
  getStr+=apiKey;
  getStr+="\r\n\r\n";
 
  //Data 가져오기
  cmd="AT+CIPSEND=";
  cmd+=String(getStr.length());
  esp8266.println(cmd);
 
  if(esp8266.find(">")){
    esp8266.print(getStr);
    if(esp8266.find("+IPD,4:")){
      String data=esp8266.readString();
      Serial.println(data);
      int num=(data[0]-48)*10;
      num+=(data[1]-48);
 
      if(num>=27){
        digitalWrite(led1Pin, HIGH);
        digitalWrite(led2Pin, LOW);
        digitalWrite(led3Pin, LOW);
      }
      else if(num>=18){
        digitalWrite(led1Pin, LOW);
        digitalWrite(led2Pin, HIGH);
        digitalWrite(led3Pin, LOW);
      }
      else{
        digitalWrite(led1Pin, LOW);
        digitalWrite(led2Pin, LOW);
        digitalWrite(led3Pin, HIGH);
      }
    }
  }
  else{
    esp8266.println("AT+CIPCLOSE");
    // alert uesp8266
    Serial.println("AT+CIPCLOSE");
  }
  
  delay(16000);
}
 
/*ESP8266의 정보를 알아내고 설정하기 위한 함수 선언*/
String sendData(String command, const int timeout, boolean debug){
  String response = "";
  esp8266.print(command); //command를 ESP8266에 보냄
  long int time=millis();
  
  while((time+timeout)>millis()){
    while(esp8266.available()){
      /*esp가 가진 데이터를 시리얼 모니터에 출력하기 위함*/
      char c=esp8266.read(); //다음 문자를 읽어옴
      response+=c;
    }
  }
  if(debug){
    Serial.print(response);
  }
 
  return response;
}
cs


    위의 코드에서 주의하실 점은 Write API key를 입력했던 이전 프로젝트와는 다르게 Read API key를 입력하셔야 한다는 것입니다. 그런 후에 아래의 화면에서 확인하실 수 있는 것처럼 Channel ID를 확인하고 45번째 라인을 바꿔주세요.



Channel Setting 탭에 들어오셔서 아래와 같이 Make Public을 체크해주세요.



적는 것은 Private mode에서도 가능했지만 Feed data를 HTTP로 확인하기 위해서는 Public 모드로 전환해주시는 것이 필요합니다.


그런 후에 Data Import/Export 탭으로 가셔서 노란색 박스로 쳐져있는 Get a Channel Field Feed를 확인해주세요. 저 주소로 가면 아래와 같은 정보가 뜨는 것을 확인할 수 있습니다.



위의 사진으로는 잘 안보이지만 자세히 확인해보면 아래와 같습니다.




제가 웹페이지에 나와있는 결과를 메모장으로 옮겨와 정리한 결과입니다.  여기에서 저희가 필요한 결과는 field1 의 결과입니다. 아마도 아래의 노란색으로 표시된 부분들이겠죠?



저는 이 중에서도 가장 최근의 값만 필요한데 너무 복잡하게 나와있어서 가장 최근의 값만 뽑아내기로 했습니다. 가장 최근 값만 가져와주는 주소는 아래와 같습니다.


https://api.thingspeak.com/channels/215132/fields/1/last.txt 


이 링크로 가면 가장 최근의 결과값 1개만이 아래와 같이 출력되는 것을 확인할 수 있습니다. 이 링크는 기존에 Get a Channel Field Feed 주소에서 1 뒤의 것을 지우고 /last.txt로 바꾼 것입니다.


새로 고침을 하면 새로운 값이 생성됩니다. 신기하죠? 그럼 우리는 이 결과를 가져오도록 하겠습니다. 그 결과를 가져오는 코드가 위의 라인 중에서 44 라인부터 59 라인까지입니다. 저는 위의 주소보다 정보를 더 정확하게 가져오기 위해서 API key를 포함한 아래의 주소를 사용하였습니다.


https://api.thingspeak.com/channels/215132/fields/1/last.txt?key=ReadAPIKey


마지막에 Read API Key 부분과 중간에 215132 부분은 본인의 Read API Key와 채널 ID를 넣으시면 됩니다. 참고로 저 과정 중에서 결과 값이 자꾸 -1로 뜬다면 제대로 channel에 접근하지 못한 것입니다. 그런 경우에는 다시 한 번 위의 과정을 수행하는 중에서 잘못된 부분이 있는 지 확인해주세요.


STEP4. 결과 확인

    한 쪽 아두이노에서 온도 센서로 측정한 온도 값을 ESP8266 모듈을 이용하여 ThingSpeak으로 보내면, 다른 쪽 아두이노에서 그 값을 읽어와 값에 맞는 LED를 켜줍니다. 코드에서 확인할 수 있듯이 27도가 넘어가면 빨간색 LED를, 18도에서 27도 사이일 경우에는 노란색 LED를, 마지막으로 18도 아래일 경우에는 초록색 LED가 켜지도록 구현하였습니다.




사람이 명령을 내리지 않아도 스스로 조절하는 모습을 확인할 수 있었습니다. 첫 스토리에서 알아보았던 사물 인터넷(IoT)의 개념과 딱 맞죠? 아래의 동영상은 온도센서가 제대로 결과를 측정해서 보내주는지, 그리고 그 결과를 제대로 받아와서 LED를 조작하는 지 알아보기 위한 실험을 수행한 결과입니다.




온도센서에 손을 대니까 시간이 지나면서 온도가 점점 올라가고, 27도가 넘어서는 순간 LED가 노란불에서 빨간불로 바뀌는 것을 확인할 수 있었습니다.



    서로 떨어져 있는데에도 스스로 결과를 출력하고 입력받아와서 LED를 조작할 수 있도록 구현해보았습니다. 이번 스토리를 작성하는 것은 자료가 많이 없어서 공부하면서 진행하느라고 시간이 오래 걸렸지만, 그래도 지난번 프로젝트의 코드를 크게 수정하지 않아도 정보를 받아올 수 있도록 작성했습니다. 이번 프로젝트의 최종 목표였던 사물 인터넷(IoT)를 직접 구현해볼 수 있어서 프로젝트를 진행하는 내내 뿌듯했고, 이 자료가 여러분에게도 큰 도움이 되었으면 좋겠네요:-)

댓글 1

MADE BY

김민정

사물인터넷, 아두이노