December 22, 2024

디바이스마트 미디어:

[66호] 원하는 색상으로 제어가 가능한 아두이노 IoT 스마트 무드등 키트 -

2021-06-25

★2021 ICT 융합 프로젝트 공모전 결과 발표! -

2021-05-12

디바이스마트 국내 온라인 유통사 유일 벨로다인 라이다 공급! -

2021-02-16

★총 상금 500만원 /2021 ICT 융합 프로젝트 공모전★ -

2021-01-18

디바이스마트 온라인 매거진 전자책(PDF)이 무료! -

2020-09-29

[61호]음성으로 제어하는 간접등 만들기 -

2020-08-26

디바이스마트 자체제작 코딩키트 ‘코딩 도담도담’ 출시 -

2020-08-10

GGM AC모터 대량등록! -

2020-07-10

[60호]초소형 레이더 MDR, 어떻게 제어하고 활용하나 -

2020-06-30

[60호]NANO 33 IoT보드를 활용한 블루투스 수평계 만들기 -

2020-06-30

라즈베리파이3가 드디어 출시!!! (Now Raspberry Pi 3 is Coming!!) -

2016-02-29

MoonWalker Actuator 판매개시!! -

2015-08-27

디바이스마트 레이저가공, 밀링, 선반, 라우터 등 커스텀서비스 견적요청 방법 설명동영상 입니다. -

2015-06-09

디바이스마트와 인텔®이 함께하는 IoT 경진대회! -

2015-05-19

드디어 adafruit도 디바이스마트에서 쉽고 저렴하게 !! -

2015-03-25

[29호] Intel Edison Review -

2015-03-10

Pololu 공식 Distributor 디바이스마트, Pololu 상품 판매 개시!! -

2015-03-09

[칩센]블루투스 전 제품 10%가격할인!! -

2015-02-02

[Arduino]Uno(R3) 구입시 37종 센서키트 할인이벤트!! -

2015-02-02

[M.A.I]Ahram_ISP_V1.5 60개 한정수량 할인이벤트!! -

2015-02-02

[56호]라즈베리파이를 활용한 허브 통합 IoT 시스템 구축

56 ict 라즈베리를 활용한 iot 시스템구축 (1)

 

2019 ICT 융합 프로젝트 공모전 입선

라즈베리파이를 활용한 허브 통합 IoT 시스템 구축

 

1. 심사평
칩센 IoT라는 것은 새로운 기술이 아닌, 기존에 있던 장치와 네트워킹 시스템을 연동하도록 하는 것이 가장 큰 핵심 내용입니다. 이러한 IoT의 개념으로 보자면 이 프로젝트는 IoT에 가장 근접한 작품 구성이 아닐까 하는 생각도 듭니다. 완전히 새로운 것이 아닌 이미 구현되어 있는 여러 기술들을 함께 사용할 수 있도록 구성의 중요 포인트에 집중하는 내용은 높이 평가합니다. 라즈베리파이를 이용하여 home bridge를 구성하여 Apple 솔루션을 적용 가능하게 하고, 타사의 상용 솔루션 하드웨어를 채택하고, IoT에 가장 유용히 사용되는 MQTT 적용을 통해 개발 제작자의 의도를 완성 시켜 나가는 방향의 진행은 매우 탁월한 것으로 보입니다. 하지만, 반대로 보자면 자신들만의 하드웨어나 솔루션이 많지 않았다는 것은 단점으로 볼수도 있는 부분이라, 구성에서 주요 파트는 직접 설계 개발하는 형태도 이후 고려하면 좋을듯 합니다.
뉴티씨 현실적인 소재를 사용하여 작품을 구현한 점이 눈에 띕니다. 실제로 적용이 가능할 것이라는 생각이 듭니다. IoT 환경에서 실제 생활환경의 장치들을 구현하는 것에 대한 연습으로, 직접 옥내서버를 사용하여 만들었다는 점에서, 로컬한 환경에서의 IoT 환경을 가진 서비스를 제공하는 것으로 작은 규모의 프로젝트 싸이트에서 사용될 수 있을 것으로 생각됩니다. 클라우드 환경에서 운영이 대세인데, 간혹 보안이나 비용등의 이유로 내부에서 운영하기를 원하는 경우도 있는데, 그런 경우에 좋은 예가 될 수 있다고 생각합니다. 좀 더 보완하여, 실제 환경에서 적용되기를 기대해 봅니다.
위드로봇 기존 오픈 소스에 이 팀만의 아이디어가 추가로 들어가면 더 좋은 작품이 될 것 같습니다.
펌테크 스마트홈 구현에 사용 가능한 다양한 응용분야를 미니어처 형태로 짜임새 있게 잘 구성한 수준급 작품이라고 생각합니다. 아이폰의 음성인식에 사용되는 시리를 사용하여 스마트홈 내부의 다양한 IOT 장치를 기술적으로 안정되게 구현한 점과 스마트홈 제어에 사용한 APP도 심플한 형태로 깔끔하게 잘 구성되었다고 생각합니다. 전체적으로 꼼꼼한 구성과 완성도가 상당히 높은 우수한 작품이라고 생각합니다.

2. 개요
알람을 따로 맞춰놓지 않더라도 예정된 일정에 따라 알아서 알람이 울리고, 일제히 전등이 켜지면서 커튼이 따라서 걷힌다. 그날 하루의 일기예보와 집주인의 패션스타일 등을 고려해 옷장에서 그날에 적합한 옷을 골라준다. 시간에 맞춰 씻을 준비를 마쳐놓은 욕실에서 씻고 나온 후 마찬가지로 준비된 식탁에서 아침을 먹고 출근을 하자 집안의 모든 전기기구의 전원이 일제히 내려간다. 우리가 한 번쯤은 영화에서 보거나 상상해본 적 있을법한 미래의 집이다.
인간은 언제나 상상을 현실로 만들기 위해 노력해왔다. 물건을 편하게 옮기고 싶다는 꿈은 바퀴를 만듦으로써 실현되었고, 하늘을 날고 싶다는 오랜 소망은 비행기를 만들어냈다. 같은 맥락으로 살아 움직이는, 알아서 나의 기호에 맞춰주는 집에 대한 상상력은 놀랍게도 영화에서나 볼법한 스마트홈을 IoT시스템을 통해 구현할 수준에 이르렀다.
여기서 스마트홈과 IoT란 정확히 무엇일까? 스마트홈이란 가전제품을 비롯한 집 안의 모든 장치를 연결해 제어하는 기술을 말하며 사물인터넷(Internet of Things : IoT)은 각종 사물에 센서와 통신 기능을 내장하여 인터넷에 연결하는 기술. 즉, 무선 통신을 통해 각종 사물을 연결하는 기술을 의미한다. IoT 시스템을 통해 스마트홈을 구축할 수 있게 된다는 것이다.
시장조사회사 가트너(Gartner)는 2012년 10대 전략기술에 IoT를 처음으로 선정했다. 또한 4차 산업혁명 시대를 선도할 기술로 주목받고 있는 사물인터넷은 처음 업계에 소개된 이후 많은 기업에서 IoT 기술이 탑재된 다양한 가전제품들이 출시되었고, 집안의 많은 가구가 상호 연결되며 상상 속에만 존재하던 스마트홈의 실현이 가능해졌다. 구글에서는 Home Assistant, 애플에서는 HomeKit, 삼성에서는 Smart Things 등 많은 회사에서 자사 IoT 가전제품을 위한 스마트허브를 출시했다. 번거롭게 움직이지 않고 스마트폰 터치만으로 해결할 수 있는 제품들에 소비자들은 환호를 보내며 매년 판매량 또한 증가하고 있다. 하지만 HY-ENA팀은 각 회사별 제품에서 공통적 장점인 편의성뿐만이 아니라 단점에도 주목하지 않을 수 없었다. 스마트 홈의 중추 역할을 해줄 스마트 허브의 가격은 결코 저렴한 가격이 아닐뿐더러 이를 구매하였을 시에 회사마다 고유의 통신 프로토콜을 통해 작동된다. 즉, A라는 회사의 스마트 허브를 구매하였을 시 A사의 IoT 가전제품만으로 스마트홈을 구성해야 하는, 소비자의 입장에서 선택의 폭이 좁아지는 문제가 발생하였다.
이렇게 비용에 대한 부담과 다양한 제품의 호환 문제들이 우리가 상상하는 스마트홈을 구축하는 데에 있어 결코 지나칠 수 없는 문제점이라 인식했기에 이에 주안점을 두고 스마트홈 제작에 착수하게 되었다.

3. 작품 설명
3.1. 주요 동작 및 특징

56 ict 라즈베리를 활용한 iot 시스템구축 (2)

저비용과 호환성은 HY-NEA팀이 구상한 스마트 홈 구축에 꼭 필요한 요소였다. 이에 매우 적합한 물건인 라즈베리 파이를 스마트 홈 허브로 이용하였다. 라즈베리 파이는 영국의 라즈베리 파이 재단에서 컴퓨터 프로그래밍 및 과학 교육 증진을 위해 만들어진 SBC(Single Board Computer)로 저렴한 가격과 확장성으로 널리 사용되고 있다.
라즈베리 파이에 Node.js 기반으로 만들어진 홈킷 에뮬레이션 서버인 Homebridge를 다운받아 이를 각종 스마트 홈 디바이스에 연결하면 아이폰 홈 앱을 통해 손쉽게 제어가 가능해진다. 다시 말해, Apple HomeKit 액세서리 인증을 받지 못한 IoT 기기라도 이 Homebridge를 통해 홈 앱으로 제어할 수 있다. 또한 아이폰에 내장되어 있는 앱은 Siri를 통한 제어를 기본 지원하기 때문에 IoT 기기들을 음성인식으로 제어할 수 있는 장점이 있다. Homebridge를 설치한 라즈베리 파이는 IoT 장치들과 네트워크로 연결되어 아이폰에서 입력된 명령을 IoT 장치들로 전송해준다.
HY-ENA 팀은 직접 제작한 IOT기기 뿐만 아니라 이미 나와있는 샤오미 온습도계를 연동하였고, Wi-Fi로 동작하는 장치들에는 다양한 프로토콜(HTTP, MQTT)을 적용했다. 이를 Homebridge와 연동해 홈 앱에서 작동되는 것을 확인함으로서 이미 나와있는 IoT 장치들과의 호환성을 확인했다. 이러한 스마트홈 가전제품들이 Wi-Fi공유기의 네트워크 내부 디바이스들과 통신하며 홈 앱에서 입력된 명령을 실행한다. HY-ENA팀에서 만든 스마트 콘센트를 예로 들자면 사용자의 홈 앱과 스마트 콘센트가 같은 네트워크 안에 존재할 때 사용자가 홈 앱에 명령을 입력하면 이를 Homebridge에서 인식해 명령을 출력해 주는 구조이다.

3.2. 전체 시스템 구성
스마트홈 시스템을 구축하기 위한 전제조건은 Wi-Fi 환경이다. 각각의 떨어져있는 IoT 기기들과 서버 역할을 하는 라즈베리파이 그리고 이를 제어할 스마트폰까지 동일한 네트워크에 속해 있어야 서로 통신을 할 수 있다. HY-ENA 팀은 네트워크를 구축하기 위해 공유기 한 대를 ‘IoT’라는 SSID로 설정해 운용했다. Zigbee는 Wi-Fi에 비해 속도는 느리지만 훨씬 적은 전력을 소모하기 때문에 배터리를 전원으로 사용하는 장치에는 적합한 통신이다. 샤오미의 온습도 센서는 Zigbee 통신을 사용하기 때문에 이를 지원하기 위해 라즈베리파이에 Ti 사의 CC2531기반의 Zigbee Packet Sniffer 모듈을 추가했다. 따라서 이번 프로젝트에서는 Wi-Fi 와 Zigbee 환경 모두를 지원할 수 있게 되었다.
네트워크가 구축이 되었다면 ESP-8266을 이용하여 IoT기기 각각의 서버를 만들어 접속을 시켜준다. 동작이 단순한 스마트콘센트와 스마트전등의 구현은 ESP-01을 통하여 구현한다. 커튼 및 선풍기 미니어쳐는 제어를 위하여 PWM 출력 및 여러 개의 I/O를 사용하기 때문에 ESP-12E 와이파이 모듈을 탑재한 개발보드인 nodeMCU를 사용한다. 이로써 시스템을 구성하기 위한 하드웨어는 준비가 끝났다.
Wi-Fi로 통신하는 기기들은 HTTP 와 MQTT 프로토콜로 Homebridge 와 통신하게 된다. 스마트 폰은 HTTP 프로토콜로 Homebridge 와 통신하지만, 선풍기 미니어처는 전원 On/Off 제어와 속도 제어까지 해야하기 때문에 MQTT 프로토콜을 이용해 통신한다.

3.3. 개발 환경
3.3.1. 아두이노 개발도구(Arduino IDE)와 Visual Studio 설치
전체적인 작품제작 과정에서 우리가 이용할 디바이스는 ESP-8266(ESP-01, NodeMCU)였다. 이 디바이스들은 간단하게 코드 업로드가 가능하며 스마트 홈에서의 통신에도 중요한 역할을 한다. 위 디바이스에 우리가 작성한 코드를 업로드하기 위해 아두이노 IDE를 사용했다. 원래 아두이노 IDE는 아두이노 개발환경에서 코드 업로드를 위해 사용되나, 우리는 아두이노 IDE에 ESP보드 라이브러리 설치를 통해 ESP 모듈에 코드 업로드를 가능하게 했다.
코드 작성을 하기에 앞서 아두이노 IDE는 간편함을 중점으로 나온 통합 개발환경이기 때문에 지속적으로 개발을 하기에는 불편한 점이 많다. 따라서 우리는 좀 더 편한 개발환경을 위해 코드 작성은 Visual Studio에서 하고 컴파일 및 업로드는 아두이노 IDE의 기능을 사용하였다. 또한 이 두 프로그램을 연동시켜주는 Visual micro 플러그인을 사용하여 Visual Studio에서 코드 작성부터 ESP 보드에 업로드까지 가능하게 하였다.

