코코아팹은 누구나 창의적 아이디어를 현실로 만들어 낼 수 있도록
만들고, 공유하고, 배울 수 있는 터전이
되고자 합니다.
아이디와 비밀번호를 잊으셨나요?아이디 / 비밀번호 찾기
코코아팹 회원이 아니신가요? 회원가입
2015-04-29 15:23:07
'아두이노'라는 것이 교육용 또는 취미용으로 보급화 되면서
RC카 프로젝트는 주변에서 흔히 찾을 수 있는 좋은 튜토리얼 소재가 되었습니다.
특히! 누구나 가지고 있는 스마트 폰으로 제어하는 RC카는 더더욱 많은 예시들이 있습니다.
하지만 자동차의 매력은, 바로 손맛이죠. 스마트 폰 제어 보다는 고유의 운전의 느낌을 살리기 위해서는
별도의 조종장치를 만들어야 합니다.
이번 프로젝트에서는 간단한 조종 장치를 만들어 RC카를 제어해 보도록 하겠습니다.
악셀 패달과 조종간을 만들어 지그비 통신을 이용하여 RC카를 제어합니다.
악셀 패달과 조이스틱 조종장치 입니다. 패달은 우드락과 압력센서, 스폰지를 이용하여
눌렸을 때의 힘을 감지하고 원래 모양대로 돌아오도록 만들었습니다.
RC카는 장난감으로 나오는 RF 조종 자동차를 분해하여 개조하였습니다.
전방 모터는 바퀴의 방향 제어용 후방 모터는 추진 용으로 설계가 되어 있었습니다.
여담이지만 조종기는 눈길한번 받지 못하고 어딘가에 짱박혀있는 불쌍한 신세가 되었네요....
NO | PART | QTY | ETC |
1 | 오렌지 보드 | 2 | |
2 | 압력 센서 | 1 | |
3 | 모터 쉴드 | 1 | |
4 | 지그비 쉴드 | 2 | XBee S1 |
5 | 저항 | 1 | 1K |
오렌지 보드 | 압력 센서 | 모터 쉴드 | 지그비 쉴드 |
브레드보드 레이아웃
* <자동차 파트> 상단 모터 - 추진력, 하단 모터 - 방향제어
*<자동차 파트> 쉴드 결합 시 오렌지보드 - 지그비 쉴드 - 모터 쉴드 순으로 결합
*<조종기 파트> 조이스틱 연결 시 x축 Pin만 연결 ( y축 Pin 사용 안함)
int a,b,e;
int e;
void setup()
{
Serial.begin(9600);
}
void loop()
{
a = analogRead(A0); // 압력센서 값 저장
b = analogRead(A1); // 조이스틱 값 저장
// 압력센서 값을 단계화 하여 3자리 표시로 송신
if(a<10){Serial.print('0');Serial.print('0');Serial.print(a);}
else if(a>=10&&a<100){Serial.print('0');Serial.print(a);}
else if(a>=100){Serial.print(a);}
if(b > 510) // 조이스틱이 좌로 향할 경우, 1024분주 값을 256분주 값으로 환산하여 송신
{
e =(b-512)/2;
if(e<10){Serial.print('L');Serial.print('0');Serial.print('0');Serial.println(e);}
else if(e>=10&&e<100){Serial.print('L');Serial.print('0');Serial.println(e);}
else if(e>=100){Serial.print('L');Serial.println(e);}
}
else if(b <500) // 조이스틱이 우로 향할 경우, 1024분주 값을 256분주 값으로 환산하여 송신
{
e =(500-b)/2;
if(e<10){Serial.print('R');Serial.print('0');Serial.print('0');Serial.println(e);}
else if(e>=10&&e<100){Serial.print('R');Serial.print('0');Serial.println(e);}
else if(e>=100){Serial.print('R');Serial.println(e);}
}
else // 조이스틱이 중간 값일 경우 0 송신
{
e = 0;
Serial.print('0');Serial.print('0');Serial.print('0');Serial.println(e);
}
delay(300);
}
일반적인 센서와 같이 아날로그 값을 읽어오는 간단한 소스입니다. 다만, 이 장치에서는 자동차에게 이 값을 전송해 주어야 하는데
자동차에서 이 값들을 일관적으로 읽을 수 있도록 하기 위해 자릿수를 맞추어 송신하도록 만들었습니다.
총 8자리 값으로 1,2,3번 값은 속도 / 4번 값은 좌 또는 우 결정값 / 5,6,7번 값은 회전각의 크기 값 / 8번 값은 줄바꿈 입니다.
// 모터 쉴드에 표시된 값으로 설정
int DA = 12;
int DB = 13;
int PA = 3;
int PB = 11;
int BA = 9;
int BB = 8;
int d,e;
//
// 조종기 파트로 부터 받는 8자리 숫자 저장 주소
char s[8];
//
int x;
int f;
void setup()
{
Serial.begin(9600);
pinMode(DA,OUTPUT);
pinMode(DB,OUTPUT);
pinMode(PA,OUTPUT);
pinMode(PB,OUTPUT);
pinMode(BA,OUTPUT);
pinMode(BB,OUTPUT);
}
void loop()
{
get_string();
Forward();
direction_car();
}
void get_string() // 조종기로 부터 받는 문자열을 배열화하여 저장
{
if(Serial.available())
{
s[x] = Serial.read();
if(s[x] == '\n') // 줄 바꿈 값이 수신될 경우 배열 저장 완료
{ // ●●●(패달입력값)◎(방향)○○○(방향입력값)◇(줄바꿈)
x=0; // 총 8개의 값을 수신 받게된다.
} // 마지막 값, 즉 s[7]에 저장된 값이 줄바꿈일 경우 s[0]부터 다시 수신 시작
else
{
x++;
}
}
}
void Forward()
{
e = ((s[0]-48)*100)+((s[1]-48)*10)+(s[2]-48); // 속도 값으로 수신된 3자리 s[0],s[1],s[2]를
if(e<50) // 십진값으로 표시
{
digitalWrite(BA, HIGH); // 일정 힘 이하일 경우 정지
}
else if(e>=50) // 일정 힘 이상일 경우 그 힘의 값을 모터 속도 값으로 입력
{
digitalWrite(DA,HIGH);
analogWrite(PA, e);
digitalWrite(BA, LOW);
}
}
void turn_l(int l) // 좌회전 함수
{
digitalWrite(DB,HIGH);
analogWrite(PB,l);
digitalWrite(BB, LOW);
}
void turn_r(int r) // 우회전 함수
{
digitalWrite(DB,LOW);
analogWrite(PB,r);
digitalWrite(BB, LOW);
}
void direction_car() // 수신된 방향값을 십진값으로 표시, s[3] 방향결정 값에 따라 좌우 결정
{
d = ((s[4]-48)*100)+((s[5]-48)*10)+(s[6]-48); // s[x]는 char 값이므로 int값으로써 계산하기위해
if(s[3] == 'L'){turn_r(d);} // s[x]-48 로 계산
else if(s[3] == 'R'){turn_l(d);}
else if(s[3] == '0'){digitalWrite(BB,HIGH);}
}
조종기에서 송신한 8자리 값을 8비트 배열에 저장하여 필요한 부분만 추출하여 처리 할 수 있도록 만들었습니다.
SaBo