위 코드로 결과값은 0~255까지의 값이 나와야합니다.
3색 LED 대신 각각 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 |
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
항상 진취적이고, 새로운 것을 추구하는 코코아팹 에디터입니다!
위 코드로 결과값은 0~255까지의 값이 나와야합니다.
3색 LED 대신 각각 LED를 사용하셔도 되지만 조도센서와의 거리가 일정해야 정확한 값이 나올겁니다.
코딩이랑 연결부분 모두 정확히 하였는데 시리얼 모니터에 값이 0밖에 뜨질 않네요....색감지 시키는 거리랑 왜자꾸 0밖에 뜨질않는지 모르겠습니다...도와주실수 있을까여?
강민상 2016-08-14 17:53:49
시리얼 값이 마이너스도 붙고 몇 천까지 되는 데 정상인가요?
그리고 삼색LED대신 각 빨,초록,파랑led써도 결과는비슷할까요?