Introduction: Arduino Self-Balance Controller Using DIGITAL IMU, at Last!

Picture of Arduino Self-Balance Controller Using DIGITAL IMU, at Last!

What is it?
DIY Segway/balance controller with modern DIGITAL IMU sensor.
Software for an Arduino that allows it to read position data from one of the newer DIGITAL accelerometer/gyroscope units, processes the data using Kalman Filtering (the really clever one) and then sends control signals to a motor controller allowing your machine to self-balance.

All my self balancers are also documented in my You Tube channel here:Click

Why do this? You have done a similar Instructable already:
I wrote an Instructable in 2010 describing a Segway style skateboard with two motors, two central wheels and a self balancing system using an Arduino as the "brain" and a combination of a solid state gyroscope and accelerometer as sensors of how much the machine was tilting.

The accelerometer and gyroscopes used put out a voltage from 0-5V proportional to the angle of tilt from the vertical (or in the case of the board, the level) position, but these are becoming very hard to find. These are known as analog Inertial measurement units (IMU's).

I updated the control system and tried to make it easier to build as an Arduino "shield" as a new Instructable in 2013, using an analog IMU still available from China. However, now, even this one is getting tricky to obtain.

So, finally, after quite a while trying, I have managed to get this control system to work using an Arduino and a commonly available DIGITAL IMU, from Sparkfun. This communicates with the Arduino via what is known as the I2C protocol.

I have used snippets of code from all over the web, and I hope I have credited them all at the top of the Arduino sketch, which is attached to Step 16.

Why is this a big deal?
People have been asking me for this for around 2 years now. It has not been easy.
The big deal is that I have tested it and IT WORKS ! ................ which is always useful when you are standing on the thing.

I have also more recently (December 2014) built a twin wheeled scooter inspired by the 1970's Raleigh Chopper using the same Sparkfun digital IMU: Raleigh Chopper inspired self-balancing scooter.

Read my earlier Instructables first if you need more information on the actual physical construction of devices of this kind:
The first skateboard 2010:

The updated control system 2013 using a just-about-still-available analog IMU:

My original big website on all things self-balancing:

will flesh this Instructable out with more information as people ask me questions but I am putting it up right now as I know people have been struggling to obtain the old analog IMU's, so now they have an alternative.

Arduino code attached to step 16. Also attached to step 16 is some code that just allows you to test the IMU and Arduino are talking to each other (it displays tilt angle on your PC screen serial-view window) before you attach all the peripherals like the deadman switch, steering switch and so on (also useful as a start point for people who want to use this for something else).
A video of this "IMU Tester" code working and displaying the angle of tilt on a laptop can be watched here:

Now I will have to remove that "ANALOG" logo from the skateboard.

Step 1: Sparkfun 6dof DIGITAL IMU SEN-10121

Picture of Sparkfun 6dof DIGITAL IMU SEN-10121

View of this IMU.

It is Code number SEN-10121 with Sparkfun.
They describe it as: IMU Digital Combo Board - 6 Degrees of Freedom ITG3200/ADXL345

It has 3 gyros and 3 accelerometers inside.

It communicates with the Arduino using the I2C protocol.

Note for enthusiasts for this sort of thing: 
Pull-up resistors are not required as they are already present on the little red circuit board the IMU sensors are mounted on.
If you don't know what this means it does not matter at all, it just refers to various on-line debates about hooking up this kind of sensor to an Arduino.

Step 2: Sparkfun 6dof Digital IMU

Picture of Sparkfun 6dof Digital IMU

Rear view showing the wiring connections.

Step 3: General Layout of a Typical Self Balancing Skateboard

Picture of General Layout of a Typical Self Balancing Skateboard

Step 4: Orientation of This IMU on the Board

Picture of Orientation of This IMU on the Board

Obviously not to scale, this shows the orientation of the IMU relative to the surface of your skateboard or segway type machine, i.e. lie it flat like this.

Step 5: Wiring Diagram for This IMU

Picture of Wiring Diagram for This IMU

LED's not vital but quite helpful.

IMPORTANT NOTE 23.6.15: One person building this found that the IMU "locked up" and stopped talking to the Arduino. He solved it by making sure he used the SAME GND PIN on the Arduino for both the IMU GND wire and also the 0V wire from the Sabertooth. There are several GND pins on an Arduino Mega and they are connected to each other on the board, however he found it was more reliable if you use the same one for all your GND connections to the Arduino.

Turn machine on with one end tilted down on ground. Wait for the LED's to both come on, while pressing in the "Deadman" switch, it is now ready for you to bring it level. When level the self-balancing will turn itself on and off you go hopefully.

If power to motors is > 50% of maximum one LED will come on while riding it.

If power to motors is > 75% of maximum both LED's will come on while riding it and this is a warning for you to slow down a little.

If you let go of the deadman switch all power to the motors will be cut after a delay of 0.5 seconds (for safety).

The thing on the right is a Dimension Engineering Sabertooth 2 x 25 Amp motor power controller.

The Arduino sends serial commands to it to tell each motor how fast to go and in what direction.

The balancing software loops 100 times per second and in this way it stays level.

There are also wires to some of the digital Pins on the Arduino and these are not shown here. These are from the deadman switch, the steering rocker switch and the rocker switch that allows fine tuning of the balance point to suit each rider.

These connections from the hand controller are all listed in Step 17.

Step 6: Wiring the IMU

Picture of Wiring the IMU

I chose to solder the wires to the Arduino from the IMU as if these connections are not good it will just not work properly.

Before anyone asks what are the extra wires on the remaining analog ports there for, I should just say I have a collection of Arduino boards now that have all been previously used in other projects. The extra wires on the analog ports 0 - 3 are there because I was too lazy to de-solder them! Please ignore them, they do nothing in this project.

Step 7: Powering the Arduino

Picture of Powering the Arduino

Keeping it simple here.

Just using 6 x AA batteries and a switch. 

Plenty of things to go wrong at the debugging stage so keep simple the things you can keep simple.

Step 8: Wiring Sabertooth to the Motors

Picture of Wiring Sabertooth to the Motors

Step 9: Setting Up the Sabertooth

Picture of Setting Up the Sabertooth

Step 10: More on Sabertooth Wiring

Picture of More on Sabertooth Wiring

Step 11: Powering the Sabertooth

Picture of Powering the Sabertooth

Step 12: Deadman, Steering and Balance-point Adjustment Switches

Picture of Deadman, Steering and Balance-point Adjustment Switches

I use a good quality microswitch for my deadman switch which "clicks" between 2 states, either on or off and nothing in between.

Pushbutton push-to-make switches, especially cheap hobby ones, have a mid zone if you only gently press the button of "just about unreliably on" which is totally not suitable for a machine like this. I have found this out the hard way by falling off.

The code has a variable that counts down to zero over 0.5 sec then cuts all power if you let go of the deadman switch. This means if the switch has dirty contacts, it will tolerate a disconnection lasting less than 0.5 sec without throwing you off.
Little things like this are important for a good user experience and again, I have been learned this the hard way!

Alternative for even better reliability would possibly be to use a double pole micro-switch, if such a thing exists, as deadman switch and wire the connections in parallel so if one contact is dirty and unreliable, the other will still do the job.

People often ask me how to use a potentiometer to create more proportional steering. It can be done of course but I would say keep it as simple as possible until you get your machine balancing OK with you on it, then, and only then, start worrying about other things. A rocker switch (NB: with a mid point where neither output is connected to GND) is simplest way to achieve steering. It is in fact "proportional" as machine tries to turn more, the longer the time you flick the switch left or right for.

Step 13: Hand Controller Detail View

Picture of Hand Controller Detail View

Step 14: Libraries You Need to Download and Put in Your Arduino Libraries Folder

Picture of Libraries You Need to Download and Put in Your Arduino Libraries Folder

Download the folder "FreeSixIMU" from this website and put whole folder into your Arduino libraries folder so then the libraries listed above can be accessed by the Arduino.

Instructions on how to download this folder and put it into your Arduino libraries folder can be found here on
this website (scroll down the page about half way):

Step 15: Putting "FreeSixIMU" Into Your Libraries Folder

Picture of Putting "FreeSixIMU" Into Your Libraries Folder

Step 16: The CODE

Picture of The CODE


This was written on Arduino Version 1.5

I have tried to attach it as an .ino  file as used by Arduino 1.5 but Instructables will not let me upload it.

Therefore have also attached it as a text document which, if copied and pasted into a new empty Arduino sketch, should then compile OK and save OK.

I have also attached a sketch (again as a text file) that allows you to wire up the IMU only, attach the Arduino via its USB cable to your computer, open the "Serial View" window (set to 9600 Baud) then play with tilting the IMU. The Angle of tilt from vertical will be displayed on the computer screen in the serial view window at half second intervals. 
Zero is level, -ve values appear (in degrees of tilt from "level") if you tilt it one way and similar sized +ve values appear if you tilt it the other way. Start with your IMU flat on table with the surface mount components facing upwards.
This allows you to test the IMU and Arduino are talking to each other, before you attach everything else such as the Sabertooth, rocker switches and deadman switch.

Here is a video of the IMU tester code sending the tilt angle to the laptop screen with the Arduino serial view window open:

Step 17: Digital Pin Listing for the Arduino

Two of the analog pins are also the pins SCL and SDA that connect to the Sparkfun IMU.
This has already been covered earlier on.
Lets now just confirm what each of the Digital Pins are connected to:

Arduino Digital (not analog) Pin                    What it does

2                                    Balance fine trim switch nose down slightly
3                                    Balance fine trim switch nose up slightly

4                                    Turn left connection on steering rocker switch
5                                    Turn right connection on steering rocker switch

9                                    Deadman switch (if you let go of this button all power to motors is cut).
                                      Safety feature.

1                                    Tx (transmit) pin from Arduino to Sabertooth motor power controller.
                                       It sends the motor power commands to the Sabertooth via a
                                       Serial communication.

***********NOTE   NOTE   NOTE   NOTE   NOTE*************************************
NOTE: You have to UNPLUG this Digital 1 Pin from the Arduino while you load the
program (sketch) else it will not load.
Once sketch is loaded, put this pin back into its socket on the Arduino again
so it can talk to the Sabertooth.

Note (for the experts) I could not use SoftSerial for this communication with the Sabertooth,
and so use a more convenient pin, as softserial would not work.
Not sure if running out of memory or what!

10                                                                          LED 1
11                                                                          LED 2


Leotiedt (author)2017-01-02

Hi XenonJohn,

I have one short question: Is it possible to use a SyRen 50A motor driver ( instead of the Sabertooth? I know that that the SyRen can just control one motor but I want to build a self-balancing unicycle. Is that possible without modifying the code? Is the communication from the Sabertooth and the SyRen the same so that the SyRen isn`t confused about, for example, that code line:

cSpeedVal_Motor2 = map (Motor2percent,






Thank you very much and a happy new year


Dawn Chang (author)2016-11-16

Good work

RicardoTrevD (author)2016-05-10

I try to make the same but it doesn't move at all, only turned on the leds after a few seconds. If anyone could help me, I'll appreciate your help. I'm using the MPU6050 PLEASE It's urgent.

Sasa_D (author)RicardoTrevD2016-07-21

I ran into lot of issues using mpu6050. Start using LSM6DS33 It works perfectly.

XenonJohn (author)RicardoTrevD2016-07-06

The code is not written for the MPU6050. It was written for the specific Sparkfun one described in the Instructable.

All the IMU's out there are not the same.

mohdnazrin (author)2016-06-23

Hi John,

I would like to use Wii Nunchuck + its adapter as hand controller. I'm using Wiichuck.h from . I found that in order to use this Wii chuck, I need analog pin 2,3,4 and 5. But in this tutorial the 6Dof IMU will use pin analog 4 & 5. Could I move /reprogram IMU code to change pin assignment to 0 & 1 respectively. If can pls advice... thank you

RicardoTrevD (author)2016-05-10

I try to make the same but it doesn't move at all, only turned on the leds after a few seconds, I'm using the MPU6050. If you anyone could help me, I'll appreciate your help. PLEASE It's urgent.

KiRkKi (author)2015-05-17

Hi! great instructable, I have a question about the gyroscope and it is if i can use the MPU 6050 instead since i already have a few of those.

thanks :)

RicardoTrevD (author)KiRkKi2016-05-10

I have the same problem. Did you fix it? How? I try to make the same but it doesn't move at all, only turned on the leds after a few seconds. If you could help me, I'll appreciate your help or someone else. PLEASE It's urgent.

jellis28 (author)2015-06-09

im rying to run the tester code with an mpu6050 gy-521 from the sainsmart self balancing robot. all i get on my serial monitor is 0's there is no change in angle as i move the imu. i thought the imu would work because it has the same output pins. what do you think could be the issue?

RicardoTrevD (author)jellis282016-05-10

I have the same problem. Did you fix it? How? I try to make the same but it doesn't move at all, only turned on the leds after a few seconds. If you could help me, I'll appreciate your help or someone else. PLEASE It's urgent.

EliasE2 (author)2016-03-20

Nice tutorial

I want to try this out and already have a imu 6050, communicating to my arduino using IC2, laying arround. Would this work instead of the 6dof imu?

What code changes would be needed?

Thanks for your answer and sorry for my bad English :P


CaelanB1 (author)2016-02-26

so how do i set up the sabertooth if I'm using lithium batteries to power my motor. because you said your set up was for none lithium batteries.

chronoxxx (author)2014-08-29

IMU works with my Segway clone -->

Build this with 2 x 300 watt brushed scooter motors... 2 x agm 9 Ah batteries... wheels comes from a mini-dirt bike, changed the sprockets from 54 tooth to 78 tooth sprocket( had to drill new holes in it) for a better ratio (7,09:1)

LiamOSM (author)chronoxxx2016-01-22

I know this was posted a year ago, but your video is private so we can't watch it.

LiamOSM (author)2016-01-22

Just ran the IMU tester on my brand new 6DOF and it works well. Can't wait to try it with motors!

RabbiSam (author)2016-01-06

Where did you get the motors, i don't know where to get them and which ones to get

docx1 made it! (author)2015-06-21

Hi all, I have made my version of this approach but it seams to have some kind of bug or glitch in code or in my Arduino. After 4-10 seconds it simply remembers last command and loops it. For example if I go forward and I tilt it back he does not react and continues to go forward. Does anybody have this glitch and does anybody know how to solve it? I have tried altering code but nothing good came from that. And does anybody know how to limit speed since I have two 350W motors?

Thanks in advance.
p.s. if you help me, I will post my Instructable with details how I made it.

docx1 (author)docx12015-06-22

I have figure it out, the problem was that IMU GND was not at same GND as Sabertooth and that caused some kind of glitch. At John's instructable about Chopper, hackerboysf has explained that he also had simmilar problem.

Now my last problem is that if I stand on it and I tilt it, it doesn't move. Maybe it is because of batteries (fingers crossed) or if it's not then to the sprocket ratio. I have on motor 11 tooth sprocket and on wheels diameter around 34cm, 44 tooth sprocket. Motors are 350W and have 1.2Nm of torque per each but maybe that could be not enough. What do you think?

SN_Goodlife (author)2015-06-19

@basbuma can You Tell me about the Problem and the Solution?

runwild14 (author)2015-03-12

i am trying to run the IMU on a 9 volt battery, and using LEDs to visualize the angles from the IMU. When I hook it up to a serial USB to a computer, it works, but on battery, the LEDs do not light up, I do not think the IMU is communicating properly with the arduino. I'm having trouble finding the problem

SN_Goodlife (author)2015-03-01

Hello sir, my Name is Basti and iam from Germany and i Love your Project! My Problem is that my sabertooth only send 12v to my Motor? What can i do? My sabertooth is the 2x32. Sorry for my Bad Englisch

basbuma (author)2014-11-27

Hi John,

great work!

We are a beginner in dealing with Arduino. This is our first major project. We use similar components: an Arduino Mega 2560 and a Sabertooth 2x32. Each component itself works fine. The IMU test program indicates the angle on the screen of my laptop reliable. We can also control the Sabertooth good and reliable when the angle is not read from the IMU. If we use the two components together, the Arduino hangs up on the call of the IMU Library. (Place in the code: sixDOF.getYawPitchRoll (angles))

Thanks in advance


soumyadip.purkayastha (author)2014-11-12

can this code be used with some other motor driver which doesn't have dip switches? is it necessary to us all the same exact components?

dbasra (author)2014-11-07

Could this code me modified to work with a A+A- B+B- type h-bridge? The sabers are kinda expensive?

jchen4coxnet (author)2014-09-07

Hi, I can't find the "freesiximu" library from the website. Can someone help me find it? Thanks.

Never mind, I got it, thanks anyway.

Kstuck (author)2014-08-28

Another great Instructable!

I have been following your development of the medical urban responder.

can see where the three potentiometers adjust values for the PID. The
fourth potentiometer is overall gain? I'm a little lost on what variable
this adjusts and how this is implemented into the code. Could you give a
brief explanation?

Thanks again for all of your hard work!

peraz91 (author)2014-08-19

Today I got the 6 DOF!
With this new IMU system is more accurate?

Dean_wood (author)2014-08-13

My seg is on way. Can you tell me, in your experience, where is the best for place gyro with respect to the axis of the wheel? Thank You!

peraz91 (author)2014-08-11

Good job! My segway now is update.... Wheels big off road

tranef (author)2014-05-29


I've just finished hooking everything up but the motors are acting strangely: they run and they cut randomly.

I'm using a 2Amp power supply, would this be the problem?


charlie8265 (author)2014-05-10

Hello John,

Great Instructable !

I have made a segway using your instructions and code, and its balance is not quite there yet. I am using geared wheelchair motors and I feel the PID parameters may need to be tweeked. Can you tell me how to fine tune your code to make this work?



XenonJohn (author)charlie82652014-05-26

Lots of ways on the web but simplest way is this:Set P I and D to zero or near zero.

Increase P value is steps until machine starts to oscillate when it is trying to balance. Then reduce the P value to about 2/3 of the value that made it oscillate.

Then increase the D value in steps. Deliberately tilt the machine forwards suddenly and see how fast it comes back to the level position. If it overshoots backwards the D value is too high, you want it to rapidly come back to level position without overshoot.

Next, increase the I value. Machine will in fact balance with no I value at all but with I value it will move according to how long (in time) it has been tilted for, helpful when going up a slope for example.

Hope this helps


anthology (author)2014-05-23


perfect work

can you post the code for controlling with remote controler ?

thanks a lot

tranef (author)2014-05-01

Hi John,

Would this code work with the nunchuk?

XenonJohn (author)tranef2014-05-03


There are self balancers using Wii sensors but to be honest the hobby IMU's have become cheaper since then to just buy and use.

tranef (author)2014-03-29

Thanks John for this incredible instructable! You're amazing!

Little question: How would I implement this code to work with the 'one wheel go kart version'. Will the code need to be heavily modified? Would a standard 250w brushed motor provide enough power?


XenonJohn (author)tranef2014-04-23

If you used big enough reduction gearing , I.e. Small sprocket on motor and big one on wheel then it should be ok with a 250watt motor but not very fast
Code would not need much modification.

tranef (author)XenonJohn2014-04-30

Thanks! IMU now working, I'll let you guys know my progress throughout the project :)

rathodrg (author)2014-04-04

i connected whole circuit as given by you.

I checked pwm output on oscilloscope, tried to tilt imu, still no change in pwm output.

XenonJohn (author)rathodrg2014-04-23

It's not a pwm output.
Output is a serial value as the code presently stands and the saber tooth is set in serial mode using the little dip switches .

mylemonjuice (author)rathodrg2014-04-11

I may have the same problem like yours. Could you see the complete square wave about 50Hz on the oscilloscope? I just got some 30MHz pulse :(

But actually I don't get the IMU yet.

tranef (author)2014-04-16

Hi everyone!

I can't get the IMU tester working. I've hooked everything up correctly but nothing is written in the serial port window. I've checked my COM port, serial rate , everything and it's not working!

Could you guys help me out?


XenonJohn (author)tranef2014-04-21


I reassembled it, loaded the IMU tester code from this instructable and it worked OK.

Video here on youtube:

Make sure the Analog pins 4 and 5 are wired to correct holes on the IMU. Make sure you have the libraries loaded (it will not compile without so you would know if that was problem), also keep the wires to the IMU fairly SHORT at least early on.


XenonJohn (author)tranef2014-04-21

Hi tranef,

I will reassemble it, check it and make a video. Give me a few days though as I have a real-world job, despite this being more fun! Anyone in the UK will find me at the Newcastle Maker Faire 26th/27th April next weekend if you want to chat and discuss.


rathodrg (author)2014-04-03

I am unable to understand what is input to pin a0, a1, a2. What is connected to these pins?

please upload full circuit diagram.

if i have two motor controllers (not sabertooth drivers), what i have to change in program?

XenonJohn (author)rathodrg2014-04-21

In step 6 I state that the extra wires are there because the arduino I used has also previously been used for lots of other projects. The Wires seen in the photo on a0 a1 a2 do nothing in this instructable and the wiring diagram I have given is correct as it stands.

tranef (author)2014-04-16

Hi everyone!

I can't get the IMU tester working. I've hooked everything up correctly but nothing is written in the serial port window. I've checked my COM port, serial rate , everything and it's not working!

Could you guys help me out?


mylemonjuice (author)2014-04-11

Hello John,

Thanks for your amazing making!

I just have a little question.Can I use the electronic controller from rc car instead of the sabertooth? Are they control by the same signal?

I just want to make a little self-balancer :)


About This Instructable




More by XenonJohn:Floating Death Star Build 2017Ardu McDuino: Bagpipe playing robot (chanter)Star Wars Maz Kanata Inspired Glasses
Add instructable to: