MobBob V2 Remix – Smart Phone Controlled Robot

[Update 20160111]
Add test video and photos

[Update 20160109]
Modify MobBob2_Remix_Jacket_L.stl
Modify MobBob2_Remix_Jacket_R.stl
Modify MobBob2_Remix_Battery_Mount_Cover.stl

[Update 20160105]
Add Shield board file Arduino_Nano_Shield_REV3.brd [Eagle CAD file]
Add modified source code MobBob2_Remix_Contol_Bluetooth.ino to .zip

[Upgrade 20160104]
Redesign Foot
MobBob2_Remix_Foot_L_Top.stl
MobBob2_Remix_Foot_L_Floor.stl
MobBob2_Remix_Foot_R_Top.stl
MobBob2_Remix_Foot_R_Floor.stl

[Update 20160102]
Add MobBob2_Remix_Cap.stl
Add MobBob2_Remix_Battery_Mount_Cover.stl
Add MobBob2_Remix_Jacket_L.stl
Add MobBob2_Remix_Jacket_R.stl

[Update 20151231]
Add Photos
Add 18650_Battery_Bank_2x_r01.stl
Add 18650_Battery_Bank_2x_Cover_swC_r01.stl


Smart Phone Controlled Robot – MobBob V2 Remix


3D Design Tool: SketchUp Pro
Design concept: RAPIRO – The Humanoid Robot and Gundam

This is an remix version of my MobBob robot.

MobBob is a smart phone controlled robot. By harnessing the power of your smart phone, MobBob is a walking, talking robot with voice recognition and computer vision that you can build for around $20. I will be continuing to extend his features over time. I want MobBob to be a companion robot that everyone can afford and have fun with.

You can see videos of MobBob V2 Remix in action here:
https://youtu.be/fE7024whSF8
https://youtu.be/aZaUMOi9q0k
https://youtu.be/LGFUjzvBPuI
…..
Coming soon!!

The main aims of the V2 remix were to:

Support standard 9g servos [previously I was using Tower Pro SG90 servos]
Make everything easier to assemble [no more need for glue]
Make it easier to adapt/modify for other phones. The new bracket system made it easier to exchange a new phone / the battery holder.

Also, in my V2 Remix build, I’m also using the Arduino Nano instead of the DIY Nano shield, so the entire build is smaller and tidier. 🙂

MobBob V2 Remix uses the same software as the original MobBob V2.

You can find the latest Arduino code here: https://github.com/cevinius/MobBob
The modified code is included: MobBob2_Remix_Control_Bluetooth.ino

You can download the latest version of the Android app from Google Play – it is free, ad-free, and without IAP:
https://play.google.com/store/apps/details?id=com.cevinius.MobBob

You can find more detailed build and wiring instructions here:
…coming soon…

The parts that you need to print:

1 x Leg Left
1 x Leg Right
1 x Foot Left………………………………Delete
1 x Foot Right…………………………….Delete
1 x Foot Cover Left……………………..Delete
1 x Foot Cover Right……………………Delete
1 x Foot Left Top
1 x Foot Right Top
1 x Foot Left Floor
1 x Foot Right Floor
1 x Waist
1 x Arduino Nano Holder
1 x Phone Mount Base
2 x Phone Mount Side
1 x Phone Mount Gear
1 x Phone Mount Back Plate
1 x Phone Mount Conn
2 x Phone Mount Bolt
2 x Phone Mount Nut
1 x Battery Bank Rack [18650 x 2]
1 x Battery Mount Cover
1 x Jacket Left
1 x Jacket Right
1 x Cap

The non-3D printed parts you need are:

4 x Tower Pro SG90 servos
1 x Arduino Nano ATmega328 [see note below]
1 x HM-10 BLE Bluetooth 4.0 CC2540 CC2541 Serial Wireless Module
1 x 5V Micro USB 1A Lithium Battery Charging Board [see note below]
1 x DC-DC Converter Step Up Boost Module 2-5V to 5V 1.2A
1 x Rectangle On/Off Long Rocker Switch SPST
2 x Snap-In Single ‘A’-‘AA’ Battery Contacts 209 [KEYSTONE ELECTRONICS CORP.]
2 x Snap-In Single ‘A’-‘AA’ Battery Contacts 228 [KEYSTONE ELECTRONICS CORP.]
2 x 18650 Lithium ion Batteries
1 x 300mm USB 2.0 A Male to Micro USB B 5pin + Mini B Male Y Splitter Cable
1 x Smart Phone [see note below]
4 x M3 5mm [for Foot Cover]
2 x M2 10mm [for Phone Connect]
4 x M2 5mm [for Phone Mount Back Plate]
2 x 2mm 5mm Tapping screw [for Foot servos]
2 x 2mm 8mm Tapping screw [for Hip servos]
2 x 1mm 5mm Tapping screw [for Foot servos hone]
2 x 1mm 8mm Tapping screw [for Hip servos hone]
2 x M3 15mm [for Jacket]
2 x M3 Nut [for Jacket]
4 x 2mm 15mm Tapping screw [for Jacket]
[Note: I got the servos, Arduino Nano, Bluetooth Module and Battery for under $30.]

