ColorSensor에 해당하는 글 2

[아두이노] 시리얼 플로터 사용

IOT/아두이노|2019. 8. 9. 09:00

[아두이노] 시리얼 플로터 사용



아두이노를 실험 할 때 지금까지는 시리얼 모니터로 디지털 값으로만 확인 해 봤습니다. 사실 지금까지 시리얼 플로터를 사용하지 않는 이유는 시이얼 플로터로 결과를 확인이 필요한 경우가 없었는데 지난 시간에 Color Sensor를 사용하면서 시리얼 플로터로 결과를 확인할 필요성이 느껴져서 이번에 post 주제로 선정했네요. 시리얼 플로터는 아날로그 파형으로 그래프 형태로 결과를 시각적으로 보여주는 출력 장치입니다. 그럼 이제 시리얼 플로터가 어떤 느낌인지 자세히 살펴보도록 하죠.

1. 시리얼 플로터


시리얼 모니터는 출력값을 디지털 형태의 숫자로 결과를 출력을 하고 시리얼 플로터는 아날로그 형태의 그래프 형태로 시각화 출력을 합니다.

그러면 시리얼 모니터와 시리얼 플로터의 출력 형태를 비교해 볼까요.

[실험 소스]

int output = 1;
unsigned long timeVal = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{   
   if(millis()-timeVal>=100){ //0.1초 단위로 1 or -1의 결과를 출력합니다.
    output=-output;
    timeVal=millis();    
   }
   Serial.println(output); //시리얼 출력
}

[시리얼모니터 결과]


[시리얼플로터 결과]


둘의 출력 형태가 어떤 느낌인지 아시겠지요.

2. 시리얼 플로터에 여러개의 데이터 출력


위에서는 한개의 데이터만 출력했습니다. 지난 시간에 실험한 Color Sensor은 3개의 RGB 데이터를 출력하는데 그러면 그 데이터는 한번에 같이 어떻게 출력 할까요.

아래와 같은 방식으로 코딩하시면 됩니다. 즉, 데이터와 데이터 사이를 공백으로 띄워서 데이터를 출력하면 나눠서 출력하게 됩니다.

int output = 1;
unsigned long timeVal = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{   
   if(millis()-timeVal>=100){ //0.1초 단위로 1 or -1의 결과를 출력합니다.
    output=-output;
    timeVal=millis();    
   }
     
     //시리얼 출력
   Serial.print(output); //데이터 1번
   Serial.print(" "); 
   Serial.println(output*2); //데이터 2번
}

즉, output와 output*2의 값 사이에 공백을 넣어주면 두개의 데이터를 동시에 아래 결과처럼 출력하게 됩니다.

[결과]


3. Color Sensor 값을 시리얼 플로터로 출력



지난 시간의 회로도를 그대로 적용 합니다.

1) Color Sensor 회로도


위 회로도는 지난시간에 만들 회로도이고 코딩도 그래도 적용합니다.

2) 코딩


시리얼 출력 부문만 약간 수정합니다.

const byte s0_pin = 3;
const byte s1_pin = 4;
const byte s2_pin = 5;
const byte s3_pin = 6;
const byte out_pin = 7;

const byte r_pin = 9;
const byte g_pin = 10;
const byte b_pin = 11;


void setup() {
  Serial.begin(9600);
  
  pinMode(r_pin, OUTPUT);
  pinMode(g_pin, OUTPUT);
  pinMode(b_pin, OUTPUT);
  
  pinMode(s0_pin, OUTPUT);
  pinMode(s1_pin, OUTPUT);
  pinMode(s2_pin, OUTPUT);
  pinMode(s3_pin, OUTPUT);
  
  pinMode(out_pin, INPUT);
  
  digitalWrite(s0_pin,HIGH);
  digitalWrite(s1_pin,LOW);
}


void loop() {
  digitalWrite(s2_pin,LOW);
  digitalWrite(s3_pin,LOW);
  int red_color = pulseIn(out_pin, LOW);
  red_color = map(red_color, 25,72,255,0);
  red_color = constrain(red_color, 0, 255);
  delay(50);
  
  digitalWrite(s2_pin,HIGH);
  digitalWrite(s3_pin,HIGH);
  int green_color = pulseIn(out_pin, LOW);
  green_color = map(green_color, 30,90,255,0);
  green_color = constrain(green_color, 0, 255);
  delay(50);
  
  digitalWrite(s2_pin,LOW);
  digitalWrite(s3_pin,HIGH);
  int blue_color = pulseIn(out_pin, LOW);
  blue_color = map(blue_color, 25,70,255,0);
  blue_color = constrain(blue_color, 0, 255);
  delay(50);

  analogWrite(r_pin, red_color);
  analogWrite(g_pin, green_color);
  analogWrite(b_pin, blue_color);

  //시리얼 플로터 출력
  Serial.print(blue_color);
  Serial.print("  ");  
  Serial.print(red_color);
  Serial.print("  ");      
  Serial.println(green_color);
  
  delay(100);
}

시리얼 출력 부분에서 시리얼 플로터 출력으로 약간 수정 했네요. 시리얼 플로터에 색상에 맞추다 보니깐 B, R, G 순으로 했네요. 혹시 여러분들이 출력을 했는데 아래 결과의 색상이 다르면 위 코딩의 색상 출력 순서를 변경하시면 됩니다.

3) 결과



Color의 변화를 시각적으로 확인 할 수 있습니다. 자세히 보시면 노이즈로 인해 색값이 변화가 중간에 심하게 발생하는 보실 수 있을꺼에요. 센서 자체가 납땜이 안되어 있고 전선꼽아서 하기 때문에 손으로 만지면 전선과 센서 사이에 잡음이 발생 할 수 밖에 없네요.

아래는 색상이 측정되고 출력되는 결과를 기록해 놓았습니다.


마무리


시리얼 플로터는 특정한 값의 변화를 시각적으로 확인하기에 편합니다. Color Sensor와 같은 부품을 제어 할 때에 값의 변화가 수치보다는 시각적 챠트로 보는게 더 효과적이겠죠. 이 챠트를 보면 색의 주파수 범위를 나중에 색종이를 가지고 지정할 때 활용하면 좋겠죠.

오늘은 간단히 시리얼 플로터를 사용하는 방법을 살펴 보았네요.


댓글()

[아두이노] Color Sensor 제어

IOT/아두이노|2019. 8. 1. 09:00

[아두이노] Color Sensor 제어



Color Sensor(TCS3200)은 색을 감지할 수 있는 센서입니다. 빛에서 색을 주파수값으로 읽는 센서인데 이 주파수 값을 가지고 RGB색을 만들어 내게 됩니다. 참고로 주파수 값을 읽을 수 있다고 해서 색값으로 바로 만들어 지지 않습니다. 각 RGB색의 값에 대한 주파수 영역을 잡아 색값 0~255사이의 값으로 변환 시켜야 합니다. 그 색 주파수 영역을 통해서 진짜 RGB색을 만들어 내는데 최근에 구매한 부품이여서 정확히 RGB 주파수 영역을 직접 만들어 내지 못했네요. 색종이로 RGB색을 측정하여 주파수 영역을 잡고 조정 작업을 해야 하는데 이미 만들놓은 분의 RGB 주파수 영역을 인용하여 간단히 실험을 하였습니다. 시간적 여유가 되시는 분들은 꼭 직접 RGB 주파수 영역을 본인이 가지고 있는 Color Sensor의 값을 측정하면서 원시값을 토대로 직접 그 영역을 만들어 보세요. 영유가 안된다면 저처럼 인용을 통해 간단히 실험하시면 됩니다.


1. Color Sensor




위 그림처럼 해당 핀에 대해서 살펴봅시다.

S0, S1 핀을 통해서 출력되는 주파수 크기값을 지정 합니다.


퍼센트 수치가 클수록 출력되는 숫자의 값은 작아 집니다. (L, H)은 숫자의 크기가 너무 큰 수가 나오고 (H,H)은 너무 작은 숫자값이 나오기 때문에 RGB색을 추출하기에는 좀 불편합니다. 그나마 색(0~255)을 만들기 위해서는 적당한 출력 수치값으로 (H,L)로 출력하면 적당한 주파수 크기로 출력됩니다. 실험에서는 (H,L)로 20% 크기로 출력됩니다.

RGB 각 색의 주파수 값을 얻기 위해서는 S2, S3의 상태로 해당 색상의 주파수 값을 얻을 수 있습니다.


위 표를 통해 RGB 색의 주파수 값을 얻게 됩니다.

결론은 S0, S1은 출력되는 주파수 크기를 지정하고 S2,S3은 해당 색을 지정해 줍니다.

2. Color Sensor 회로도




Color 센서에서 측정된 RGB 값을 3색 LED로 출력하는 회로도 입니다.

3. 코딩


위 데이터시트에의 나온 표를 기반으로 Color Sensor의 색을 읽기

Red 색 읽기

digitalWrite(s0_pin,HIGH); //출력 크기
digitalWrite(s1_pin,LOW);

digitalWrite(s2_pin,LOW); //Red 색
digitalWrite(s3_pin,LOW);
int Red = pulseIn(out_pin, LOW); //Red 주파수 값

Green 색 읽기

digitalWrite(s0_pin,HIGH);
digitalWrite(s1_pin,LOW);
digitalWrite(s2_pin,HIGH); //Green 색
digitalWrite(s3_pin,HIGH);
int Green = pulseIn(out_pin, LOW);

Blue 색 읽기

digitalWrite(s0_pin,HIGH);
digitalWrite(s1_pin,LOW);
digitalWrite(s2_pin,LOW); //Blue 색
digitalWrite(s3_pin,HIGH);
int Blue = pulseIn(out_pin, LOW);

3가지 색을 이렇게 읽게 됩니다.

스케일 20%로 고정이니깐 출력 크기는 setup()함수로 빼내고 나머지 각 색은 Loop함수에서 지정해 주면 되겠죠.

R,G,B 색값을 읽으면 그 색값이 색으로 보여지지 않습니다. 데이터시트에 가시면 주파수 챠트가 있는데 그걸 보고 색의 추출 범위를 지정해야 합니다.

색종이 같은 걸로 Red, Green, Blue 색의 주파수 최소 최대 범위를 지정하면 좋은데 색종이가 없어서 색의 범위 지정하기 어려워서 색의 범위를 만든 post를 겨우 찾아서 색의 범위를 지정할 수 있게 되었네요.



위 post 출처에서 Red, green, blue의 범위를 인용하여 실험했네요.

red_color = map(red_color, 25,72,255,0);
green_color = map(green_color, 30,90,255,0);
blue_color = map(blue_color, 25,70,255,0);

제가 보유한 Color Sensor는 깔금하게 색을 만들어 내지 못하더군요. 그리고 색 값이 0~255 범위를 벗어나는 값이 나오기 때문에 constrain()함수로 0~255사이로 묶어 두었습니다. 0보다 작은 값은 0에 고정되게 하고 255값을 벗어나면 255에 고정되게 만들었네요.

Red을 기준으로 표현하면

int Red = pulseIn(out_pin, LOW);
red_color = map(red_color, 25,72,255,0);
red_color = constrain(red_color, 0, 255);

나머지 색도 위 코딩과 같이 코딩하시면 됩니다.

Color 값을 만들었다면 그 값을 3색 LED로 핀은 PWM 핀으로 아날로그값을 출력하기 때문에 아래와 같이 코딩하면 됩니다.

RGB LED 출력

analogWrite(r_pin, red_color);
analogWrite(g_pin, green_color);
analogWrite(b_pin, blue_color);

종합해 보면,

const byte s0_pin = 3;
const byte s1_pin = 4;
const byte s2_pin = 5;
const byte s3_pin = 6;
const byte out_pin = 7;

const byte r_pin = 9;
const byte g_pin = 10;
const byte b_pin = 11;


void setup() {
  Serial.begin(9600);
  
  pinMode(r_pin, OUTPUT);
  pinMode(g_pin, OUTPUT);
  pinMode(b_pin, OUTPUT);
  
  pinMode(s0_pin, OUTPUT);
  pinMode(s1_pin, OUTPUT);
  pinMode(s2_pin, OUTPUT);
  pinMode(s3_pin, OUTPUT);
  
  pinMode(out_pin, INPUT);
  
  digitalWrite(s0_pin,HIGH);
  digitalWrite(s1_pin,LOW);
}

void loop() {

  //Red Color Read
  digitalWrite(s2_pin,LOW);
  digitalWrite(s3_pin,LOW);
  int red_color = pulseIn(out_pin, LOW);
  red_color = map(red_color, 25,72,255,0);
  red_color = constrain(red_color, 0, 255);
  delay(50);
  
  //Green Color Read
  digitalWrite(s2_pin,HIGH);
  digitalWrite(s3_pin,HIGH);
  int green_color = pulseIn(out_pin, LOW);
  green_color = map(green_color, 30,90,255,0);
  green_color = constrain(green_color, 0, 255);
  delay(50);
  
  //Blue Color Read
  digitalWrite(s2_pin,LOW);
  digitalWrite(s3_pin,HIGH);
  int blue_color = pulseIn(out_pin, LOW);
  blue_color = map(blue_color, 25,70,255,0);
  blue_color = constrain(blue_color, 0, 255);
  delay(50);

  //3색 LED에 RGB 출력
  analogWrite(r_pin, red_color);
  analogWrite(g_pin, green_color);
  analogWrite(b_pin, blue_color);
  
  Serial.print("RED: ");
  Serial.print(red_color);
  Serial.print("  ");
  
  Serial.print("GREEN: ");
  Serial.print(green_color);
  Serial.print("  ");

  Serial.print("BLUE: ");
  Serial.print(blue_color);
  Serial.println("  ");
  
  delay(1000);
}

4. 결과


시리얼 모니터에 색값을 출력해 보았습니다.


스케일을 2%로 지정했다면 위 값은 천단위로 출력되고 스케일을 100% 했다면 일단위로 값이 출력됩니다. 위 결과처럼 20%가 가장 적당합니다. 참고로 위 결과는 20% 스케일의 map()함수를 이용하여 주파수 값을 색값으로 변환하고 다시 constrain()함수로 0~255사이로 고정시켜 나온 결과입니다.

아래 3색 LED에 Color Sensor로 측정한 값이 출력한 영상인데 깔끔하게 출력되지 않네요. Color Sensor를 딱 붙이지 않고 좀 높이를 어느정도 띄워서 측정하면 색이 좀 더 측정하는 색에 가깝게 출력되더군요. 한손으로 측정하고 한손으로 스마트폰 촬영을 하다 보니깐 높이를 제대로 맞추지 못해서 결과는 마음에 들지 않게 나왔네요.


마무리


Color Sensor부품은 처음에는 좀 쉽게 생각했는데 다루기가 좀 까다로운 부품이네요. 동작 코딩은 어렵지 않지만 정확하게 색의 값을 만들어 내는게 쉽지 않네요. 센서의 연결 부분에 노이즈가 발생하면 값의 변화가 크고 정확하게 RGB값으로 분리해 내기도 어렵습니다. 직접 사용하는 센서의 측정되는 RGB값의 범위를 일일히 잡아야 하는게 쉬운 부품이 아니네요. RGB 색값의 범위를 지정 할 수 있다면 나머지 부분은 간단하기 때문에 컨트롤 하기는 어렵지는 않는데 색 주파수 영역이 문제네요.


댓글()