Introduction: Brushless Gimbal Balancing Robot

The following project is a result of viewing the Cubli video and becoming interested in the control of unstable equilibrium using brushless motors. The simpler inverted pendulum problem was decided on in order to complete the project before loosing interest. Many people provide better descriptions than I can, therefore I will only focus on the build and try to offer useful links when needed.

Step 1: Parts

As the project title hints, the robot uses parts from a brushless gimbal camera stabilizer. This is ideal as the motor controllers and microcontroller are on the same circuit board and already setup to work with the included brushless motors and inertial measurement unit (IMU). The chosen gimbal system is designed to work with GoPro sized cameras with several iterations found cheaply online.

    • Gimbal control board BGC 2.0, look closely at the provided picture (2X L6234 brushless motor control ICs, mega328p microcontroller, Silabs CP2102 USB to serial)

    Note: other boards may work, it will need to be programmable using the Arduino IDE, therefore must contain a compatible microcontroller and ISP header to burn the bootloader

    • gy-521 IMU (MPU-6050 3-axis gyroscope and 3-axis accelerometer)
    • 2X 2208 brushless gimbal motors (fasteners to mount motor, they were included with my gimbal)
    • LiPo battery 3S (Turnigy nano-tech 460mAh 25-40C 57X31X17mm)
    • Colson Performa wheels 2" X 7/8"
    • 5/8" aluminum plate or bar to CNC robot body from, body made of two halves with finished size 2.50X4.89X0.55" (1/2" plate or bar also works, body will be 0.1" thinner)
    • 2X 6-32 X 1" button head screws
    • 1/8" X 3/4" dowel pin
    • 6" X 1/2" double sided Velcro strap to hold battery in
    • Other assembly stuff: double sided foam tape, hot glue, hook-up wire, 0.8mm piano wire to lengthen Bluetooth antenna, sticky rubber bumpers, battery plugs, indicator LEDs and stuff I have not thought of

    Step 2: SolidWorks Model

    The SolidWorks model is provided for machining and reference. Make sure your electronics, battery, motors and other parts work with the design before starting. Some modification might be needed.

    Step 3: Machining

    The inside diameter of the wheels need to be opened up on a lathe to allow for the motors to be pressed into the wheels. Measure the outer diameter of the motors and turn the inner diameter of the wheels about 0.001-0.002" smaller for a press fit. The depth should match the dimension of the outrunner motor bell. The wheel core is made of a hard plastic and holds decent tolerance. I held the wheels by the rubber exterior, in a six jaw chuck and indicated in off the plastic face.

    Remove the motor bell/shaft assemblies by pulling the snap ring off the shaft on the back side of the motor and drawing the assembly out of the bearings. Press the bells into the wheels by putting pressure on the edge of the bell (not the shaft).

    The body consists of two identical halves except for the alignment pin holes and the fasteners (see provided drawing). The two halves are CNC milled from 5/8" (1/2" also works but robot will be 0.1" thinner) aluminum plate. The SolidWorks part is provided to use with your CAM software of choice. I marked the motor mounting holes, alignment pin hole and fastener holes on the CNC using a center drill before the parts were separated from the plate. The parts should now be deburred and cleaned. I then complete the drilling, tapping and countersinking (this can also be accomplished on the mill before the parts are removed from the plate).

    Step 4: Assembly

    Look at the provided picture for part orientation.

    • Press the dowel pin into place
    • Attach the control board using double sided foam tape on the webs of the aluminum body
    • Attach the brushless motors to the body with the wires on top
    • Hot glue the IMU into place making sure it sits flush on the aluminum tabs and the IC is located inline with the motor shafts
    • Create a full wave antenna (~12.5cm) out of the piano wire for the Bluetooth module and attach so it goes outside the body (I drilled a small hole through the module allowing the antenna to go out the backside and provide more support)
    • Attach the Bluetooth module using double sided foam tape
    • Reset the default values on the HC-05 using AT commands and these instructions. My Bluetooth module had a pushbutton instead of a "KEY" pin, that needed to be held during power up and programming. The device name and password are reset and the baud rate is set to 230400.
    • Connect the Bluetooth TX to RX, Bluetooth RX through a voltage divider to TX to reduce the voltage to 3.3v and supply the needed power
    • Attach a battery connector (I added a 2amp fuse inline to offer a little more protection)
    • Hookup the IMU and motors to the control board (they came with attached connectors)
    • Attach an indicator LED to pin A1 using a 1k ohm resistor (I attached two and pointed them out the bottom of the robot)
    • Other optional stuff: Velcro straps on the top to hold the battery in, hot glue the wires for strain relief, rubber bumpers to protect the floor
    • Both halves should now fit together and be held in place using the two #6-32 fasteners

    Step 5: Arduino Code

    -The code is running on a mega328p and was compiled using Arduino 1.6.6
    -The code cycle time is a constant ~250Hz

    At the heart of the code is a counter that is advanced every time TIMER1 overflows and triggers an interrupt routine. This counter triggers other events at specific intervals allowing the code to run at a known rate and simplify math in the control loop.

    The tilt angle of the robot is calculated using a complementary filter with gyrometer and acceleration values from the MPU6050 IC. This is fed into a control loop with three other values: the time derivative of the tilt angle, robot velocity (acceleration integral) and robot displacement (velocity integral). All four values are added with preset gain to get an output term proportional to robot acceleration. A good explanation of this control loop by David P. Anderson and more information on his balancing robot.

    To move the robot an offset is added to the displacement value in the control loop. To turn left or right an offset is added/subtracted from the left and right wheel velocities. The wheel velocities are fed into the the motor control portion of the code.

    Brushless motors require 3-phase power. Look at this explanation of how angle control of brushless gimbal motors is achieved. The motor control portion of my code is based off of the BruGi brushless gimbal control code. All three timers are set to output 31.25KHZ phase correct PWM (6 PWM outs). A useful article on adjusting Arduino timers.

    A lookup table containing space vector PWM values is used to pull three values with 120 degree phase separation. The values pulled from the lookup table are advanced at a rate proportional to the needed left or right robot wheel velocity.

    The code handles motor power adjustment to correct for torque falloff at higher speeds and greater needed torque during higher acceleration. The battery voltage is monitored to prevent damage to the LiPo batteries. The code also handles Bluetooth communication between a smartphone.

    Step 6: Tuning Control Loop for Balance

    The control loop has four gain values that need to be set.

    1. kp angle gain
    2. kd angle velocity gain
    3. kv velocity gain
    4. kc position gain

    This is how I tuned the robot for balance, it is probably not ideal but it worked. Start with all gain values set to zero. Slowly increase kp gain until the robot no longer falls forward, now increase kd gain until the robot stands but slowly oscillates with growing amplitude until the robot falls over. Increase the kv value until the robot no longer oscillates and recovers from a light push on the top. At this point the robot should have the desired performance. It should stand in one place and recover from a disturbance. Play with the three values to get a better feel for how they behave. Now increase kc gain until the robot returns to the same place after a disturbance but not too large resulting in decreased performance.

    I reset all values to zero and started over several times until I achieved decent results. If it looks like the loop is completely failing make sure all the calculated values in the loop have the correct sign and behavior and the feedback values have the correct sign.

    Step 7: Bluetooth Control

    The android app Joystick BT Commander is used to communicate with the Bluetooth device on the robot. The app is setup to display the robot battery voltage, relative motor output power and the code cycle time. The cycle time is important because it must not exceed the time interval between calls (~4ms) in order to maintain proper timing for derivative and integral calculations. The app also has two buttons setup. A power button "ON" turns on the motor control portion of the code when activated. The second button "Fast" increases the robots top speed by a factor of two when pressed.

    Step 8: Finished

    When the robot is first powered it needs to be set on its front or back within 5 seconds. At this point the indicator LED will flicker for 10 seconds as 1024 gyroscope readings are averaged to obtain a calibration value. If the battery is charged the indicator led should now start to turn on and off every 2 seconds. A connection can now be made between the smartphone Bluetooth application and the robot. Press the "ON" button and place the robot within 1 degree of vertical to start balancing. Use the joystick to drive the robot. Once the battery is depleted the robot will no longer balance and the indicator LED will stay on.


    jimkan made it!(author)2017-06-23

    Before putting everything in place, try to hook up all electronics load up the sketch without problem, can see IMU values changes in serial console but motors are not moving at all. Any advise?

    271828- made it!(author)2017-06-24

    There could be a few possible reasons. The robot needs to be connected to the Bluetooth controller on the cellphone and turned on using the app to move. The robot also needs to be almost vertical in order to start balancing, therefore the IMU needs to be held in the vertical orientation that it will be in while the robot is running for the motors to move.

    jimkan made it!(author)2017-07-02

    Hi 271828, I am using BGC 3.0, upload the program fine and Joystick app show voltage changes but that is all, no activities on motors, button one and two seem to do nothing. The board I use does not have an INT is this why it's not working?

    271828- made it!(author)2017-07-08

    The first button turns the control loop on, it should be green when on. The second button increases the max allowed speed and can stay off. With the app connected, turn the first button on and try to hold the IMU in the vertical position it would be inside the robot when balancing. Look at the assembly photo. The motors should momentary turn on when the IMU reaches vertical. The joystick will do nothing until it's actually balancing.

    jimkan made it!(author)2017-06-28

    yes, you were right, after hooking up the Bluetooth module the motors started to response with the movement of IMU but they don't response to the updated android app, is the older version of the app like the one you posted here still available?


    271828- made it!(author)2017-06-29

    The linked page under step 7 has the version I used (5.2). You will need to add the labels for the buttons and value within the app manually. The joystick within the app does not directly control the motor motion so you might not see much response if just holding the parts. The app is working if you are able to turn the power on and see the battery voltage.

    Tyde made it!(author)2017-05-19

    Good work

    I have built a house with no turn I have to change wheels

    Did you have a trick to make wheels

    Thank you

    271828- made it!(author)2017-05-19

    You could try 3D printing wheels that fit the outside of your motors or try and drill out the inside of some wheels using a drill press and a forstner drill bit. Not sure what you have access to.


    How can I change the code for such engines?

    271828- made it!(author)2017-05-04

    The linked motors should work for a balancing robot but my code is not what you want to use. A lot of my code is for controlling the brushless motors. The linked DC (direct current) motors are easier to control and are more commonly used for this project. Take a look at the other balancing projects on Instructables for code examples. I would also recommend adding encoders or purchasing motors with encoders built in.

    ItsMe-Phil made it!(author)2016-06-29

    Very cool...

    Newbie question, You say you are using 2208 motors. Does the KV matter for this project?


    271828- made it!(author)2016-06-30


    If the motors are designed for brushless gimbal camera stabilizers they should work. This kind of motor is not the same as the ones used for spinning a propeller. The 2208 motors typical are in the range of 80-100 KV.

    ItsMe-Phil made it!(author)2016-06-30

    Got it! Thank so much.

    Then this is the one I'll buy:

    271828- made it!(author)2016-07-02

    Those should work!

    AndreQ1 made it!(author)2016-05-01
    Hello I found this amazing project, but for me this hard to understand. It would be possible to describethe code for programming the engines in addition to the links between the components?


    271828- made it!(author)2016-05-03

    Thank you!

    I would recommend reading about the inverted pendulum problem and once that is understood, try building a balancing robot using brushed motors. A lot of this projects complexity comes from the control of brushless motors. The wiring and code is not easily described in its entirety. I will try to answer any particular questions you have.

    macgverl made it!(author)2016-04-11

    Wow is Very Cool.

    I have doen . But needs tuning PID.

    Thank very match shareing.

    271828- made it!(author)2016-04-12

    Great job!

    Glad you like it and thanks for linking the video!

    DhamirH made it!(author)2016-03-09

    Great project..
    but i still looking for the wiring scheme and pins configuration.

    is that attached or i just cant found it?

    sorry im a newbie in this

    271828- made it!(author)2016-03-09


    I never created a wiring schematic as it uses the gimbal electronics with little modification. Step 4 mentions the Arduino pins used, but there exists several gimbal control boards with different pin configurations so the relation between hardware and software will have to be determined for the board being used.

    Gelstronic made it!(author)2015-12-30

    Hi, i finished building so far and got some problems.

    Of course the bot won't balance :-)

    So, what i've done :

    Check battery power,

    check looptime under 4ms

    check robot_angle (see video, debug_data_field)

    change the motor direction.

    Changing the k-values not effect anything.

    The wheels dither very much and the bot fall over.

    My gimbal motors:

    2208 80KV

    Weight: 39g
    Motor Type:12N14P
    70 turns,3mm shaft

    here's a link with the video:

    any suggestions what to do ?

    271828- made it!(author)2015-12-31

    looking good so far!

    The motor dithering is caused by the loop trying to command wheel movement faster than the wheels can accelerate. This results in the motors stalling and the noise you hear. Because the robot is not moving, the commanded velocity continues to increase, while the motors slip, until a max velocity value in the code is reached and the control loop is turned off.

    Start by setting all the k values to zero except Kp. Set Kp to something small like 0.01 and see if the wheels spin in the proper direction when the robot is tilt while held off the ground. The robot wheel speed should increase as the robot angle increases and the robot should try to move in the direction of tilt.

    Check if the vertical equilibrium angle is measured as zero with everything in place and no external forces acting an the robot (balancing the robot by hand). If it is not close you will need to adjust the mounting of the MPU6050 or add an offset to the angle measurement.

    If everything is working to this point, try following the tuning instructions in the Instructable.

    Gelstronic made it!(author)2015-12-14

    Hi, very nice project.

    i've started to build this tiny little bot. I like to use potentiometers for getting the right

    kp angle-, kd angle velocity-, kv velocity-, kc position-gain values.

    Can you tell me the estimated range of the values like 0-10,0-100 ?

    Thanks in advance.

    271828- made it!(author)2015-12-14


    The gain values are defined at the start of my code as:

    //loop tuning values
    #define kc 0.0002 //position feedback gain, (reposition robot after disturbance)0.0002
    #define kv 0.02 //velocity feedback gain 0.02
    #define kp 0.2 //angle gain 0.2
    #define kd 0.025/(2*0.004) //angle velocity gain 0.025

    They can be significantly different if the code structure is changed, or the shape/mass of the robot is changed. The gain values should be of the same order as my values if the robot and code are not changed significantly. For example kp would be in the range of 0-1. I would increment the value at one greater significant figure. (kp would be incremented at 0.01).

    Adding more analog reads within the main loop could increase the loop time beyond 4ms. This would cause the time interval between loop calls to become unknown as the previous call overlaps with the next. A constant time interval is required for the angle calculation and control loop. Try to place the analog reads in a loop that is only called when adjusting the tuning parameters. For example, when a button is held down.

    EduardoH20 made it!(author)2015-12-13

    Wow! your robot is incredibly stable, can i ask you something? in the atmega, where is connect the "INT" of the IMU? i can't find the schematic, and sorry for my bad english

    271828- made it!(author)2015-12-14

    It connects to one of the interrupt pins on the atmega, on my board it's "ch1". The INT connection is not needed If using my code which only reads the raw acceleration and gyroscope values. It's needed when using the MPU6050 motion processing (DMP).

    san_t made it!(author)2015-12-06

    Cooool! :)

    DamasoC made it!(author)2015-11-26

    Hello, awesome project, I converted the part files to stl so I can 3d print them. Will the change in weight from materials affect the firmware?

    271828- made it!(author)2015-11-26


    The loop tuning will have to be adjusted as the mass and the center of mass will be different. The aluminum body also acts as a heat sink for the motors as they can be damaged from overheating if run at full power continually. I'm not sure how much heat the 3d printed parts will dissipate. You might have to turn down the motor power, just something to keep in mind.

    DamasoC made it!(author)2015-11-26

    Thanks for the advice, I'm thinking on using ABS, it should handle some heat. But I'll check on the loop tuning.

    BradBuilds made it!(author)2015-11-24

    Looks great! Wish you luck:)

    271828- made it!(author)2015-11-25


    strooom made it!(author)2015-11-23

    You could use Blynk and create a nice remote control app on your phone. Today it is Wifi only, but in the future it will support BLE as well

    271828- made it!(author)2015-11-23

    Blynk looks like a useful app! I will have to try it when Bluetooth is added.

    strooom made it!(author)2015-11-23

    Very good. Inspiring.
    Can you post a few links to the gimbal you used? It should be arduino based and reprogrammable I guess.

    271828- made it!(author)2015-11-23

    Thank you!

    I'm not entirely sure of the model as I purchased it used. It looks like a BGC 2.0 control board. The important components on the board include a compatible microcontroller (ATmega328P) and ISP header to burn the bootloader so the Arduino IDE can be used

    ThomasK19 made it!(author)2015-11-23

    Thanks for putting in the link to the balancing algorithm. I tried to build such a vehicle using DC motors with a Fischer Technik frame. But I never got it in any way stable. Either it flipped over or it did not come up. Never was sure whether it was my algorithm or just the motors (I salvaged from a printer) being too weak.

    Your device is awesome. Unfortunately I don't have a machine to make such a frame.

    hobbyman made it!(author)2015-11-23

    This is simply beautiful. I loved it.

    amberrayh made it!(author)2015-11-23

    Great looking little robot. Thanks for sharing!

    About This Instructable




    Bio: Hi! You can call me Matt. I'm a problem solver with interests in many fields. Sites like this are a great resource, therefore I ... More »
    More by 271828-:Adjustable CNC Router Dust BootCustom Wye Fittings for Your Dust Collector Simple Slap Bracelet / Cycling Trouser Strap
    Add instructable to: