FreeIMU: an Open Hardware Framework for Orientation and Motion Sensing

FreeIMU is an ongoing research project which aims to design Open Hardware 9/10 DOM/DOF Inertial Measurement Units as well as easy to use Orientation and Motion Sensing libraries, built on top of the Arduino platform.
The goal of the FreeIMU Framework is to simplify the development of projects based upon the most powerful and new consumer grade inertial, magnetic and pressure sensors.

FreeIMU version 0.2 (left) and version 0.1 (right)

The main application of FreeIMU is orientation sensing: by reading the data from the various sensors is possible to compute precisely the orientation of FreeIMU in the space. Recent boards also feature an high resolution barometer allowing to precisely track the device altitude. This can be useful in many applications: human-computer interaction device prototyping, flying machines, robots, human movement tracking and everywhere orientation sensing is a key aspect.

As FreeIMU breakout the sensors interrupt pins, it's also possible to detect per axis single and double taps, free fall as well as activity or inactivity. This makes FreeIMU a very good choice for Human-Computer devices prototyping. Interrupts pins are also very useful if you are into interrupt based reading of the sensors, useful to develop high frequency interrupt based sensor reading.

Video presentation of FreeIMU

Older video presentations: FreeIMU v0.3, FreeIMU v0.1 and 0.2.

A true Open Hardware project

Open Hardware Logo

FreeIMU is a true Open hardware, released under the CC-BY-SA. You are free, actually encouraged, to use it for any purpose, to study and modify its designs, to make your own copies of FreeIMU and even sell your own FreeIMU based hardware. But, you will have to share your designs based on FreeIMU keeping attribution and sharing them using the same libre license.

On FreeIMU repository (see development section below) and from the downloads on this page, you have access to everything you need to build your own FreeIMU board. You have access to the schematics, the PCB designs and even the bill of material so that you can build your own FreeIMU.

Moreover, FreeIMU has been designed using KiCAD, an excellent libre PCB design software, so you don't have to rely on proprietary software to study or modify FreeIMU.

Getting FreeIMU

An assembled, tested and ready to use FreeIMU board can be bought from:

The FreeIMUs boards bought from the above shops financially support the project. The boards have been produced and assembled in Italy by reasonably paid workers in a safe environment in respect with European and Italian laws.

Build your own FreeIMU

If you have SMD soldering experience (or if you are up for experimentation) you can build your own FreeIMU. From the downloads below you have access to all the designs needed to have your FreeIMU PCB manufactured.

You can get cheap PCB with awesome quality from Dorkbot PDX and order the various components needed from you favorite electronic distributor: the Bill of Materials (BOM) files will tell you exactly which components you'll need for your FreeIMU.

The are various ways of soldering the board. If you only need a couple of boards done, tack flux, solder wire and hot air reflow station are enough to build your boards (Remember not to use hot air over the pressure sensor). See this video for good instructions. In case you are building more units, an SMD stencil with solder paste is the suggested method.

In case you need help, just post a comment below.

FreeIMU versions

FreeIMU version 0.1

FreeIMU v0.1

WARNING: Discontinued due to the phasing out of the HMC5843.

FreeIMU v0.1 is the simplest FreeIMU available. It contains the ADXL345 accelerometer, the ITG3200 gyroscope and the HMC5843 magnetometer, their respective capacitors and an additional 10uF capacitor to help keeping the power to the sensors stable. It doesn't have any voltage regulator nor any level translator so it needs to be connected to a 3.3V power source and the I2C level signals have to be 3.3V. When used on a 5V microcontroller, an I2C level converter and a voltage regulator are needed.

FreeIMU version 0.2

FreeIMU v0.2

WARNING: Discontinued due to the phasing out of the HMC5843.

FreeIMU v0.2 has the same sensors (ADXL345, ITG3200 and HMC5843) and size of v0.1 but I added an integrated voltage regulator (MIC5205) and a logic level converter (PCA9306). With these components it's extremely simple to use FreeIMU v0.2 on 5V boards like 16MHz Arduinos, just connect FreeIMU to the 5V, GND, SDA and SCL on Arduino and you are ready to go!

IMPORTANT: in version 0.2 sent to production there is a bug in the drill size of the connectors. The drill hole should have been 0.04" while it is actually 0.032". Consequence of this is that only rounded pins will fit inside the drill and standard squared pins won't fit. This is not really a problem as the big oval pad makes actually possible to use 90 deg squared pin arrays using the pad as a smd connector. The Kicad sources above and the gerbers marked with "Fixed" have this issue fixed. However they haven't been tested on production so double check them before send them to fabrication.

FreeIMU version 0.3

FreeIMU v0.3

FreeIMU version 0.3 replaces the accelerometer and magnetometers used in v0.1 and v0.2 with the ADXL346 as accelerometer and the HMC5883L as magnetometer. The gyroscope is still the ITG3200. FreeIMU v0.3 integrates a voltage regulator (MIC5205) and a logic level translator (PCA9306) as well as all the pullups resistors needed.

FreeIMU version 0.3.1

FreeIMU v0.3.1 is a minor revision of FreeIMU v0.3. There have been some corrections in the silkscreen and the footprint of the HMC5883L have been made slightly bigger to make assembly easy. Everything else is just as in FreeIMU v0.3.

FreeIMU version 0.3.5

FreeIMU 0.3.5 top view

FreeIMU 0.3.5 is a small (22x20 mm) 9 degrees of measurement IMU MARG sensor featuring the BMA180 accelerometer, the ITG3200 gyroscope and the HMC5883L magnetometer.

FreeIMU 0.3.5 also has two additional subversions, FreeIMU 0.3.5_MS which features the MS5611-01BA high resolution pressure sensor and the FreeIMU 0.3.5_BMP which features the BMP085 pressure sensor.

FreeIMU v0.3.5 has an integrated voltage regulator (MIC5203) allowing you to plug it from 3V3 to 16V providing you 80mA of current which you can use to chain it to other 3V3 sensors or devices. By using the MIC5203, no tantalum caps are used in the whole design. Tantalum is not a good idea socially and environmentally.

The board has integrated 2K2 pullups resistors (which can be enabled or disabled by means of a solder switch) but doesn't have an integrated logic level converter. We decided to not include the LLC (which is present in my FreeIMU v0.2 and v0.3) as it adds considerable complexity in the design and schematics without being strictly necessary. In fact, given a properly configured software, it's a redundant part. Moreover the upcoming development of many 3V3 based control boards (eg: Multipilot 32) makes adding an LLC not a very far-seeing choice.

The IMU board is however compatible with my LLC board which can be stacked above the IMU, so that you can easily add the LLC protection keeping the amount of additional wires at the minimum.

The board, a part from the usual power and I2C connectors, breaks out the interrupt pins for all the three sensors. This should empower software developers to design interrupt based sensor reading and sensor fusion algorithms (opposed to the currently common polling based approach) which should provide possibility to shorten the cycle path of our algorithms.

FreeIMU version 0.3.5_MS

FreeIMU v0.3.5_MS

FreeIMU v0.3.5_MS is a variation of FreeIMU v0.3.5 which features the BMA180 accelerometer, the ITG3200 gyroscope, the HMC5883L magnetometer and the MS5611-01BA high resolution pressure sensor.

The board comes with a voltage regulator (MIC5203) and 2K2 pullups optionally disabled by using of a solder switch.

FreeIMU version 0.3.5_BMP

FreeIMU v0.3.5_BMP top view

FreeIMU v0.3.5_BMP is a variation of FreeIMU v0.3.5 which features the BMA180 accelerometer, the ITG3200 gyroscope, the HMC5883L magnetometer and the BMP085 pressure sensor.

The board comes with a voltage regulator (MIC5203) and 2K2 pullups optionally disabled by using of a solder switch.

FreeIMU version 0.4

FreeIMU v0.4.1

FreeIMU v0.4 features the MPU6050 gyroscope+accelerometer, the HMC5883L magnetometer and the MS5611-01BA high resolution altimeter.

The magnetometer is attached to the AUX I2C bus of the MPU6050 thus allowing it to be read directly by the MPU6050.

FreeIMU library