3.3.2. 스마트 홈 개발을 위한 네트워크 환경 구축
IoT 기기간의 통신은 기본적으로 Wi-Fi 환경을 기반으로 이루어진다. 따라서 우리는 개발용 공유기를 별도로 설치해 SSID = ‘IoT’, Password = ‘12345678’ 으로 설정하여 사용하였다. 또한 이 프로젝트에서 사용하는 장비중 샤오미 온습도계는 Zigbee 환경을 사용하기 때문에 라즈베리파이에 CC2531기반의 Zigbee Packet Sniffer 모듈을 장착하여 Zigbee 통신환경도 구축하였다.

3.3.3. 라즈베리 파이 개발환경(raspbian이미지 라이팅, ssh 활성화) 구축
라즈베리 파이를 사용하기에 앞서 라즈베리 파이를 운용할 수 있도록 운영체제를 설치해 주어야 한다. 라즈베리 파이에서 사용되는 라즈비안(Raspbian)은 리눅스 계열의 운영체제인데 이는 라즈베리 파이 홈페이지(https://www.raspberrypi.org)에서 다운받을 수 있다. 우리는 Raspbian Stretch (2018.11 version)을 사용했다. 라즈비안 이미지를 sd카드에 라이팅(복사) 해야 하는데 이때 ‘rufus’ usb 툴을 이용했다. rufus는 부팅 가능한 ISO파일(윈도우, 리눅스 등)을 usb를 이용하여 설치할 때 사용된다.
2016년 11월 25일 이후, 출시된 라즈비안은 보안상의 이유로 디폴트로 ssh가 비활성화 되어 있다. 활성화 하기 위해서는 라즈비안 sd 카드의 root 폴더에 ssh 라는 이름의 파일을 생성해주면 활성화 된다.
4. 단계별 제작 과정
4.1. 라즈베리파이 개발환경 구축 (Node.js 및 Homebridge 설치)
4.1.1. 라즈베리 파이에 할당된 IP 확인
명령 프롬프트에 ‘ipconfig’ 라는 명령어를 실행하면 기본 게이트웨이(사용자의 컴퓨터와 라즈베리파이가 사용하는 공유기) ip를 알아낸다. 게이트 웨이 ip를 통해 공유기 관리 페이지에 접속한다. 라즈베리파이에 랜선이 연결되어 있다면 라즈베리 파이는 이 공유기 네트워크를 사용하므로 할당된 IP를 확인할 수 있다.

4.1.2. powershell을 통해 라즈베리파이 접속
Windows 에서 PowerShell은 시스템 관리자를 위해 특별히 설계된 Windows 명령줄 셸이다. powershell을 켠 후 라즈베리 파이에 접속하기위해 다음과 같은 명령어를 작성한다.
ssh pi@192.168.2.13(HY-ENA팀이 할당받은 라즈베리 파이 IP 예시)
다음은 비밀번호를 입력하는데 이는 디폴트값으로 raspberry 로 설정되어 있다.

4.1.3. 시스템 최적화
sudo apt-get update
sudo apt-get upgrade
위 명령어는 시스템에 설치된 프로그램들을 최신화하는 과정이다.

4.1.4. Homebridge 설치에 필요한 라이브러리 설치
Homebridge는 Node.js 기반 애플리케이션이므로 Node.js를 먼저 설치한다.
필요한 라이브러리를 설치한다.

wget -O – https://raw.githubusercontent.com/sdesalas/node-pi-zero/master/install-node-v.lts.sh | bash

Homebridge를 설치한다. 다음과 같이 -g 옵션을 주어 전역 패키지로 설치한다.

$ sudo apt-get install libavahi-compat-libdnssd-dev

다음과 같이 node.sh 프로필을 작성한다.

$ npm i -g homebridge

텍스트 에디터로 위의 파일을 열어서 다음과 같이 입력하고 저장한다.

sudo touch /etc/profile.d/node.sh
sudo chmod +x /etc/profile.d/node.sh

export PATH=$PATH:/opt/nodejs/bin

4.1.5. Homebridge 데몬화
Homebridge의 데몬화는 프로세스를 background에서 이용하기 위해 필요하다. Homebridge서버 관리를 위해 Node.js의 프로세스 매니저인 pm2를 설치한다. 먼저 PM2를 설치하고 OS를 리부트할 때 PM2가 자동으로 시작되도록 설정한다.

4.1.6. 플러그인 설치

$ npm i -g pm2
$ pm2 startup systemd
$ cd ~/.homebridge
$ pm2 start homebridge
$ pm2 save

homebridge는 NPM에서 다양한 플러그인을 다운로드 받아 설치해 줄 수 있다. 이번 프로젝트에서 사용한 플러그인은 다음과 같다.
위의 4개의 플러그인을 설치하기위해 SSH 쉘에 아래와 같이 입력한다.

homebridge-config-ui-x : homebridge를 편하게 설정하기 위한 플러그인
homebridge-http : HTTP 프로토콜을 사용하기 위한 플러그인
homebridge-fan-accessory : MQTT프로토콜로 Fan을 제어하기 위한 플러그인
homebridge-zigbee : Zigbee 모듈을 사용하기 위한 플러그인

미니어처 선풍기는 MQTT 프로토콜을 사용하기 때문에 MQTT Broker를 설치해야 한다. MQTT Broker 로는 오픈소스 Broker인 Mosquitto를 사용한다.

npm i -g homebridge-config-ui-x
npm i -g homebridge-http
npm i -g homebridge-fan-accessory
npm i -g homebridge-zigbee

모든 설치를 다 했다면 이를 homebridge에서 사용할 수 있도록 config.json 파일에 등록을 해줘야 한다. config.json 파일은 ./homebridge 경로에 있다.

wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key
sudo apt-get add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-stretch.list
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients
sudo /etc/init.d/mosquitto.conf

config.json 파일은 보고서의 길이를 고려하여 6.기타에 별도로 첨부하였다. 이렇게 config.json 파일을 작성하면 라즈베리 파이 환경 구축이 끝난다.

cd ~/.homebridge
nano config.json

4.1.7. Homebridge 등록
아이폰에 있는 “홈” 앱에 위에서 설정한 Homebridge를 등록한다. 그림에서 나타난 QR 코드를 이용한다.

56 ict 라즈베리를 활용한 iot 시스템구축 (3)

4.2. 릴레이를 이용한 스마트 콘센트

4.2.1. ESP-01에 스케치 업로드
이 디바이스들은 공통적으로 ESP-01 Wi-Fi 모듈을 이용한다. ESP-01 은 Wi-Fi 네트워크 통신을 지원하는 통신 모듈로, 하드웨어 제어 기능도 상당부분 수행할 수 있다. ESP-01에 하드웨어 제어를 위한 코드를 업로드하기 위해 Serial Programming 모드로 실행시킨다. 코드를 업로드 하기 위해 PC와 연결해야 하는데 이때는 FTDI 모듈을 사용했다. FTDI와 ESP-01의 각 단자별 연결법을 아래에 설명했다.

<ESP-01> <FTDI>
RX ———————–> TX
TX ———————–> RX
GPIO0 (LOW) ——————> GND
GPIO2 (HIGH) ——————> VCC
VCC (HIGH) ——————-> 3.3V
GND (LOW) ——————-> GND
CH_PD (HIGH) —————–> VCC

여기서 주의할 점은 ESP-01은 3.3V 전압을 이용한다는 점이다. 이번 프로젝트에서는 ESP-01을 개발하기위한 IDE로 아두이노 IDE를 사용할 것이다. 따라 Serial Programming 모드가 실행되었다면, 아두이노 IDE를 이용하여 스케치를 업로드한다.

4.2.2. 회로구성

56 ict 라즈베리를 활용한 iot 시스템구축 (4)

회로구성에 있어서 중요한 점은 ESP-01모듈에는 전원이 지속적으로 공급되어야 함과 동시에 콘센트와 전구에는 전원이 끊겨있는 상태를 유지하는 것이었다. 이를 실현시키기 위해서 콘센트와 전구에 들어가는 (+)전선을 끊어 그 사이에 릴레이를 배치했다.

56 ict 라즈베리를 활용한 iot 시스템구축 (1) 56 ict 라즈베리를 활용한 iot 시스템구축 (2)

이 릴레이는 ESP-01에서 신호를 주었을 때만 연결되도록 설계되었다. 이와 별개로 ESP-01모듈에는 3.3V전원이 지속적으로 공급되어야 하는데 이는 끊기지 않은(-) 전원과 플러그에서 나와 릴레이로 곧바로 들어가는 (+)전선에서 선을 따로 빼 AC to DC 컨버터에 연결했다. 컨버터에서 변압된 3.3V DC 전류는 ESP-01에 공급되어 콘센트와 전구에는 전원이 끊겨있는 상태는 유지하면서 외부에서의 제어에는 반응할 수 있는 상태로 만들 수 있게 되었다.

4.3. DC모터 및 L9110 드라이브를 이용한 스마트 커튼 미니어쳐 제작
스마트 커튼 미니어쳐 제작의 핵심은 DC모터의 정역회전을 제어하는 것인데 이는 L9110 드라이버를 이용하여 구현하였다.

56 ict 라즈베리를 활용한 iot 시스템구축 (5)

L9110 드라이버의 모습과 각 핀에 대한 설명이다.

56 ict 라즈베리를 활용한 iot 시스템구축 (6)

56 ict 라즈베리를 활용한 iot 시스템구축 (3)

모터의 회전을 제어하기 위해 두개의 입력이 필요하므로 nodeMCU (ESP-8266)와 드라이버를 연결하는 회로를 구성한 후 Visual Micro를 통해 코드를 업로드하여 드라이버에 입력되는 값을 제어할 수 있게 하였다.

4.4. 선풍기 미니어처 제작
4.4.1. nodeMCU와 MQTT 프로토콜
이 선풍기 미니어처에는 앞에서 사용하였던 ESP-8266계열의 ESP-01 Wi-Fi 모듈을 사용하지 않고 ESP-12E 모듈 기반의 nodeMCU를 사용하였다. 둘다 Wi-Fi 네트워크 통신을 지원하는 통신 모듈이며, 하드웨어 제어 기능 있었지만 pwm(펄스폭 제어) 기능을 ESP-01에서는 지원하지 않기 때문에 nodeMCU를 선택하게 되었다. 이 pwm 기능을 통해 선풍기는 단계적으로 속도를 제어할 수 있게 되었다.
또한 단순히 켜고 끔만 통제하는 것이 아닌 속도제어까지 해야하기 때문에 HTTP 프로토콜이 아닌 MQTT 프로토콜을 사용하였다. MQTT 프로토콜은 MQTT Client가 MQTT broker에게 메시지를 publish 하게 되면 이를 subscribe한 또다른 MQTT Client(연결된 기기)들이 메시지를 수신하는 구조의 프로토콜로 메시지 내용에 다양한 내용을 담을 수 있기 때문에 HTTP 대비 더욱 복잡한 제어를 할 수 있다는 장점이 있다.

4.4.2. 회로구성

56 ict 라즈베리를 활용한 iot 시스템구축 (7)
회로 구성에 있어서 한 개의 capacitor를 사용하였다. 모터가 동작하는 데에 있어 상대적으로 큰 전류를 사용하기에 전원공급이 불안정해질 수 있었다. 이에 전압이 불안정해지고 ESP-12E 모듈이 불안정해졌기 때문에 50V 100㎌의 capacitor를 사용해 이 문제를 해결하였다.

※스마트 선풍기 세기별 작동상태

4.5. CC2531 Zigbee packet sniffer를 이용한 샤오미 온습도 센서 연동

56 ict 라즈베리를 활용한 iot 시스템구축 (4)

56 ict 라즈베리를 활용한 iot 시스템구축 (5) 56 ict 라즈베리를 활용한 iot 시스템구축 (6)

샤오미 온습도계는 Wi-Fi 통신을 사용하는 것이 아닌 Zigbee 통신을 사용한다. 원래는 샤오미 온습도계를 사용하기 위해서는 샤오미 게이트웨이를 통해 연결해야 하지만 이번 프로젝트에서는 Ti 사의 CC2531 Zigbee Packet Sniffer를 이용하여 게이트웨이 없이 바로 Homebridge에 연결하여 홈앱에서 사용할 수 있도록 하였다.
CC2531 Zigbee 모듈을 Homebridge에서 사용하기 위해서는 펌웨어를 교체해야 한다. 펌웨어를 교체하기 위해서는 SmartRF Flash Programmer 프로그램과 Smartrf04EEB 프로그래머 보드를 이용해야 하므로 링크(https://github.com/itsmepetrov/homebridge-zigbee/blob/HEAD/docs/Flashing.md)에서 드라이버와 교체할 펌웨어를 다운로드받는다.

56 ict 라즈베리를 활용한 iot 시스템구축 (8)

펌웨어를 업로드 한 뒤 라즈베리파이에 연결하고 Config.json을 설정한 다음 Homebridge를 실행하면 홈앱 화면에 Permit Join 이라는 스위치가 생긴다. 그 후 Permit Join 스위치를 켜고 Zigbee 기기와 페어링을 진행하면 .homebridge 폴더에 Zigbee.db 라는 파일이 생성되며 그 파일 안에 페어링 된 기기가 등록된다.

56 ict 라즈베리를 활용한 iot 시스템구축 (9)

4.6. 우드락을 이용한 홈 미니어쳐 제작

스마트 홈 구현과 시연을 위해 우드락으로 집 모형을 제작하였다.

56 ict 라즈베리를 활용한 iot 시스템구축 (7) 56 ict 라즈베리를 활용한 iot 시스템구축 (8)

5. 스마트 홈 구현
스마트 콘센트

56 ict 라즈베리를 활용한 iot 시스템구축 (10)

스마트 전구

56 ict 라즈베리를 활용한 iot 시스템구축 (11)
스마트 커튼

56 ict 라즈베리를 활용한 iot 시스템구축 (12)

스마트 선풍기

56 ict 라즈베리를 활용한 iot 시스템구축 (9)
온습도계

56 ict 라즈베리를 활용한 iot 시스템구축 (10)

6. 기타

6.1. 소스코드
6 config.json 파일

{ “bridge”: {
“name”: “Homebridge”,
“username”: “CC:22:3D:E3:4A:30”,
“port”: 51826,
“pin”: “031-78-157”
},
“accessories”: [
{
“accessory”: “Http”,
“name”: “SmartPlug”,
“on_url”: “http://192.168.2.5/gpio/0”,
“off_url”: “http://192.168.2.5/gpio/1”,
“http_method”: “GET”
},
{
“accessory”: “Http”,
“name”: “Smart_Light”,
“on_url”: “http://192.168.2.9/crispy/0”,
“off_url”: “http://192.168.2.9/crispy/1”,
“http_method”: “GET”
},
{
“accessory”: “Http”,
“name”: “Curtain”,
“on_url”: “http://192.168.2.10/curtain/0”,
“off_url”: “http://192.168.2.10/curtain/1”,
“http_method”: “GET”
},
{
“accessory”: “fan-accessory-rotation”,
“name”: “Room Fan”,
“url”: “mqtt:localhost”,
“topics”: {
“getOn”: “getFanOn”,
“setOn”: “OnOff”,
“getRotationSpeed”: “getSpeed”,
“setRotationSpeed”: “Speed”
}
}
],
“platforms”: [
{
“platform”: “config”,
“name”: “Config”,
“port”: 8080,
“sudo”: false
},
{
“platform”: “ZigBeePlatform”
}
] }

Relay Switch를 이용한 스마트 콘센트 제어 스마트 전등 및 스마트 콘센트 소스코드

#include <ESP8266WiFi.h>

#define relay_pin 0

const char* ssid = “IOT”;
const char* password = “12345678”;

WiFiServer server(80);

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

pinMode(relay_pin, OUTPUT);

digitalWrite(relay_pin, 1);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.begin();
}

void loop() {

// Serial.println(“intro”);
// Check if a client has connected
WiFiClient client = server.available();
// Serial.println(digitalRead(sw_pin));

if (!client) {
return;
}

// Wait until the client sends some data
while (!client.available()) {
// Serial.println(“0”);

delay(10);
}

// Serial.println(“2”);

// Read the first line of the request
String req = client.readStringUntil(‘\r’);
Serial.println(req);
client.flush();

// Serial.println(“3”);

// Match the request
int val;
if (req.indexOf(“/gpio/0”) != -1) {
val = 0;
}
else if (req.indexOf(“/gpio/1”) != -1) {
val = 1;
}
else {
client.stop();
return;
}

// Serial.println(“4”);

// Set GPIO according to the request
digitalWrite(relay_pin, val);

client.flush();

// Prepare the response
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now “;
s += (val) ? “high” : “low”;
s += “</html>\n”;

// Send the response to the client
client.print(s);
delay(1);

//Serial.println(“5”);
}

*스마트 전등

#include <ESP8266WiFi.h>

#define relay_pin 0

const char* ssid = “IOT”;
const char* password = “12345678”;

WiFiServer server(80);

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

pinMode(relay_pin, OUTPUT);

digitalWrite(relay_pin, 1);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.begin();
}

