top of page

Term-Project

Term-Project 결과보고서

 

name of project : Smart RC Car

(Bluetooth RC Car & Autonomous driving RC Car)

 

name of participants : 2017103729 서민영, 2017103733 우수진

 

 

<Autonomous driving RC Car>

스스로 장애물을 피하는 Smart RC Car의 경우 전동 전선을 Dual L9110 motor driver에 연결시킨다. 전원을 켜면 자동차가 스스로 움직이면서 장애물이 감지될 때마다 방향을 바꾸어 이동하였다. 장애물인식 거리를 20cm로 설정시켰기 때문에 사방이 장애물로 둘러 싸여 있으면 오른쪽이나 왼쪽으로 계속 회전을 하는 현상을 보였다. 또한 초음파 센서보다 낮게 위치한 물체의 경우는 잘 인식해내지 못하였다. Autonomous driving RC Car의 경우 회로도 연결이 쉽지 않았는데 특히나 pin number를 잘 확인하고 코드를 짜야했다.

 

 

<Bluetooth RC Car>

핸드폰으로 제어를 할 수 있는 Bluetooth RC Car의 경우 전동 전선을 아두이노 Uno위 모터드라이버 쉴드(Genuino Uno)의 모터와 연결시킨다. 그리고 블루투스 모듈을 연결시키고 핸드폰과 같은 와이파이를 쓰는 조건 하에서 BlueTooth Serial Controller 앱을 연결시킨다. 연결하기 전에 미리 앱을 programming 해두어 좌우, 전진, 후진 버튼을 통해 RC car를 제어할 수 있도록 한다. 이때 주의 할 점은 소스를 업로드 할 때에는 Bluetooth를 보드에서 제거한 채로 업로드 해주어야 했다.

 

 

 

 

 

<아쉬운 점>

처음 목표는 Autonomous driving RC Car와 Bluetooth RC Car의 기능이 동시에 발휘될 수 있도록 하는 것이었다. 따라서 블루투스 모듈와 연결시켜 작동을 제어하면서 사용자가 미처 장애물을 보지 못하였을 경우에 초음파 센서로 장애물을 감지하여 스스로 피할 수 있도록 하는 것이 목표였다. 그러나 우리가 제작한 RC Car의 경우 Autonomous driving RC Car와 Bluetooth RC Car의 기능들은 각기 다른 모터드라이버를 요구했기에 한 번에 작동을 시킬 수 없었다.

 

<느낀 점>

또한 이번 텀 프로젝트를 통해서 프로젝트의 주제를 정한다 하더라도 그 주제를 실현하기 위한 부품을 구하는 것이 쉽지 않다는 것을 깨달을 수 있었다. 단종 되어버린 경우도 많았고, 한국에서 구매할 수 있는 부품도 많지 않았기 때문이다. 그래서 외국기업이나, 관세청 등에도 직접 전화를 해보며 다양한 정보를 얻었고, 처음으로 직구나 소규모 도매도 해보며 다양한 경험을 해 볼 수 있었다. 무엇보다도 아두이노를 통해 physical computing이라는 것을 직접 체험해보면서 힘들면서도 즐거웠고 전공에 대한 확신을 좀 더 가질 수 있는 계기가 된 것 같다.

<Autonomous driving RC Car 코딩>

define MOTOR_A_SPD 10  //모터A의 속력을 결정하는 핀
#define MOTOR_B_SPD 11  //모터B의 속력을 결정하는 핀
#define MOTOR_A_DIR 12  //모터A의 방향을 결정하는 핀
#define MOTOR_B_DIR 13  //모터B의 방향을 결정하는 핀
#define A_BAL 1   //모터A 속력 균형 계수 기본값 1
#define B_BAL 1   //모터B 속력 균형 계수 기본값 1

unsigned char m_a_spd = 0, m_b_spd = 0; //모터의 속력을 결정하는 전역변수
boolean m_a_dir = 0, m_b_dir = 0; //모터의 방향을 결정하는 전역변수

void setup()  
{
  Serial.begin(9600); //시리얼 통신 초기화

  pinMode(MOTOR_A_DIR, OUTPUT); //모터A 방향 핀 출력으로 설정
  pinMode(MOTOR_B_DIR, OUTPUT); //모터B 방향 핀 출력으로 설정
  
  Serial.println("Hello!"); //터미널 작동 확인용 문자열
}

void loop()
{
  unsigned char bt_cmd = 0; //명령어 저장용 문자형 변수

  if (Serial.available()) //데이터가 입력되었을 때
  {
    bt_cmd = Serial.read(); //변수에 입력된 데이터 저장
    rc_ctrl_val(bt_cmd);  //입력된 데이터에 따라 모터에 입력될 변수를 조정하는 함수
  }
  motor_drive();  //모터를 구동하는 함수
}

void rc_ctrl_val(unsigned char cmd) //입력된 데이터에 따라 모터에 입력될 변수를 조정하는 함수
{
  if(cmd == 'w')  //'w'가 입력되었을 때, 전진
  {
    m_a_dir = 1;  //모터A 정방향
    m_b_dir = 0;  //모터B 정방향
    m_a_spd = 80*A_BAL;  //모터A의 128의 PWM
    m_b_spd = 80*B_BAL;  //모터B의 128의 PWM
  }
  else if(cmd == 'a')  //'a'가 입력되었을 때, 제자리 좌회전
  {
    m_a_dir = 1;  //모터A 정방향
    m_b_dir = 1;  //모터B 역방향
    m_a_spd = 80*A_BAL;  //모터A의 128의 PWM
    m_b_spd = 80*B_BAL;  //모터B의 128의 PWM
  }
  else if(cmd == 'd')  //'d'가 입력되었을 때, 제자리 우회전
  {
    m_a_dir = 0;  //모터A 역방향
    m_b_dir = 0;  //모터B 정방향
    m_a_spd = 80*A_BAL;  //모터A의 128의 PWM
    m_b_spd = 80*B_BAL;  //모터B의 128의 PWM
  }
  else if(cmd == 's')  //'s'가 입력되었을 때, 후진
  {
    m_a_dir = 0;  //모터A 역방향
    m_b_dir = 1;  //모터B 역방향
    m_a_spd = 80*A_BAL;  //모터A의 128의 PWM
    m_b_spd = 80*B_BAL;  //모터B의 128의 PWM
  }
  else if(cmd == 'x')
  {
    m_a_dir = 1;  //모터A 정방향
    m_b_dir = 0;  //모터B 정방향
    m_a_spd = 0;  //모터A의 정지
    m_b_spd = 0;  //모터B의 정지
  }
}

void motor_drive()  //모터를 구동하는 함수
{
  digitalWrite(MOTOR_A_DIR, m_a_dir);  //모터A의 방향을 디지털 출력
  digitalWrite(MOTOR_B_DIR, m_b_dir);  //모터B의 방향을 디지털 출력
  analogWrite(MOTOR_A_SPD, m_a_spd);  //모터A의 속력을 PWM 출력
  analogWrite(MOTOR_B_SPD, m_b_spd);  //모터B의 속력을 PWM 출력
}
#include <SoftwareSerial.h> //시리얼 통신 라이브러리 호출
 
//모터 PIN 설정
#define LEFT_A1 4 //왼쪽 바퀴
#define LEFT_B1 5 //왼쪽 바퀴
#define RIGHT_A2 6 //오른쪽 바퀴
#define RIGHT_B2 7 //오른쪽 바퀴
 
//초음파 센서 PIN 설정
#define IR_TRIG 9 //TRIG 핀 설정 (초음파 보내는 핀)
#define IR_ECHO 8 //ECHO 핀 설정 (반사된 초음파 받는 핀)
 
void setup() {
  Serial.begin(9600);   //시리얼모니터 
 
  //모터 핀모드 설정
  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);  
 
  //초음파 센서 핀모드 설정
  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}
 
void loop() {
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 
  // echoPin 이 HIGH를 유지한 시간
  duration = pulseIn(IR_ECHO, HIGH);
  // HIGH 였을 때 시간(초음파가 보냈다가 다시 들어온 시간)을 가지고 거리를 계산 한다.
  // 340은 초당 초음파(소리)의 속도, 10000은 밀리세컨드를 세컨드로, 왕복거리이므로 2로 나눠주면 거리가 cm 로 나옴
  distance = ((float)(340 * duration) / 10000) / 2;
  Serial.print("\nDIstance : ");
  Serial.println(distance);
     
  if(distance < 20) {         //장애물 감지 (20cm 이내)
     Serial.println("stop");
     stop();  //정지(1초)
     Serial.println("backward");
     backward();  //후진(0.5초)
     int rnd = random(0,2);   //장애물 감지시 좌/우회전 랜덤처리
     if(rnd == 0){
        Serial.println("right");
        right();
     }else{
        Serial.println("left");
        left();
     }
   }else{         //장애물 없음
     Serial.println("forward");
     forward();
   }
}
 
void forward(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void backward(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(500);
}
void left(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(1000);
}
void right(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000);
}
void stop(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
  delay(1000);
}

<Bluetooth RC Car 코딩>

#include <SoftwareSerial.h> //시리얼 통신 라이브러리 호출
 
//모터 PIN 설정
#define LEFT_A1 4 //왼쪽 바퀴
#define LEFT_B1 5 //왼쪽 바퀴
#define RIGHT_A2 6 //오른쪽 바퀴
#define RIGHT_B2 7 //오른쪽 바퀴
 
//초음파 센서 PIN 설정
#define IR_TRIG 12 //TRIG 핀 설정 (초음파 보내는 핀)
#define IR_ECHO 13 //ECHO 핀 설정 (반사된 초음파 받는 핀)
 
void setup() {
  Serial.begin(9600);   //시리얼모니터 
 
  //모터 핀모드 설정
  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);  
 
  //초음파 센서 핀모드 설정
  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}
 
void loop() {
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 
  // echoPin 이 HIGH를 유지한 시간
  duration = pulseIn(IR_ECHO, HIGH);
  // HIGH 였을 때 시간(초음파가 보냈다가 다시 들어온 시간)을 가지고 거리를 계산 한다.
  // 340은 초당 초음파(소리)의 속도, 10000은 밀리세컨드를 세컨드로, 왕복거리이므로 2로 나눠주면 거리가 cm 로 나옴
  distance = duration/58.2;
  Serial.print("\nDIstance : ");
  Serial.println(distance);
     
  if(distance < 20) {         //장애물 감지 (20cm 이내)
     Serial.println("stop");
     stop();  //정지(1초)
     Serial.println("backward");
     backward();  //후진(0.5초)
     int rnd = random(0,2);   //장애물 감지시 좌/우회전 랜덤처리
     if(rnd == 0){
        Serial.println("right");
        right();
     }else{
        Serial.println("left");
        left();
     }
   }else{         //장애물 없음
     Serial.println("forward");
     forward();
   }
}
 
void forward(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void backward(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(500);
}
void left(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(1000);
}
void right(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000);
}
void stop(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
  delay(1000);
}

내 채널

내 채널

내 채널
동영상을 검색하세요.
KakaoTalk_Video_20171210_1655_20_976

KakaoTalk_Video_20171210_1655_20_976

01:32
동영상 보기
bottom of page