Arduino Nano:

This is a small, Arduino compatible ATmega328 board with DIY extension board. MobBob V2 app connects to the Bluetooth module using its Bluetooth LE service. The app to support other Bluetooth cards.

Battery Extender:

You can use other batteries that provide 5V with a steady current. If you use other batteries, you may need to adapt the battery rack for your battery’s size.
Use 18650 Lithium Battery Charging Board With Protection Charger Module and Step Up Boost Module 3.7V to 5V for Smart Phone
http://www.thingiverse.com/thing:1235749

Smart Phone:

You can use other Android Smart Phones with This app.
You do not need to adapt the size of the phone holder for your phone. The app has been successfully tested with Nexus and Samsung, LG phones, but should work on other Android phones.

Instructions:

Print all the required parts
Get all the non-3D printed parts
Assemble as per the photos – I’ll be writing some more detailed instructions on my website soon!
Install the Arduino code from the GitHub link in the description – You will need to update the Arduino pins in the code to match yours, and probably update the centering values for the servos.
Install the Android app from the link in the description.

Have fun!

If you hit any problems, please post a question on this website: [http://www.cevinius.com], here, or on YouTube channel. A few people have built MobBobs now, so there are people around who can help.

Coming soon update!!


Print Settings


Printer: PANDORA DXs – DIY 3D Printer
Slicer: Cura 15.04.2

Layer height (mm): 0.1
Shell thickness (mm): 0.8

Bottom/Top thickness (mm): 1.2
Fill Density (%): 00

Print speed (mm/s): 50
Print temperature: 200
Bed temperature: 70

Support type:

  • Touching buildplate:
    MobBob2_Remix_Phone_Mount_Side.stl,
    MobBob2_Remix_Phone_Mount_Nut_L.stl,
    MobBob2_Remix_Phone_Mount_Nut_R.stl,
    MobBob2_Remix_Phone_Mount_Conn.stl,
    18650_Battery_Bank_2x_Cover_swC_r01.stl
  • Everywhere:
    MobBob2_Remix_Nano_Shield_Holder.stl
    MobBob2_Remix_Battery_Mount_Cover.stl
    MobBob2_Remix_Jacket_L.stl
    MobBob2_Remix_Jacket_R.stl

Platform adhesion type: Brim

Filament: PLA
Filament Diameter (mm): 1.75


3D Files:

https://www.thingiverse.com/thing:1232619

Low-Cost, Arduino-Compatible Drawing Robot

I designed this project for a 10-hour workshop for ChickTech.org whose goal is to introduce teenage women to STEM topics. The goals for this project were:

  • Easy to build.
  • Easy to program.
  • Did something interesting.
  • Low-cost so participants could take it home and continue to learn.

With those goals in mind, here were a couple of the design choices:

  • Arduino compatible for ease of programming.
  • 4xAA battery power for cost and availability.
  • Stepper motors for accurate motion.
  • 3D Printed for ease of customization.
  • Pen plotting with Turtle graphics for interesting output.
  • Open Source so you could make one of your own!

Here is the robot that came closest to what I wanted to do: http://mirobot.io. I don’t have a laser cutter and shipping from England was prohibitive. I do have a 3D printer, so I guess you can see where this is going . . .

Don’t let the lack of a 3D printer deter you. You can locate local hobbyists willing to help you out at https://www.3dhubs.com/.

It took a lot of work, but I’m please with how it turned out. And, I learned quite a bit in the process. Let me know what you think!

Step 1: Parts

There are a number of ways to power, drive, and control robots. You may have different parts on hand that will work, but these are the ones I’ve tried and found to work well:

Electronics:

*Note: See the last step for a discussion on using regular Arduino or Raspberry Pi boards.

Hardware:

3D-Printed Parts (check out www.3dhubs.com if you don’t have access to a printer):

Tools and Supplies:

  • Phillips screw driver
  • Hot glue gun
  • Digital multi-meter
  • Sharp knife
  • Crayola colored markers

Step 2: Flash the Firmware

Before we get too far into construction, lets load the test firmware on to the microcontroller. The test program just draws for boxes so we can check for proper direction and dimension.

To talk to the Trinket Pro, you are going to need:

  1. Driver from https://learn.adafruit.com/introducing-pro-trinket…
  2. Arduino software from https://learn.adafruit.com/introducing-pro-trinket…

Lady Ada and the Adafruit team have created a far better set of instructions in the links above than I can provide. Please use them if you are stuck.

Note: The one trick that makes the Trinket different from regular Arduino is that you have to reset the board before uploading the sketch.

Step 3: Pen Holder and Battery Holders

  1. Install the Pen Holder with the Servo Bracket on the shorter side of the chassis (Image 1).
  2. Insert the nuts on the top side of the chassis (Image 2)
  3. Attach the battery holders on the bottom of the chassis using 3Mx6mm flat-head screws (Images 3 & 4).
  4. Thread the battery leads through the rectangular cable runs (Image 4 & 5).
  5. Repeat for the other battery holder.

Note: Unless specified, the remainder of the screws are 3Mx8mm pan head srews.

Step 4: Wheels

  1. Test fit your wheel to the stepper shaft (Image 1).
    1. If it is too tight, you can heat the wheel hub with a hair drier or hot air gun and then insert the shaft.
    2. If it is too loose, you can use a 3Mx8mm screw to hold it against the flat of the shaft (Image 2).
    3. If you are a perfectionist, you can calibrate your printer and get it just right.
  2. Place the o-ring around the rim of the wheel (Image 3 & 4).
  3. Repeat for the other wheel.

Step 5: Stepper Brackets

  1. Insert a nut into the stepper bracket and attach them to the top of the chassis with a screw (Image 1).
  2. Insert the stepper into the bracket and attach with screws and nuts.
  3. Repeat for the other bracket.

Step 6: Caster

  1. Insert the ball bearing into the caster.
    • Do not force it in or it will break. Use a hair-drier or hot air gun to soften the material if needed.
  2. Attach the caster to the bottom side of the chassis in front of the battery holder.

Step 7: Breadboard

  1. Remove one of the power rails using a sharp knife, cutting through the bottom adhesive (Image 1).
  2. Holding the breadboard over the chassis rails, mark where they intersect the edge (Image 2).
  3. Using a straight edge (like the removed power rail), mark the lines and cut through the backing (Image 3).
  4. Place the breadboard on the chassis with the rails touching the exposed adhesive (Image 4).

Step 8: Power

  1. Place the microcontroller, darlington driver, and power switch on to the bread board (Image 1).
    • I’ve added orange dots for visibility to mark the following:
      • Pin 1 of the darlington driver.
      • The battery pin of the microtroller.
      • The power switch “on” position.
  2. With the right-hand battery leads:
    1. Connect the red line to the first pin of the power switch (Image 2).
    2. Connect the black lead to an empty row between the microcontroller and the darlington chip (Image 2).
  3. With the left-hand battery leads:
    1. Connect the red line to the same row as the black lead of the other battery (Image 3).
    2. Connect the black line to the negative rail of the breadboard (Image 3).
  4. Connect power to the microcontroller:
    1. Red jumper from positive rail to the battery pin (orange dot, Image 4).
    2. Black jumper from the negative rail to the pin marked “G” (Image 4).
  5. Install batteries and switch the power on. You should see the green and red lights of the controller come on (Image 5).

Troubleshooting: If the microcontroller lights do not come on, immediately turn the power off and troubleshoot:

  1. Batteries installed in the correct orientation?
  2. Double check battery leads positioning.
  3. Double check switch leads positioning.
  4. Use a multi-meter to check voltages of batteries.
  5. Use multi-meter to check power rail voltages.

Step 9: Headers and Servo wiring

Male header pins allow us to connect the 5-pin servo JST connectors to power and the darlington driver (Image 1):

  1. The first 5-pin header starts one row in front of the darlington driver.
  2. The second servo header should then line up with the end of the darlington driver.

Before the wiring gets to complicated, lets get the servo wired up:

  1. Add a 3-pin header for the servo on the right edge of the forward section of the breadboard( Image 2).
  2. Add a red jumper from the center pin to the positive side of the power rail.
  3. Add a black or brown jumper from the outer pin to the negative side of the power rail.
  4. Add a colored jumper from the inner pin to Pin 8 of the microcontroller.
  5. Install the servo horn with the shaft to the full clock-wise position and the arm extending to the right-side wheel (Image 3)
  6. Install the servo in the pen holder using the servo’s screws (Image 3).
  7. Connect the servo connector aligning the colors (Image 4).

Step 10: Stepper Control

Time to wire power for the darlington driver and steppers, which will be driven directly from the battery:

  1. Connect a black or brown jumper from the lower right darlington pin to the negative side of the power rail (Image 1).
  2. Connect a red jumper from the upper right darlington pin to the positive side of the power rail.
  3. Connect a red jumper from the upper left pin header to the positive side of the power rail (Image 2).
  4. Connect the left stepper connector to the left side pin header with the red lead on the right side (Image 3).
  5. Connect the right stepper connector to the right side pin header with the read lead on the left side.

Note: The red lead of the stepper connector is the power and should match the red leads on the breadboard.

Step 11: Stepper Control (Continued)

Now we will connect the stepper signal wires from the microcontroller to the input side of the darlington driver:

  1. Starting with Pin 6 of the microcontroller, connect the leads for four control jumpers for the left stepper motor (Image 1).
  2. Match these jumpers to the input side of the darlington on the right. All colors should match with the exception of green, which matches the pink wire of the stepper (Image 2).
  3. Starting with Pin 13 of the microcontroller, connect the leads for the four control jumpers for the right stepper motor (Image (3).
  4. Match these jumpers to the input side of the darlington on the left. All colors should match with the exception of green, which matches the pink wire of the stepper (Image 3).

Step 12: Testing and Calibration

Hopefully you already uploaded the firmware in Step 2. If not, do it now.

The test firmware just draws a square repeatedly so we can check direction and accuracy.

  1. Place your robot on a smooth, flat, open surface.
  2. Turn the power on.
  3. Watch your robot draw squares.

If you are not seeing lights on the microcontroller, go back and troublshoot power as in Step 8.

If your robot is not moving, double check the power connections to the darlington driver in Step 9.

If your robot is moving erratically, double check the pin connections for the microcontroller and darlington driver in Step 10.

If your robot is moving in an approximate square, it is time to put some paper down and put a pen in it (Image 1).

Your calibration points are:

float wheel_dia=66.25;  // mm (increase = spiral out)
float wheel_base=112;   // mm (increase = spiral in)
int steps_rev=128;      // 128 for 16x gearbox, 512 for 64x gearbox

I started with a measured wheel diameter of 65 mm and you can see the boxes rotating inward (Image 2).

I increased the diameter to 67, and you can see it was rotating outward (Image 3).

I eventually arrived at a value of 66.25 mm (Image 4). You can see that there is still some inherent error due to gear lash and such. Close enough to do something interesting!

Step 13: Raising and lowering the pen

We’ve added a servo, but haven’t done anything with it. It allows you to raise and lower the pen so the robot can move without drawing.

  1. Place the pen collar on the pen (Image 1).
  2. If it is loose, tape it in place.
  3. Check that it will touch the paper when the servo arm is lowered.
  4. Check that it will not touch the paper when raised (Image 2).

The servo angles can be adjusted either by removing the horn and re-positioning it, or through the software:

int PEN_DOWN = 170; // angle of servo when pen is down
int PEN_UP = 80;    // angle of servo when pen is up

The pen commands are:

penup();
pendown();

Step 14: Have Fun!

I hope you made is this far without too many curse words. Let me know what you struggled with so I can improve the instructions.

Now it is time to explore. If you look at the test sketch, you will see I have provided you some standard “Turtle” commands:

forward(distance);   // millimeters
backward(distance);
left(angle);         // degrees
right(angle);
penup();
pendown();
done();              // release stepper to save battery

Using these commands, you should be able to do just about anything, from drawing snow flakes or writing your name. If you need some help getting started, check out:

Step 15: Other Platforms

Could this robot be done with a regular Arduino? Yes! I went with the Trinket because of the low cost and small size. If you increase the chassis length, you can fit a regular Arduino on one side and the breadboard on the other (Image 1). It should work pin-for-pin with the test sketch, plus, you now can get to the serial console for debugging!

Could this robot be done with a Rasberry Pi? Yes! This was my first line of investigation because I wanted to program in Python, and be able to control it over the web. Like the full size Arduino above, you just place the Pi on one side, and the breadboard on the other (Image 2). Power becomes the primary concern because four AA is not going to cut it. You need to provide about 1A of current at a stable 5V, otherwise your WiFi module will stop communicating. I’ve found the Model A is much better on power consumption, but I’m still working out how to supply reliable power. If you figure it out, let me know!

Wii 리모컨(Wiimote)으로 RC Car 조종하기

이젠 벽돌이 되어버린 니텐도 Wii를 바라보다 갑자기 아깝다는 생각이 들어 폭풍 검색을 하다가 Wii 리모컨을 활용할 수 있는 괜찮은 소스를 찾은 것 같아 아래와 같이 소개 합니다.

잘~ 응용하면 재밋는 장난감이 되겠네요.

Circuit@Home에서 소개 받았습니다!

RC car controlled by Wii Remote on Arduino http://www.circuitsathome.com/mcu/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 용 라이브러리는 github 에 있습니다.
이 라이브러리는 Richard Ibbotson이 만든 코드 wiiblue.pde 을 기반으로하고 있습니다.
또한 이 라이브러리를 사용하기 위해서는, 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 0
enum 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 throttle
int 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();
    }
  }
} // myapp
int 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)) );
    }
}