산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

부품 및 소모품

타워프로 서보 (TowerPro SG90)×1
소형 경첩×1
버튼×1
아두이노 윤 (Arduino Yun)×1
100A 전류 변환기 (CT)×1
저항 및 커패시터×7개

프로젝트 소개

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

아래 두 영상으로 프로젝트 빠르게 이해하실 수 있습니다.

물리적 인터페이스의 필요성

인터페이스는 정보를 전달하고 제어를 가능하게 합니다. 대부분의 홈 오토메이션 플랫폼은 '가상 인터페이스'에 의존합니다. 스마트폰 앱을 열어 집 상태를 확인하고 조명을 켜고 끕니다. 외출 시엔 괜찮지만, 가상 화면을 보고 정보를 파악하는 건 집중이 필요하고 직관적이지 않습니다.

저는 '물리적 인터페이스'를 만들고 싶었습니다. 실제 집 상태를 물리적으로 모방하는 작은 모델 하우스입니다. 실제 차고 문이 열리면 모델의 차고 문도 열립니다. 이 모델을 거실 탁자나 사무실 책상에 두면 한눈에 차고 문이나 현관문 개폐 상태를 알 수 있습니다. VPN으로 집과 연결하면 원격에서도 가능하죠. 이 물리적 인터페이스는 만드는 이의 창의성만큼 유연하게 확장 가능합니다.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

구현 계획

  1. 모델 하우스 제작: 문 위치, 에너지 사용량, 조명 온오프 상태 표시
  2. 에너지 모니터 제작: OpenEnergyMonitor 아두이노 라이브러리 사용, 모델 하우스와 OpenHAB로 데이터 전송
  3. 문/창문 위치 센서 연동: Wink 허브와 Wink 'Tripper' 접점 센서 데이터를 DIY 홈 오토메이션에 활용
  4. 출력 제어: Wink와 아두이노로 실제 차고 문 개폐, 조명 온오프 제어

모델 하우스에는 서보와 LED가 아두이노 컨트롤러에 연결돼 있습니다. 이 컨트롤러는 MQTT 메시지(문 위치, 에너지 사용량)를 구독해 서보를 작동시킵니다. 조명 표시 LED도 마찬가지. 센서 정보를 MQTT 브로커로 보내는 방법은 여러 가지라 나중에 자세히 설명합니다. 중심엔 라즈베리파이가 MQTT 브로커(Mosquitto)와 OpenHAB을 돌립니다. OpenHAB은 모델 하우스 필수는 아니지만 스마트폰 앱 인터페이스와 원격 모니터링/제어를 위해 필요합니다. 물리적 인터페이스를 원한다고 가상 인터페이스를 버리는 건 아니니까요.

모델 하우스엔 버튼 2개도 있습니다. 하나는 지그비 전구 온오프 토글, 다른 하나는 실제 집 차고 문 개폐 제어.

파트 1: 하우스 제작

1단계: 모델 하우스 제작
2단계: 제어 옵션, 배선, 코드

파트 2: 입력 (센서)

3단계: 센서 - 에너지 모니터
4단계: 센서 - DIY 무선 센서 노드
5단계: 센서 - Wink 허브 & Tripper 접점 센서

파트 3: 출력

6단계: 출력 - 조명
7단계: 출력 - 차고 문 오프너

1단계: 모델 하우스 제작

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

이 단계를 처방적으로 쓰진 않겠습니다. 저는 미술/공예엔 아마추어라 제 방식만 공유합니다. 본인 집과 닮게, 관심 있는 요소를 반영해 만드세요. 창의성 발휘할 여지 많습니다. 사진 속 일부 부품(전류 변환기 등)은 나중 단계에서 쓰입니다.

부품:

지붕

박스 측면 날개 하나를 잘라 다른 쪽(아직 붙어 있는) 날개에 붙여 지붕 형성. 직각 유지를 위해 작은 박스로 받치고 나중에 레고 조각으로 보강. 집 주변 물건로 직각 만들면 됩니다.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

문/창문

표시하고 싶은 문 위치에 구멍 내고 경첩으로 문 달기(양면 테이프 활용). 화려하진 않지만 집 주변 재료로 improvisation 하세요. 3M 폼 양면 테이프(훅용)로 서보 모터도 고정했습니다. 차고 문은 서보 암이 밀어서 열고 중력으로 닫히게. 현관문은 경첩 달린 문에 실 묶어 서보 암으로 당겨 열리게. 보이는 노란 레고 조각은 서보를 경첩에서 떨어뜨리는 오프셋용.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

에너지 미터

화살표 모양 잘라 서보 암에 붙이고, 관목 모양으로 킬로와트 눈금 표시. 서보를 박스에 마찰 고정(관목 사이에 끼움). 에너지 서보 위에 빨간 LED 테이프로 부착.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

조명/차고 문 제어용 순간 버튼 2개. 너트로 박스 벽에 고정, 반대편 금속 접점에 전선 납땜.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

2단계: 모델 하우스 - 배선 및 코드

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

배선

박스 안 배선은 엉망이라 배선도로 대체. 핀 할당만 보면:

컨트롤러 옵션

편한 대로 선택. 저렴한($20) 옵션: 아두이노 우노 클론 + 이더넷 실드. 처음엔 이랬는데 랜선 때문에 제약이 있어 아두이노 윤($65)으로 변경. 와이파이 자유도 확보. 윤 설정은 간단: 1) 공유기에 랜선 연결, 2) 윤 웹페이지 접속, 3) 비밀번호 및 공유기 고정 IP 설정, 4) 윤 스케치 업로드.

아래 아두이노 우노용/윤용 스케치 첨부. 이더넷 브리지 부분 빼곤 거의 동일. 윤으로 바꾼 후 버튼 2개 추가돼 우노 스케치엔 버튼 코드 없음.

1단계 영상은 윤 버전. 우노+이더넷 실드 버전 영상도 있음(버튼 미장착 상태지만 나머지 동일).

첨부 파일: smarthome_ethernet.ino, smarthome_yun.ino

3단계: 센서 - 에너지 모니터

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

모델 하우스로 에너지 사용량 표시 준비됐으니, 이제 집 전력 소비를 읽어 MQTT 브로커로 발행할 센서 노드 제작. 방법 여러 가지지만 전 아두이노 윤 사용(가장 단순, 최저가는 아님). 아두이노 우노+이더넷 실드+와이파이 브리지 공유기나, 라즈베리파이+OpenEnergyMonitor 패키지도 가능. 여기선 윤 방식만 다룸.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

이베이 $7 전류 변환기(YHDC SCT-013-000 100A) 사용. 위 배선도대로 연결하고 하단 아두이노 윤 스케치 업로드. MQTT 브로커 IP 주소 코드에 반영 필수. OpenEnergyMonitor 라이브러리 참고: https://github.com/openenergymonitor/EmonLib

이상적 부품값:

제 에너지 모니터 사진은 회로도와 다릅니다. 정확한 부품이 없어 68Ω 저항 2개 병렬(≈33Ω)로 대체, 10μF 커패시터 대신 22μF 2개 직렬(≈11μF)로 대체. 실측 시 시판 암페어미터보다 꾸준히 1A 높게 나와 코드에서 1A 보정.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

OpenHAB 연동

데이터 들어오니 OpenHAB에도 표시해 그래프로 보게 설정.

아이템 정의:

Number itm_smarthome_energy_amps "Energy (amps) [%.1f]" {mqtt="<[mymosquitto:2853:state:default]"}
Number itm_smarthome_energy_watts "Energy (Watts) [%.1f]" {mqtt="<[mymosquitto:2852:state:default]"}

사이트맵:

Text label="Energy" icon="firstfloor" {
  Frame label="Energy Usage" {
    Text item=itm_smarthome_energy_amps
    Text item=itm_smarthome_energy_watts
    Chart item=itm_smarthome_energy_watts period=h refresh=5000
  }
}

퍼시스턴스 (RRD4J):

Strategies {
  everyMinute : "0 * * * * ?"
}
Items {
  itm_smarthome_energy_watts : strategy = everyUpdate
}
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

첨부: energy_monitor_yun.ino

4단계: 센서 - DIY 무선 센서 노드

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

무선 개폐 센서 옵션 몇 가지:

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

5단계: 센서 - Wink 허브

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

초기 Wink 허브 사용자가 허브 루팅 후 PHP 익스플로잇으로 'aprontest' 유틸리티 실행해 페어링된 기기 제어하는 블로그 글 발견. 이 방법으로 OpenHAB 인터페이스에서 조명 제어 성공.

가장 큰 장점: 로컬 제어 가능. Wink 허브/API는 원래 인터넷 통해 Wink 서버 거쳐야 조명 제어/센서 상태 조회 가능. PHP 익스플로잇으로 로컬 LAN 내에서 모든 처리 가능. 훌륭합니다.

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

라즈베리파이에서 돌리는 PHP 스크립트 첨부(파일 열기 안 되면 링크 시도). 이 스크립트는 Wink 허브를 폴링해 Wink Tripper 리드 스위치 2개 상태 조회 후 OpenHAB REST API로 전송. OpenHAB이 MQTT 토픽 발행→모델 하우스 컨트롤러가 구독해 문 개폐 반영.

첨부된 OpenHAB 설정 파일 3개(items, sitemap, rules) 필요. 폴링 스크립트가 REST로 상호작용하는 접점 아이템 정의, 지그비 전구 제어 예제 스크립트도 포함.

첨부: sitemap.txt, rules.txt, items.txt, demo_1_general.sh, polling.php

6단계: 출력 - 조명

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

앞선 단계 설정 파일들로 '커넥티드 전구'를 물리적 인터페이스와 OpenHAB 양쪽에서 제어 가능해짐. Wink 허브 지원 전구면 됨. Cree Connected Bulb, GE Wink 테스트 완료. 조도 센서와 버튼으로 스마트 전구 제어하는 영상 참조.

7단계: 출력 - 차고 문 오프너

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

5단계 설정 파일에 차고 문 제어용 OpenHAB 아이템 대부분 포함. 실제 차고 문 개폐 장치는 별도 필요. 이전 인스트럭터블 부품으로 제작:

아두이노가 리드 릴레이 제어→건식 접점 개폐→여분 리모컨 버튼과 병렬 연결→리모컨 버튼 눌림 효과. 아두이노 핀 5와 GND를 리드 릴레이 코일 양단(외측 핀 2개)에 연결, 릴레이 내부 접점(내측 핀 2개)을 리모컨 버튼에 연결.

아두이노가 MQTT 토픽 구독하다 개폐 명령 수신 시 리드 릴레이 순간 작동→리모컨 버튼 닫힘→차고 문 작동. 아두이노 스케치 첨부. 5단계 rules 외에 garage_monitor_rules.txt 추가 필요. 초음파 센서 방식 안 쓰면 해당 부분 수정.

차고 문 소음 적거나 다른 곳에서도 개폐 알림 원하면 오디오 파일 재생 규칙 추가(첫 데모 영상 1분 30초 부근에서 확인 가능).

첨부: garage_monitor_rules.txt, grage_opener.ino

8단계: 기타 생각들

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

이 프로젝트의 결정들은 제가 익숙한 도구, 가진 부품, 우선순위 반영입니다. 여러분은 다른 도구, 부품, 아이디어가 있을 겁니다.

MQTT와 OpenHAB은 유연성이 높아 제 방식대로 안 해도 됩니다. 모델 하우스 컨트롤러는 아두이노, 라즈베리파이, 스파크코어 등 아무거나 가능. DIY 센서도 아두이노나 독립형 ESP8266 가능. 제약은 센서 데이터가 MQTT 브로커로 발행돼야 한다는 것뿐. OpenHAB에 USB Z-wave 스틱 있으면 Z-wave→MQTT 브리지로 Z-wave 센서 활용 가능.

