SomfyDuino: Arduino Nano로 Somfy IO 리모컨 USB 어댑터 만들기
부품 및 소모품
| 부품 |
수량 |
| Arduino Nano R3 |
1 |
| 평면 케이블 7코어 |
1 |
| Somfy IO 리모컨 (예: GX037 1채널) |
1 |
| 수축 튜브 (정리용) |
1 |
필요한 도구
프로젝트 소개
아이디어
Somfy IO 프로토콜 롤러 셔터를 클라우드 의존적인 공식 허브 없이 DIY 홈 오토메이션 시스템에 연동하고자 했습니다. Somfy IO 리모컨을 해킹하여 Arduino로 버튼을 에뮬레이트하는 방식입니다. 결과: 성공!
준비물
- Somfy IO 리모컨 (1채널 GX037 사용, 5채널도 동일 레이아웃)
- USB 커넥터가 있는 Arduino (Nano, Micro, Pro Micro 등). 소프트웨어 시리얼도 가능
- 7심 평면 케이블 + 수축 튜브
배선 방법
리모컨 내부 버튼 패드에 납땜으로 연결. 리모컨 전원은 Arduino 5V에서 공급 (송신 시 약 20mA). 반드시 리모컨 배터리 제거 후 작업.
핀 매핑 (코드 기준):
- 핀 8: PROG 버튼
- 핀 9: SELECT 버튼
- 핀 10: DOWN 버튼
- 핀 11: MY 버튼
- 핀 12: UP 버튼
- 핀 13: 상태 LED
모든 버튼 핀은 Active LOW (기본 HIGH, 누르면 LOW)로 풀업 저항 내장 활용.
코드 설명
시리얼 명령어로 버튼 조합 및 홀드 시간 제어:
u: UP 준비, d: DOWN 준비, m: MY 준비
p: PROG 준비, s: SELECT 준비
1~9: 홀드 시간 추가 (×100ms)
r: 반복 횟수 증가
e: 실행 (정의된 버튼 조합으로 홀드 시간만큼 누름)
예: u5e = UP 버튼 500ms 누름, ud9993e = UP+DOWN 동시 3초 누름 (페어링 모드 등)
Raspberry Pi 등에서 제어 시 Serial.print 디버그 출력 제거 권장.
소스 코드
// SomfyDuino by Bjoern Foldenauer 05/2017
int progPin = 8, upPin = 12, downPin = 10, myPin = 11, selectPin = 9, ledPin = 13;
bool upPress=false, downPress=false, myPress=false, progPress=false, selectPress=false;
unsigned long holdTime = 0;
int repeatSend = 0;
char incomingChar;
void setup() {
Serial.begin(9600);
Serial.println("SomfyDuino 0.71");
Serial.println("명령: u/d/m/p/s (버튼), 1-9 (시간x100ms), r (반복), e (실행)");
pinMode(progPin, OUTPUT); pinMode(upPin, OUTPUT); pinMode(downPin, OUTPUT);
pinMode(myPin, OUTPUT); pinMode(selectPin, OUTPUT); pinMode(ledPin, OUTPUT);
digitalWrite(progPin, HIGH); digitalWrite(upPin, HIGH); digitalWrite(downPin, HIGH);
digitalWrite(myPin, HIGH); digitalWrite(selectPin, HIGH); digitalWrite(ledPin, LOW);
}
void loop() {
while (Serial.available() == 0) delay(50);
if (Serial.available() > 0) {
incomingChar = Serial.read();
if (incomingChar == 'u') upPress = true;
if (incomingChar == 'd') downPress = true;
if (incomingChar == 'm') myPress = true;
if (incomingChar == 'p') progPress = true;
if (incomingChar == 's') selectPress = true;
if (incomingChar >= '1' && incomingChar <= '9') holdTime += (incomingChar - '0') * 100;
if (incomingChar == 'r') repeatSend++;
if (incomingChar == 'e') somSend();
}
}
void somSend() {
for (int i = 0; i <= repeatSend; i++) {
if (upPress) { digitalWrite(upPin, LOW); Serial.print("up "); }
if (downPress) { digitalWrite(downPin, LOW); Serial.print("down "); }
if (myPress) { digitalWrite(myPin, LOW); Serial.print("my "); }
if (progPress) { digitalWrite(progPin, LOW); Serial.print("prog "); }
if (selectPress){ digitalWrite(selectPin, LOW); Serial.print("select "); }
digitalWrite(ledPin, HIGH);
Serial.print("for "); Serial.print(holdTime); Serial.println(" ms");
delay(holdTime);
digitalWrite(progPin, HIGH); digitalWrite(upPin, HIGH); digitalWrite(downPin, HIGH);
digitalWrite(myPin, HIGH); digitalWrite(selectPin, HIGH); digitalWrite(ledPin, LOW);
delay(holdTime);
}
upPress=downPress=myPress=progPress=selectPress=false; holdTime=0; repeatSend=0;
Serial.println("done.");
}
회로도
리모컨 PCB 버튼 패드 납땜 포인트 사진 3장 포함. 1채널 리모컨의 경우 SELECT 버튼은 채널 전환 효과 없음 (작동 안 함 but 고장도 안 남).