레고의 NXT 다음 버전인 EV3로 색상 분류기를 구현 하였다.

 

색상분류기의

작동은 색블럭을 칼라센서에 인식시키고

인식된 색은 메모리에 차례로 저장되며

저장된 색에 따라 색 블럭을 해당 위치에 분류해낸다.

 

제작도와 프로그램이 기본으로 들어있어

제작은 물론 프로그램을 해석하여 그 작동 방법을

알아낼수 있다.

 

아래 영상은 프로그램을 프로그램을 해석한후

직접 다시 작성 해보았다.

(물론 거의 보고 따라한 수준에 불과 하지만...)

 

 

 

'레고로봇 > ev3' 카테고리의 다른 글

레고 마인드 스톰  (0) 2012.06.28
레고NXT vehicle  (1) 2012.06.28

가속도 센서로 각도를 측정하여

자작한 LCD쉴드에 출력

 

serial모니터로 출력하여 측정된값을

컴퓨터로 출력하여 확인하지 않고

아두이노에 LCD를 부착하여 측정값을 바로

확인할수 있도록 하였다.

 

LCD쉴드 http://eskelt.tistory.com/78  글 참고

가속도센서 http://eskelt.tistory.com/79 글 참고

가속도센서로 각도측정 http://eskelt.tistory.com/80 글 참고

 

소스 스케치

============================================================================

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
float x,y,z;

void setup(){
  lcd.begin(16, 2);
}

void loop(){
 
  x = analogRead(0);
  y = analogRead(1);
  z = analogRead(2);
 
  float xsintheta = constrain(mapinfloat(x,268,406,-1,1),-1,1);
  float ysintheta = constrain(mapinfloat(y,267,406,-1,1),-1,1);
  float zsintheta = constrain(mapinfloat(z,275,412,-1,1),-1,1);
 
 
 
  float xtheta = asin(xsintheta)*180/PI;
  float ytheta = asin(ysintheta)*180/PI;
  float ztheta = asin(zsintheta)*180/PI;
 
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("x: ");
  lcd.setCursor(5,0);
  lcd.print(xtheta);
 
  lcd.setCursor(0,1);
  lcd.print("y: ");
  lcd.setCursor(5,1);
  lcd.print(ytheta);
 
  delay(100); 
}

float mapinfloat(float i, float imin,float imax, float omin, float omax){
  float o = (i-imin)*(omax-omin)/(imax-imin) + omin;
  return o;
}

============================================================================

 

작동 영상

영상에서는 x축만 출력하였다.

참고로 -70~70도 사이에서는 비교적 정확하게 측정되나

-70과 70도를 벗어나면서 정확한 값을 측정하기 어려움.

 

가속도 센서로 각도 측정

 

가속도센서에 대한 기본은 이전글 확인

http://eskelt.tistory.com/79

 

이전글에서 확인할수 있듯이

사용한 ADXL335 센서는 한축을 -90~90도로 기울이면

-1g~1g값을  아날로그 값으로 출력해준다

 이값을 아두이노에서 아날로그 입력을 받아

각도로 변환 출력하면 된다.

 

즉, 입력받은 값을 -1 ~ 1 값으로 매핑

이 값은 sin(-90도)~sin(90도) 값이므로

asin(-1)~asin(1)로 라디안 값을 구하고 각도로 변환하면 된다.

 센서회전(가속도)

센서에서

출력되는 값

sin(-90도)~sin(90도) 값으로 매핑

asin으로

라디안 얻고 

라디안값을 각도로 변환 

 -90도 (-1g)

 270

 -1

 asin(-1) = -π/2

 asin(-1)*180/π = -90

 0도( 0g)

 338

 0

 asin( 0) = 0

 asin( 0)*180/π = 0

 90도( 1g)

 407

 1

 asin( 1) = π/2

 asin( 1)*180/π = 90

 

 

스케치 소스

========================================================================

float x,y,z;

 

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

void loop(){
 
  x = analogRead(0);
  y = analogRead(1);
  z = analogRead(2);


// 센서에서 읽은 값을 -1~1 사이의 범위가 좁은 값으로 변환하기 위해

// 실수형으로 변수 선언하고 스케치 맨 하단 mapinfloat 함수를 호출을 통해 변환

// 그리고 -1~ 1 사이를 벗어나지 않도록 constrain 처리
  float xsintheta = constrain(mapinfloat(x,268,406,-1,1),-1,1);
  float ysintheta = constrain(mapinfloat(y,267,406,-1,1),-1,1);
  float zsintheta = constrain(mapinfloat(z,275,412,-1,1),-1,1);
  

// -1~1 사이의 값을 각도 값으로 변환  
  float xtheta = asin(xsintheta)*180/PI;
  float ytheta = asin(ysintheta)*180/PI;
  float ztheta = asin(zsintheta)*180/PI;
 

  Serial.print("x : ");
  Serial.print(xtheta  );
  Serial.print("   ");
  Serial.print("y : ");
  Serial.print(ytheta);
  Serial.print("   ");
  Serial.print("z : ");
  Serial.println(ztheta);
}

 

// -1~1 사이의 범위가 좁은 값으로 변환하기 위한 함수

float mapinfloat(float i, float imin,float imax, float omin, float omax){
  float o = (i-imin)*(omax-omin)/(imax-imin) + omin;
  return o;
}

========================================================================

 

작동영상

먼저 x축을 90도까지 기울여 값을 serial모니터에 출력

다음 y축을 -90도에서 90도까지 기울여 serial모니터에 출력한 화면.

확인한 결과 -70~70도 사이에서는 비교적 정확한 값을 측정한 반면

그 ±70도 이상에서는 정확하지 않은 값이 측정됨.

 

+ Recent posts