The Balancing Robot

Now avaliable as a kit
A balancing robot kit is now avaliable via Kickstarter: Check out the blog post as well:

Hello everybody
I have for a long time wanted to build a remote controllable balancing robot aka Segway – that’s was actually the main reason why I created the PS3 Bluetooth Library both for Arduino and the FEZ Devices. It has been a long time since the sneak peak and the performance has been improved a lot since then. The original one had a FEZ Rhino as the main processor, but I discovered that it was not fast enough to read the encoders, as it is not running embedded code. Also I was already using more than 10ms per loop, which I used as a fixed time loop, so I decided to step up a notch and go for a much more powerful device: the mbed microcontroller, which is an ARM Cortex-M3 running 96MHz.

It might have been possible with just a normal Arduino (NB: I have now ported the code to Arduino, see update for the code), but I didn’t want the speed of the processor to be an issue, so I decided to go for the mbed. The robot also features an Arduino Duemilanove with a USB Host Shield on top running a sketch based on my PS3 Bluetooth Library. The mbed board actually has USB Host functionality, but I decided not to port the PS3 Bluetooth Library as my original thought were to use an Arduino Due, but as you might know it hasn’t been released yet, despite the Arduino team announced, that it would be released by the end of 2011. But as soon as it is released I think I will port the code to it instead.

Video Demonstration
Here is a short video demonstration of the robot and me explaining some of the concepts of the design and how it works:

The Hardware
Here are some pictures of the robot:

Here is a list of all the hardware I used:

I also used:

The robot itself is made of three pieces of 215x75x7.5mm MDF wood and four threaded rods. The distance between the plates is 7cm at the bottom and 7.5 at the top. In total the robot is 27cm high including the battery.
See the 3D model for more information.

3D Model
I have created a 3D model in Autodesk Inventor with true dimensions, this will hopefully inspire other people for there robot design. All files can be found at github.
The 3D model can also be viewed at the following site:

Check out these rendered images of the robot:

The Code
All the code and 3D model can be found at our github. Here is a list of hyperlinks for all the repositories:

Also check out the wiki.

I have now ported the code to Arduino. The code can be found at github:

I have thought about how I could improve the performance of the robot. First of all I could try to use an accelerometer with a smaller resolution, as the one I got is a ±3g and ±1.5g would be sufficient for my needs. Also my gyro got a resolution of ±300 deg/s and I have seen people use gyro with a resolution as low as ±50 deg/s.

Another aspect would to use belts to minimize backlash, instead of connecting the wheels directly to the motors – a bit like this one.

Also I don’t compensate for the battery level in the code – so it behaves differently depending on the battery level.

Overall I am really happy about the end result – it balances pretty well and the remote control works perfect!

It has been a really good learning experience for me and a really fun project to do, but also very time-consuming – I have spend many nights tweaking the PID values and adjusting tiny bits of the code before I accomplished the end result.

The next step would to build a full size one, but I don’t know if I will do it the near future – but hopefully some day :)

That’s all for now. Hope you like my robot. Feel free to post a comment below and I will answer as quickly as possible.

  1. December 15th, 2013 at 22:34 | #1

    Nice idea about increasing the I2C frequency -- I do not know why I have not though of that :) But it is better to set it like so: instead of hardcoding the value.

    I have sent you an email. I will take a look at your code when you reply 😉

  2. December 16th, 2013 at 00:23 | #2

    Hi Lauszus

    Both me and my son are embarking on making a balancing robot from your information.
    My question is as followes.
    do you have a wiring diagram for the equipment you specified in you articles, as it would be extremely helpful ?



  3. December 16th, 2013 at 09:41 | #3

    No unfortunately not, but you should take a look at the Balanduino PCB: -- it shows how the MCU should be connected to the IMU, motor driver etc.
    You could also consider pre-ordering the main board: or even the kit.

  4. December 23rd, 2013 at 23:36 | #4

    Thank you Lauszus, i placed a pre-order request recently, just deciding on the full diy kit
    or just the PCB.


  5. December 24th, 2013 at 00:05 | #5

    Okay. If you got quality motors, wheels and everything else you need, then I would say that you should go for the PCB, but note that in my experience the quality of the motors, wheels and other hardware makes a huge difference! So if you want parts that you know will work, then go for the kit :)

    Anyway it also depends on the goal of your project -- do you want to build it from the ground up or want to hack/modify/improve an existing platform.

    One of my big hopes for the Balanduino -- and one of the big reasons for making the kit -- is that in collaboration with a lot of other people we will be able to great a even more impressive robot! Up until now I have been the only one working on the code, so I can’t wait to see what other people can come up with 😉

  6. December 24th, 2013 at 02:23 | #6

    The idea of working up from components to a finished robot is the idea, your original robot with separate processors ect, seems a far better learning tool for my son. he as just started
    to study engineering and needs a project. And yours is by far the best we have found.
    Along with your blog and information which can only improve his knowledge.



  7. December 24th, 2013 at 14:53 | #7

    Okay I see you point. Would you be interested in buying a version with all you need except the main board? If there is a demand for it we might open up for that as well.
    It will consist of all the parts in the full kit except the main board, so people can use there own electronics.

  8. December 27th, 2013 at 21:07 | #8

    Happy New year kristian

    i have been looking at your balancing robot sketch, the IMU that you used is no longer available.
    would it be very difficult to use a MPU6050 imu as a substitute ?
    Would i just have include the code, or would it mean a major re-write of the whole balancing robot sketch ?



  9. December 27th, 2013 at 23:26 | #9

    You should use the Balanduino firmware: It uses the MPU-6050 and has several improvements compared to the old code.

  10. December 28th, 2013 at 14:55 | #10

    Thank you for the advice, so we can use a normal Arduino board, which do you recommend ?
    Along with a motordrive ect, would the pin-out be the same as for the old code, except for the encoder connections. I appreciate this cant be very entertaining as we are only just getting started but thank you for your help.


  11. December 28th, 2013 at 18:24 | #11

    Sorry Kristian, i meant to say IMU connections.


  12. December 28th, 2013 at 19:12 | #12

    I recommend the Arduino mega if you are going to use an Arduino, as you will run out of space on an ATmega328P based (Uno, Mini etc.) really quickly.

    I have actually made it really easy to change the pins recently: It might look a bit more complicated than using digitalWrite/digitalRead, but they advanced is that it is just as fast as reading and writing directly to the registers, but it is much easier to port to other boards than just the Balanduino main board.

    For the IMU connections you should connect the IMU to the I2C pins on the boards. It should be labeled in the Arduino -- there is a reference here as well:

  13. Blanco Lucas Ezequiel
    December 30th, 2013 at 21:12 | #13

    Hello! with respect to code MPU6050 have a problem, my balancing robot needs an angle, but when I remove the code the angle I need not make sampling very boring. Aydar Could I find the problem? Sorry for my English and I am from Argentina. Sample Code:

    while(i2cRead(0x3B, i2cData, 14));
    accX = ((i2cData[0] << 8) | i2cData[1]);
    accZ = ((i2cData[4] << 8) | i2cData[5]);
    gyroY = ((i2cData[10] << 8) | i2cData[11]);
    accYangle = (atan2(accX,accZ) + PI) * RAD_TO_DEG;
    double gyroYrate = -((double)gyroY/131.0);
    gyroYangle += gyroYrate*((double)(micros()-timer)/1000000);
    kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
    timer = micros();
  14. December 31st, 2013 at 01:39 | #14

    @Blanco Lucas Ezequiel
    Sorry, but I don’t understand what you are trying to say?
    Anyway you will find the Balanduino code here: It is the newest version of the code and uses the MPU-6050, which you are trying to use, as indicated by your code above.

  15. Venugopal
    February 12th, 2014 at 11:34 | #15

    I am a final year student of Aeronautical engg,. from India
    I would be happy if i get an aid from you for doing a project on SELF BALANCING ABILITY OF THE AIRCRAFT using this method. kindly give me a reply Sir

  16. February 19th, 2014 at 16:49 | #16

    What do you got problems with? You should checkout the Balanduino repo: where you will find all the hardware drawings and firmware.

  17. March 10th, 2014 at 09:56 | #17

    Do you have the schematic of the robot circuit. I didnt see any schematic and block diagram of the robot. If it present, can you please inform me and give its link


  18. March 10th, 2014 at 22:38 | #18

    @Lentin Joseph
    You should take a look at the Balanduino schematic:

  19. March 25th, 2014 at 10:46 | #19

    I’m not sure why but thos weblog is loading very slow for me.
    Is anyone else having this problem oor is it a issue on my end?
    I’ll check back laater and see if the problem still exists.

  20. March 25th, 2014 at 17:53 | #20

    It might be slow at peak times, but in general it should respond pretty fast. Are you still experiencing problem?

  21. Warman
    April 13th, 2014 at 04:19 | #21


    A nice piece of work. I am curious to know about the PID controller architecture. Do you have any information about the controller design. (E.g: what is/are your reference commands? what variables are used to calculate the PID error terms? Inner/Outer loop architecture etc? Any information about the design of the controller for your specific robot would be of great help. Please let me know.


  22. April 17th, 2014 at 15:05 | #22

    You should take a the source code here:
    Currently I use kind of a PD controller for the encoders, the output of this is then used as the input for a second PID controller which outputs the PWM value.

    I did not calculate the PID values. I tuned it manually.

  23. MKB
    May 3rd, 2014 at 12:29 | #23

    Hello Lauszus!
    I bought a motor DC 12V speed load 220rpm weight 250g, current load 1200mA, you think that it has enough torque to robot balancing ? I try to look for value PID but my robot not balancing.
    Thanks you!

  24. May 3rd, 2014 at 13:20 | #24

    Please send me the link to the motors. I need to know the torque.
    But they sound like they would work.
    What code are you using?

  25. MKB
    May 3rd, 2014 at 18:09 | #25

    Torque : This is code:

    #define   GUARD_GAIN   20.0

    float K = 1.4;
    int   Kp =11;                      
    int   Ki = 0;                  
    int   Kd = 10;  
    int last_error = 0;
    int integrated_error = 0;
    int pTerm = 0, iTerm = 0, dTerm = 0;

    int updatePid(int targetPosition, int currentPosition)   {
      int error = targetPosition - currentPosition;
      pTerm = Kp * error;
      integrated_error += error;                                      
      iTerm = Ki * constrain(integrated_error, -GUARD_GAIN, GUARD_GAIN);
      dTerm = Kd * (error - last_error);                            
      last_error = error;
      return -constrain(K*(pTerm + iTerm + dTerm), -255, 255);

    I was very impressed with your robot. Thanks you.

  26. MKB
    May 3rd, 2014 at 18:11 | #26


    int Drive_Motor(int PWM_val)  {
    if (PWM_val& > 255)
    if ((kalAngleY > 150) && (kalAngleY < 166))
      if ((kalAngleY > 166) && (kalAngleYsetPoint)
      analogWrite(PWM1, PWM_val);
      analogWrite(PWM2, PWM_val);
      digitalWrite(InA1, LOW);
      digitalWrite(InB1, LOW);
      analogWrite(PWM1, PWM_val);
      analogWrite(PWM2, PWM_val);
      digitalWrite(InA1, HIGH);
      digitalWrite(InB1, HIGH);
      analogWrite(PWM1, 0);
      analogWrite(PWM2, 0);
      digitalWrite(InA1, HIGH);
      digitalWrite(InB1, HIGH);
  27. slo3
    May 28th, 2014 at 05:13 | #27

    Great site and thanks for sharing the code… but I’m a bit confused about how everything “fits together”… What code runs where?
    The mbed code runs on the mbed (or a second Arduino in the updated version?)
    But does that mean that the Kalman filtering code runs on an Arduino alongside the USB shield and the PS3 control input? How? I’ve only ever run a single piece of code on an Arduino at once… What am I missing?

  28. June 6th, 2014 at 09:25 | #28

    In this video demonstration all the real-time control and regulation (stabilization) of the robot is done with the Arduino. The mbed is only used for the USB control with the PS3 controller thru Bluetooth.

    In our new version, the Balanduino, the main board takes care of all this in one single processor, an ATmega1284P. This Arduino compatible board includes both the regulator design and the USB Host control application, embedded into one system and one project.

  29. July 10th, 2014 at 19:48 | #29


    I am a high school student who is building this self-balancing robot, and I was wondering for the Kalman filter Arduino library, how did you calculate the GYRO_SCALE and ACC_SCALE? My raw gyro values are fairly small, and dividing them by the even smaller GYRO_SCALE makes them very large and noisy. Where should I look on the IMU’s data sheet? Thank you very much!


  30. July 11th, 2014 at 23:58 | #30

    You should read my guide here:,58048.0.html. I believe it will answer your questions.

  31. Jan
    August 14th, 2014 at 15:06 | #31

    Hi Lauszus, thanks for sharing your project. I just watched your video and I recently started with my own(Just a different shape and so on). How did you start tuning your PID controller? Did you set the Ki and Kd values to 0 and then increased the Kp value like Ziegler Nicols tuning or did you just manually tune them until they worked?


  32. August 14th, 2014 at 20:38 | #32

    I simply increase Kp until it oscillates, then turn it a bit down. Then increase Ki until it oscillates slowly. Finally I increase Kd to damped the system.

  33. Piet
    August 28th, 2014 at 09:05 | #33

    Hi, your robot looks great. Im also trying to build one using the exact same motors but using a pic. My pid algorithm looks mores or less the same as yours but im am having a problem with the motors. It seems like the motors take to long to respond, they only start moving when it is to late and then the robot falls over. Did you also have this problem? Thanks

  34. August 28th, 2014 at 17:58 | #34

    It sounds to me like you need to tune your PID controller. Perhaps you could upload a video somewhere, so I could have a look?

  35. Piet
    August 29th, 2014 at 05:27 | #35

    Thanks i will defnitly upload a video as soon as i can. I have only been trying to set the proportional constant to get it to oscillate at least but no luck

  36. Mounika
    January 3rd, 2015 at 16:33 | #36

    Hello Lauszus,
    I would like to know the total cost of the project involved in its making.

  37. January 3rd, 2015 at 19:49 | #37

    I honestly can’t remember, but you can just add up all the parts yourself. But it quickly becomes quite expensive, so expect to spend $500 if you built it from scratch.

  38. Rafael
    January 7th, 2015 at 22:27 | #38

    Your robot is impresive. Also the Balanduino project. Unfortunately at our school we can’t affford to get one and we are trying to build it like the one in this article. We have the motors with encoders, an MPU6050 and an Arduino Due. But we do not know how to connect them, and we do not find that information in this page. Could you please tell me how to do it?
    Also, I have read that the accelerometer is better to be placed near the wheels axis, but we do not know if it needs to go in a special position. Could you clarify this, please?

    Thank you very much
    Rafael Caballos

  39. January 14th, 2015 at 14:56 | #39

    The best resource is to look at the Balanduino schematic:

    Just between the two motors is the ideal location.

  40. Osama
    January 26th, 2015 at 23:08 | #40

    Hi Lauszus
    I’m an Electrical Engineering student
    you have a really nice robot there ^^

    I wonder if you could update the hardware and software so we can try to work on it
    Also, have you ever considered using Wiimote instead of IMU??

    Thank you

  41. nela
    March 7th, 2015 at 23:03 | #41

    Hi Lauszus. I am working on my own self-balancing robot. I have everything done. The software seems to be ok. But is this normal that motors start to spin only when the torque send is high (over 180)? I keep tracking torque on the serial monitor. I tried to tune PID, becuase I thought that may be the issue. But after couple of tries with tuning PID, I am not sure now if this a problem with this or something else. Motors start to spin when torque on the serial monitor is like 180 or more. When it’s like for example 30 or 50, motors do not move. Could you help me? Did you had that problem too? Maybe you know what can couse that? I look foward to hearing from you.

  42. March 9th, 2015 at 22:56 | #42

    You should check out the Balanduino: which is the newest is the robot. No I see no need for it, as IMU’s like the MPU-6050 is so cheap it does not make sense to use the one in the Wiimote.

    No that is not normal. They should start spinning at even low values. When you talk about torque, are you then talking about the value here: or something else?

    Can you send me a link to the motors you are using?

  43. nela
    March 11th, 2015 at 18:43 | #43

    Hi yes I’m sorry, I named it as a torque in my code. Anyway I’m talking about speed of the motors. I try to tune PID and motors only start spinning while the pwm value is bigger than 150 more less. These are the motors I am using. I cannot say now if this is a problem with motors (hopefully not!) or my code or just pid tuning… I actually spend hours on tuning pid and I can see that behaviour of motors changes but still cannot get the right values. If you want I can send you my code. I would be pleased if you could give me any advice/ help with this. I really want to see my robot balancing :) Thanks

  44. nela
    March 12th, 2015 at 23:25 | #44

    update: I tried to fix that my motors do not move at low speeds. I read about the ‘dead zone’ of the dc motors, and maybe that is the reason. So I changed my speed form 0 -> 255 to 70 -> 255. I don’t know if I did right thing, but anyway motors start moving at small angles as well. But then I tried to tune my pid and only I get is jittering around error=0 position. With changing pid constants, jittering gets bigger or smaller, but the robot cannot balance. I cannot find that ‘oscillation point’ while tuning kp. My last constants were like float kP = 280;
    float kI = 0;
    float kD = 110;
    The biggest kI I can use is 1, becuase bigger makes my robot even worse. For try and error method I left kI = 0. With bigger kP I see the response is faster but still it cannot balance. After maximum 3 seconds of jittering it falls over. Could you help me? I will send you my code on e-mail, so you could take a look. Thank you

  45. March 15th, 2015 at 00:30 | #45

    It would be better if you could upload a video on YouTube and then send a link to it? It sound to me like you might need some better motors.

  46. March 15th, 2015 at 00:35 | #46

    Also I could see from your email that you are using a Intel Galileo.

    It worries me a bit, as it is not good for applications like this, as it is not real time. You could try to install a real time OS (RTOS) on it though and see if it helps (if it even possible), but I would recommend using a “normal” microcontroller instead.

  47. nela
    March 15th, 2015 at 00:53 | #47


    The thing is I have to use Intel Galileo (college project requires that). I saw few self-balancing robots with using Intel Galileo so that’s why I know it’s possible to do that. They didn’t say about installing RTOS, so I think they didn’t install it, but I could be wrong. Anyway, I am still trying to balance that robot :) here’s my youtube video. Take a look

  48. nela
    March 15th, 2015 at 18:02 | #48

    update: I saw I got really odd values from my mpu ( I got results 0 -> +/- 1.5 instead of 0 -> +/- 90 degrees), so I changed calcOutput to be a global variable equal to 0 at the beginning of my code ( the result from the mpu are now from 0 to +/- 86 degrees). I did the same with calcPID.. The robot stopped jittering at error = 0 and I can see that is oscillates now with kp = 10. With that value, robot becomes pretty unstable and moves from side to side at high speed. What is more important, my motors spin at low angles now as well. Well, maybe that’s some progress? I don’t know yet, because it’s still not balancing, but I eliminated that annoying vibration. If my robot don’t balance, there is something wrong with the code. But what can be wrong? Any suggestions? 😉

  49. March 19th, 2015 at 23:48 | #49

    I really don’t think it’s a good idea to use the Galileo, as you can only toggle a “normal” pin at about 230 Hz according to this page: when using the standard digitalWrite function. See that page for some tips on how to increase the I/O speeds.

    You are using the Intel Galileo 1, right? The Intel Galileo 2 has more pins that can be used as “fast pins”. You can check if it is a fast pin and set the output like so:

    if (pinToFastPin(pin))
        pinMode(pin, OUTPUT_FAST);
        pinMode(pin, OUTPUT);

    And then you can write to the pin like so:

    fastDigitalWrite(pin, HIGH);

    Also check out these lines in the USB Host library:

    It sounds like you need to make a calibration routine for the accelerometer. Please see these lines for the Balanduino:

    Btw also see:

  50. nela
    March 20th, 2015 at 15:28 | #50

    Hi Lauszus,
    Thank you for your reply.
    I am using Galileo Gen 2. I saw two projects with this Galileo, there were working fine. I am sure mine one will work fine too :) I wish I could use Arduino (I am not a Galileo fan), but I have to make my robot with using Galileo. Anyway, I will read about these ‘fastpins’. Maybe that will help somehow. But I have one more quiestion about PID tuning and the ‘oscillation point’. With just only kp set, my robot will balance or almost balance? I now there will be some overcorrection etc. But I am not really sure how this should look like. Do I need to turn up kp to the moment the robot will catch itself? Or am I thinking wrong.. Because sometimes tuning is difficult when you don’t know what to expect. Thanks

Comment pages
1 9 10 11 12 13 2196
  1. No trackbacks yet.