FreeIMU can be easily used on Arduino compatible boards using the Arduino FreeIMU library which implements sensor fusion MARG orientation filter enabling you to do easy and straightforward orientation sensing.

FreeIMU library - 2012/11/22
Use Arduino 1.0.1 IDE or later version.

Install the libraries as explained in the Arduino Libraries Reference section Contributed Libraries.
The FreeIMU library now supports all the versions up to v0.4. By default it's configured to be used on v0.4. In order to use on different boards, open the file FreeIMU.h and uncomment the correct version of your board.

The FreeIMU library also supports the following 3rd parties boards:

  • Sparkfun IMU Digital Combo Board - 6 Degrees of Freedom ITG3200/ADXL345 SEN-10121
  • Sparkfun 9 Degrees of Freedom - Razor IMU SEN-10736
  • Sparkfun 9 Degrees of Freedom - Sensor Stick SEN-10724
  • Sparkfun 9 Degrees of Freedom - Sensor Stick SEN-10183
  • DIYDrones ArduIMU+ V3
  • Generic MPU6050 Breakout boards (eg: GY-521, SEN-11028 and other MPU6050 wich have the MPU6050 AD0 pin connected to GND.)

Note for FreeIMU v0.1 and 0.2 users: from April 2011 the default magnetometer configuration is for HMC5883L. In order to use the library with HMC5843 (v0.1 and v0.2) edit the file HMC58X3.h and uncomment the line #define ISHMC5843.

FreeIMU Processing Programs
The FreeIMU library comes with Processing visualization demos. In order to use them, Download and install Processing. Copy the folders within the processing folder of the FreeIMU library archive into your Processing sketchbook.
Remember to change the Serial port address in the Processing code to match the address used by arduino on your system.

Ports to Other platforms

FreeIMU library on PIC 24 microcontroller by Hari Nair hair [dot] nair [at] gmail [dot] com. Author notes: 1. assumes a 6MHz crystal is attached and x4PLL internally, so Fosc = (6x4)/2 = 12 Mhz 2. trivial to use the internal FRC oscillator, instead of FNOSC_PRIPLL in the configuration words, use FNOSC_FRCPLL. This will give you Fosc = (8x4)/2 = 16MHz, but of course with less precision. 3. transmits ascii quaternion data at 38400baud. This does slow down the sampling rate. Without the quaternion print, the code completes in less than 10mS, so the sampling rate is exactly 100Hz as set by the timer.

FreeIMU library on NXP LPC1343 Cortex m3 processor by Hari Nair hair [dot] nair [at] gmail [dot] com. More details and possibility to contact the author on the FreeIMU community development forum.

Have you ported the FreeIMU library to other platforms? Please let me know and I'll list your work here!


A calibration GUI application is available. The software is currently in alpha state, however many people are already using it.

The calibration, when properly executed, drastically improve the orientation sensing performance of the FreeIMU framework. If you are experiencing drifting or inconsistent results, your sensors may need to be calibrated using the Calibration GUI.


There is now a FreeIMU Community website, which has been set up to become the central point of interaction between users of the FreeIMU framework. This is the place where you can get help, join others in developing new features, discuss IMUs applications and much more.

Previously we used FreeIMU answers on Launchpad as well as comments on Fabio's website for supporting users, however we decided to create an ad-hoc website to facilitate information gathering and collaboration between people.

Development, Bug Reports and Suggestions

Development of FreeIMU boards and libraries can be followed on FreeIMU project page on Launchpad which also hosts our software and hardware repository.

Suggestions or bug reports can be made on the FreeIMU Community, in the development forum.Previously bug reports were posted on the Launchpad bug reporting interface but that's not used anymore.

FreeIMU repository holds all the various library sources as well as design files and schematics. Everything is revisioned meaning that all the changes are logged and annotated.

The contents of the repository are available using Bazaar (bzr) with the command:
bzr co lp:freeimu

Never used bzr before? Not a big deal, it's very similar to git, svn or others. You may wanna have a look at the cheatsheet to have an overview of the commands available or read more documentation on bzr.

Alternatively, in case you have problems setting up bzr on your system, you can simply get the latest repository contents from here. The resulting file is a .tar.gz archive which can be opened with the excellent 7zip under Windows. Mac and Linux users shouldn't have problems opening such files.

The files on the repository can also browsed from a browser here. A list of recent changes is available here.

FreeIMU users videos

Here some videos made by FreeIMU users on their projects using FreeIMU.

rtsdrums flies like crazy with FreeIMU on his quadcopter.. check out the triple flip!

Warthox testing indoor FreeIMU v0.4r3 on one of his quadcopters.

Warthox stress test FreeIMU v0.3.5_MS on one of his quadcopters.

Chris uses FreeIMU on his VTOL EDF Tricopter powered by the MultiWii software.

Danilo Del Console uses FreeIMU in a 2 wheels self balancing robot.

Francesco Ferrara uses FreeIMU for a camera stabilization system.

Francesco Ferrara with his super fast implementation of the AHRS algorithm capable of displaying the rotating cube at 333Hz with FreeIMU! Great work!

Marchino65 with his first test with FreeIMU and the FreeIMU library on Arduino. The cube is spinning pretty good!

Francesco Ferrara in his first flight with FreeIMU on his very young quadcopter project called Simplo.

Sorry for not replying

Submitted by fabio on Sat, 2012-06-16 00:31.

Sorry for not replying before.. looks like I missed your comments. Sorry for that.

That's very strange what you are seeing.. drifting caused by uncalibrated magnetometer usually is in the 10-15 degrees, not a minute or so of drifting.

Please post a piece of the raw output of your board...

Also.. are you using the board near sources of electro magnetic interferences? Like speakers, lamps, iron tables, etc...


Submitted by zencuke (not verified) on Sat, 2012-06-16 15:58.


Thanks for the reply.

I'll have to get back to you on most of your questions. I just purchased a couple of LIPO batteries but when I plugged one into my Seed Stalker sparks happened and many things no longer work. I thought the battery connector was polarized but seedstudio apparently used a non standard connector that fits either way. Like an idiot I had the FreeIMU plugged in when I tried the battery so I don't know if it is even alive. I'll switch to my Pro Mini and see what happens. If I have to buy another FreeIMU it will take a while for me to save up my pennies again. Sigh...

For these experiments the FreeIMU sits on my desk between the Mac, keyboard and monitor. There is nothing else within 2 feet unless there is something strange I forgot about in one of my desk drawers. ;-)


Wow. Sometimes that happens..

Submitted by fabio on Sun, 2012-06-17 00:28.

Wow. Sometimes that happens.. to everyone no matters how experienced.

If you had connected the board to the 5V connector, it's still probably alive (the voltage regulator can handle up to 12V reversed/shorted voltage)... but if you were using the 3V3 connector... well, cross your fingers! :-)

Some Advice?

Submitted by Matthew Biermann (not verified) on Sat, 2012-05-26 13:48.

Hi Fabio, great site and great work! I am currently working on a senior class project to implement a 6DOF module and Arduino and have found your work and others very informative. However, I am still in early stage of development figuring out which direction to go and just had a couple simple questions for you (and I apologize if you have explained this elsewhere):

1) You look like you are mainly programming in C and not the Arduino language. What IDE do you use for development for this? Any recommendations? Arduino plugin for Eclipse? AVRSTudio?

2) Do you have a particular resource you can point me to to start figuring out how to translate one of these axes of movements into a PWM output? Is it a special C library for the ATMEGA? Will I need to create my own?

There is such a flood of information and options out there I was hoping you could steer me down the right path.

Thanks again!

1) If you look closely,

Submitted by fabio on Sat, 2012-05-26 18:36.

1) If you look closely, you'll see that, even if I'm writing C++ code with classes, I'm still using Arduino libraries. Also, the example programs strictly follow the Arduino programming conventions.

Personally, while I find the Arduino environment pretty comfortable in terms of APIs ease of use, I don't really like the IDE. So, I'm using the IDE with the "use external editor" option turned on, so that I can use my favorite editor (Kate) for editing source files and only use the Arduino IDE to compile and upload the programs.

2) I need more informations on the application you are developing to answer.

Thanks for your reply! I

Submitted by Matthew Biermann (not verified) on Sat, 2012-05-26 18:50.

Thanks for your reply! I guess I need to spend more time going over the Arduino libraries and code!

What I would like to do is simply use a single axis to control the output of a PWM which would thus feed a VCO for sound output. You rotate the unit right, the pitch goes up (duty cycle increases). You rotate the unit left and the pitch goes down (decrease the duty cycle).

I was able to get this working with just a simple gyroscope, but the drift was unbearable, which led me to your fantastic work here! The thing is I am still learning the Arduino environment and code and am a little intimidated by all that math... Is there a way to simply access just a single axis' angle information to then convert into a PWM output?

ie, 0 to 90 degrees = 2.5 V to 5 V and 0 to -90 = 2.5 V to 0 V? I can do the conversions into the PWM output (analogWrite() method), I was just wondering how to get the angle values of a single axis in the Arduino IDE to do that?


Have a look at the

Submitted by fabio on Sat, 2012-05-26 19:01.

Have a look at the FreeIMU_yawpitchroll example in the FreeIMU library. That example will show you how to use the getYawPitchRoll function which will return the 3 angles of rotation you need.

Once you have them, simply feed one of its angle, opportunely scaled, to the analogWrite function of the Arduino API.

It shouldn't bee too complex. Write here if you need support.

Nice! Just found it and

Submitted by Matthew Biermann (not verified) on Sat, 2012-05-26 19:11.

Nice! Just found it and testing now. I will gladly post my results when I have something.

ThereMEM Working Proof of Concept

Submitted by Matthew Biermann (not verified) on Mon, 2012-06-04 04:24.

Fabio, just wanted to thank you once again for your help. I was able to get the axis rotation information needed to drive the PWM output of the Arduino, and as you can see from the videos, I am making some progress.

I have some fine-tuning to do (literally). Apologies for the bad artistry. I only built the thing. Hopefully someone else can learn how to play it better than I can! :)


Awesome! I like it!

Submitted by fabio on Mon, 2012-06-04 08:30.

Awesome! I like it!

Magnetometer broken on my FreeIMU v0.4r3?

Submitted by Bobotus (not verified) on Thu, 2012-05-24 23:17.


My new IMU seems to be broken :(

Library tested: (Had to resort to the alternative Wire.h to compile in Arduino 1.0)

FreeIMU_raw gives only zeroes except for temperature & pressure which seem to work just fine.

However MPU6050_raw seems to work just fine.

HMC58X3_basic gives just static output like this:
Ints x:27909,27653,27397, Floats x:27909.00 y:27653.00 z:27397.00 Heading: 44.74 (no change when moving the board)

Tested with Arduino Nano (328P) with and without logic level converter.

Am I missing something?

Hello Bobotus, did you follow

Submitted by fabio on Fri, 2012-05-25 09:52.

Hello Bobotus, did you follow this instruction? Have you selected the correct board version in FreeIMU.h?

The FreeIMU library now supports all the versions up to v0.4. By default it's configured to be used on v0.3.5_MS. In order to use on different boards, open the file FreeIMU.h and uncomment the correct version of your board.

That did the trick

Submitted by Bobotus (not verified) on Fri, 2012-05-25 12:01.

I tried, but apparently failed. Shouldn't do these things when tired :) Now it works flawlessly.

Thank you for the fast reply, and maybe add a reminder to the library test sketches about the board selection in future releases :p

And I guess since the magnetometer is connected to the MPU6050 AUX channel, the HMC58X3 test sketches wont work?

Hopefully this comment helps some other tired customer :)

Exactly.. the software would

Submitted by fabio on Fri, 2012-05-25 18:02.

Exactly.. the software would need to enable the i2c bypass mode in the MPU6050 before loading the HMC5883L code... putting this on my todo list ;-)

vibration issues

Submitted by Tom (not verified) on Tue, 2012-05-22 13:41.


I am using the FREEIMU library and was thinking about implementing a simple low pass filter to eliminate positioning errors from the acceleration sensor.
I have false roll and pitch values during certain frequencies...

