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

Arduino 101 - 인텔 퀴리 패턴 매칭 드레스

구성품 및 소모품

NeoPixel 스트립
개별 RGB LED로 대체 가능
× 1
아두이노 101
× 1
SparkFun 푸시버튼 스위치 12mm
× 1
저항 10k 옴
× 1
점퍼 와이어(일반)
LED를 어깨에서 손으로 유도하려면 긴 전선이 필요할 수 있습니다.
× 1
9V 배터리(일반)
× 1
9V 대 배럴 잭 커넥터
× 1
Adafruit Flora RGB 네오픽셀 LED- 4개 팩
네오픽셀 스트립을 교체하는 데 사용할 수 있습니다.
× 1
봉제 가능한 전도성 스레드
일부 전선 교체 옵션
× 1

필요한 도구 및 기계

뜨거운 글루건(일반)
재봉틀(일반)
납땜 인두(일반)

앱 및 온라인 서비스

Arduino IDE

이 프로젝트 정보

소개

저는 과학과 예술을 결합한 프로젝트를 즐기는 엔지니어이자 예술가입니다. 저는 전자 부품의 특정 기능을 사용하여 디자인 테마를 향상시킬 수 있도록 마이크로컨트롤러가 내장된 드레스 디자인을 만들어 왔습니다. 이 프로젝트에서는 Arduino 101의 Intel Curie 내부에 있는 패턴 매칭 엔진(PME)과 가속도계를 사용하고 싶습니다. Curie는 신경망 기능이 있기 때문에 PME 애플리케이션용으로 만들어졌지만 PME 예제가 많지 않았습니다. . 이 예가 Curie의 PME 기능을 추출하는 데 영감을 줄 수 있기를 바랍니다.

드레스는 내 그래픽 노블의 페이지를 패브릭으로 사용합니다. 과학자와 그녀의 로봇이 망원경을 들여다보고 있습니다. 착용자가 허공에 패턴을 그리면 별자리 모양으로 배열된 LED 세트가 천의 밤하늘에 빛납니다.

지침

*참고:이 프로젝트가 게시된 후 전자 회로 부분을 개조했습니다. LED를 천에 부착하는 개선된 방법과 내구성을 높이는 방법은 3단계 이후에 아래에 게시됩니다.

** 업데이트:하루 종일 몇 번의 데모 이벤트에서 이 드레스를 입고 배터리 수명을 추정했습니다. 이 드레스에 전원을 공급하려면 9V 배터리를 약 3시간마다 교체해야 합니다. 배터리는 소모되지 않지만 9V 이하로 떨어지므로 패턴 매칭을 수행하는 것이 비효율적입니다. 다른 용도로 배터리를 절약할 수 있습니다.

1단계

Adafruit의 NeoPixel 스트립을 사용하여 조각으로 자르고 별자리 모양으로 배열했습니다. 개별 RGB LED와 같은 다른 유형의 LED를 자유롭게 사용하십시오. 베이스 천에 풀로 붙이거나 꿰매십시오.

2단계

상단에 인터페이싱 천을 놓으면 별자리의 윤곽을 그릴 수 있습니다. 이 단계는 선택 사항이지만 구조를 강화하기 위해 여러 겹의 천을 사용하는 것이 도움이 된다는 것을 알았습니다. 나는 실제로 기본 천의 뒷면에 다른 두꺼운 천을 꿰매었다. 따라서 LED를 사이에 두고 베이스로 총 3개의 레이어가 있습니다.

3단계

LED를 납땜하십시오. 바느질 가능한 개별 LED를 사용하는 경우 전도성 스레드를 사용하여 연결할 수도 있습니다. 어느 쪽이든 많은 수작업이 필요하고 인내가 필요합니다. 나에게는 4개의 별자리(오리온, 북두칠성, 백조자리, 카시오페이아)가 있으므로 4개의 자취로 구분했습니다. 각각 다른 Arduino 101 핀에 연결됩니다.

개선된 단계

위의 단계에서 사용한 천은 너무 부드러워서 LED와 전선을 쉽게 구부려 납땜 이음매가 부러졌습니다. 다음 개선된 방법으로 전체 프로세스를 다시 수행했습니다.