void loop() {

// Serial.println(“intro”);
// Check if a client has connected
WiFiClient client = server.available();
// Serial.println(digitalRead(sw_pin));

if (!client) {
return;
}

// Wait until the client sends some data
while (!client.available()) {
// Serial.println(“0”);

delay(10);
}

// Serial.println(“2”);

// Read the first line of the request
String req = client.readStringUntil(‘\r’);
Serial.println(req);
client.flush();

// Serial.println(“3”);

// Match the request
int val;
if (req.indexOf(“/crispy/0”) != -1) {
val = 0;
}
else if (req.indexOf(“/crispy/1”) != -1) {
val = 1;
}
else {
client.stop();
return;
}

// Serial.println(“4”);

// Set GPIO according to the request
digitalWrite(relay_pin, val);

client.flush();

// Prepare the response
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now “;
s += (val) ? “high” : “low”;
s += “</html>\n”;

// Send the response to the client
client.print(s);
delay(1);

//Serial.println(“5”);
}

void sw_interrupt(int sw_statue)
{
WiFiClient client;
int val;
val = !sw_statue;
digitalWrite(relay_pin, val);
// Prepare the response
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now “;
s += (val) ? “high” : “low”;
s += “</html>\n”;

// Send the response to the client
client.print(s);
delay(1);
}