I used a Kalman filter before I started using the FREEIMU and achieved good results by low-pass filtering the acceleration sensor.

What you guys think?

That's surely an option.. you

Submitted by fabio on Tue, 2012-05-22 15:59.

That's surely an option.. you may also want to investigate the integrated DLPF features of your sensors.. ADXL345, BMA180 and MPU6050 have them and save the main microcontroller for additional computations.

Great idea, thanks.

Submitted by Tom (not verified) on Wed, 2012-05-23 10:14.

Great idea, thanks. Unfortunately I did not find anything in the datasheet. I use an ADXL345...

Can you give me some hints, please?


ehm.. ops.. sorry, looks like

Submitted by fabio on Wed, 2012-05-23 10:49.

ehm.. ops.. sorry, looks like the ADXL345 doesn't have integrated LPF circuitry.. I'm using too many sensors and I sometime confuse between them! Sorry.

So, it looks like you only have the possibility to filter that in software.

Our Balancing Robot

Submitted by patrice (not verified) on Wed, 2012-05-16 11:13.

Hi Guys,

Here is what we've made with the IMU

you can see that it really stable !!

Very nice

Submitted by Osman Eralp (not verified) on Wed, 2012-05-16 16:19.

Your bot looks very stable! Did you use the FreeIMU Arduino library for the sensor fusion?

Good work! Any chance you

Submitted by fabio on Wed, 2012-05-16 11:27.

Good work! Any chance you could share a bit more about the project? A couple of pictures and something about the implementation? (microcontroller used, programming language, communication, etc?)

I'd love to make a blog post on your work.


Submitted by patrice (not verified) on Wed, 2012-05-16 15:48.

We've used an Arduino Mega programmed in C.
We communicated in Bluetooth or Wifi via a laptop that we put in the body.

Two control Loop is working based on X position and angle.

We have a channel on Facebook Projet JBot if you are interrested.

Why Honeywell mag instead of Freescale mag?

Submitted by Osman Eralp (not verified) on Sat, 2012-05-05 06:05.

I was looking for AHRS code for an IMU that I designed when I came across your site. You've done a great job of documenting your project! I'm also using the Invensense MPU-6050, but on my IMU I used the Freescale MAG3110. It's about half the cost of the Honeywell mag. Did you consider using the Freescale mag when designing the FreeIMU? Thanks!

I wasn't aware of that sensor

Submitted by fabio on Mon, 2012-05-07 11:27.

I wasn't aware of that sensor when I designed v0.4r3.. I'll consider/test it on the next revision.

help for a self balancing bot

Submitted by Anonymous (not verified) on Sat, 2012-04-21 04:16.


i have been working on this project for past 3 months
found your code at tested with the 6dof digital imu from sparkfun

i would like to know what changes do i have to make in your code with an on chip filter so as to get measured values of pitch and yaw so as to drive the motors? if i have to use this library what do i need here?

please help
its urgent

has any one done a similar project with the same IMU and willing to share their code?

i tried the example to get

Submitted by Anonymous (not verified) on Sat, 2012-04-21 05:45.

i tried the example to get pitch roll and yaw
it works fine but der seems to be a drift

can someone help me implement a simple kalman

Try this link

Submitted by Mickey (not verified) on Fri, 2012-04-27 13:24.

Altitude fusion ?

Submitted by Cam (not verified) on Thu, 2012-04-19 17:18.


I wonder if your library supports any sort of sensor fusing to improve the altitude readings provided by the barometric pressure sensor ? Barometer and accelerometer possibly.


I don't have yet published

Submitted by fabio on Thu, 2012-04-19 17:44.

I don't have yet published anything about this yet.. however I'm working on this so probably something will be included soon...

Excellent news ! Where is

Submitted by Cam (not verified) on Thu, 2012-04-19 17:51.

Excellent news ! Where is best to check for the arrival of this update.

Here or on the blog...

Submitted by fabio on Thu, 2012-04-19 17:59.

Here or on the blog...

decodeFloat function in C

Submitted by Mickey (not verified) on Thu, 2012-04-19 05:31.