LED 위치 지정

Adafruit의 NeoPixel 스트립을 사용하여 조각으로 자르고 별자리 모양으로 배열했습니다. 개별 RGB LED와 같은 다른 유형의 LED를 자유롭게 사용하십시오. 베이스 천에 풀로 붙이거나 꿰매십시오.

펠트는 구조를 부여하고 뜨거운 접착제와 잘 작동하는 좋은 유형의 두꺼운 천입니다. LED가 켜질 때 별자리의 별을 반사하도록 LED를 각각의 위치에 배치합니다.

LED 및 전선 계획

몇 지점에서 펠트에 LED 줄무늬를 붙입니다. 그림과 같이 열수축 튜브를 움직일 수 있는 여유가 필요하므로 전체 스트립 아래에 접착제를 바르지 마십시오. 연선을 올바른 길이로 자르고 동일한 펠트 조각의 상대적 위치에 놓습니다. 나는 아직 전선을 뜨겁게 붙이지 않는 것이 좋습니다. 그런 점에서 내 모습은 실수다. 차라리 LED에 납땜할 때 전선 위치를 조절할 수 있도록 임시 테이프로 전선을 제자리에 고정하는 것이 좋습니다.

모든 조각을 재봉할 준비를 하십시오

그림은 내가 4개의 별자리(오리온, 북두칠성, 백조자리 및 카시오페이아)를 4개의 개별 조각으로 준비했음을 보여줍니다. 납땜 접합부 주변을 납땜하고 열수축한 후에는 모든 것을 펠트에 단단히 붙일 수 있습니다.

테스트!

더 진행하기 전에 회로를 테스트하십시오! 각 트레이스에 대해 NeoPixel Strandtest를 수행할 수 있습니다.

좋습니다. 일단 코드를 이해하면 과학적으로 어렵지 않기 때문에 레벨을 "쉬움"으로 지정했지만 패브릭의 케이블을 안정화하는 데 많은 작업이 필요합니다.

Arduino IDE가 최신 버전이고 Curie PME 라이브러리가 있는지 확인하십시오. Arduino 웹 편집기를 사용하는 것이 좋습니다. 여기에서 라이브러리를 다운로드하세요.

드레스 만들기

병렬로 (비유적으로) 드레스를 만드십시오. 회로를 테스트한 후 LED가 있는 기본 천을 드레스 안쪽에 꿰매십시오. LED가 그래픽을 통해 빛날 것입니다.

보시다시피 Arduino 101이 내 손에 있습니다. 아두이노 101과 배터리용 3D프린팅 케이스를 만들었습니다. LED와 기판을 연결하는 긴 전선이 슬리브에 숨겨져 있습니다.

아래 코드는 보드 프로그래밍 방법에 대한 정보를 제공합니다. 코드를 플래시한 후 뉴런을 먼저 훈련시켜 어떤 패턴이 있는지 학습합니다. ~0:30에 이 비디오 보기:

더 많은 사진 및 기타 테크-패션/패브릭-온-패브릭 디자인을 보려면 내 웹사이트를 확인하세요 :)

<섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

코드

