반응형
Notice
Recent Posts
Recent Comments
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Web Control
- 3D Printing
- 라즈베리파이
- Drawing Machine
- raspberry pi
- Laser Engraver
- XY Plotter
- miniMe
- CnC
- 카메라
- WiFi Control
- Balancing Robot
- 3D modeling
- GRBL
- Arduino
- WeMos D1 mini
- esp8266
- 4xiDraw
- CoreXY
- AxiDraw
- Robot Platform
- 3D Design
- concept
- 원격제어
- Robonoid
- 로봇
- remote control
- 3D Printer
- Drawing Robot
- Bluetooth Control
Archives
- Today
- Total
Zalophus's DesignHouse
Wii 리모컨(Wiimote)으로 RC Car 조종하기 본문
반응형
이젠 벽돌이 되어버린 니텐도 Wii를 바라보다 갑자기 아깝다는 생각이 들어 폭풍 검색을 하다가 Wii 리모컨을 활용할 수 있는 괜찮은 소스를 찾은 것 같아 아래와 같이 소개 합니다.
잘~ 응용하면 재밋는 장난감이 되겠네요.
Circuit@Home에서 소개 받았습니다!
RC car controlled by Wii Remote on Arduino
곳곳에서 Wii 리모컨을 사용한 재미있는 프로젝트를 볼 수 있습니다. PC에서 Bluetooth Stack를 이용한 프로젝트는 많은 있지만, PC를 사용하지 않고 마이컴 (AVR, PIC)에서 Bluetooth Stack를 이용한 프로젝트는 적은 것 같습니다. 그래서 (새삼 느낌입니다 만...) 마리오 카트를 조종하는 느낌으로 무선조종을 만들어 보았습니다. #바나나를 던지거나 하지는 않습니다.
하드웨어 (Hardware)
Arduino에서 Bluetooth Stack을 실현하여 무선조종서보와 ESC를 제어합니다.
송신기 (Transmitter)
- Wii 리모컨 (Wiimote)
수신기 (Reciver)
- Arduino
- USB Host Shield
- Bluetooth USB 어댑터 (Dongle)
통신 거리는 Bluetooth 특성상 대략 10m 정도 밖에 안될 거라고 예상합니다. 통신 거리를 늘리려면 XBee 등을 사용해야 할 것 입니다.
소프트웨어 (Software)
Arduino 용 라이브러리는 에 있습니다.
이 라이브러리는 Richard Ibbotson이 만든 코드 을 기반으로하고 있습니다.
또한 이 라이브러리를 사용하기 위해서는, Oleg Mazurov가 개발 한 가 필요합니다.
샘플 스케치 (Sketch)
SterringWii.ino
#include "WiiRemote.h"#include <MemoryFree.h>#include <Servo.h>#define PIN_STEERING_SIGNAL 2#define PIN_ESC_SIGNAL 3#define SERIAL_DEBUG 0enum eAngle { STEERING_ANGLE_MAX = 165, // to right STEERING_ANGLE_MIN = 15, // to left STEERING_ANGLE_CENTER = 90, STEERING_ANGLE_STEP = 5, THROTTLE_ANGLE_MAX = 80, THROTTLE_ANGLE_MIN = 10, THROTTLE_ANGLE_CENTER = 90,};enum eServoPulse { SERVO_PULSE_NEUTRAL = 1500, // Futaba compatible, 1.55msec SERVO_PULSE_MAX = 1800, // to left SERVO_PULSE_MIN = 1200, // to right};enum eESCPulse {/* * Futaba timing * * 0us 1072us 1522us 1922us * +---------*------------+-*-+-------------* * | n/a | forwad |d|d| Reverse | * +---------*------------+-*-+-------------* * Max Forwad Neutral Max Reverse * * d: dead zone, +10us and -10us */ ESC_PULSE_NEUTRAL = 1522, ESC_PULSE_BRAKE = 1600, ESC_PULSE_FWD_MAX = 1200, // 1072 ESC_PULSE_FWD_MIN = 1510, ESC_PULSE_FWD_3RD = (ESC_PULSE_FWD_MIN - 200), ESC_PULSE_FWD_2ND = (ESC_PULSE_FWD_MIN - 140), ESC_PULSE_FWD_1ST = (ESC_PULSE_FWD_MIN - 80), ESC_PULSE_REV_FIX = 1650, ESC_PULSE_REV_MAX = 1700, // 1922 ESC_PULSE_REV_MIN = 1600,};enum eGear { GEAR_1ST = 1, GEAR_2ND = 2, GEAR_3RD = 3,};WiiRemote wiiremote;Servo SteeringServo;Servo ESC;void setup(){#if SERIAL_DEBUG Serial.begin(9600); Serial.print("\r\nfreeMemory() reports: "); Serial.print(freeMemory(), DEC);#endif SteeringServo.attach(PIN_STEERING_SIGNAL); SteeringServo.writeMicroseconds(SERVO_PULSE_NEUTRAL); ESC.attach(PIN_ESC_SIGNAL); ESC.writeMicroseconds(ESC_PULSE_NEUTRAL); wiiremote.init(); /* unsigned char wiiremote_bdaddr[6] = {0x00, 0x1e, 0x35, 0xda, 0x48, 0xbc}; wiiremote.setBDAddress(wiiremote_bdaddr, 6); wiiremote.setBDAddressMode(BD_ADDR_FIXED); */}void loop(){ wiiremote.task(&myapp);}int steering_angle = STEERING_ANGLE_CENTER;int old_steering_angle = STEERING_ANGLE_CENTER;bool analog_throttle = false; // false = use "One" button as throttleint throttle_angle = THROTTLE_ANGLE_CENTER;int gear = GEAR_1ST;int pulse_steering;int pulse_esc;void myapp(void) {#if SERIAL_DEBUG Serial.print("\r\n");#endif /* Steering */ steering_angle = getSteeringAngle(); pulse_steering = map(steering_angle, STEERING_ANGLE_MIN, STEERING_ANGLE_MAX, SERVO_PULSE_MAX, SERVO_PULSE_MIN); SteeringServo.writeMicroseconds(pulse_steering); //delay(15); Serial.print("\tServo="); Serial.print(pulse_steering); /* Brake and Throttle */ if (wiiremote.buttonPressed(WIIREMOTE_ONE)) { if (pulse_esc < ESC_PULSE_NEUTRAL) { // moving forward before press "One" brake(); pulse_esc = ESC_PULSE_NEUTRAL; } else { // while stopping or moving backward, keep moving backward pulse_esc = ESC_PULSE_REV_FIX; } } else { if (analog_throttle) { throttle_angle = getThrottleAngle(); pulse_esc = map(throttle_angle, THROTTLE_ANGLE_MIN, THROTTLE_ANGLE_MAX, ESC_PULSE_FWD_MIN, ESC_PULSE_FWD_MAX); } else if (wiiremote.buttonPressed(WIIREMOTE_TWO)) { switch (gear) { case GEAR_1ST: pulse_esc = ESC_PULSE_FWD_1ST; break; case GEAR_2ND: pulse_esc = ESC_PULSE_FWD_2ND; break; case GEAR_3RD: pulse_esc = ESC_PULSE_FWD_3RD; break; default: pulse_esc = ESC_PULSE_NEUTRAL; break; } } else { pulse_esc = ESC_PULSE_NEUTRAL; } } ESC.writeMicroseconds(pulse_esc); //delay(15); Serial.print("\tESC="); Serial.print(pulse_esc); /* Throttle mode */ if (wiiremote.buttonClicked(WIIREMOTE_A)) { analog_throttle = !analog_throttle; if (analog_throttle) { wiiremote.setLED(WIIREMOTE_LED4); // analog mode } else { wiiremote.setLED(WIIREMOTE_LED1); // fixed mode, 1st gear gear = GEAR_1ST; } } /* Shift up or down */ if (!analog_throttle) { if (wiiremote.buttonClicked(WIIREMOTE_RIGHT)) { shiftUp(); } else if (wiiremote.buttonClicked(WIIREMOTE_LEFT)) { shiftDown(); } }} // myappint getSteeringAngle(void) { double rad; int deg; rad = acos((double) wiiremote.Report.Accel.Y); deg = (int) (rad * 180.0 / PI); /* clipping */ if (deg > STEERING_ANGLE_MAX) { deg = STEERING_ANGLE_MAX; } if (deg < STEERING_ANGLE_MIN) { deg = STEERING_ANGLE_MIN; } return deg;}int getThrottleAngle(void) { double rad; double compensate_z; int deg; rad = asin((double) wiiremote.Report.Accel.Y); compensate_z = (double) wiiremote.Report.Accel.Z / cos(rad); rad = asin(compensate_z); deg = (int) (rad * 180.0 / PI); /* clipping */ if (deg > THROTTLE_ANGLE_MAX) { deg = THROTTLE_ANGLE_MAX; } if (deg < THROTTLE_ANGLE_MIN) { deg = THROTTLE_ANGLE_MIN; } return deg;}inline void brake(void){ ESC.writeMicroseconds(ESC_PULSE_BRAKE); delay(15); ESC.writeMicroseconds(ESC_PULSE_NEUTRAL); delay(15);}inline void shiftUp(void){ if (gear < GEAR_3RD) { gear++; wiiremote.setLED( (WIIREMOTE_LED1 << (gear - GEAR_1ST)) ); }}inline void shiftDown(void){ if (gear > GEAR_1ST) { gear--; wiiremote.setLED( (WIIREMOTE_LED1 << (gear - GEAR_1ST)) ); }}반응형
'Arduino' 카테고리의 다른 글
| 28BYJ-48 Stepper Motor (0) | 2016.12.23 |
|---|---|
| Wii 리모컨(Wiimote)으로 RC Car 조종하기 - 2WS (Tamiya M-03) (0) | 2016.06.27 |
Comments