Hi, can someone please help me to understand what's the mistake in my C code for doing the decodeFloat function.
Link to my code:

Found the solution

Submitted by Mickey (not verified) on Fri, 2012-04-27 13:25.

if someone is interested email me...

Ops sorry.. looks like I lost

Submitted by fabio on Fri, 2012-04-27 18:12.

Ops sorry.. looks like I lost your first comment..

Yaw offset on rotating Roll

Submitted by Somapanam (not verified) on Wed, 2012-03-28 21:18.

I just bought a FreeIMU 4 and loaded the "FreeIMU_Yaw_Pitch_Roll" code in to my Arduino mega and was able to get it working. But I always see an OFFSET in the YAW when I ROLL the IMU back and forth by 90 degrees. The OFFSET is close to 30 degrees in yaw. I also see a small drift in the yaw but that is not my concern right now.

Are the ROll and the YAW axes coupled in some way? Why is this happening? Rotating ROLL in clockwise and counterclockwise directions produce the same offset.

Check this video to see the offset in action.


Roll and Yaw are of course

Submitted by fabio on Wed, 2012-03-28 22:48.

Roll and Yaw are of course not correlated. But they get if the magnetometer isn't calibrated. Please read my other comment for an explanation on why this happens and pointers to calibration code.

sensor fusion

Submitted by Anonymous (not verified) on Fri, 2012-03-23 23:40.

what kind of algorithm did you use in the library to fuse the sensor readings?

It's a quaternion

Submitted by fabio on Mon, 2012-03-26 10:59.

It's a quaternion implementation of the Mahony's sensor fusion filter which incorporates Sebastian Madgwick's magnetic declination fixes from his filter. The filter code is available from

For the math details see the following papers:

  • Madgwick, S. O. An efficient orientation filter for inertial and inertial/magnetic sensor arrays.
  • Madgwick, S. O., Harrison, A. J., and Vaidyanathan, R. Estimation of imu and marg orientation using a gradient descent algorithm. In International Conference on Rehabilitation Robotics (ICORR) (July 2011).
  • Mahony, R., Cha, S.-H., and Hamel, T. A coupled estimation and control analysis for attitude stabilisation of mini aerial vehicles. Mahony, R., Hamel, T., and Pflimin, J.-M. Nonlinear complementary filters on the special orthogonal group. In IEEE TRANSACTIONS ON AUTOMATIC CONTROL, VOL. 53, NO. 5, JUNE 2008 (2008).

Introductory material is also available in my thesis.

Yaw Drift

Submitted by zaclem01 (not verified) on Tue, 2012-03-20 03:25.

Hi there,

Great library. So much easier than trying to figure out all these angle representations on my own.

As many other people have mentioned, when using the [yaw, pitch, roll] outputs from the library, I get yaw drifting at about 1-2 degrees per second. I'm using the Sparkfun 6DOF IMU (with the ADXL345 and ITG3200). From what I understand, the only way to calculate yaw in the case that you only have an accelerometer and gyro is to use purely gyro readings. I've also read that gyros suffer from baseline drift, so I think that is where the yaw drift originates from.

Is there any way to compensate for this? Maybe take a baseline drift reading for the gyro and compensate for it? Please let me know if anyone knows how to take care of this problem. Thanks!

Are you keeping the board

Submitted by fabio on Tue, 2012-03-20 08:08.

Are you keeping the board still in the first 10 seconds after Arduino reset? In these seconds, the code is doing exactly what you suggested so it should remove as much drift as it could. When you see the TX/RX leds starting blinking then the auto calibration has completed and the board can be moved.

Thank You!

Submitted by zaclem01 (not verified) on Wed, 2012-03-21 01:20.

Sorry about that. I guess I missed that point when reading about the library. Anyway, thank you so much, and keep up the great work!

Pretty Bad Drift

Submitted by Sung (not verified) on Thu, 2012-03-15 00:10.

Hi Fabio,

Thanks for the great work. Your code has helped me immensely as I'm pretty new.

I've built a FreeIMU .2 using the 9 Degrees of Freedom - Sensor Stick SEN-10183. I've commented(or uncommented) the magnetometer as well as my board.