Wink 개폐 센서도 루팅 없이 Wink API로 상태 가져와 OpenHAB이나 MQTT로 포워딩 가능(윙크 서버 경유하지만 루팅 제약 제거).

다양한 접근법이 있습니다. 전 아두이노와 종이 박스 같은 '최소 공통 분모' 하드웨어를 선호합니다.

코드

smarthome_yun.ino (전문)

// Eric Tsai // 2015-04-13 // Arduino Yun code for controlling physical smart home interface
// Modify MQTT topic names to match your use // Modify MQTT broker IP address
#include 
#include 
#include 
#include 

unsigned long keepalivetime=0; unsigned long MQTT_reconnect=0;
YunClient yun; PubSubClient client("192.168.1.101", 1883, callback, yun);
bool conn_ok;
int ledPin = 4; int statusPin = 7;
int servo1Pin = 3; int servo2Pin = 5; int servo3Pin = 6;
Servo servo1; Servo servo2; Servo servo3;
int button1 = 8; int button2 = 9;

int servo1_target = 5; int servo2_target = 5; int servo3_target = 180;
int servo1_pos_cur = 5; int servo2_pos_cur = 5; int servo3_pos_cur = 180;
int servo1Opened = 5; int servo1Closed = 130;
int servo2Opened = 5; int servo2Closed = 150;
unsigned long servo1_time = 0; unsigned long servo2_time = 0; unsigned long servo3_time = 0;
unsigned long button1_db = 0; unsigned long button2_db = 0;
int button=0; int callback_flag = 0; char buff_message[12];

void callback(char* topic, byte* payload, unsigned int length) {
  int mytopic = atoi(topic);
  payload[length] = '\0';
  float mymsg = atof((const char *) payload);
  if (mytopic == 2822) { digitalWrite(ledPin, mymsg == 1 ? HIGH : LOW); }
  if (mytopic == 2832) { servo1_target = (mymsg == 1) ? servo1Opened : servo1Closed; }
  if (mytopic == 2842) { servo2_target = (mymsg == 1) ? servo2Opened : servo2Closed; }
  if (mytopic == 2852) {
    if (mymsg > 6000) mymsg = 6000; if (mymsg < 0) mymsg = 0;
    servo3_target = 180-((1-((6000-mymsg)/6000))*180)-25; callback_flag=1;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT); pinMode(statusPin, OUTPUT);
  pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP);
  digitalWrite(ledPin, HIGH); Bridge.begin();
  client.connect("yun smarthome"); client.publish("watch", "Smart Home Connected!");
  keepalivetime=millis(); MQTT_reconnect = millis();
  client.subscribe("2822"); client.subscribe("2832"); client.subscribe("2842"); client.subscribe("2852");
  digitalWrite(ledPin, LOW);
  servo1.attach(servo1Pin); servo1.write(90);
  servo2.attach(servo2Pin); servo2.write(90);
  servo3.attach(servo3Pin); servo3.write(5);
}

void loop() {
  client.loop();
  if ((millis() - servo1_time) > 20) {
    if (servo1_pos_cur > servo1_target) servo1_pos_cur--;
    else if (servo1_pos_cur < servo1_target) servo1_pos_cur++;
    servo1.write(servo1_pos_cur); servo1_time = millis();
  }
  if ((millis() - servo2_time) > 20) {
    if (servo2_pos_cur > servo2_target) servo2_pos_cur--;
    else if (servo2_pos_cur < servo2_target) servo2_pos_cur++;
    servo2.write(servo2_pos_cur); servo2_time = millis();
  }
  if ((millis() - servo3_time) > 20) {
    if (servo3_pos_cur > servo3_target) servo3_pos_cur--;
    else if (servo3_pos_cur < servo3_target) servo3_pos_cur++;
    servo3.write(servo3_pos_cur); servo3_time = millis();
  }
  if (callback_flag == 1) { callback_flag = 0; dtostrf(servo3_target, 4, 5, buff_message); client.publish("watch", buff_message); }
  button = digitalRead(button1);
  if (button == 0) { if ((millis() - button1_db > 3000) || (button1_db > millis())) { button1_db = millis(); client.publish("2862", "button1 yaya"); } }
  button = digitalRead(button2);
  if (button == 0) { if ((millis() - button2_db > 3000) || (button2_db > millis())) { button2_db = millis(); client.publish("2872", "button2 yaya"); } }
  if ((millis() - MQTT_reconnect) > 60000) {
    conn_ok = client.connected();
    digitalWrite(statusPin, conn_ok ? HIGH : LOW);
    if (!conn_ok) { client.disconnect(); delay(5000); while (client.connect("smarthouse") != 1) { digitalWrite(statusPin, LOW); delay(4000); } digitalWrite(statusPin, HIGH); }
    MQTT_reconnect = millis(); client.publish("watch","smart home heartbeat!");
  }
}

