코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
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 |
5 | 점퍼케이블 | 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
항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!