앱을 사용하지 않고, 사회적 모임에서 멀리 떨어진 상대에게 눈맞춤 신호를 보낼 수 있다면 어떨까요? 저는 새로운 데이트 방식을 제안하는 것이 아닙니다. 블루투스를 인간 상호작용 분야에 새롭게 적용해보는 것입니다.
인텔 퀴리(Curie) 모듈이 BLE 중앙(central) 및 주변(peripheral) 장치로 동작할 수 있다는 것을 알게 되자마자 이 안경을 만들고 싶었습니다. (CurieBLE 자세히 보기) Adafruit 튜토리얼 덕분에 3D 프린팅 LCD 안경의 기본 프레임워크를 얻을 수 있었습니다. 여기에 두 안경을 동시에 제어하는 BLE 통신(한 쪽은 마스터/중앙, 다른 쪽은 슬레이브/주변)을 추가하고, 3D 프린팅 프레임을 재설계했습니다.
이 프로젝트는 아두이노 101에서 처음 개발하고 tinyTILE로 프로토타이핑했습니다. 둘 다 인텔 퀴리 모듈을 탑재하고 있습니다. 향후 인텔 퀴리 모듈을 구하기 어려워지더라도, 이 방법론이 여전히 유용하길 바랍니다. 블루투스 중앙/주변 기능의 다양한 적용 방식을 상상해보며, 이 주제에 대한 토론을 기대합니다.
1단계: 개발
두 개의 아두이노 101과 두 개의 LED로 회로와 코드를 개발 및 테스트했습니다. 최종 회로가 복잡하므로 브레드보드에서 시작해 납땜으로 넘어가는 것이 좋습니다.
브레드보드에서 LED로 BLE 통신 테스트
주변 장치(Peripheral) 측은 CurieBLE 예제의 Peripheral → LED 코드를 사용하고 HIGH/LOW를 반전시킵니다(이유는 마지막 단계 참조). 중앙 장치(Central) 측 코드는 프로젝트 끝에 제공되며, CurieBLE → Central → LEDcontrol 예제와 거의 동일하나 LCD 제어 코드가 몇 줄 추가되었습니다.
개발용 회로도상세 연결도
tinyTILE은 아두이노 101의 축소판과 같습니다. 중앙 직사각형이 인텔 퀴리 모듈입니다. 같은 코드로 플래싱 가능합니다. 아두이노 101은 핀 사용이 편하지만, tinyTILE은 웨어러블에 적합한 크기입니다. 저는 아두이노 101로 개발 후 tinyTILE로 이식하는 방식을 선호합니다. 폼팩터가 중요하지 않다면 아두이노 101을 사용하세요 (예시 참조).
tinyTILE로 이식 후 LCD 셔터 테스트
아두이노 101을 tinyTILE로, LED를 LCD 셔터로 변경하며 각 부품을 단계별로 테스트했습니다.
2단계: 3D 프린팅
Adafruit이 제공하는 디자인을 기반으로 SolidWorks로 프레임을 재설계했습니다. 기본 디자인 다운로드 후 선호하는 소프트웨어로 수정해 3D 프린팅하세요. 제가 디자인한 하트 모양과 우주 모양이 마음에 드신다면 첨부 파일을 사용하세요. 디자인 의도는 영상을 참조하세요.
하트(마스터)와 우주(슬레이브) 프레임
디자인을 수정해 얼굴에 더 잘 맞게 할 수 있습니다. 저는 코가 작아 고정이 좀 어려웠습니다. 요즘은 3D 얼굴 스캔으로 맞춤 안경을 제작하는 업체도 있어 좋습니다.
3단계: 조립
Adafruit 튜토리얼의 배선, 납땜, 장착 조언이 매우 유용합니다. 꼭 확인해보세요. 저는 tinyTILE과 버튼을 추가했을 뿐입니다. 와이어 길이를 정확히 자르는 데 주의하세요.
완성된 안경 내부 회로
4단계: 완성 및 즐기기!
전원을 켜면 LCD 셔터에 전압이 걸려 어두운 선글라스 상태가 됩니다. 마스터 측 버튼을 누르면 마스터의 전압이 차단되어 투명해지고, 동시에 블루투스로 슬레이브에도 신호를 보내 슬레이브도 투명해집니다.
어두운 상태 (왼쪽)와 투명 상태 (오른쪽)동작 시연버튼 하나로 양쪽 동시 제어
두 안경은 BLE 범위 내라면 꽤 멀리서도 제어 가능합니다. 집에서 테스트해보니 하트(마스터)가 우주(슬레이브)의 주의를 최소 15걸음 밖에서도 끌 수 있었습니다.
버튼 대신 제스처, 고개 끄덕임, 심박 동기화 등으로 제어한다면 더 멋지겠죠!
하트 (마스터=중앙): "당신의 세련된 마음이 마음에 들어요 <3"
우주 (슬레이브=주변): "당신을 봤어요. 얘기해요."
코드
중앙 장치용 버튼 제어 코드 (아두이노)
/*
* Copyright (c) 2016 Intel Corporation. All rights reserved.
* 라이선스 조건은 파일 하단 참조.
*/
/*
* Sketch: LedControl.ino
* 설명:
* 특정 서비스와 특성을 가진 주변 장치를 찾는 중앙 장치 스케치.
* 발견 시 버튼 상태를 읽어 주변 장치 특성에 기록.
*/
#include
// 버튼 변수
const int buttonPin = 3;
int oldButtonState = LOW;
const int ledPin = 5; // LCD 제어용 핀 (LED 대신)
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
BLE.begin();
Serial.println("BLE Central - LED control");
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
void loop() {
BLEDevice peripheral = BLE.available();
if (peripheral) {
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
BLE.stopScan();
controlLed(peripheral);
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214");
}
}
void controlLed(BLEDevice peripheral) {
Serial.println("Connecting ...");
if (!peripheral.connect()) {
Serial.println("Failed to connect!");
return;
}
Serial.println("Connected");
Serial.println("Discovering attributes ...");
if (!peripheral.discoverAttributes()) {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
Serial.println("Attributes discovered");
BLECharacteristic ledCharacteristic = peripheral.characteristic("19b10001-e8f2-537e-4f6c-d104768a1214");
if (!ledCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
} else if (!ledCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable LED characteristic!");
peripheral.disconnect();
return;
}
while (peripheral.connected()) {
int buttonState = digitalRead(buttonPin);
if (oldButtonState != buttonState) {
oldButtonState = buttonState;
if (buttonState) {
Serial.println("button pressed");
ledCharacteristic.writeByte(0x01); // LCD ON (투명)
digitalWrite(ledPin, LOW); // 로컬 LCD도 ON
} else {
Serial.println("button released");
ledCharacteristic.writeByte(0x00); // LCD OFF (어두움)
digitalWrite(ledPin, HIGH); // 로컬 LCD도 OFF
}
}
}
Serial.println("Peripheral disconnected");
}
/* 라이선스: GNU Lesser General Public License v2.1 이상 */
회로도
중앙: 핀 3(버튼), 5(LCD) / 주변: 핀 6(LCD)
커스텀 파트 및 인클로저
3D 프린팅용 CAD 파일은 Thingiverse 등에서 다운로드 가능합니다. (Adafruit 기본 디자인 기반 수정)