안녕하세요~ 매드 입니다.
지난 영상강좌로 칼라센서를 했었는데 블로깅 하기도 전에 시간이 벌써 이렇게 지나버렸네요. ㅎㅎ
지난 시간에 말씀드린데로 이번 칼라센서는 2부로 진행하면서 ... 블로깅은 한번에 진행하겠습니다. 하하;; (게으름)
1부 영상에서 말씀드린데로 칼라센서 동작을 시키고 그걸로 RGB LED의 색깔을 나타내고자 합니다. 1부 에서는 정신 없이 진행하느라 동작에 대해서 잘 알 수 없었는데 제가 알아본 칼라센서의 특징에 대해서 알아보도록 하죠.
23-1. 칼라센서란?
< 출처 : 구글 사진 > |
칼라센서로 측정할 수 있는 데이터는 RGB로 출력되는데요. 이 데이터는 저희가 기존에 알고 있던 RGB 888 과 같은 데이터는 아니고 센서가 칼라에 따라서 출력되는 펄스값을 출력하는 것입니다. 그럼 이걸로 어떻게 칼라를 구별하냐구요?
이 칼라센서 같은경우 8가지? 정로는 판별할 수 있을 것 같지만 그 이상이되면 오류가 많아 질 것 같네요. 기준이 되는 색깔을 미리 준비해두고 하나하나 측정하면서 값의 범위를 기록하여 오차범위를 계산해서 그 안에 들어오면 칼라를 구별 할 수 있도록 프로그램을 코딩하면 될 것 같습니다. ㅠ
아 .. 먼가 복잡하네요 ㅎㅎ 이 칼라센서 같은 경우는 한두가지의 색 구별 또는 판단용으로만 사용하는게 맞을 것 같네요! ㅎㅎ
그럼 연결해서 사용해보도록 할까요?~
23-2. 칼라센서 회로
< 출처 : http://www.dfrobot.com/wiki/index.php/TCS3200_Color_Sensor_(SKU:SEN0101) > |
구글에 검색해보니 위와 같이 연결 방법을 정리 둔 것이 있네요! ㅎㅎ 간단하죠~?
기능에 비해서 사용법은 대략 까다로운 편인 것 같습니다.
가격대비 성능을 본다면 생각에는 그냥 OV7670 CMOS의 RGB 출력을 이용하여 칼라를 판별하는 것이 좀 더 정확하고 확실할 것 같네요 ㅎㅎ
특별한 연결은 없지만 OE 핀이 있으신분은 GND에 연결하여 사용하시면 될것 같습니다. OUT ENABLE 핀인데 ㅎㅎ 이 핀을 활성화 시켜주셔야 출력이 나가기 때문이죠
센서의 OUT을 아두이노의 D2에 연결하는 이유는 아두이노가 가지고 있는 외부인터럽트 핀이 2개(D2,D3)가 있는데 이를 이용하여 센서로부터 출력되는 신호를 모드 잡아내기 위해서 이렇게 연결한 것 같네요. ㅎㅎ
저희는 여기에 좀 더 화려하게 보이기 위해서 센서로 측정한 데이터를 RGB LED를 통해 칼라를 포현하도록 해보겠습니다. RGB LED는 이전에 했었던 WS2812b 를 가지고 해보겠습니다~~
23-3. 펌웨어 코드
- RGB 칼라 비교 검출 코드
int s0=3,s1=4,s2=5,s3=6;
int flag=0;
int counter=0;
int countR=0,countG=0,countB=0;
void setup()
{
Serial.begin(9600);
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);
pinMode(s2,OUTPUT);
pinMode(s3,OUTPUT);
}
void TCS()
{
digitalWrite(s1,HIGH);
digitalWrite(s0,LOW);
flag=0;
attachInterrupt(0, ISR_INTO, CHANGE);
timer2_init();
}
void ISR_INTO()
{
counter++;
}
void timer2_init(void)
{
TCCR2A=0x00;
TCCR2B=0x07; //the clock frequency source 1024 points
TCNT2= 100; //10 ms overflow again
TIMSK2 = 0x01; //allow interrupt
}
int i=0;
ISR(TIMER2_OVF_vect)//the timer 2, 10ms interrupt overflow again. Internal overflow interrupt executive function
{
TCNT2=100;
flag++;
if(flag==1)
{
counter=0;
}
else if(flag==2)
{
digitalWrite(s2,LOW);
digitalWrite(s3,LOW);
countR=counter/1.051;
Serial.print("red=");
Serial.println(countR,DEC);
digitalWrite(s2,HIGH);
digitalWrite(s3,HIGH);
}
else if(flag==3)
{
countG=counter/1.0157;
Serial.print("green=");
Serial.println(countG,DEC);
digitalWrite(s2,LOW);
digitalWrite(s3,HIGH);
}
else if(flag==4)
{
countB=counter/1.114;
Serial.print("blue=");
Serial.println(countB,DEC);
digitalWrite(s2,LOW);
digitalWrite(s3,LOW);
}
else
{
flag=0;
TIMSK2 = 0x00;
}
counter=0;
delay(2);
}
void loop()
{
delay(10);
TCS();
if((countR>10)||(countG>10)||(countB>10))
{
if((countR>countG)&&(countR>countB))
{
Serial.print("red");
Serial.print("\n");
delay(1000);
}
else if((countG>=countR)&&(countG>countB))
{
Serial.print("green");
Serial.print("\n");
delay(1000);
}
else if((countB>countG)&&(countB>countR))
{
Serial.print("blue");
Serial.print("\n");
delay(1000);
}
}
else
{
delay(1000);
}
}
- WS2812b 를 이용해서 검출한 칼라를 출력하는 코드!
#include <Adafruit_NeoPixel.h>
#define PIN 7
#define NUMPIXELS 1
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int s0 = 3, s1 = 4, s2 = 5, s3 = 6;
int flag = 0;
int counter = 0;
int countR = 0, countG = 0, countB = 0;
void setup()
{
Serial.begin(9600);
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);
pixels.begin(); // This initializes the NeoPixel library.
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
}
void TCS()
{
digitalWrite(s1, HIGH);
digitalWrite(s0, LOW);
flag = 0;
attachInterrupt(0, ISR_INTO, CHANGE);
timer2_init();
}
void ISR_INTO()
{
counter++;
}
void timer2_init(void)
{
TCCR2A = 0x00;
TCCR2B = 0x07; //the clock frequency source 1024 points
TCNT2 = 100; //10 ms overflow again
TIMSK2 = 0x01; //allow interrupt
}
int i = 0;
ISR(TIMER2_OVF_vect)//the timer 2, 10ms interrupt overflow again. Internal overflow interrupt executive function
{
TCNT2 = 100;
flag++;
if (flag == 1)
{
counter = 0;
}
else if (flag == 2)
{
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
countR = counter / 1.051;
Serial.print("red=");
Serial.println(countR, DEC);
digitalWrite(s2, HIGH);
digitalWrite(s3, HIGH);
}
else if (flag == 3)
{
countG = counter / 1.0157;
Serial.print("green=");
Serial.println(countG, DEC);
digitalWrite(s2, LOW);
digitalWrite(s3, HIGH);
}
else if (flag == 4)
{
countB = counter / 1.114;
Serial.print("blue=");
Serial.println(countB, DEC);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);
}
else
{
flag = 0;
TIMSK2 = 0x00;
}
counter = 0;
delay(2);
}
void loop()
{
delay(10);
TCS();
if ((countR > 10) || (countG > 10) || (countB > 10))
{
if ((countR > countG) && (countR > countB))
{
Serial.print("===== red =====");
Serial.print("\n");
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1000);
}
else if ((countG >= countR) && (countG > countB))
{
Serial.print("===== green =====");
Serial.print("\n");
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1000);
}
else if ((countB > countG) && (countB > countR))
{
Serial.print("===== blue =====");
Serial.print("\n");
pixels.setPixelColor(0, pixels.Color(0, 0, 255)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1000);
}
}
else
{
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(1000);
}
}
1부
2부
오늘도 다들 수고 하셨구요~~~ ㅎㅎ 다음에는 아두이노에서 그 유명한 ESP8266 WiFi 모듈을 다뤄보도록 하겠습니다!! ㅎㅎ
그럼 다음주에 뵐께요~~!
2 댓글
저기 이대로 했는데 값이 10000넘게 출력되는경우에 어디를 건드려야 될까요??ㅠㅠ
답글삭제안녕하세요~ ㅎㅎ
삭제칼라 데이터 출력되는건 어느정도 차이가 생길 수도 있습니다.
좀 더 상세한 정보를 알려주셔야 답변이 가능할 것 같네요~~ >,.<