DC모터 및 L9110 드라이브를 이용한 커튼 미니어쳐 제작

#include <ESP8266WiFi.h>

#define motor_1 4
#define motor_2 5

const char* ssid = “IOT”;
const char* password = “12345678”;

WiFiServer server(80);

int val = 3;
void setup() {
Serial.begin(115200);
delay(10);

pinMode(motor_1, OUTPUT);
pinMode(motor_2, OUTPUT);
digitalWrite(motor_1, LOW);
digitalWrite(motor_2, LOW);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
server.begin();
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
}

void loop() {

WiFiClient client = server.available();

if (!client) {
return;
}

while (!client.available()) {
delay(10);
}

String req = client.readStringUntil(‘\r’);
Serial.println(req);
client.flush();

if (req.indexOf(“/curtain/0”) != -1) {
val = 0;
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now “;
s += (val) ? “high” : “low”;
s += “</html>\n”;

client.print(s);
Serial.println(“curtain/0”);
delay(1);
}
else if (req.indexOf(“/curtain/1”) != -1) {
val = 1;
String s = “HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now “;
s += (val) ? “high” : “low”;
s += “</html>\n”;

client.print(s);
Serial.println(“curtain/1”);
delay(1);
}
else {
client.stop();
return;
}
if (val == 0) {
digitalWrite(motor_1, HIGH);
digitalWrite(motor_2, LOW);
delay(7000);
digitalWrite(motor_1, LOW);
digitalWrite(motor_2, LOW);
val = 3;
}
else if (val == 1) {
digitalWrite(motor_2, HIGH);
digitalWrite(motor_1, LOW);
delay(7000);
digitalWrite(motor_1, LOW);
digitalWrite(motor_2, LOW);
val = 3;
}
client.flush();
}