smarthome_ethernet.ino (전문)

// Eric Tsai // 2015-04-1 // Arduino Uno w/ Ethernet
#include  #include  #include  #include 
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x43, 0x13 }; byte server[] = { 192, 168, 1, 101 };
EthernetClient ethClient; PubSubClient client(server, 1883, callback, ethClient);
// ... (윤 버전과 로직 동일, 이더넷 초기화 및 DHCP 처리 추가)

energy_monitor_yun.ino (전문)

/* Eric Tsai 2015-04-22 Arduino Yun energy monitor */
#include  #include  #include  #include "EmonLib.h"
int LED = 3; EnergyMonitor emon1; unsigned long MQTT_reconnect=0, read_energy=0; double Irms; bool conn_ok;
YunClient yun; PubSubClient client("192.168.1.101", 1883, callback, yun);

void callback(char* topic, byte* payload, unsigned int length) { digitalWrite(LED, HIGH); delay(500); digitalWrite(LED, LOW); }

void setup() { pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); delay(1000); digitalWrite(LED, LOW); Bridge.begin(); client.connect("yun_energy"); client.publish("watch", "Energy Monitor Connected!"); client.subscribe("yun_energy"); digitalWrite(LED, HIGH); delay(3000); digitalWrite(LED, LOW); emon1.current(5, 60); }

void loop() {
  char buff_message[12]; float value; client.loop(); Irms = emon1.calcIrms(1480);
  if (millis() - read_energy > 10000) { value = Irms; dtostrf(value, 4, 5, buff_message); client.publish("2853", buff_message); value = Irms*115; dtostrf(value, 4, 5, buff_message); client.publish("2852", buff_message); read_energy = millis(); }
  if ((millis() - MQTT_reconnect) > 60000) { conn_ok = client.connected(); digitalWrite(LED, conn_ok ? HIGH : LOW); if (!conn_ok) { client.disconnect(); delay(5000); while (client.connect("yun_energy") != 1) delay(4000); digitalWrite(LED, HIGH); client.publish("watch", "Energy Monitor reconnected"); } MQTT_reconnect = millis(); }
}

회로도

홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인
홈 오토메이션을 위한 견고한 물리적 인터페이스: 모델 하우스로 실시간 상태 확인

제조공정

  1. 가정용 임신 테스트: 작동 원리, 설계, 미래
  2. C# 인터페이스 마스터하기: 정의, 구현, 실전 활용 사례
  3. Java 인터페이스 마스터: 개념, 구현, 모범 사례
  4. 스마트 홈 기술이 일상을 바꾸는 방법
  5. 라즈베리 파이 기반 홈 오토메이션 시스템으로 원격 제어 구축하기
  6. Labman Automation: 산업 전반에 맞춤형 로봇 솔루션을 개척하다
  7. IoT와 홈 오토메이션: 내일의 스마트 라이프 형성
  8. C# 인터페이스 마스터하기: 견고한 객체 지향 설계를 위한 계약
  9. 산업 자동화 4.0: 생산 효율성 혁신
  10. 프레스 자동화 마스터하기: 기술·안전·효율의 모든 것