중급 예제

약간은 익숙하시거나 익숙해지셨나요? 그렇다면 조금더 깊이 다뤄볼까요?

조도센서 x RGB LED-조도센서를 컬러 센서로 사용하기

2015-05-12 14:49:50

개요 

컬러 센서란 색상을 추출해 낼 수 있는 센서를 말합니다. 

 

이미지 출처  : 엘레파츠

 

물체의 색상을 감지하고 r,g,b에 해당하는 데이터를 얻을 수 있습니다. 

 

이번 튜토리얼에서는 조도 감지(cds cell) 센서와 RGB led를 이용해 컬러 센서의 기능을 구현해보겠습니다. 

장단점은 다음과 같습니다. 

 

- 장점 : 컬러 센서에 비해 가격이 저렴하다. 

- 단점 : 컬러 센서에 비해 정확도가 떨어진다. cds cell에 특징 상 주변 환경(빛)의 영향을 많이 받는다. 

 

즉 대략적인 색상 구분 기능을 필요로 하신 분 중 컬러 센서를 구매하시기 부담스러운 분들은 가지고 계신 RGB led와 조도 센서를 사용해 컬러 센서의 기능을 구현해보는 것도 좋을 것 같습니다. 

 

정확한 색상 값을 필요로 하시는 분들은 컬러 센서를 사용하시는 것을 추천합니다. 

 

 

 

 

원리 

 

조도 센서(cds cell)을 이용해 색상을 구별하는 원리는 다음과 같습니다. 

 

이미지 출처 : instructable / fjordcarver's page

 

위의 표를 보시면, 물체에서 반사된 빛의 파장에 대한 반응 정도가 조도센서와 눈이 비슷하다는 것을 알 수 있습니다. 

왜냐하면, 색상이 특정 파장은 받아드리고, 또 다른 특정 파장은 반사하기 때문입니다. 

따라서 색상 마다 반사하는 파장이 다르기에 색상을 구별할 수 있는 것입니다. 

 

 

 

부품 목록

 

NO 부품명 수량 상세설명
1 아두이노 1 오렌지보드
2 조도 센서 1 cds cell
3 RGB led 1  
4 브레드 보드 1 mini
점퍼케이블 10  

 

부품명 오렌지 보드 조도 센서 RGB led 브레드보드 점퍼케이블
파트

 

 

 

하드웨어 메이킹 

 

브레드보드 레이아웃 

 

 

회로도

 

 

 

소프트웨어 코딩

 


int ledArray[] = {2,3,4};

boolean balanceSet = false;

int red = 0;
int green = 0;
int blue = 0;

float colourArray[] = {0,0,0};
float whiteArray[] = {0,0,0};
float blackArray[] = {0,0,0};


int avgRead;

void setup(){
 

  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
 

  Serial.begin(9600);
 
}


void loop(){

    checkBalance();
    checkColour();
    printColour();
    }
    
 
 void checkBalance(){

  if(balanceSet == false){
    setBalance();
  }
}


void setBalance(){

   delay(5000);                              
  
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);          
     whiteArray[i] = avgRead;
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
  
    delay(5000);              
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);
     blackArray[i] = avgRead;
     //blackArray[i] = analogRead(2);
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
   
  balanceSet = true;
  delay(5000);     
  }
  
  void checkColour(){
    for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);  
     delay(100);                      
     getReading(5);                  
     colourArray[i] = avgRead;        
     float greyDiff = whiteArray[i] - blackArray[i];                    
     colourArray[i] = (colourArray[i] - blackArray[i])/(greyDiff)*255; 
     digitalWrite(ledArray[i],LOW);   //turn off the current LED
     delay(100);
  }
 
 
}

void getReading(int times){
  int reading;
  int tally=0;
for(int i = 0;i < times;i++){
   reading = analogRead(0);
   tally = reading + tally;
   delay(10);
}
avgRead = (tally)/times;
}


void printColour(){
 int r = map(int(colourArray[0]),0,110,0,255);
 r = constrain(r,0,255);
Serial.print("R = ");
Serial.println(int(colourArray[0]));

int g = map(int(colourArray[1]),0,110,0,255);
g = constrain(g,0,255);
Serial.print("G = ");
Serial.println(int(colourArray[1]));

int b = map(int(colourArray[2]),0,110,0,255);
b = constrain(b,0,255); 
Serial.print("B = ");
Serial.println(int(colourArray[2]));
//delay(2000);
}

 

컬러 감지는 다음과 같은 순서로 진행됩니다. 

 

 - 밸런스 설정 / setBalance()

    처음 실행 후 5초 후에 r,g,b led가 한 번씩 깜박인 후 white 색상의 파장을 스캔합니다. 

    5초 후에 r,g,b led가 한 번씩 깜박인 후 black 색상의 파장을 스캔합니다. 

 

- 색상 감지 / checkColour()  

     r,g,b led가 깜박이며, 색상의 파장을 스캔합니다. 

 

- 화면 출력 /  printColour()

     색상 감지에서 감지한 파장을 serial monitor에 출력합니다. 

     

 

밸런스를 설정하는 부분 

 

void setBalance(){
  //흰색에 대한 밸런스를 설정합니다.
   delay(5000);                              //센서 앞에 흰색 샘플을 가져다 놓을 수 있도록 5초동안 대기합니다.
  //흰색 샘플을 스캔합니다.
  //샘플에 대한 red,blue,green 파장을 whiteArray에 저장합니다.
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);          // 인자는 파장 측정을 반복하는 횟 수 입니다. 반복하는 이유는 평균 값을 얻기 위함입니다.
     whiteArray[i] = avgRead;
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
  //흰색 샘플 스캔이 끝나면, 검은색(또는 회색) 샘플을 센서 위에 가져다 놓을 수 있도록 5초간 대기합니다.
   //검정색에 대한 밸런스를 설정합니다.
   //샘플에 대한 red,blue,green 파장을 blackArray에 저장합니다.
    delay(5000);              
  for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);
     delay(100);
     getReading(5);
     blackArray[i] = avgRead;
     //blackArray[i] = analogRead(2);
     digitalWrite(ledArray[i],LOW);
     delay(100);
  }
   //밸런스를 설정이 완료된 수 balanceSet을 true로 바꿉니다. 최초에 밸런스 설정이 되었는지 판단하기 위함입니다.
  balanceSet = true;
  delay(5000);     //5초간 대기합니다.
  }
  

 

     

색상을 감지하는 부분

 

색상을 감지하는 원리는 빨간색, 초록색, 파란색 불빛을 물체에 출력함으로서 빨간색, 초록색, 파란색 불빛에 반사되는 파장을 측정하는 것입니다. 

 

void checkColour(){
    for(int i = 0;i<=2;i++){
     digitalWrite(ledArray[i],HIGH);  //반복적으로 LED로 빨간색, 초록색, 파란색 불빛을 킵니다.
     delay(100);                      //cds cell 인식할 수 있도록 0.1초간 대기합니다.
     getReading(5);                  
     colourArray[i] = avgRead;        //물체에서 반사된 파장을 colourArray에 저장합니다.
     float greyDiff = whiteArray[i] - blackArray[i];                    //흰색과 검은색의 명도차를 구합니다.
     colourArray[i] = (colourArray[i] - blackArray[i])/(greyDiff)*255; // colourArray에 저장한 파장 데이터를 보기 편리하게 가공하는 부분입니다. 사용해 본 결과 추후 데이터 가공이 더 필요합니다.
     digitalWrite(ledArray[i],LOW);   //반복적으로 LED로 빨간색, 초록색, 파란색 불빛을 끕니다.
     delay(100);
  }

 

 

감지한 색상 데이터를 화면에 출력하는 부분 

 

불빛을 빨간색, 초록색, 파란색 순서로 출력하기 때문에

빨간색 불빛을 출력했을 때 반사된 파장은 colourArray[0]에, 

초록색 불빛을 출력했을 때 반사된 파장은 colourArray[1]에,

파란색 불빛을 출력했을 때 반사된 파장든 colourArray[2]에 저장됩니다. 

각 데이터는 serial monitor를 통해 화면에 출력됩니다.

 

void printColour(){
 //r,g,b 데이터 값을 가공하기 위해, 검정색 샘플일 때 들어오는 색 파장 값을 0으로, 흰색 샘플일 때 들어오는 색 파장 값을 255로 변환시켰습니다.
 int r = map(int(colourArray[0]),0,110,0,255);
 r = constrain(r,0,255);
Serial.print("R = ");
Serial.println(int(colourArray[0]));

int g = map(int(colourArray[1]),0,110,0,255);
g = constrain(g,0,255);
Serial.print("G = ");
Serial.println(int(colourArray[1]));

int b = map(int(colourArray[2]),0,110,0,255);
b = constrain(b,0,255); 
Serial.print("B = ");
Serial.println(int(colourArray[2]));
//delay(2000);
}

 

 

 

kocoafabeditor

항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!

조도센서, 아두이노, 오렌지보드

강민상 2016-08-14 17:53:49

시리얼 값이 마이너스도 붙고 몇 천까지 되는 데 정상인가요?
그리고 삼색LED대신 각 빨,초록,파랑led써도 결과는비슷할까요?

kocoafab 2019-02-08 15:35:27

위 코드로 결과값은 0~255까지의 값이 나와야합니다.

3색 LED 대신 각각 LED를 사용하셔도 되지만 조도센서와의 거리가 일정해야 정확한 값이 나올겁니다.

허허거참 2019-06-08 19:16:00

코딩이랑 연결부분 모두 정확히 하였는데 시리얼 모니터에 값이 0밖에 뜨질 않네요....색감지 시키는 거리랑 왜자꾸 0밖에 뜨질않는지 모르겠습니다...도와주실수 있을까여?