산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

낡은 RC카를 아두이노와 엑스박스 컨트롤러로 조종하는 차량으로 개조하기

필요한 부품 및 소모품

부품 수량 비고
아두이노 우노 1 메인 컨트롤러
아두이노 USB 호스트 쉴드 1 무선 리시버 연결용
엑스박스 360 무선 컨트롤러 1 조작용
엑스박스 360 무선 리시버 1 USB 호스트 쉴드에 연결
L293D 모터 드라이버 (또는 SN754410) 2개 각 모터당 1개 (H-브리지)
7812 전압 레귤레이터 1 로직 전원용 12V 출력
78S12 고전류 전압 레귤레이터 1 모터 구동용 12V 출력 (2A 이상)
스위치 1 전원 온/오프
방열판 1세트 레귤레이터 발열 해소용
전원 플러그 및 배터리 커넥터 각 1 AA 배터리 8~12개 직렬 연결용

프로젝트 개요

낡은 RC카의 기존 제어 회로를 제거하고 아두이노 + USB 호스트 쉴드 + 엑스박스 360 무선 리시버 조합으로 무선 조종이 가능하게 개조합니다. L293D 드라이버 2개로 구동 모터(전진/후진)와 조향 모터(좌/우)를 각각 제어하며, 배터리 전압을 7812/78S12로 강압해 아두이노와 모터에 공급합니다.

단계별 제작 과정

1. RC카 분해

구형 RC카(몬스터 트럭 권장)에서 기존 제어 기판을 모두 제거하고 구동 모터 2개와 조향 모터 1개의 선만 남깁니다.

2. 아두이노 + USB 호스트 쉴드 장착

아두이노 우노 위에 USB 호스트 쉴드를 적층하고 차체 빈 공간에 고정합니다. 기존 기판 고정 홀을 활용하면 편리합니다.

3. 회로 구성 (브레드보드 또는 퍼프보드)

전원부: AA 1.5V 배터리 10~12개 직렬(15~18V) → 78S12(모터용 12V, 대용량) / 7812(로직용 12V) → 각 레귤레이터 출력을 모터 드라이버 VCC2, 아두이노 VIN 등에 분배. 방열판 필수.

모터 드라이버부: L293D 2개 사용. 각 드라이버의 입력 핀을 아두이노 PWM 핀(5, 6번: 구동 / 4, 7번: 조향)에 연결. 인에이블 핀은 PWM으로 속도 제어.

4. 차체에 회로 장착 및 배선

구동 모터 2개는 병렬로 첫 번째 L293D에, 조향 모터는 두 번째 L293D에 연결. 무선 리시버를 USB 호스트 쉴드에 꽂습니다.

소스 코드 (핵심 로직)

Kristian Lauszus의 USB Host Shield 2.0 라이브러리의 Xbox 예제를 기반으로 수정했습니다.

주요 핀 매핑

#define motorPinOne 5   // 구동 모터 PWM 1
#define motorPinTwo 6   // 구동 모터 PWM 2
#define motor2PinOne 4  // 조향 모터 제어 1
#define motor2PinTwo 7  // 조향 모터 제어 2
#define BRAKE 2         // 브레이크 제어 핀

컨트롤러 매핑

핵심 함수

전체 코드

/* Xbox Wireless Receiver 라이브러리 예제 기반 수정 */
#include <XBOXRECV.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
USB Usb;
XBOXRECV Xbox(&Usb);

#define motorPinOne 5
#define motorPinTwo 6
#define motor2PinOne 4
#define motor2PinTwo 7
#define BRAKE 2

int pulse = 0;
int forward = 0;
int brake_on = 0;

void setup() {
  TCCR1B = TCCR1B & 0b11111000 | 0x02; // PWM 주파수 조정
  Serial.begin(115200);
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while(1); // halt
  }
  Serial.print(F("\r\nXbox Wireless Receiver Library Started"));
  pinMode(motorPinOne, OUTPUT);
  pinMode(motorPinTwo, OUTPUT);
  pinMode(motor2PinOne, OUTPUT);
  pinMode(motor2PinTwo, OUTPUT);
  pinMode(BRAKE, OUTPUT);
  digitalWrite(BRAKE, LOW);
  motors_stop();
  center();
}

void loop() {
  Usb.Task();
  if (Xbox.XboxReceiverConnected) {
    for (uint8_t i = 0; i < 4; i++) {
      // L2: 후진
      if (Xbox.getButtonPress(L2, i)) {
        pulse = Xbox.getButtonPress(L2, i);
        forward = 0;
        clockwise();
      }
      // R2: 전진
      if (Xbox.getButtonPress(R2, i)) {
        pulse = Xbox.getButtonPress(R2, i);
        forward = 1;
        counterClockwise();
      }
      // 아날로그 스틱: 조향
      if (abs(Xbox.getAnalogHat(LeftHatX, i)) > 7500 || 
          abs(Xbox.getAnalogHat(LeftHatY, i)) > 7500 || 
          abs(Xbox.getAnalogHat(RightHatX, i)) > 7500 || 
          abs(Xbox.getAnalogHat(RightHatY, i)) > 7500) {
        if (Xbox.getAnalogHat(LeftHatX, i) > 7500) {
          if (Xbox.getAnalogHat(LeftHatX, i) > 26000) turn_right();
          else center();
        }
        if (Xbox.getAnalogHat(LeftHatX, i) < -7500) {
          if (Xbox.getAnalogHat(LeftHatX, i) < -26000) turn_left();
          else center();
        }
      }
      // 버튼들
      if (Xbox.getButtonClick(B, i)) { // 급브레이크
        digitalWrite(BRAKE, HIGH);
        brake_on = 1;
        pulse = 100;
        if (forward) clockwise(); else counterClockwise();
      }
      if (Xbox.getButtonClick(Y, i)) motors_stop(); // 정지
      if (Xbox.getButtonClick(XBOX, i)) {
        Xbox.setLedMode(ROTATING, i);
      }
      // 기타 버튼(UP, DOWN, A, X 등)은 시리얼 출력만
    }
  }
  delay(1);
}

void clockwise() { // 전진
  analogWrite(motorPinOne, pulse);
  analogWrite(motorPinTwo, 0);
  if (brake_on) { delay(600); digitalWrite(BRAKE, LOW); brake_on = 0; pulse = 0; }
}
void counterClockwise() { // 후진
  analogWrite(motorPinOne, 0);
  analogWrite(motorPinTwo, pulse);
  if (brake_on) { delay(600); digitalWrite(BRAKE, LOW); brake_on = 0; pulse = 0; }
}
void turn_left() { digitalWrite(motor2PinOne, HIGH); digitalWrite(motor2PinTwo, LOW); }
void turn_right() { digitalWrite(motor2PinOne, LOW); digitalWrite(motor2PinTwo, HIGH); }
void motors_stop() { analogWrite(motorPinOne, 0); analogWrite(motorPinTwo, 0); pulse = 0; }
void center() { digitalWrite(motor2PinOne, LOW); digitalWrite(motor2PinTwo, LOW); }

라이브러리 및 참고 자료

제조공정

  1. 블루투스 제어 라즈베리 파이 로봇 만들기 - 오디오 피드백 포함
  2. 제스처 제어 RGB 테이블 램프 – 인터랙티브 핸즈프리 조명
  3. 라즈베리 파이와 알렉사로 LED 제어하기 – 초보자를 위한 단계별 가이드
  4. 아두이노 메가 기반 닌텐도 눙크 컨트롤 6자유도 로봇 암 키트
  5. 아두이노 나노와 조이스틱으로 2개 스테퍼 모터 제어하기 – 비주이노(Visuino) 튜토리얼
  6. 아두이노 나노로 만드는 음성 제어 로봇 - 블루투스와 안드로이드 앱 활용
  7. 스마트 주차 카운터: 아두이노, 프로세싱, PHP로 실시간 차량 추적
  8. 피봇(PiBot): 아두이노 기반 88건반 피아노 연주 로봇
  9. Wi-Servo: 웹 브라우저로 와이파이 서보 모터 제어하기
  10. 게이밍용 커스텀 아두이노 조이스틱 스티어링 휠 만들기