프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

DIY RC카 만들기

2014-09-15 11:10:44

개요


RC 카란 Radio Control의 약자로 무선조종이 가능한 자동차를 말합니다.
장난감으로 치부하기에는 굉장한 매니아 층을 형성하고 있습니다.


출처 : RC카 경주대회 - www.rcmodelswiz.co.uk

국내외 다양한 동호회에서 자신들만의 노하우를 공유하고,
실제 오프라인 공간에서 그랑프리가 열리기도 합니다.
하지만 이러한 RC카 세계에 입문하기에는
모터에 대한 전문지식이 필요하고, 많은 비용이 들기 마련입니다.




출처 : 다양한 전동 키트 - http://www.scoop.it/

하.지.만 아두이노를 이용하면, 
다양한 키트를 기반으로 자신만의 RC카를 만들수 있을 뿐만 아니라,


출처 : 초음파 센서를 장착한 RC카 - www.svenbluege.de

카메라, 초음파센서, LED등 다양한 기능을 추가할 수 있고,
제어방식 또한 원하는 방식으로 설정할 수 있습니다.

이번 프로젝트에서는 기존의 DC 모터 자동차 키트와 블루투스 모듈을 이용하여
스마트폰으로 제어하는 DIY RC카를 만들어 보겠습니다.

미리보기 동영상




필요한 사전지식


부품목록


NO 부품명 수량 상세설명
1 오렌지 보드 1 아두이노 호환보드
2 점퍼케이블 7 점퍼케이블
3 미니브레드보드 1 브레드보드
4 블루투스 모듈 1 HC-05
5 아두이노 모터 쉴드 1 모터 쉴드
6 2.1mm DC 잭 1 DC 잭 male
7 Amphibious vehicle kit (DC모터 내장) 1 타미야
8 서보모터 1 sg-90
9 9v 건전지 2 배터리
10 9v 어답터 2 어답터
11 케이블타이(선택) 5 케이블타이
12 글루건(필수) 1 글루건
13 커터칼 1
14 니퍼 1 니퍼
15 스크류 드라이버 1 +,- 혼합형
16 핸드드릴(선택) 1 핸드드릴
17 인두기 1 인두기
18 1
19 안드로이드 스마트폰 1 안드로이드

부품명 오렌지 보드 미니 브레드보드 점퍼케이블 블루투스 모듈 아두이노 모터 쉴드
파트 x1 x1 x7  x1
부품명 2.1mm DC 잭 Amphibious vehicle kit 서보모터 9v 건전지 9v 어답터
파트 x1 x1 x1  x1
부품명 글루건 커터칼 니퍼 스크류 드라이버 인두기
파트 x1 x1 x1  x1
부품명 안드로이드 스마트폰
파트 x1 x1

하드웨어 Making

RC CAR 만들기 - Amphibious vehicle kit 해킹하기
본 프로젝트에서는 타미야의 Amphibious vehicle kit 를 이용하여 진행하였습니다.
1. 본체 조립하기
- 키트에 포함된 메뉴얼에 따라 조립을 해주세요.
- 모터 부분을 조립하기 전에 DC 모터에 전선을 납땝하여 연장해 주세요.

2. 앞바퀴 축을 서보모터와 연결 합니다.
나사는 약1cm 이상의 못머리가 넓은 나사를 사용하였습니다.
글루건으로 벌어진 틈새를 보강하였습니다.

3. 서보모터와 키트 본체를 연결합니다.
키트에 들어있는 나사와 규격이 맞지않아 핸드 드릴로 구멍을 넓혀 주었습니다.

키트의 연결부쪽 둥그런 부분이 서보모터와 닿는 다면, 사포로 갈아 주세요

4. 아두이노 보드를 결합하기 위해 표시된 부분을 칼이나, 핸드드릴로 잘라줍니다.
주의: 단단한 플라스틱이기 때문에 가공시 베이지 않도록 주의하세요.

