저는 과학과 예술을 결합한 프로젝트를 즐기는 엔지니어이자 아티스트입니다. 마이크로컨트롤러를 내장한 드레스 디자인을 만들어 전자 부품의 기능을 디자인 테마를 강화하는 데 활용해 왔습니다. 이 프로젝트에서는 아두이노 101의 인텔 퀴리(Intel Curie) 내부에 있는 패턴 매칭 엔진(PME)과 가속도계를 사용합니다. 퀴리는 신경망 기능을 갖춰 PME 애플리케이션에 적합하지만, PME 예제는 많지 않았습니다. 이 예제가 퀴리의 PME 기능을 활용하는 데 영감을 주길 바랍니다.
이 드레스는 제 그래픽 노블의 한 페이지를 원단으로 사용했습니다. 과학자와 그녀의 로봇이 망원경을 들여다보고 있는 장면입니다. 착용자가 공중에 패턴을 그리면, 별자리 모양으로 배치된 LED 세트가 원단의 밤하늘에서 빛납니다.
제작 지침
참고: 이 프로젝트 공개 후 전자 회로 부분을 개선했습니다. LED를 원단에 부착하고 내구성을 높이는 개선된 방법은 3단계 이후에 설명되어 있습니다.
업데이트: 이 드레스를 여러 번 종일 시연 행사에서 착용해 본 결과 배터리 수명을 추정할 수 있었습니다. 9V 배터리는 약 3시간마다 교체해야 합니다. 배터리가 방전되는 것이 아니라 9V 미만으로 떨어져 패턴 매칭에 비효율적이게 됩니다. 다른 용도로 배터리를 재사용할 수 있습니다.
1단계: LED 배치
아다프루트 네오픽셀 스트립을 잘라 별자리 모양으로 배열했습니다. 개별 RGB LED 등 다른 유형의 LED를 사용해도 됩니다. 베이스 원단에 접착하거나 재봉하세요.
2단계: 인터페이싱 원단 추가
위에 인터페이싱 원단을 대고 별자리 윤곽을 잡습니다. 이 단계는 선택 사항이지만, 여러 겹의 원단으로 구조를 강화하는 데 도움이 된다고 느꼈습니다. 실제로 베이스 원단 뒷면에 두꺼운 원단을 한 겹 더 재봉했습니다. 총 세 겹(베이스, 중간, 뒤)으로 LED를 샌드위치 구조로 만들었습니다.
3단계: LED 납땜
LED를 납땜하세요. 재봉용 개별 LED를 사용하는 경우 전도성 실로 연결할 수도 있습니다. 어느 쪽이든 많은 수작업과 인내가 필요합니다. 네 개의 별자리(오리온, 큰곰자리, 백조자리, 카시오페이아)가 있어 네 개의 트레이스로 분리했습니다. 각각 아두이노 101의 다른 핀에 연결됩니다.
개선된 제작 방법
위 단계에서 사용한 원단이 너무 부드러워 LED와 와이어가 쉽게 구부러지며 납땜 접점이 끊어졌습니다. 다음과 같은 개선된 방법으로 전체 과정을 다시 진행했습니다.
LED 위치 잡기
아다프루트 네오픽셀 스트립을 잘라 별자리 모양으로 배열했습니다. 자유롭게 다른 유형의 LED를 사용하세요. 베이스 원단에 접착하거나 재봉하세요.
펠트는 구조를 잡아주고 핫글루와 잘 어울리는 적당히 두꺼운 원단입니다. LED를 각각의 위치에 배치해 점등 시 별자리의 별 위치를 반영하도록 하세요.
LED와 와이어 계획하기
LED 스트립을 펠트에 몇 군데 접착하세요. 전체에 접착하지 말고 열수축 튜브를 끼울 여유를 두세요(그림 참조). 적절한 길이로 자른 연선을 펠트 위 상대적 위치에 놓으세요. 와이어를 아직 핫글루로 고정하지 않는 것이 좋습니다. 그림에서는 이미 접착되어 있지만, 납땜 시 와이어 위치를 조정할 수 있도록 임시 테이프로 고정하는 편이 낫습니다.
모든 조각을 재봉 준비하기
그림처럼 네 개의 별자리(오리온, 큰곰자리, 백조자리, 카시오페이아)를 네 개의 별도 조각에 준비했습니다. 납땜하고 열수축 튜브로 접점을 감싼 후 모든 것을 펠트에 단단히 접착하세요.
테스트!
더 진행하기 전에 회로를 테스트하세요! 각 트레이스별로 네오픽셀 스트랜드 테스트를 실행해 보세요.
코드를 이해하면 과학적으로 어렵지 않아 '쉬움'으로 표시했지만, 원단 위에 케이블을 안정적으로 고정하는 데 많은 작업이 필요합니다.
아두이노 IDE가 최신 버전이고 Curie PME 라이브러리가 있는지 확인하세요. 아두이노 웹 에디터 사용을 권장합니다. 라이브러리는 여기에서 다운로드하세요.
드레스 만들기
병행해서(말 그대로) 드레스를 만드세요. 회로 테스트 후 LED가 달린 베이스 원단을 드레스 안쪽에 재봉하세요. LED가 그래픽을 통해 빛납니다.
보시다시피 아두이노 101이 제 손에 있습니다. 아두이노 101과 배터리용 3D 프린트 케이스를 만들었습니다. LED와 보드를 연결하는 긴 와이어는 소매 안에 숨겨져 있습니다.
아래 코드는 보드 프로그래밍 방법을 보여줍니다. 코드를 업로드한 후 먼저 뉴런을 훈련시켜 패턴을 학습시키세요. 영상 0:30 부근을 참조하세요.
이전 코드에서 업데이트된 스크립트입니다. 훈련 데이터를 저장합니다. 현재 초기화 단계로 설정되어 있습니다. 첫 번째 LED 시리즈는 전원 켜짐 시 빨간색으로 표시됩니다. 아두이노 101을 평평하게 놓고 USB 포트가 수평 방향을 향하게 한 상태에서 버튼을 누르면 이전 훈련 데이터를 사용합니다. 이 LED는 버튼을 떼면 녹색, 파란색으로 변하며 시스템 준비 완료를 알립니다. 아두이노 101을 USB 포트가 수직 방향을 향하게 한 상태에서 버튼을 누르면 이전 훈련 데이터가 지워집니다. 버튼을 떼면 시스템을 재훈련할 수 있습니다.
/*
* 이 예제는 패턴 매칭 엔진(CuriePME)을 사용하여
* CurieIMU의 가속도계 데이터 스트림을 분류하는 방법을 보여줍니다.
*
* 먼저 공중에 글자를 그려보라는 메시지가 나타납니다(보드를 펜으로,
* 보이지 않는 화이트보드에 쓰는 상상을 하세요). 이 동작의 IMU 데이터가
* PME의 훈련 데이터로 사용됩니다. 훈련이 끝나면 계속 글자를 그리며
* PME가 어떤 글자인지 추측하게 할 수 있습니다.
*
* 이 예제는 디지털 핀 4에 연결된 버튼이 필요합니다.
* https://www.arduino.cc/en/Tutorial/Button
*
* 참고: 최상의 결과를 위해 최소 1-2피트 높이의 큰 글자를 그리세요.
*
* Copyright (c) 2016 Intel Corporation. All rights reserved.
* 라이선스 고지는 파일 끝을 참조하세요.
*/
#include "CurieIMU.h"
#include "CuriePME.h"
#include <CurieSerialFlash.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>
#define PINM 6 // 네오픽셀이 연결된 핀
#define PINC 3
#define PINS 9
#define PINO 5
Adafruit_NeoPixel stripM = Adafruit_NeoPixel(10, PINM, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripS = Adafruit_NeoPixel(10, PINS, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripC = Adafruit_NeoPixel(10, PINC, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripO = Adafruit_NeoPixel(10, PINO, NEO_GRB + NEO_KHZ800);
int tr = 0, tg = 0, tb = 0; // 색상 타겟/현재값 (스무딩용)
int r = 0, g = 0, b = 0;
int rawX = 0, rawY = 0; // 퀴리 가속도계 값
float angle = 0.0;
const unsigned int trainingReps = 4; // 훈련 반복 횟수
const unsigned char trainingStart = 'A';
const unsigned char trainingEnd = 'D';
const unsigned int buttonPin = 4;
const unsigned int sampleRateHZ = 200;
const unsigned int vectorNumBytes = 128;
const unsigned int samplesPerVector = (vectorNumBytes / 3);
const unsigned int upperStart = 0x40;
const unsigned int sensorBufSize = 2048;
const int IMULow = -32768;
const int IMUHigh = 32767;
const char *filename = "NeurDataDress.dat";
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
CurieIMU.begin();
CuriePME.begin();
CurieIMU.setAccelerometerRate(sampleRateHZ);
CurieIMU.setAccelerometerRange(2);
if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)) {
Serial.println("SPI 플래시 칩에 접근할 수 없습니다");
}
stripM.begin(); stripS.begin(); stripC.begin(); stripO.begin();
stripM.show(); stripS.show(); stripC.show(); stripO.show();
solidM(stripM.Color(255, 0, 0), 50); // 빨간색: 입력 대기
}
// ... (이하 생략: 전체 코드는 GitHub 참조)
PME_LED (아두이노)
Curie PME로 LED를 제어하는 코드입니다. 기본적으로 '공중에 그리기' PME 코드와 아다프루트 네오픽셀 예제 코드를 결합한 것입니다. 정확히 같은 별자리 배열을 만들지 않을 것이므로 일반적인 코드로 제공하며, 필요에 맞게 수정하세요(예: 다른 LED 스트립용 핀 배분 변경). 나중에 개선된 코드로 업데이트할 수 있습니다.
/*
* 이 예제는 패턴 매칭 엔진(CuriePME)을 사용하여
* CurieIMU의 가속도계 데이터 스트림을 분류합니다.
* '공중에 그리기' 예제를 수정한 것입니다:
* https://github.com/01org/Intel-Pattern-Matching-Technology
*
* 먼저 공중에 패턴을 그리라는 메시지가 나타납니다...
* (이하 생략: 전체 코드는 GitHub 참조)
*/
회로도
LED를 아두이노 101 핀에 연결하고 버튼을 핀 4에 연결하면 됩니다(코드 참조: https://www.arduino.cc/en/Tutorial/Button). 회로도는 아다프루트의 이 프리칭 다이어그램과 유사합니다: https://learn.adafruit.com/adafruit-neopixel-uberguide/basic-connections