The roll and pitch angles stay very stable and don't drift. However, When i tilt them at 90 degree angles, I don't ever get 90 degrees. Instead I get something like 82 degrees.

The big problem is that when I leave the device stationary, the yaw drift goes crazy. It changes about 2 degrees per second and continues to change. Is there any way to fix this?


Very bad drift

Submitted by Cosmin (not verified) on Sun, 2012-03-04 22:27.

Hi Fabio,

First of all I'd like to thank you for your work. It's really great that there are persons like you providing this kind of code and documentation to the community.

Now, to my problem... I've built a FreeIMU 0.4 using the MPU6050 and an HMC5883L compass, connected it to the Arduino and it seems to work... Well... more or less. I have a pretty big problem with the yaw axis drifting away. I mean, when I leave the IMU stationary, the pitch and roll angles are pretty stable but the yaw angle drifts away. Also, if I move the unit let's say from 0 to 90 degrees, the yaw angle goes up to 90 degrees at first and then it starts to drift back towards 0. It never reaches 0 but, it goes back around 20-30 degrees or so...

Are there any settings I should make in the software or do I have to calibrate the sensors in some specific way?

Also, I wanted to ask you how to change the gyro gain? Now, it's set at 2000 deg/s and in FreeIMU::getValues() it's divided by 16.4
If I change it to 250 deg/s, what's the value I should divide the gyro value by? How is this value calculated?


Please check with FreeIMU_raw

Submitted by fabio on Mon, 2012-03-05 22:33.

Please check with FreeIMU_raw and the Serial monitor that your axis displays correctly the values. I guess your drifting may be a consequence of a bad axis on the magnetometer.

Regarding the scale factors of the gyroscope, please refer to the MPU6050 official datasheet for finding them.

Hi fabio, thanks for the code

Submitted by George (not verified) on Wed, 2012-02-29 18:13.

Hi fabio, thanks for the code and the great work.
I'm using the combo board with the ITG3200 and ADXL345. Is there any way to stop all the drift that i get without an magnetometer? Or would you recommend me to get one.

Also, when I was looking at your code, what exactly does this code compute? I can't seem to find where you combine the quaternions representations and euler rotations?
q[0] = cos(halfAngle);
q[1] = -axis[0] * sinHalfAngle;
q[2] = -axis[1] * sinHalfAngle;
q[3] = -axis[2] * sinHalfAngle;

and where is quat defined in here?
conj[0] = quat[0];
conj[1] = -quat[1];
conj[2] = -quat[2];
conj[3] = -quat[3];


Where did you find this code

Submitted by fabio on Sun, 2012-03-04 13:23.

Where did you find this code in the FreeIMU library exactly???

Oh also, i'm running the

Submitted by George (not verified) on Wed, 2012-02-29 18:18.

Oh also, i'm running the free_imu cube with the freeimu quaternion at the same time. I can't seem to find any place where you use the gyro values rawvalues[3-5] either. Sorry, if i have a lot of questions.

I sell a FreeIMU 0.3.5MS

Submitted by Javier Lloret (not verified) on Fri, 2012-02-17 17:25.

I have a FreeIMU 0.3.5MS that I bought in case I needed it. I've never used it. It is in its original closed plastic wrapping. If anyone is interested in buying it, send me an email.

FreeIMU 0.3.5MS -SELL

Submitted by Hussin Mohamed Syed (not verified) on Sun, 2012-02-26 09:06.

how much it cost to sell to me in us$
email me at :- hussin [dot] syed [at] yahoo [dot] com

Hi Fabio, Thanks for the

Submitted by Alex (not verified) on Wed, 2012-02-15 16:25.

Hi Fabio,

Thanks for the code. I'm fairly new to arduino. I have uploaded the freeimu quaternion to my arduino and am trying to run the cube in processing. I have placed the folder FreeIMU_cube in the lib folder under processing. However when i try to run i get the following errors,

No library found for processing.serial

as well as

the following error occurred while executing this line:
C:\Program Files\Android\android-sdk\tools\ant\build.xml:70: taskdef class cannot be found

I can't really figure out how to fix these