5. 모터쉴드를 사용하여 DC모터와 서보모터를 연결합니다.
아두이노 모터쉴드에 DC모터 (A채널)와
5번 핀을 사용하는 PWM 핀에 서보모터를 연결하였습니다. 
무선으로 구동하기 위해 9V 배터리를 모터쉴드와 아두이노 보드에 연결하였습니다.

미니 브레드보드에 HC-05 블루투스모듈을 연결하여 서보모터 위에 고정하였습니다.

6.연결된 하드웨어를 키트와 고정합니다.
글루건을 이용하여 보드와 본체를 고정하였습니다.
적당한 양을 사용해주세요.


7.최종 완성된 모습입니다.


회로도


브레드보드 레이아웃




소프트웨어 Coding

#include <SoftwareSerial.h> // 블루투스 통신을 위한 SoftwareSerial 라이브러리
#include <Servo.h> // 서보모터를 제어하기 위한 라이브러리

SoftwareSerial BTSerial(6, 7); // SoftwareSerial(RX, TX)
byte buffer[1024]; // 데이터 수신 버퍼
int bufferPosition; // 버퍼에 기록할 위치

Servo servo;

int dcMotor = 12;
int dcSpeed = 3;
// DC모터의 움직임을 제어하는 핀(12)과 속도를 제어하는 핀(3) int motorAngle = 0; int motorSpeed = 0;
// 서보모터의 각도와, DC모터의 속도 void setup () { servo.attach(5); // 5번핀에 연결된 서보모터 pinMode(dcMotor, OUTPUT); BTSerial.begin(9600); Serial.begin(9600); bufferPosition = 0; } void loop () { if (BTSerial.available()) { // 블루투스 통신이 가능할 경우 byte data = BTSerial.read(); buffer[bufferPosition++] = data; // 블루투스에서 받아온 값을 byte data에 저장 Serial.println(data); switch(data){ // 블루투스에서 받아온 값에 따라 맞는 동작을 함 case 'q': // q일경우 프로그레스바에 값을 속도로 speedSet(); break; case 'w': // 스마트폰의 기울기(양수)에 따라 서보모터 각도 제어 angleSet(0); break; case 'e': // 스마트폰의 기울기(음수)에 따라 서보모터 각도 제어 angleSet(1); break; case 'j': // -60도 버튼을 눌렀을 경우 angleWrite(30); break; case 'i': // -30도 버튼을 눌렀을 경우 angleWrite(60); break; case 'k': // 0도 버튼을 눌렀을 경우 angleWrite(90); break; case 'o': // 30도 버튼을 눌렀을 경우 angleWrite(120); break; case 'l': // 60도 버튼을 눌렀을 경우 angleWrite(150); break; case 'F': // Forward 토글버튼을 눌렀을 경우(토글버튼에 불이 켜졌을 경우) 모터를 정방향으로 돌림 motorDirection(0, motorSpeed); break; case 'f': // Forward 토글버튼을 눌렀을 경우(토글버튼에 불이 꺼졌을 경우) 모터를 멈춤 motorDirection(0, 0); break; case 'B': // Back 버튼을 눌렀을 경우(토글버튼에 불이 켜졌을 경우) 모터를 역방향으로 돌림 motorDirection(1, motorSpeed); break; case 'b': // Back 버튼을 눌렀을 경우(토글버튼에 불이 꺼졌을 경우) 모터를 멈춤 motorDirection(1, 0); break; case '\n': // 문장이 끝낫을 경우 bufferPosition = 0; break; } } } void speedSet() { // 프로그레스바에 맞는 값을 읽어 모터의 속도를 조절하는 함수 if (bufferPosition == 4) { motorSpeed = (buffer[0]-48)*100 + (buffer[1]-48)*10 + (buffer[2]-48); } else if (bufferPosition == 3) { motorSpeed = (buffer[0]-48)*10 + (buffer[1]-48); } else if (bufferPosition == 2) { motorSpeed = buffer[0] - 48; } analogWrite(dcSpeed, motorSpeed); } void angleSet(boolean flag){ // 스마트폰에 기울기를 읽어 서보모터의 각도를 조절하는 함수 if(buffer[0] != 10){ if (bufferPosition == 4) { motorAngle = (buffer[0]-48)*100 + (buffer[1]-48)*10 + (buffer[2]-48); } else if (bufferPosition == 3) { motorAngle = (buffer[0]-48)*10 + (buffer[1]-48); } else if (bufferPosition == 2) { motorAngle = buffer[0] - 48; }
if(flag){ // flag가 0이면 왼쪽(기울기가 양수), flag가 1이면 오른쪽(기울기가 음수) motorAngle *= -1; } Serial.print("motorAngle = "); Serial.println(motorAngle); motorAngle = map(motorAngle, 150, -150, 30, 150); // 서보모터의 각도로 범위를 재지정 해줌 servo.write(motorAngle); } } void angleWrite(int angle){ // 서보모터의 각도 조절 servo.write(angle); } void motorDirection(boolean dir, int speedVal) { // Dc모터의 방향 및 속도 제어 motorSpeed = speedVal; if (dir == 0) { digitalWrite(dcMotor, HIGH); } else { digitalWrite(dcMotor, LOW); } analogWrite(dcSpeed, motorSpeed); }


소프트웨어 설명

RC카를 제어할 안드로이드 어플(rc_Test.apk)을 받으신 후, 실행 하면 밑의 사진처럼 화면이 나옵니다.


 switch(data){ // 블루투스에서 받아온 값에 따라 맞는 동작을 함
      case 'q':  // q일경우 프로그레스바에 값을 속도로 
        speedSet();
        break;
        
      case 'w': // 스마트폰의 기울기(양수)에 따라 서보모터 각도 제어
        angleSet(0);
        break;
       
      case 'e':  // 스마트폰의 기울기(음수)에 따라 서보모터 각도 제어
        angleSet(1);
        break;
        
      case 'j': // -60도 버튼을 눌렀을 경우
        angleWrite(30);
        break;
      
      case 'i': // -30도 버튼을 눌렀을 경우
        angleWrite(60);
        break;
        
      case 'k': // 0도 버튼을 눌렀을 경우
         angleWrite(90);
         break;
         
       case 'o': // 30도 버튼을 눌렀을 경우
         angleWrite(120);
         break;
         
       case 'l': // 60도 버튼을 눌렀을 경우
         angleWrite(150);
         break;
         
       case 'F': // Forward 토글버튼을 눌렀을 경우(토글버튼에 불이 켜졌을 경우) 모터를 정방향으로 돌림
         motorDirection(0, motorSpeed);
         break;
         
       case 'f': // Forward 토글버튼을 눌렀을 경우(토글버튼에 불이 꺼졌을 경우) 모터를 멈춤
         motorDirection(0, 0);
         break;

       case 'B': // Back 버튼을 눌렀을 경우(토글버튼에 불이 켜졌을 경우) 모터를 역방향으로 돌림
         motorDirection(1, motorSpeed);
         break;
         
       case 'b': // Back 버튼을 눌렀을 경우(토글버튼에 불이 꺼졌을 경우) 모터를 멈춤
         motorDirection(1, 0);
         break;
         
       case '\n': // 문장이 끝낫을 경우
         bufferPosition = 0;
         break;
   }
안드로이드 어플에서 각 동작마다 해당 동작에 대한 값을 블루투스로 보내줍니다.  각각 q, w, e, j, i, k, o, l, F, f, B, b(대문자 소문자 구분 합니다.) 값을 보내는 데, 

q는 프로그레스바, w와 e는 스마트폰의 기울기, j, i, k, o, l은 각각 기울기 버튼, F, f는 Forward버튼 B, b는 Back버튼 입니다.

void speedSet() { // 프로그레스바에 맞는 값을 읽어 모터의 속도를 조절하는 함수
  if (bufferPosition == 4) {
     motorSpeed = (buffer[0]-48)*100 + (buffer[1]-48)*10 + (buffer[2]-48);
  } else if (bufferPosition == 3) {
    motorSpeed = (buffer[0]-48)*10 + (buffer[1]-48);
  } else if (bufferPosition == 2) {
    motorSpeed = buffer[0] - 48;
  }

  analogWrite(dcSpeed, motorSpeed);
}
'q' 가 들어왔을 때 DC모터의 속도를 제어하는 함수입니다. 블루투스 통신은 byte단위 한글자씩 전송하므로 각 자리를 버퍼에 저장해 두었다가, 마지막 글자가 q일 경우 버퍼에 저장된 값을 읽어 프로그레스바의 숫자를 저장합니다. (제일 큰 자리의 수가 먼저 들어옵니다. buffer[0] 번 부터)

이렇게 읽은 값만큼 속도를 제어합니다. 

void angleSet(boolean flag){ // 스마트폰에 기울기를 읽어 서보모터의 각도를 조절하는 함수
  if(buffer[0] != 10){
    if (bufferPosition == 4) {
       motorAngle = (buffer[0]-48)*100 + (buffer[1]-48)*10 + (buffer[2]-48);
    } else if (bufferPosition == 3) {
      motorAngle = (buffer[0]-48)*10 + (buffer[1]-48);
    } else if (bufferPosition == 2) {
      motorAngle = buffer[0] - 48;
    }
if(flag){ // flag가 0이면 왼쪽(기울기가 양수), flag가 1이면 오른쪽(기울기가 음수) motorAngle *= -1; } Serial.print("motorAngle = "); Serial.println(motorAngle); motorAngle = map(motorAngle, 150, -150, 30, 150); // 서보모터의 각도로 범위를 재지정 해줌 servo.write(motorAngle); } }
'w', 'e'가 들어왔을 때 서보모터의 각도를 제어하는 함수 입니다. 'w'가 들어오면 기울기가 양수(flag == 0), 'e'가 들어오면 기울기는 음수(flag == -1)입니다.

위 프로그레스 막대바의 값을 읽는 것과 마찬가지로 숫자들을 버퍼에 저장한 후 'w'나 'e' 가 들어왔을 때 buffer 에 저장된 값을 읽어 기울기를 구합니다. 

그 후 읽은 값을 map 함수를 이용하여 서보모터 각도 제어 범위(0~180도 이지만 0, 180도로 꺽으면 rc카가 움직이지 못하므로 30~150도로 조정했습니다.)로 재설정 해 준 후 재설정된 값에 맞게 서보모터의 각도를 조정합니다.

void angleWrite(int angle){ // 서보모터의 각도 조절
  servo.write(angle); 
}

void motorDirection(boolean dir, int speedVal) { // Dc모터의 방향 및 속도 제어
  motorSpeed = speedVal;
  
  if (dir == 0) {
    digitalWrite(dcMotor, HIGH);
  } else {
    digitalWrite(dcMotor, LOW);
  }

  analogWrite(dcSpeed, motorSpeed);
}
나머지 서보모터의 각도 버튼(-60~60도)과 Forward 토글버튼, Back 토글버튼에 맞게 동작 합니다. 각도 버튼을 눌렀을 경우 그 버튼에 각도에 맞게 서보모터를 조정하고, Forward / Back 버튼에 맞게 DC모터의 방향을 조정합니다.(정방향은 모터 방향핀 High, 역방향은 모터 방향핀 Low로 해주시면 됩니다.)






hihyo

아두이노,모터쉴드,DC모터,서보모터,모터제어,블루투스,HC-05,스마트폰,안드로이드,무선통신,DIY,RC카,