반응형

【 아두이노Proj#8 사륜구동 4WD 블루투스 RC카 만들기~! (with 모터쉴드)

 지난시간, 블루투스모듈을 이용한 통신을 학습하였다. 또한 미니카도 만들어 제어해보았는데, 이제 이 것들을 종합해서 업그레이드 해보도록 하자! 

 바퀴 4개를 이용하여 4륜 구동으로 만들고 아두이노 프로미니로 소형 리모컨을 만들어 무선제어를 한다면, 교육적이고 멋진 아두이노 장난감을 만들어 낼 수 있다.  여기에 Adafruit 사의 모터쉴드를 이용하면, 별다른 선연결도 없이 간단히 4개의 DC모터를 제어할 수 있다.

Let's get it~!

 

▶ 선수 학습 :

    1. [아두이노 모듈#16] 아두이노... 블루투스통신 (블루투스 설정법 참조) ☜ (클릭)

    2. [아두이노 모듈#18] 아두이노... 블루투스통신 (블루투스 제어법 참조) ☜ (클릭)

    3. [아두이노 모듈#22] Adafruit의 4채널 모터쉴드(모터쉴드 사용법 참조) ☜ (클릭)
    4. [아두이노 ProMini#2] 초소형 블루투스 리모컨 만들기(리모트 컨트롤러 참조) ☜ (클릭)

 

▶ 실습 목표 :  

 1. [ Adafruit 모터 쉴드의 사용법을 익힐 수 있고 4개의 DC모터 제어를 할 수 있다.] 

 2. [ 조이스틱의 컨트롤 기능을 익힐 수 있다.  ]

 3. [ 블루투스 모듈의 셋업과 페어링(연결) 및 사용법을 익힐 수 있다. ]

 4. [ 아두이노 두 대 상호간 통신을 통해 제어하는 방법을 익힐 수 있다 ]

 

▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)

[1.  사륜 구동 본체 연결도]

[2. 블루투스 리모컨 연결도]

- 1. 우노 리모컨

우노(나노)보드 조이스틱 조정기 연결도

- 2. 프로미니 리모컨

프로미니 보드 조이스틱 조정기 연결도

※ 블루투스 페어링(자동 연결)을 위해서는, 선수학습 1번을 통해 블루투스 설정법을 확인하여, 본체에 있는 블루투스 모듈은 슬레이브로(Slave)로 설정하고, 조이스틱 조정기의 블루투스는 마스터(Master) 설정 작업이 필요하다.  
(물론 마스터와 슬레이브가 반대로 바뀌어도 상관이 없다)

  - 선수학습을 참고하면 좀더 상세하게 조이스틱 컨트롤로(조정기) 회로를 조립할 수 있다.

  - 우노회로나, 프로미니 회로 모두 같은 코드를 사용하니 상황에 따라 적합한 것을 선택할 수 있다.

 

▶ 실습 절차  :  

1.   부품을 준비하여 위와 같은 회로를 각각 구성한다. 

   -  사륜카의 베이스 판은 아크릴 판 혹은 MDF 등 주변에서 쉽게 구할 수 있는 것으로 사용해도 무방하다.

   -  여기서는 3D 프린팅으로 출력한 것을 베이스로 사용하였다.

   -  모터와 베이스를 연결하는 적합한 나사가 없을 경우, 두꺼운 양면테잎 혹은 글루스틱으로 부착하여도 무방.

   -  3.7V 베터리 2개를 직렬연결 해주면, 충분한 전류가 공급되어 힘있고 빠르게 구동된다.

2.   아래 코드를 작성하고 각각의 프로그램을 로딩 후 실행시킨다.

 

 

▶ 프로그램 코드 및 설명  : 

 

【 코드1-본체 

#include  <AFMotor.h>            // Adafruit 모터 쉴드 라이브러리 사용
#include  <SoftwareSerial.h>    //블루투스 통신을 위한 기본 헤더 선언
                                 
SoftwareSerial BTSerial(2, 3);  // 블루투스 모듈과 통신을 위한 아두이노 연결핀(TX = 2 , RX = 3)
//모터의 전후좌우 방향을 컨트롤하는 PIN번호를 상수로 선언
AF_DCMotor MOTOR1(1);     // 모터쉴드 M1 지정
AF_DCMotor MOTOR2(2);     // 모터쉴드 M2 지정
AF_DCMotor MOTOR3(3);     // 모터쉴드 M3 지정
AF_DCMotor MOTOR4(4);     // 모터쉴드 M4 지정
#define ActionTime 3000
/*  for (i=0; i <255; i++) {
    motor.setSpeed(i);
    delay(20);
  }
*/
void Stop_Release() {
  MOTOR1.run(RELEASE);
  MOTOR2.run(RELEASE);
  MOTOR3.run(RELEASE);
  MOTOR4.run(RELEASE);
  delay(20);
}

void Go_Forward() {
  MOTOR1.run(FORWARD);
  MOTOR2.run(FORWARD);
  MOTOR3.run(FORWARD);
  MOTOR4.run(FORWARD);
  delay(20);
}

void Go_Backward() {
  MOTOR1.run(BACKWARD);
  MOTOR2.run(BACKWARD);
  MOTOR3.run(BACKWARD);
  MOTOR4.run(BACKWARD);
  delay(20);
}

void Go_Left() {
  MOTOR1.run(FORWARD);
  MOTOR2.run(BACKWARD);
  MOTOR3.run(BACKWARD);
  MOTOR4.run(FORWARD);
  delay(20);
}

void Go_Right() {
  MOTOR1.run(BACKWARD);
  MOTOR2.run(FORWARD);
  MOTOR3.run(FORWARD);
  MOTOR4.run(BACKWARD);
  delay(20);
}

void setup() {
  BTSerial.begin(9600); //블루투스와 통신하기 위한 속도설정(모듈의속도 확인필요)
  Serial.begin(9600);   // 시리얼(모니터) 통신 속도를 설정
  MOTOR1.setSpeed(250);
  MOTOR2.setSpeed(250);
  MOTOR3.setSpeed(250);
  MOTOR4.setSpeed(250);
}

void loop() {
/* 기본 동작  
  Go_Forward();
  Stop_Release();
  Go_Left();
  Stop_Release();
  Go_Right();
  Stop_Release();
  Go_Backward();
  Stop_Release();
*/
  if (BTSerial.available()) {   // 블루투스로 신호가 있을 경우 실행되는 루틴
    char cmd = (char) BTSerial.read();   // 블루투스로 읽은 값을 char타입 변수에 저장
    Serial.println(cmd);  //cmd변수에 저장된 내용을 사용자가 `시리얼모니터`로 확인
    
    if ( cmd == 'f') {          //블루투스에서 'f'값이 들어오면 전진
      Go_Forward();
    } else if (cmd == 'l') {     //블루투스에서 'l'값이 들어오면 좌회전
        Go_Left();
    } else if (cmd == 'r') {     //블루투스에서 'r'값이 들어오면 우회전
        Go_Right();
    } else if (cmd ==  'b') {    //블루투스에서 'b'값이 들어오면 후진
        Go_Backward();
    } else if (cmd == 's') {    //블루투스에서 's'값이 들어오면 멈춤
        Stop_Release();
    }
  }
}

 

【 코드2-조이스틱 조정기 

/*  블루투스 조이스틱 조정기 만들기        */
#include  <SoftwareSerial.h>
SoftwareSerial BTSerial(2, 3);  // BTSerial(Rx, Tx)
int BTstates=0;       // 블루투스 신호 상태 저장용 변수
const int X_AXIS =0; //마우스 X 축 (A0)
const int Y_AXIS =1; //마우스 Y 축 (A1) 
int xVal=0;
int yVal=0;

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

void loop() {  
  xVal=map(analogRead(X_AXIS),0,1023,100,0); //x축값 읽어 저장 
  yVal=map(analogRead(Y_AXIS),0,1023,300,200); //Y축값 읽어 저장
  
  // 모터 전진 //
  if (xVal >= 60 && yVal >= 225 && yVal <=275)  { 
    BTSerial.write('f');
    Serial.println('f');
  }
  
  // 모터 후진 //
  else if (xVal <= 40 && yVal >= 225 && yVal <=275)  { 
    BTSerial.write('b');
    Serial.println('b');
  }
  
  // 모터 좌회전 //
  else if (yVal <= 240 && xVal >= 25 && xVal <= 75)  { 
    BTSerial.write('l');
    Serial.println('l');
  }

  // 모터 우회전 //
  else if (yVal >= 260 && xVal >= 25 && xVal <= 75)  { 
    BTSerial.write('r');
    Serial.println('r');
  }

 else { 
    BTSerial.write('s');
    Serial.print('s');
  }
  delay(100); 
}

 

▶ 코드 다운로드 :

 (위 두 가지 코드 압축파일로 다운로드)

(PROJ03) 4WD_CAR.zip
0.00MB

 

위 코드에 사용된  AFMotor.h 라이브러리 첨부 :

Adafruit-Motor-Shield.zip
0.01MB

(만약 위 라이브러리를 다운 받아 추가 할 경우, 압축을 풀지말고, 아두이노 라이브러리 포함하기 메뉴에서 .zip 라이브러리 추가... 메뉴를 이용해서 추가해주세요. )

 

 

▶ 회로 제작/동작 영상 :

(YouTube : 1080P 고화질로 보기)

https://youtu.be/0tEaw29_dJc

 

(카카오로 보기)

 

 

프로젝트 제작에 사용된 3D 프린팅용 파일 :

1. Car 베이스
( 1. 아래는 본 영상에 사용된 Car-베이스 오리지널 출력 파일 입니다.
오리지널 파일은 고정용 나사 구멍이 뚫려 있습니다.)

아래 파일 출력 예상 이미지

 

ORIGINAL_chasis01.STL
0.27MB



( 2. 아래는 직경이 다소 큰 바퀴를 사용할 경우 가운데 부분이 걸릴 수 있어 바퀴 나뉘는 부분을 좀더 좁게 , 그리고 두께를 4t 정도 되도록한 파일 입니다.  그리고 직접 드릴로 나사의 고정 위치를 잡도록 나사구멍이 없는 파일입니다. 
- 다만, 수정한 파일은 직접 출력해서 테스트해 보지 않았기에, 먼저 오리지널 파일을 사용해 보시고 필요할 경우 아래 파일을 출력해 보시기 바랍니다.)

아래 파일 출력 예상 이미지
Rasino_4WheelCar_base_01.stl
1.48MB

2. 모터 고정용 브라켓
(본 게시글에 사용된 모터를 Car 베이스에 고정하기 위한 브라켓 입니다. )
아래 출력용 모터 서포터는 좌측용과 우측용 2가지이며,  각각 2개씩 총 4개를 출력하면 됩니다.

아래 파일 출력 예상 이미지
soporte_motor1.STL
0.04MB
soporte_motor2.STL
0.04MB


3. 모터 고정용 전용 브라켓(M3 나사) 별도 구매용
( 위 2번의 브라켓은 출력용이다 보니 아무래도 RC-Car를 
운행 할 수록 Car 베이스에 단단히 고정되지 않고 흔들거릴 수 있습니다.  때문에,   본 게시글에 사용된 모터 전용 M3나사 브라켓을 별도로 구매해서 고정시키셔도 좋을 것 같습니다.)

브라켓 구매 링크 :  smartstore.naver.com/domekit/products/2988750683  (2개 1셋 이기 때문에 구매하실때는 2개구매 혹은 여유 있게 구매)

 

반응형
반응형

【 아두이노Proj#6 선없는 조이스틱 블루투스 무선 미니카 만들기~! (HC-05)

 지난 시간 조이스틱을 이용한 미니카를 만들어 보았다. 하지만, 선이 연결되어 있어 움직임과 거리에 제약이 있어 많이 불편하였다. 이에, 최근에 다루었던 블루투스 통신 기능을 활용하여 무선으로 깔끔하게 제작해 보도록 하자.

 

▶ 선수 학습 :

    1. [아두이노 모듈#14] 조이스틱 Joystick 사용하기 #1 ☜ (클릭)

    2. [아두이노 모듈#15] L9110S 모듈 사용하기 #1 (모터 드라이버 참조)  ☜ (클릭)

    3. [아두이노 모듈#6] 조이스틱 미니카 만들기 (유선 미니카 기본 참조)  ☜ (클릭)

    4. [아두이노 모듈#16] 아두이노... 블루투스통신 (블루투스 설정법 참조) ☜ (클릭)

    5. [아두이노 모듈#18] 아두이노... 블루투스통신 (블루투스 제어법 참조) ☜ (클릭)

 

 미니카 제작 재료 (우노보드 대신 나노보드로 대체 가능)

( ※ 배터리 전원을 5V이하로 공급 시 Step-UP 컨버터를 사용하면 되고, 5V이상을 공급 시에는 AMS1117과 같은 5V 정전압 컨버터 같은 것을 사용하면 됩니다)
예시) 18650 3.7v 1개 사용시 → Step-Up컨버터 / 18650 3.7v 2개 사용시→ 정전압 컨버터

▶ 실습 목표 :  

 1. [ L9110S 모터 모듈을 활용하는 방법에 대해 이해 할 수 있다. 

 2. [ 조이스틱의 컨트롤 기능을 익힐 수 있다.  ]

 3. [ Step up 컨버터를 이용해 낮은 입력 전압을 5V전압으로 승압해 주는 컨버터를 다룰 수 있다. ]

 4. [ 블루투스 모듈의 셋업과 페어링(연결) 및 사용법을 익힐 수 있다. ]

 5. [ 아두이노 두 대 상호간 통신을 통해 제어하는 방법을 익힐 수 있다 ]

 

▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)

[1. 미니카 본체 연결도]
※ 18650(3.7v) 배터리를 1개 사용하는 미니카 회로도 입니다. 
당연히 움직이는 속도가 빠르지 않을 수 있고 동작 시간도 짧을 수 있습니다. 만약 배터리를 추가하여 활용하고자 할 때는 아래 미니카 전원보강회로 도면을 참고해 주세요.

 

[2. 미니카 블루투스 조정기 연결도]

※ 블루투스 페어링(자동 연결)을 위해서는, 선수학습 4번을 통해 블루투스 설정법을 확인하여, 본체에 있는 블루투스 모듈은 마스터(Master)로 설정하고, 조이스틱 조정기의 블루투스는 슬레이브로(Slave)로 설정 작업이 필요하다. 
(물론 마스터와 슬레이브가 반대로 바뀌어도 상관이 없다)

[ 5V 이상의 배터리 2개를 사용시 회로 연결도 ]
:  만약 5v이상의 배터리를 공급한다면,  Stepup 모듈은 필요치 않으며, 18650 두 개를 직렬로 연결하면 7.4v가 되고 Vin에 입력하고,  모터 드라이버 모듈에도 공급을 해주면 높은 전압(전력)으로인해 모터에 힘이 잘 전달 됩니다.  
이 때, 블루투스는 5V를 넘겨 입력하면 안 되기에, 아두이노의 5V 단자에서 연결해야 하니 주위하세요.

▶ 실습 절차  :  

1.   부품을 준비하여 위와 같은 회로를 각각 구성한다. 

   -  미니카의 베이스 판은 아크릴 판 혹은 MDF 등 주변에서 쉽게 구할 수 있는 것으로 한다.

   -  미니카의 구동 바퀴 외에 보조바퀴를 달아도 되고, 여기처럼 미끌리면서 지지 해줄 수 있는 둥근 나사로 간단히 해결하여도 좋다. 

   - 미니카의 구동속도나 파워를 높이고자 한다면, 3.7V 베터리 2개를 직렬연결 해주거나, 충분한 전류가 공급될 수 있도록 베터리부분을 보강 해준다. 

2.   아래 코드를 작성하고 각각의 프로그램을 로딩 후 실행시킨다.

3.  응용실습 :  코딩 부분을 수정하여 조이스틱의 대각선 방향 제어가 되도록 실습해본다. (선수학습 3번 참조)

 

▶ 프로그램 코드 및 설명  : 

【 코드1-본체 

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(2, 3); // BTSerial(Rx, Tx)
int A_1A = 9;
int A_1B = 10;
int B_1A = 5;
int B_1B = 6;
int speed = 250;   // speed: 0~ 255
char joyBT;

void setup() {
  //핀을 초기화 하고, 출력설정
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);
  Serial.begin(9600);  
  BTSerial.begin(9600);
}

void loop() {
  if (BTSerial.available()) {      
    joyBT = BTSerial.read();
    Serial.println(joyBT);        
    switch (joyBT) { 
     case 'f' :        // 모터 전진        
        //모터A
        analogWrite(A_1A, speed);
        analogWrite(A_1B, 0);    
        //모터B
        analogWrite(B_1A, speed);
        analogWrite(B_1B, 0);
        break;
     
    case 'b' :        // 모터 후진                
        analogWrite(A_1A, 0);
        analogWrite(A_1B, speed);            
        analogWrite(B_1A, 0);
        analogWrite(B_1B, speed);  
        break;
       
    case 'l' :        // 모터 좌회전                
        analogWrite(A_1A, speed);
        analogWrite(A_1B, 0);            
        analogWrite(B_1A, 0);
        analogWrite(B_1B, speed);        
        break;    
    
    case 'r' :        //모터 우회전                
        analogWrite(A_1A, 0);
        analogWrite(A_1B, speed);            
        analogWrite(B_1A, speed);
        analogWrite(B_1B, 0);
        break;
    
    case 's' :        // 모터 정지      
      analogWrite(A_1A, 0);  
      analogWrite(A_1B, 0);    
      analogWrite(B_1A, 0);
      analogWrite(B_1B, 0);
      break;    
    }
  }
}

 

 

【 코드2-조정기 

#include <SoftwareSerial.h>
SoftwareSerial BTSerial(2, 3); // BTSerial(Rx, Tx)
int BTstates=0;       // 블루투스 신호 상태 저장용 변수

const int X_AXIS =0; //마우스 X 축 (A0)
const int Y_AXIS =1; //마우스 Y 축 (A1) 
int xVal=0;
int yVal=0;

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

void loop() {
  
  xVal=map(analogRead(X_AXIS),0,1023,100,0); //x축값 읽어 저장 
  yVal=map(analogRead(Y_AXIS),0,1023,300,200); //Y축값 읽어 저장
  
  // 모터 전진 //
  if (xVal >= 60 && yVal >= 225 && yVal <=275)  { 
    BTSerial.write('f');
    Serial.println('f');
  }
  
  // 모터 후진 //
  else if (xVal <= 40 && yVal >= 225 && yVal <=275)  { 
    BTSerial.write('b');
    Serial.println('b');
  }
  
  // 모터 좌회전 //
  else if (yVal <= 240 && xVal >= 25 && xVal <= 75)  { 
    BTSerial.write('l');
    Serial.println('l');
  }

  // 모터 우회전 //
  else if (yVal >= 260 && xVal >= 25 && xVal <= 75)  { 
    BTSerial.write('r');
    Serial.println('r');
  }

 else { 
    BTSerial.write('s');
    Serial.print('s');
  }
  delay(100); 
}

 

 

▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)

[ BlueTooth Joystick_L9110 ].zip
0.00MB

 조립 과정 및 동작 영상 :

[ YouTube 고화질 영상보기 ]

https://youtu.be/zcgeo4yLVnw

 

반응형
반응형

【 아두이노Proj#6 조이스틱 미니카 만들기~! 

 조이스틱을 이용하여 아두이노 미니카(mini car)를 만들어 보려 한다. 

물론 무선으로 제어가 가능한 방법들도 많이 있지만, 구성이 간단하고 쉽게 조립해서 바로 실행시켜 볼 수 있어 유선으로 제어를 해보려 한다. 아두이노를 배우는 단계에 있다면, 쉬운것 부터 차근 차근 만들어 보는 경험을 쌓는 것이 매우 도움이 되기 때문이다. 또한 조이스틱과 소형의 L9110s 모터 드라이버를 활용해보는 공부도 될 것이다. 

▶ 선수 학습 :

    1. [아두이노 모듈#14] 조이스틱 Joystick 사용하기 #1 ☜ (클릭)

    2. [아두이노 모듈#15] L9110S 모듈 사용하기 #1 (모터 드라이버 참조)  ☜ (클릭)

 

 미니카 제작 재료

 

▶ 실습 목표 :  

 1. [ L9110S 모터 모듈을 활용하는 방법에 대해 이해 할 수 있다.

 2. [ 조이스틱으로 유선 제어를 응용해 볼 수 있다. ]

 3. [ Step up 컨버터를 이용해 낮은 입력 전압을 5V전압으로 승압해 주는 컨버터를 다룰 수 있다. ]

 

▶ 실습 회로도면 :
  (이미지 클릭하면 확대 가능)

※ 위 회로 연결에서 모터의 회전 방향이 반대가 될 경우 연결선을 서로 바꾸어 주면 된다. 

  (예를 들어, Motor A 가 반대 방향으로 회전 할 경우 A1-A 와 A1-B 에 연결한 선을 서로 바꾸어 연결한다)

 속도제어를 위해서는 디지털 포트 중에서 PWM신호 출력이 가능한 아두이노 포트(숫자앞 '~'표시) 를 연결해야 한다.

 

▶ 실습 절차  : 

 

1.   부품을 준비하여 위와 같은 회로를 구성한다. 

   -  미니카의 베이스 판은 아크릴 판 혹은 MDF 등 주변에서 쉽게 구할 수 있는 것으로 한다.

   -  조이스틱과 연결 되는 케이블은 유연성이 있는 연선(4선 혹은 3선)으로 연결한다.

2.   아래 코드를 작성하고 프로그램을 로딩 후 실행시킨다.(혹은 첨부파일 다운)

3.  코딩1은 조이스틱으로 상하좌우 제어만 가능한 기본 코드로 먼저 적용해 본다.

4.  코딩2는 조이스틱의 대각선 방향을 제어 해볼 수 있는 코드로, 필요한 경우 시리얼모니터링을 통해 데이터 값을 참고하여 코드 속 수치 값을 변경해주거나  자신만의 알고리즘으로 변경해본다. 

 

 

 

※  선수학습 1(조이스틱 편) 을 참고하여, 조이스틱을 상하좌우, 대각선방향 등 작동시켰을 때 나오는 값을 참고 하여, 아래 코딩에서 사용 되는 Jox, Joy의 좌표값을 적당한 값으로 수정할 필요가 있을 수 있다. 

(예를 들어, " if (Joy >= 90 && Jox < 20) ..." 에서  '90' 이나 '20'과 같은 수치 값 조정)

 

▶ 프로그램 코드 및 설명 (코드1) : 

/* 조이스틱 미니카 제어 (방향 : 상하좌우) */

/* L9110s 모터드라이버
   오른쪽모터
   L9110s A_1A 9 
   L9110s A_1B 10 
   왼쪽모터
   L9110s B_1A 5
   L9110s B_1B 6
*/
int A_1A = 9;
int A_1B = 10;
int B_1A = 5;
int B_1B = 6;
int speed = 250;   // speed: 0~ 255

void setup ( ) {  
  //핀을 초기화 하고, 출력설정
  pinMode(A_1A, OUTPUT);
  pinMode(A_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  digitalWrite(A_1A, LOW);
  digitalWrite(A_1B, LOW);
  digitalWrite(B_1A, LOW);
  digitalWrite(B_1B, LOW);
  Serial.begin(9600);  
}

void loop ( )  {
  int Jox = map(analogRead(A0), 0, 1023, -100, 100);
  int Joy = map(analogRead(A1), 0, 1023, -100, 100);
  Serial.print(" JoX : ");
  Serial.print(Jox);
  Serial.print("    JoY : ");
  Serial.println(Joy);
   
  if (Jox >= 90 && Joy <= 20 && Joy >= -20)  {
    // 모터 전진
    //모터A
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    //모터B
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);
  }
  else if (Jox <= -90 && Joy <= 20 && Joy >= -20) {
    // 모터 후진
    //모터A
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    //모터B
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed); 
  }
  else if (Joy >= 90 && Jox < 20)  {
    //모터 우회전
    // 모터A 
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    // 모터B 
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);
  }   
  else if (Joy <= -90 && Jox < 20) {
    // 모터 좌회전
    // 모터A 
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    // 모터B 
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed);  
  }

    // 모터 정지
  else {
    analogWrite(A_1A, 0);  
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, 0);
  }
}

 

▶ 프로그램 코드 및 설명 (코드2): 

/* 조이스틱 미니카 제어 (방향 : 상하좌우 & 대각선 제어) */

/* L9110s 모터드라이버 
   오른쪽모터 
   L9110s A_1A 9 
   L9110s A_1B 10 
   왼쪽모터 
   L9110s B_1A 5 
   L9110s B_1B 6 
*/ 
int A_1A = 9; 
int A_1B = 10; 
int B_1A = 5; 
int B_1B = 6; 
int speed = 250;   // speed: 0~ 255 

void setup ( ) {  
  //핀을 초기화 하고, 출력설정 
  pinMode(A_1A, OUTPUT); 
  pinMode(A_1B, OUTPUT); 
  pinMode(B_1A, OUTPUT); 
  pinMode(B_1B, OUTPUT); 
  digitalWrite(A_1A, LOW); 
  digitalWrite(A_1B, LOW); 
  digitalWrite(B_1A, LOW); 
  digitalWrite(B_1B, LOW); 
  Serial.begin(9600);   
} 

void loop ( )  {
  int Jox = map(analogRead(A0), 0, 1023, -100, 100); 
  int Joy = map(analogRead(A1), 0, 1023, -100, 100); 
  Serial.print(" JoX : "); 
  Serial.print(Jox); 
  Serial.print("    JoY : "); 
  Serial.println(Joy); 
    
  if (Jox >= 90 && Joy <= 20 && Joy >= -20)  { 
    // 모터 전진 
    //모터A 
    analogWrite(A_1A, speed); 
    analogWrite(A_1B, 0);     
    //모터B 
    analogWrite(B_1A, speed); 
    analogWrite(B_1B, 0); 
  } 
  else if (Jox <= -90 && Joy <= 20 && Joy >= -20) { 
    // 모터 후진 
    //모터A 
    analogWrite(A_1A, 0); 
    analogWrite(A_1B, speed);     
    //모터B 
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, speed);  
  } 
  else if (Joy>=90 && Jox<20 Jox<=20 && Jox>=-20 && Joy>=90)  { 
    //모터 우회전 
    // 모터A  
    analogWrite(A_1A, 0); 
    analogWrite(A_1B, speed);     
    // 모터B  
    analogWrite(B_1A, speed); 
    analogWrite(B_1B, 0); 
  }    
  else if (Joy<=-90 && Jox<20 Jox<=20 && Jox>=-20 && Joy<=-90) { 
    // 모터 좌회전 
    // 모터A  
    analogWrite(A_1A, speed); 
    analogWrite(A_1B, 0);     
    // 모터B  
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, speed);   
  }

   // 동북방향
  else if ( Jox >= 90 && Joy >= 90 ) {
    analogWrite(A_1A, 120);
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, speed);
    analogWrite(B_1B, 0);  
  }

   // 서북방향
  else if ( Jox >= 80 && Joy <= -80) {    
    analogWrite(A_1A, speed);
    analogWrite(A_1B, 0);    
    analogWrite(B_1A, 140);
    analogWrite(B_1B, 0);  
  }
  
  // 동남방향
  else if ( Jox <= -90 && Joy >= 80) {    
    analogWrite(A_1A, 0);
    analogWrite(A_1B, 120);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, speed);  
  }
  // 서남방향
  else if ( Jox <= -80 && Joy <= -80) {    
    analogWrite(A_1A, 0);
    analogWrite(A_1B, speed);    
    analogWrite(B_1A, 0);
    analogWrite(B_1B, 140);  
  }

   // 모터 정지
  else { 
    analogWrite(A_1A, 0);   
    analogWrite(A_1B, 0);     
    analogWrite(B_1A, 0); 
    analogWrite(B_1B, 0); 
  } 
}

 

▶ 아두이노 파일다운 :

(다운받아서 압축을 풀어 사용하세요)

# 1.  <코딩 1>

L9110_miniCar_JoyII.zip
0.00MB

# 2.  <코딩 2>

L9110_miniCar_JoyIII.zip
0.00MB

 

조립 과정 및 동작 영상 :

아두이노 미니카 제작 영상

[ ▶ 유튜브에서 보기 ]

https://youtu.be/GbwqPd2gi_s

 

반응형
반응형

【 아두이노 기초 】 #27 DC 모터 제어 하기 7

 지난 시간에 DC 모터를 버튼 하나를 이용하여 정회전과 역회전을 시켜보았다. 이번에는 버튼 하나를 더 추가 하여 버튼A를 누르면 좌회전,  버튼B를 누르면 우회전,  버튼 A와 B를 동시에 누르면 역회전을 하는 회로를 실습해보도록 하자. 이 실습을 거치게 되면, RC카의 기본적인 구동원리를 이해하게 된다. 


※ 모터 구동을 도와 주는 H브릿지 IC(L293D)에 대한 설명은 앞의 게시글을 참조.   ( # 24 DC 모터 제어하기 4 바로가기 )  


▶ L293D 모터 제어 드라이버 IC 핀배열 및 구성도 :





▶ 실습 목표 :  

  처음에는 두 개의 모터를 정회전(전진)시키고, 좌버튼(버튼A)을 누르고 있는 동안은 좌회전, 우버튼(버튼B)을 누르고 있는 동안은 우회전,  두 개의 버튼(A&B)을 동시에 누르면 역회전(후진) 시켜서,  버튼 두 개로 마치 RC자동차 처럼 동작 시킬 수 있다. 



▶ 실습 회로도면 :

  (이미지 클릭하면 확대 가능)


※ 모터에 공급되는 별도의 전원은 본인이 실험하는 모터의 용량에 맞추어(4.5V~35V사이) 입력을 하되, 가급적 낮은 전압을 공급하라. 높은 전압은 L293D IC의 높은 발열과 고장의 원인이 되니 주의 할 것!








▶ 부대품 목록 : 아두이노 보드, 브레드 보드


▶ 부품 목록    : L293D IC , DC 모터 x 2 , 푸쉬버튼 x 2 , 가변저항 10KΩ~500KΩ 사이 아무거나


▶ 실습 절차  : 

 1. 회로도를 참고하여 모터 와 부품들을 연결한다.
 
 2. 위 선연결 이미지를 참조 하여 회로 연결을 완성한다. 회로 연결에서 VCC1(IC의 16번 핀)에 아두이노의 +5V 단자를 연결하고, 모터 구동을 위한 VCC2(IC의 8번 핀)에는 모터 구동하기에 무리가 없는 4.5V~36V 사이의 별도 전원을 공급한다. ※ 구동 토크가 크거나, 비교적 큰 모터를 연결하게 되면 L293D IC에 발열이 심하게 나고 나가버릴 수 있으니 주의 할 것.

 3. 회로의 모든 GND(그라운드, - 단자)는 하나로 연결 한다. 

 4. 속도 제어를 위해서는 PWM신호 출력이 가능한 아두이노 포트를 사용해야 한다. (디지털 포트중 '~'물결 무늬가 표시된 포트가 PWM 출력이 가능한 포트 이다)  따라서 IC의 1번핀(Enable 단자)에는 반드시 아두이노의 PWM 포트를 연결하도록 한다. (~3,~5,~6,~9,~10,~11 포트 중 아무거나 사용해도 무방) 

 5. 모터 연결선 +,- 두 가닥은 PWM 기능과는 무관 함으로 디지털 포트 중, 아무 포트에 연결 하도록 한다. 

 6. 스위치 역활을 할 수 있는 푸쉬 버튼을 아두이노 남는 포트에 연결 한다. 
 (만약 푸쉬 버튼이 없을 경우 점퍼선으로 대체 가능하다)


▶ 프로그램 (코드& 설명) : 


#define btnFront 0  // '버튼정지' 변수를 '0'의 숫자값으로 정의

#define btnLeft  1

#define btnRight 2

#define btnBack  3

int in1=7;  

int in2=8;

int in3=12; 

int in4=13;

int btnL= 9;  // 모터 방향 변경을 위한 버튼 변수 선언

int btnR=10;  // 모터 방향 변경을 위한 버튼 변수 선언

int Direction; // 모터 방향 변수

int MotorL=6;  // 왼쪽 모터

int MotorR=11; // 오른쪽 모터

int pwm;      // 모터 회전 속도 변수


void setup() {

  pinMode(in1, OUTPUT);  // L293D의 1번 채널의 입력 1

  pinMode(in2, OUTPUT);  // L293D의 1번 채널의 입력 2

  pinMode(in1, OUTPUT);  // L293D의 2번 채널의 입력 1

  pinMode(in2, OUTPUT);  // L293D의 2번 채널의 입력 2

  pinMode(MotorA, OUTPUT);

  pinMode(MotorBOUTPUT);

  pinMode(btnL, INPUT_PULLUP); //좌버튼 입력을 내부풀업 입력으로설정

  pinMode(btnR, INPUT_PULLUP); //우버튼 입력을 내부풀업 입력으로설정    

}


void loop() {

  boolean btnL_HL = digitalRead(btnL);  // 좌측 버튼의 논리값 저장

  boolean btnR_HL = digitalRead(btnR); // 우측 버튼의 논리값 저장

  pwm = analogRead(A0)/4;                // 0~256 값을 넣기 위해 '/4' 


 // 버튼 누름에 따른 비교문(if)과 , Case 선택문 실행

if ( btnL_HL == HIGH && btnR_HL == HIGH) 

  {

  Direction = 0;  

  }

else if ( btnL_HL == LOW && btnR_HL == HIGH) 

  {

  Direction = 1;   

  }

else if ( btnL_HL == HIGH && btnR_HL == LOW) 

  {

  Direction = 2;   

  }

else if ( btnL_HL == LOW && btnR_HL == LOW) 

  {

  Direction = 3;   

  }


switch (Direction)

{

  case btnFront             // 전진  [ L, R 모터 정회전 ]

  {

  analogWrite(MotorL, pwm);

  digitalWrite(in1, HIGH);

  digitalWrite(in2, LOW);

  analogWrite(MotorR, pwm);

  digitalWrite(in3, HIGH);

  digitalWrite(in4, LOW);     

  break;      

  }

 

  case btnLeft :                 // 좌회전 [ L모터 정지, R모터 전진 ]

  {

  analogWrite(MotorL, pwm);

  digitalWrite(in1, LOW);

  digitalWrite(in2, LOW);

  analogWrite(MotorR, pwm);

  digitalWrite(in3, HIGH);

  digitalWrite(in4, LOW); 

  break;    

  }

case btnRight :                 // 우회전 [ L모터 전진, R모터 정지 ]

  {

  analogWrite(MotorL, pwm);

  digitalWrite(in1, HIGH);

  digitalWrite(in2, LOW);

  analogWrite(MotorR, pwm);

  digitalWrite(in3, LOW);

  digitalWrite(in4, LOW); 

  break;

  }

  case btnBack :                  // 후진 [ L, R 모터 역회전 ]

  {

  analogWrite(MotorL, pwm);

  digitalWrite(in1, LOW);

  digitalWrite(in2, HIGH);

  analogWrite(MotorR, pwm);

  digitalWrite(in3, LOW);

  digitalWrite(in4, HIGH); 

  break;

  } 

 }

}

 

▶ 실행 영상 : 





▶ 아두이노 소스 코드 다운로드 : 


DCmortorAB_2Button.ino




반응형