A dynamically stable omnidirectional robot that balances on a 22cm ball

Similar projects worth following
For more info, go to where more regular updates will be posted.


  • 50mm 18 ring omniwheels
  • Maxon DCX22s motors with 16:1 gearbox and ENX16 Encoders
  • Laser cut acrylic and 3D printed parts
  • MPU-9250
  • Teensy 3.x
  • Miscellaneous components (switches, v-regs etc.)
  • TI LMD18200 motor controllers
  • HM-11 bluetooth? (currently not on robot)
  • 1/2" shaft that goes through centre of robot -- for adjustment of centre of gravity (higher centre of gravity => better. Just imagine balancing a broom with the head at the top or bottom)

The PCB is designed in Cadsoft Eagle and manufactured by Elecrow.

  • Motors singing in harmony - Pachelbel's canon

    Brian Chen12/16/2015 at 08:05 0 comments

    [this post was first published on my blog @]

    Technically I did this last Saturday, but I was too lazy to upload the video with my ridiculously slow internet.

    Anyway, here it is: the ballbot playing Pachelbel's canon (aka Canon in D) with it's motors by changing the PWM frequency for the motor controllers! Only the first dozen or so bars are played since this is one of my earlier revisions of the program.

    And yes, I still don't have my 18650 battery holders, so I'm using a 4s lipo.

    Unfortunately, most of the PWM pins on the Teensy correspond to one FTM timer, and so the PWM frequency of any of the 3 motors needs to be the same at the same time. This explains why no two motors are ever playing at the same time.

    BoardTimerPWM PinsDefault Frequency
    Teensy 3.1 & 3.2FTM05, 6, 9, 10, 20, 21, 22, 23488.28 Hz
    FTM13, 4488.28 Hz
    FTM225, 32488.28 Hz

    Eventually I stopped playing with the music at the end of the day, and I did get get two motors playing different notes at the same time by using a separate timer, FrequencyTimer2.

    On the software side of things, I used an interrupt that acted as a metronome, except my metronome was ticking at every semiquaver instead of crotchet. I treated the semiquaver as the fundamental unit of time and created 3 large 2D arrays for each of the motors to play (the first element of each row corresponding to the frequency and the second

    element corresponding to the number of semiquaver beats to be played). You can find all the functions and routines I wrote here.

    WARNING: If you try this, your motor controllers can get VERY HOT due to the low frequencies that you need to be operating at. See Eventually, one of my motor controllers burned out the day after, though I'm not sure whether this was the reason.

  • Update 1

    Brian Chen12/09/2015 at 03:20 0 comments

    Currently the 18650 battery holders have not arrived so I'm unable to get the robot moving. However, the circuitry seems to work. I have implemented reading the quadrature encoders and IMU in software.

View all 2 project logs

Enjoy this project?



Pedro H. J. wrote 03/24/2019 at 12:58 point

I'm from Brazil. I made a ballbot as well.

Some videos about my ballbot:

Your ballbot, do you set position = 0 then ballbot return to 0 position (x and y axis) ?

Dude I can not translation ballbot, please help me.

I made this:

error = position - setpoint ;

output1 = error * kp1;

errorAngle = output1 - Angle ;
diffError = errorAngle - errorAnglePrev  / time ;

output2= errorAngle * kp2 + diffError * kd ;

It's just a axis, but i made it for roll and pitch, so i convert to 3 stepper motors (using convert ETH ballbot).

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates