프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

컬러 오르골 만들기[part 1]

2015-10-22 13:36:12

안녕하세요! 

얼마 전부터 '날씨 정보를 알려주는 무드 램프 만들기'를 진행하고 있는데요. 

3D 프린터로 열심히 외관을 출력하고 있습니다 ;)

3D 프린터로 외관을 출력하는 과정에서 시간이 조금 걸려, 새로운 프로젝트와 병행하여 진행하려고 합니다.

 

개요

 

새로운 프로젝트의 큰 구상은 컬러 센서를 이용해 악기를 만들어 보는 것인데요!

그 큰 구상의 첫 번째로 컬러 센서를 이용해 오르골을 만들어보려고 합니다! 일명 컬러 오르골이죠 ;)

구상한 내용은 다음과 같습니다.

1. 음계에 해당하는 색을 지정해준다.

2. 오르골용 악보에 음계에 해당하는 색을 색칠한다.

3. 악보를 오르골에 넣으면, 컬러 센서가 색을 인식해 색에 해당하는 음을 낸다.

 

아이들이 싸인펜이나 색종이를 이용해 직접 오르골 악보를 만들어 보고 재생 시켜볼 수 있도록 구상하였습니다. 

구상을 마치고 우선 프로토타입을 만들어보았는데요. 

part 1에서는 프로토타입을 제작하는 과정과 외관 구상까지의 과정을 소개하고자 합니다.

 

 

 

부품 목록

 

NO 부품명 수량 상세 설명
1 오렌지보드 1 아두이노 UNO
2. 컬러 센서 1  TCS34725
3.  네오픽셀 RGB LED 1  
4 피에조 부저 1  
5 점퍼 케이블 10개 이상  
6 브레드 보드 1  

 

 

부품명 오렌지보드 컬러 센서 네오픽셀 RGB LED 피에조 부저
부품사진

 

 

 

하드웨어 메이킹

 

컬러 센서의 와이러링은 다음과 같습니다.

 

컬러 센서 오렌지보드
3V 5V 
GND  GND
SDA Analog 4
SCL Analog 5

 

브레드보드 레이아웃

 

<참고 사항> 

Flora color sensor의 frizing 파일을 불러오는데 에러가 있어 Flora LSM9DS0으로 대체하였습니다. 

핀 배열은 같으니 컬러 센서도 브레드보드 레이아웃과 같이 연결하시면 됩니다.

neopixel LED도 저는 하나만 사용하였습니다. strip LED를 가지고 계신 분은 하나만 잘라서 쓰시면 되겠죠?

 

 

 

회로도(스케메틱) 

 

 

 

 

스프트웨어 코딩

 

컬러 센서 사용 방법은 컬러 픽셀 장갑 만들기를 참고하였습니다.

#include
#include "Adafruit_TCS34725.h"
#include
#define CLEARTHRESHHOLD 2000

// RGB값을 '눈'이 인식가능한 감마값으로 변환합니다.
byte gammatable[256];


// 컬러센서에 사용된 TCS34725를 사용준비합니다.
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
// 네오픽셀을 6번핀에 연결합니다.
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 6, NEO_GRB + NEO_KHZ800);

// 피에조 부저를 3번핀에 연결합니다.
int piezo = 3;

void setup() {
  
  Serial.begin(9600);
  pinMode(piezo,OUTPUT);

  //컬러센서가 준비되면, 시리얼모니터상에 found sensor를 전송합니다.
  if (tcs.begin()) {
    Serial.println("Found sensor");
  } 
  else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); 
  }

  //컬러 재생을 위해 초기화를 실행 합니다.
  strip.begin();
  strip.show(); // 모든 네오픽셀을 꺼짐 상태로 만듭니다.


  // 사람이 인지할수있는 감마값으로 색정보를 변홥 합니다.
  for (int i=0; i<256; i++) {
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;

    gammatable[i] = x;      

  }
}


void loop() {
  uint16_t clear, red, green, blue;

  tcs.setInterrupt(false);      // LED를 켭니다.

  delay(60);  //60밀리초동안 읽습니다.

  tcs.getRawData(&red, &green, &blue, &clear);

  tcs.setInterrupt(true);  // LED를 끕니다.

  //충분한 색정보를 불러올 수 있는 대상이 없을 경우
  if (clear < CLEARTHRESHHOLD) {
    strip.setPixelColor(0, strip.Color(0, 0, 0)); // LED를 끕니다.
    strip.show();
    noTone(piezo);
    return;
  }

  // 시각화를 위해 hex code를 계산합니다.
  uint32_t sum = red;
  sum += green;
  sum += blue;
  sum = clear;
  float r, g, b;
  r = red; 
  r /= sum;
  g = green; 
  g /= sum;
  b = blue; 
  b /= sum;
  r *= 256; 
  g *= 256; 
  b *= 256;
  if (r > 255) r = 255;
  if (g > 255) g = 255;
  if (b > 255) b = 255;

  float remove, normalize;
  if ((b < g) && (b < r)) {
    remove = b;
    normalize = max(r-b, g-b);
  } 
  else if ((g < b) && (g < r)) {
    remove = g;
    normalize = max(r-g, b-g);
  } 
  else {
    remove = r;
    normalize = max(b-r, g-r);
  }
  //작은 소수를 제거합니다.
  float rednorm = r - remove;
  float greennorm = g - remove;
  float bluenorm = b - remove;
  // 가장 높은수를 정상화 합니다.
  rednorm /= normalize;
  greennorm /= normalize;
  bluenorm /= normalize;

  strip.setPixelColor(0, strip.Color(gammatable[(int)r], gammatable[(int)g], gammatable[(int)b]));
  strip.show();
    
  //색상 값을 시리얼 모니터에 출력합니다.
  Serial.print("red: "); 
  Serial.print(gammatable[(int)r]);
  Serial.print('\t'); 
  Serial.print("green :"); 
  Serial.print(gammatable[(int)g]); 
  Serial.print('\t'); 
  Serial.print("blue :");
  Serial.print(gammatable[(int)b]); 
  Serial.println();    
  
  //도
  if((gammatable[(int)r]>73 && gammatable[(int)r]<82) && (gammatable[(int)g]>3 && gammatable[(int)g]<7) && (gammatable[(int)b]>2 && gammatable[(int)b]<5)){
    tone(piezo,523);
  }
  
  //레
  if((gammatable[(int)r]>25 && gammatable[(int)r]<32) && (gammatable[(int)g]>19 && gammatable[(int)g]<24) && (gammatable[(int)b]>1 && gammatable[(int)b]<3)){
    tone(piezo,587);
  }  
  
  //미
  if((gammatable[(int)r]>9 && gammatable[(int)r]<16) && (gammatable[(int)g]>30 && gammatable[(int)g]<38) && (gammatable[(int)b]>2 && gammatable[(int)b]<6)){
    tone(piezo,659);
  }   
  //파
  if((gammatable[(int)r]>2 && gammatable[(int)r]<6) && (gammatable[(int)g]>12 && gammatable[(int)g]<16) && (gammatable[(int)b]>37 && gammatable[(int)b]<42)){
    tone(piezo,698);
  }     
  //솔
  if((gammatable[(int)r]>33 && gammatable[(int)r]<42) && (gammatable[(int)g]>12 && gammatable[(int)g]<17) && (gammatable[(int)b]>4 && gammatable[(int)b]<8)){
    tone(piezo,783);
  }   
  //라
  if((gammatable[(int)r]>36 && gammatable[(int)r]<43) && (gammatable[(int)g]>5 && gammatable[(int)g]<9) && (gammatable[(int)b]>12 && gammatable[(int)b]<16)){
    tone(piezo,880);
  }    
  
  //시
  if((gammatable[(int)r]>7 && gammatable[(int)r]<11) && (gammatable[(int)g]>15 && gammatable[(int)g]<21) && (gammatable[(int)b]>17 && gammatable[(int)b]<22)){
    tone(piezo,987);
  }  

  //도
  if((gammatable[(int)r]>65 && gammatable[(int)r]<74) && (gammatable[(int)g]>5 && gammatable[(int)g]<9) && (gammatable[(int)b]>6 && gammatable[(int)b]<11)){
    tone(piezo,1046);
  }   
  
  //무음(종이의 흰색)
  if((gammatable[(int)r]>11 && gammatable[(int)r]<15) && (gammatable[(int)g]>15 && gammatable[(int)g]<19) && (gammatable[(int)b]>10 && gammatable[(int)b]<14)){
    noTone(piezo);
  } 
}

 

 

 

제작 과정

 

1. 컬러 센서의 특성 상 주변 환경에 민감하기 때문에 3D 프린터를 이용해 케이스를 출력하였습니다. 

 

 

2. 출력한 케이스와 컬러 센서를 결합시켜 줍니다 ;) 컬러 센서와 딱 맞게 잘 출력되었네요~

 

 

3. 브레드보드 레이아웃과 맞게 각 부품들을 와이어링 합니다.

 

 

 

4. 각 음계에 따라 색상을 지정하기 위해 컬러 샘플을 만들어 테스트를 실시하고, 색상 세팅을 마쳤습니다 ;)

 

 

5. 지~ 이제 오르골에 들어갈 악보를 만들어 봐야겠죠? A4 용지를 잘라 샤프로 샤샤샥 가이드를 그렸습니다.

 

 

6. 악보도 만들었으니 악보에 색칠을 해보았습니다. 얼마만에 색칠 공부인지ㅎㅎ 재밌네요~

오르골 악보도 그렸으니 이제 색깔에 맞게 음계가 잘 재생되는지 테스트 해보는 것만 남았네요ㅎㅎ

 

 

 

 

동영상

 

현재 영상 편집 중입니다. 조금만 기다려주세요 ;)

 

 

 

외관 설계(디자인)

 

현재는 기능 테스트를 위한 기계부만 완성이 되있는 단계죠~

 

3D 프린터로 외관을 출력하기 위해 스케치업으로 외관 디자인을 진행하였습니다.

구름과 다르게 이번 오르골의 컨셉은 로봇입니다 ;) 어떤가요? 귀엽나요?~

 

 

 

기능 설명입니다. 

머리 위에는 피에조 부저가 위치하여 컬러 센서에서 인색한 색에 따라서 음을 출력합니다. 

이마 부분에는 neopixel RGB LED가 있습니다. 컬러 센서에서 인색한 색을 실시간으로 출력합니다.

본체의 밑 쪽에 컬러 센서가 위치합니다. 종이에 색칠된 색을 인식합니다. 

종이를 이동시키는 기계부를 자동으로 할까, 수동으로 할까 고민했습니다. 

뭔가 자동으로 종이가 끌려 들어가는 것보다 손으로 손잡이를 돌리며 종이를 움직이는게 감성적이라고 생각해 수동으로 결정하였습니다 ;)

 

 

 

 

마치며..... 

 

테스트 해본 결과 잘 작동되기는 하나 컬러 센서가 워낙 민감해서 발생되는 문제를 줄일 필요가 있다고 생각했습니다.

소스 딴에서 인식된 색의 값(R,G,B)을 버퍼에 담아 평균값을 내어 색의 편차를 줄여볼까 합니다.

사용자가 사용할 색을 직접 컬러 센서에 대주기만 하면, 자동으로 색이 설정되는 것이죠. 그렇게 한다면 LCD도 써야하는데 최대한 안쓰는 쪽으로 구상을 하고 있습니다.

혹시 좋은 방법이 있으시면 댓글로 남겨주세요 ;) 

곧 날씨 정보를 알려주는 무드 램프 완성품도 소개할테니 기대해주세요~!!!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Klant

오렌지보드,코코아팹,컬러오르골,컬러센서,orangeboard,kocoafab,colorsensor,colororgel