<울>
  • PME_4LED_new.ino
  • PME_LED
  • PME_4LED_new.ino아두이노
    이것은 이전 스크립트에서 업데이트된 스크립트입니다. 훈련 데이터를 저장합니다. 현재 초기화 단계로 설정되어 있습니다. 첫 번째 시리즈의 LED는 전원이 켜지면 빨간색으로 표시됩니다. USB 포트가 수평 방향을 향하도록 Arduino101을 평평하게 잡고 버튼을 누르면 이전 교육에서 사용할 수 있습니다. 버튼에서 손을 떼면 이 LED가 녹색으로 바뀌고 시스템이 준비되었음을 나타냅니다. USB 포트를 세로 방향으로 잡고 Arduino101을 잡고 버튼을 누르면 이전 훈련 데이터가 지워집니다. 버튼을 놓으면 시스템을 다시 훈련할 수 있습니다.
    /* * 이 예는 CurieIMU에서 가속도계 데이터 스트림을 분류하기 위해 * 패턴 일치 엔진(CuriePME)을 사용하는 방법을 보여줍니다. * * 먼저, 스케치는 공중에 글자를 그리라는 메시지를 표시하고(보드를 펜으로 사용하여 보이지 않는 화이트보드에 쓰고 있다고 * 상상해보십시오), 이러한 동작의 IMU 데이터는 * PME. 훈련이 끝나면 계속해서 글자를 그릴 수 있고 PME *는 당신이 어떤 글자를 그리고 있는지 추측하려고 할 것입니다. * * 이 예에서는 버튼이 디지털 핀 4에 연결되어야 합니다. * https://www.arduino.cc/en/Tutorial/Button * * 참고:최상의 결과를 얻으려면 최소 1-2피트 높이의 큰 글자를 그립니다. * * Copyright (c) 2016 Intel Corporation. 판권 소유. * 파일 끝에 있는 라이선스 고지를 참조하십시오. */#include "CurieIMU.h#include "CuriePME.h#include #include #include #define PINM 6 //// NeoPixels 핀은 무엇입니까 #define PINC 3#define PINS 9#define PINO 5 Adafruit_NeoPixel stripM =Adafruit_NeoPixel(10, PINM, NEO_GRB + NEO_KHZ800); /// 스트립의 길이는 15픽셀입니다. 개별 스트립의 픽셀 수에 대해 이를 변경할 수 있습니다.Adafruit_NeoPixel stripS =Adafruit_NeoPixel(10, PINS, NEO_GRB + NEO_KHZ800);Adafruit_NeoPixel stripC =Adafruit_NeoPixel(10, PINC, NEO_GRB + NEO_KHZ80);Adafruit_NeoPixel(10, PINC, NEO_GRB + NEO_KHZ80 , NEO_GRB + NEO_KHZ800);int tr =0; // 평활화를 위해 "color-target" 및 "color-current"를 유지하는 일부 변수...int tg =0;int tb =0;int r =0;int g =0;int b =0;int rawX =0; ///// 퀴리의 가속도계 값을 유지하기 위해 int rawY =0;//int rawZ =0;float angle =0.0;/* 이것은 훈련 중에 문자를 몇 번이나 그려야 하는지를 제어합니다. * 4보다 크면 알파벳의 26자 * 모두에 대한 뉴런이 충분하지 않을 수 있습니다. 4 미만은 편지를 훈련하는 데 필요한 작업이 적다는 것을 의미하지만 * PME는 해당 편지를 분류하는 데 더 어려움을 겪을 수 있습니다. */const unsigned int trainingReps =4;/* 원한다면 이것을 'AZ'로 늘리십시오. 훈련하는 데 시간이 훨씬 더 오래 걸립니다. */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;/* 뉴런 내부에 들어갈 수 있는 처리된 샘플 수(1 샘플 ==accel x, y, z) * /const unsigned int samplesPerVector =(vectorNumBytes / 3);/* 이 값은 ASCII 문자 AZ *를 10진수 값 1-26으로 변환하고 다시 변환하는 데 사용됩니다. */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 ); //while(!직렬); 핀모드(버튼핀, 입력); /* IMU(Intertial Measurement Unit) 시작 */ CurieIMU.begin(); /* PME(패턴 매칭 엔진) 시작 */ CuriePME.begin(); CurieIMU.setAccelerometerRate(sampleRateHZ); CurieIMU.setAccelerometerRange(2); /* 초기화 SPI 플래시 칩 */ if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)) { Serial.println("SPI 플래시 칩에 액세스할 수 없습니다."); } 스트립M.begin(); // 네오픽셀 스트립 초기화 stripS.begin(); 스트립C.begin(); stripO.begin(); stripM.show(); // 모든 픽셀을 'off'로 초기화 stripS.show(); 스트립C.show(); stripO.show(); solidM(stripM.Color(255, 0, 0), 50); //Red for ready for input}/* 이 함수는 이전 예제에서 저장한 파일을 읽습니다. * 파일에는 이전에 학습된 다음 저장한 모든 데이터가 포함되어 있습니다. * 네트워크가 복원되면 재학습할 필요 없이 * 다시 패턴을 분류할 수 있습니다.*/void restoreNetworkKnowledge ( void ){ SerialFlashFile file; int32_t 파일 신경 세포 수 =0; Intel_PMT::neuronData 뉴런 데이터; // 파일을 열고 테스트 데이터 쓰기 file =SerialFlash.open(filename); CuriePME.beginRestoreMode(); if (file) { // 네트워크를 반복하고 데이터를 저장합니다. while(1) { Serial.print("뉴런 읽기:"); uint16_t 뉴런필드[4]; file.read( (void*) neuronFields, 8); file.read( (void*) neuronData.vector, 128 ); neuronData.context =neuronFields[0]; neuronData.influence =neuronFields[1]; neuronData.minInfluence =neuronFields[2]; neuronData.category =neuronFields[3]; if (neuronFields[0] ==0 || neuronFields[0]> 127) break; 파일뉴런카운트++; // 이 부분은 복원될 때 각 뉴런을 인쇄하므로 // 무슨 일이 일어나고 있는지 확인할 수 있습니다. Serial.print(fileNeuronCount); Serial.print("\n"); Serial.print(뉴런필드[0]); Serial.print( "\t"); Serial.print(뉴런필드[1]); Serial.print( "\t"); Serial.print(뉴런필드[2]); Serial.print( "\t"); Serial.print(뉴런필드[3]); Serial.print( "\t"); Serial.print( neuronData.vector[0] ); Serial.print( "\t"); Serial.print( neuronData.vector[1] ); Serial.print( "\t"); Serial.print( neuronData.vector[2] ); Serial.print( "\n"); CuriePME.iterateNeuronsToRestore(뉴런데이터); } } CuriePME.endRestoreMode(); Serial.print("지식 집합이 복원되었습니다. \n");}부울 longPress=false;int startTime=0;int lastOrientation =- 1; // 이전 방향(비교용)int lastReading =-1;boolean lastPress=false;void 루프(){ int orientation =- 1; // 보드의 방향 String orientationString; // 방향 설명을 인쇄하기 위한 문자열 // 보드의 방향:// 0:평면, 프로세서가 위로 향함 // 1:평면, 프로세서가 아래로 향함 // 2:가로, 아날로그 핀 아래로 // 3:가로, 아날로그 핀 업 // 4:세로, USB 커넥터 위로 // 5:세로, USB 커넥터 아래로 // 가속도계 읽기:int x =CurieIMU.readAccelerometer(X_AXIS); 정수 y =CurieIMU.readAccelerometer(Y_AXIS); int z =CurieIMU.read가속도계(Z_AXIS); // 가장 큰 값을 결정하기 위해 절대값을 계산합니다. int absX =abs(x); 정수 absY =abs(y); 정수 absZ =abs(z); if ( (absZ> absX) &&(absZ> absY)) { // Z 기준 방향 if (z> 0) { orientationString ="up"; 방향 =0; } else { 오리엔테이션 문자열 ="아래로"; 방향 =1; } } else if ( (absY> absX) &&(absY> absZ)) { // 기본 방향은 Y if (y> 0) { orientationString ="디지털 핀업"; 방향 =2; } else { orientationString ="아날로그 핀업"; 방향 =3; } } else { // X의 기본 방향 if (x <0) { orientationString ="connector up"; 방향 =4; } else { orientationString ="커넥터 다운"; 방향 =5; } } // 방향이 변경된 경우 설명을 출력합니다. if (orientation !=lastOrientation) { Serial.println(orientationString); lastOrientation =방향; } // 방향이 변경된 경우 설명을 출력합니다. if (orientation !=lastOrientation) { lastOrientation =orientation; } 정수 읽기 =digitalRead(buttonPin); if (lastReading !=읽기) { Serial.print("buttonPin="); Serial.println(읽기); lastReading =읽기; } if (읽기 ==HIGH) { if (startTime ==0) { startTime=millis(); } else if ((millis() - startTime)>2000) { longPress=true; if (!lastPress) { Serial.println("longPress"); // 길게 누르면 녹색 solidM(stripM.Color(0, 255, 0), 50);// 녹색 lastPress=true; } } } if ( ==LOW &&longPress 읽기) { blackout(5); Serial.print("방향="); Serial.print(방향); Serial.print(" SerialFlash.exists(파일명)="); Serial.println(SerialFlash.exists(파일명)); if (orientation!=4 &&SerialFlash.exists(filename)) { restoreNetworkKnowledge(); Serial.print("훈련이 복구되었습니다."); } else { 기차편지(); 정전(5); Serial.print("교육이 완료되었습니다."); } Serial.println(" 이제 몇 개의 글자를 그리세요("를 기억하십시오); Serial.println("버튼을 누르고 있으면 PME가 분류할 수 있는지 확인하십시오."); solidM(stripM.Color(0, 0, 255), 500); //일치할 준비가 된 파란색 blackout(5); // 매칭을 위해 끄기 while (true) { match(); } }} 무효 solidM(uint32_t c, uint8_t 대기) { for (uint16_t i=0; i  (num * 3) - (step * 3)) { ret =samples[pos]; } 그렇지 않으면 { 레트 =0; pos -=(단계 * 3); for (unsigned int i =0; i  sensorBufSize) { break; } } } undersample(accel, samples, vector);}void trainLetter(char letter, unsigned int repeat){ unsigned int i =0; while (i <반복) { 바이트 벡터[vectorNumBytes]; if ( 문자 =='A' ) { colorWipeM(stripM.Color(0, 255, 0), 50); // 녹색 TheaterChaseM(stripM.Color(127, 127, 127), 50); // 흰색 stripM.show(); } else if ( 문자 =='B') { colorWipeS(stripS.Color(255, 0, 0), 50); // 레드 TheaterChaseS(stripS.Color(127, 127, 127), 50); // 흰색 stripS.show(); } else if ( 문자 =='C') { colorWipeC(stripC.Color(0, 0, 255), 50); // 파란색 TheaterChaseC(stripC.Color(127, 127, 127), 50); // 흰색 stripC.show(); } else if ( 문자 =='D') { colorWipeO(stripO.Color(255, 0, 255), 50); // 파란색 TheaterChaseO(stripO.Color(127, 127, 127), 50); // 흰색 stripO.show(); } if (i) Serial.println("그리고 다시..."); readVectorFromIMU(벡터); CuriePME.learn(벡터, vectorNumBytes, 문자 - upperStart); Serial.println("알았다!"); 지연(1000); ++나; }}bool create_if_not_exists(const char *filename, uint32_t fileSize) { if (!SerialFlash.exists(filename)) { Serial.println("파일 생성 중" + String(filename)); 반환 SerialFlash.createErasable(파일 이름, 파일 크기); } Serial.println("파일 " + String(파일 이름) + " 이미 존재함"); return true;} 무효 saveNetworkKnowledge( 무효 ){// const char *filename ="NeurData.dat"; 직렬 플래시 파일 파일; Intel_PMT::neuronData 뉴런 데이터; uint32_t 파일 크기 =128 * sizeof(뉴런 데이터); Serial.print( "저장할 파일 크기는 ="); Serial.print( 파일 크기 ); Serial.print("\n"); create_if_not_exists( 파일 이름, 파일 크기 ); // 파일을 열고 테스트 데이터 쓰기 file =SerialFlash.open(filename); 파일.지우기(); CuriePME.beginSaveMode(); if (file) { // 네트워크를 반복하고 데이터를 저장합니다. while( uint16_t nCount =CuriePME.iterateNeuronsToSave(neuronData)) { if( nCount ==0x7FFF) 중단; Serial.print("뉴런 저장 중:"); Serial.print(nCount); Serial.print("\n"); uint16_t 뉴런필드[4]; neuronFields[0] =neuronData.context; neuronFields[1] =neuronData.influence; neuronFields[2] =neuronData.minInfluence; neuronFields[3] =neuronData.category; file.write( (void*) neuronFields, 8); file.write( (void*) neuronData.vector, 128 ); } } CuriePME.endSaveMode(); Serial.print("지식 집합이 저장되었습니다. \n");}void trainLetters(){ for (char i =trainingStart; i <=trainingEnd; ++i) { Serial.print("버튼을 누른 상태에서 문자를 그립니다. '"); Serial.print(String(i) + "' 공중에 떠 있습니다. 버튼을 빨리 놓으십시오 "); Serial.println("완료했습니다."); trainLetter(i, trainingRep); Serial.println("알겠습니다, 이 문자로 끝냈습니다."); 지연(2000); } // 초기화 SPI 플래시 칩 if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)) { Serial.println("SPI 플래시 칩에 액세스할 수 없습니다."); } saveNetworkKnowledge();}/*Adafruit Strandtest의 특수 조명 기능 예제 코드 * 색상 값을 얻으려면 0에서 255 사이의 값을 입력하십시오. 위의 무지개 효과에 사용됩니다. * Adafruit 가닥 테스트 예제 코드의 극장 체이스 조명. 이것은 현재 RGB 값이 무엇이든 간에 "극장 추적" 효과를 수행합니다. *//*극장 스타일의 크롤링 조명.*/void theaterChasePIN(uint8_t p,uint32_t c, uint8_t wait) { Adafruit_NeoPixel 스트립 =Adafruit_NeoPixel(10, p, NEO_GRB + NEO_KHZ800); for (int j=0; j<10; j++) { // 10주기의 추적 for (int q=0; q <3; q++) { for (uint16_t i=0; i  
    PME_LED아두이노
    이것은 Curie PME를 사용하여 LED를 제어하는 ​​것입니다. 기본적으로 Draw in the Air PME 코드와 Adafruit NeoPixel 예제 코드의 조합입니다. 이 코드는 내가 사용한 것과 정확히 일치하지 않습니다(조금 복잡함). 정확히 같은 종류의 별자리 배열을 만들지 의심스럽기 때문입니다. 대신, 필요에 맞게 수정할 수 있는 일반 코드가 있습니다. 예:다른 LED 스트립에 핀을 분배하는 방법을 변경할 수 있습니다. 나중에 개선된 코드로 업데이트할 수 있습니다.
    /* * 이 예제는 CurieIMU에서 가속도계 데이터 스트림을 분류하기 위해 패턴 일치 엔진(CuriePME)을 사용하는 것을 보여줍니다. 이 코드는 Draw in the Air 예제의 수정입니다. * https://github.com/01org/Intel-Pattern-Matching-Technology * * First, the sketch will prompt you to draw patterns in the air (just * imagine you are writing on an invisible whiteboard, using your board as the * pen), and the IMU data from these motions is used as training data for the * PME. Once training is finished, you can keep drawing letters and the PME * will try to guess which letter you are drawing. * * This example requires a button to be connected to digital pin 4 * https://www.arduino.cc/en/Tutorial/Button * * NOTE:For best results, draw big letters, at least 1-2 feet tall. * * Copyright (c) 2016 Intel Corporation. 판권 소유. * See license notice at end of file. */#include "CurieIMU.h"#include "CuriePME.h"#include #define PIN 6 //// what pin are the NeoPixels connected to?Adafruit_NeoPixel strip =Adafruit_NeoPixel(54, PIN, NEO_GRB + NEO_KHZ800); /// the strip is 15 pixels long. You can change this for the number of pixels in your individual strip.int tr =0; //Some variables to hold "color-target" and "color-current" for smoothing...int tg =0;int tb =0;int r =0;int g =0;int b =0;int rawX =0; ///// to hold values from the Curie's accelerometerint rawY =0;//int rawZ =0;float angle =0.0;/* This controls how many times a letter must be drawn during training. * Any higher than 4, and you may not have enough neurons for all 26 letters * of the alphabet. Lower than 4 means less work for you to train a letter, * but the PME may have a harder time classifying that letter. */const unsigned int trainingReps =4;/* Increase this to 'A-Z' if you like-- it just takes a lot longer to train */const unsigned char trainingStart ='A';const unsigned char trainingEnd ='D';/* The input pin used to signal when a letter is being drawn- you'll * need to make sure a button is attached to this pin */const unsigned int buttonPin =4;/* Sample rate for accelerometer */const unsigned int sampleRateHZ =200;/* No. of bytes that one neuron can hold */const unsigned int vectorNumBytes =128;/* Number of processed samples (1 sample ==accel x, y, z) * that can fit inside a neuron */const unsigned int samplesPerVector =(vectorNumBytes / 3);/* This value is used to convert ASCII characters A-Z * into decimal values 1-26, and back again. */const unsigned int upperStart =0x40;const unsigned int sensorBufSize =2048;const int IMULow =-32768;const int IMUHigh =32767;void setup(){ Serial.begin(9600); // while(!Serial); 핀모드(버튼핀, 입력); /* Start the IMU (Intertial Measurement Unit) */ CurieIMU.begin(); /* Start the PME (Pattern Matching Engine) */ CuriePME.begin(); CurieIMU.setAccelerometerRate(sampleRateHZ); CurieIMU.setAccelerometerRange(2); trainLetters(); //Serial.println("Training complete. Now, draw some letters (remember to "); // Serial.println("hold the button) and see if the PME can classify them."); strip.begin(); // intialize neopixel strip strip.show(); // Initialize all pixels to 'off'}void loop (){ /// these functions are written out at the bottom of the sketch. Serial.println("Training complete. Now, draw some letters (remember to ");Serial.println("hold the button) and see if the PME can classify them."); byte vector[vectorNumBytes]; unsigned int category; char letter; char pattern; /* Record IMU data while button is being held, and * convert it to a suitable vector */ readVectorFromIMU(vector); /* Use the PME to classify the vector, i.e. return a category * from 1-26, representing a letter from A-Z */ category =CuriePME.classify(vector, vectorNumBytes); if (category ==CuriePME.noMatch) { Serial.println("Don't recognise that one-- try again."); //theaterChase(); theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); // delay(10); } else { letter =category + upperStart; pattern =letter; if ( pattern =='A' ) { //red colorWipe(strip.Color(0, 255, 0), 50); // Green theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='B') { colorWipe(strip.Color(255, 0, 0), 50); // Red theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='C') { colorWipe(strip.Color(0, 0, 255), 50); // Blue theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); } else if ( pattern =='D') { colorWipe(strip.Color(255, 0, 255), 50); // Blue theaterChase(strip.Color(127, 127, 127), 50); // White strip.show(); }Serial.println(letter); } }/* Simple "moving average" filter, removes low noise and other small * anomalies, with the effect of smoothing out the data stream. */byte getAverageSample(byte samples[], unsigned int num, unsigned int pos, unsigned int step){ unsigned int ret; unsigned int size =step * 2; if (pos <(step * 3) || pos> (num * 3) - (step * 3)) { ret =samples[pos]; } else { ret =0; pos -=(step * 3); for (unsigned int i =0; i  sensorBufSize) { break; } } } undersample(accel, samples, vector);}void trainLetter(char letter, unsigned int repeat){ unsigned int i =0; while (i   

    회로도

    It's just connecting the LEDs to the Arduino 101 pins and a button to pin 4 (as described in the code:https://www.arduino.cc/en/Tutorial/Button). The circuit diagram is similar to this Fritzing from Adafruit:https://learn.adafruit.com/adafruit-neopixel-uberguide/basic-connections
    I plugged the 9 V battery directly into the barrel jack.

    제조공정

    1. 의류 패턴
    2. 점퍼 와이어 없이 Arduino 브레드보드 만들기
    3. DHT11 센서(LED 및 피에조 스피커 포함)
    4. Arduino 스파이봇
    5. FlickMote
    6. 수제 TV B-Gone
    7. 마스터 시계
    8. Arduino + LED + MIDI 키보드 + MuseScore =피아노 교사
    9. Raspberry Pi를 통한 Alexa 제어 LED
    10. 나를 찾기