IRF520 Mosfet을 이용한 선풍기 미니어쳐 제작

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = “IOT”;
const char* password = “12345678”;
const char* mqtt_server = “192.168.2.8”; //MQTT Broker 서버 주소
char* Fan_OnOff = “OnOff”; //OnOff 토픽을 Fan_OnOff 로 설정
char* Fan_Speed = “Speed”; //Speed 토픽을 Fan_Speed 로 설정

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int pwm_value = 0;
bool onoff;

//WI-FI 설정부분
void setup_wifi() {

delay(10);
Serial.println();
Serial.print(“Connecting to “);
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}

randomSeed(micros());

Serial.println(“”);
Serial.println(“WiFi connected”);
Serial.println(“IP address: “);
Serial.println(WiFi.localIP());
}

//MQTT 메세징이 도착했을때 CallBack 해주는 함수
void callback(char* topic, byte* payload, unsigned int length) {
int j = 0;
pwm_value = 0;
Serial.println(length);
if (length == 4) //메세지 길이가 4글자이면(true)
onoff = true;
else if (length == 5) //메세지 길이가 5글자이면(false)
onoff = false;
if (onoff == true) {
if ((char)payload[0] >= 48 && (char)payload[0] <= 57) {
for (int i = length; i > 0; i–) {
pwm_value += ((char)payload[i - 1] – 48) * pow(10, j); //메세지로 받은 내용을 숫자로 변경
j++;
}
Serial.print(“PWM : “);
Serial.println(pwm_value);
analogWrite(5, pwm_value * 2); //PWM 출력
}
}
else if (onoff == false) {
analogWrite(5, 0);
}

}
//예외 처리
void reconnect() {
// Loop until we’re reconnected
while (!client.connected()) {
Serial.print(“Attempting MQTT connection…”);
// Create a random client ID
String clientId = “ESP8266Client-”;
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println(“connected”);
// Once connected, publish an announcement…
client.publish(“outTopic”, “hello world”);
// … and resubscribe
client.subscribe(“inTopic”);
}
else {
Serial.print(“failed, rc=”);
Serial.print(client.state());
Serial.println(“ try again in 5 seconds”);
}
}
}

void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883); //MQTT 서버 접속
client.setCallback(callback); //Callback 설정
}

void loop() {

if (!client.connected()) {
reconnect();
client.subscribe(Fan_OnOff); //Fan_OnOff 토픽 구독
client.subscribe(Fan_Speed); //Fan_Speed 토픽 구독
}
client.loop();
}

 

 

 

Leave A Comment

*