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.

Probably, as you suggest,

Submitted by fabio on Mon, 2011-11-14 15:34.

Probably, as you suggest, changing the read axis from the sensors is the best way to do so. Keep in mind that Sparkfun 9DOF doesn't have the three sensors axis aligned.

Working with Sparkfun 9 DOF IMU

Submitted by Blake (not verified) on Sun, 2011-11-06 01:59.

I want to say your site is awesome, and reading your post are extremely insightful. I bought a sensor awhile back from Sparkfun, this one to be exact, I rearranged some of the axis and have a working unit. Only thing is I have the pitch and roll reversed. I know it is as simple as just flipping the variable names, but I was hoping you could point me in the direction to really find out what is going on. I know you reference some papers, can you point me in the direction to get them. Thank you.

If the pitch and roll are

Submitted by fabio on Sun, 2011-11-06 11:27.

If the pitch and roll are reversed, you just have to swap the X and Y axis of your sensors. Old user comments on this website explain how to fix the axis orientation for using the FreeIMU library with Sparkfun's 9DOF stick (use the search on the website).

Thanks for your appreciation.


Submitted by Anonymous (not verified) on Tue, 2011-10-11 23:29.

Please, can somebody help me?? Yesterday evening i flew my y6 multiwii with FImu 0.3.5.BMP ar home without stability problems, and with great satisfation for the performances of my new FIMU just installed. Today, i tried to do the same outside, in the countryside, but at the 1st attempt my y6 went upsidedown and it was impossible to find stability. this evening, once connected to the mutlwii conf software i discovered tha all the signals of the sensors were to 0. I connect the FIMU following the schemas on my arduino mega, I disabled the I2C internal pullups, and I'm not able to understand this fault. Can somebody help me?

Cross posted at

Submitted by fabio on Wed, 2011-10-12 08:33.

Cross posted at .. Answering there.

FreeImu - where to buy

Submitted by Tony (not verified) on Thu, 2011-10-06 19:03.


Can you please indicate where I can buy one of your boards (latest version if possible)?


Hi Tony, right now you can

Submitted by fabio on Thu, 2011-10-06 20:40.

Hi Tony, right now you can buy the FreeIMU v0.3.5_BMP from On November we will have the v0.3.5_MS back for sale.

Thanks and another question...

Submitted by Tony (not verified) on Fri, 2011-10-07 14:18.

Dear Fabio,

Thank you very much for your promptly reply.
I am an Oil&Gas System Engineer and trying to build a new application specific quad rotor controller using the Digilent/Microchip Chipkit Uno32 platform however it would be nice to know if there are already controllers using the FreeIMU. I found some videos in the net which indicate that there are already FreeIMU controllers. It would be nice to have a look on those controllers as this area(quad rotors) is not within my expertise, can you please give me a link for one of those solutions where the code is available?

Thanks very much again.


There you

Submitted by fabio on Fri, 2011-10-07 15:11.

Thanks very

Submitted by Tony (not verified) on Fri, 2011-10-07 15:26.

Thanks very much.


Submitted by Dave Fletcher (not verified) on Wed, 2011-09-28 13:58.

My reported problems below about setup etc are i think solved. What i am seeing is probably gibal lock or sigularities due to using Euler angles, which has a provided solution getYawPitchRoll.

Thanks again for a great project.


My post maybe misleading!

Submitted by Dave Fletcher (not verified) on Mon, 2011-09-26 11:43.

Sorry my post "Problem with imufilter or my setup" is probably misleading, I should have stated that the graphics using Processing is correct. My comments refer to the Euler angles theta and phi above the graphics, I hope its now clear.



Problem with imufilter or my setup

Submitted by Dave Fletcher (not verified) on Mon, 2011-09-26 11:08.

Fabio thanks for a great site and project. I have been following since your first 6DOF. I believe that either I have a setup problem, an understanding problem or there is a problem with the imu filter.
When I set my pitch to 90 deg. and roll in the z plane (a vertical roll) I see the roll on the pitch is this correct? This is seen using processing. Thankyou for any help.


freeIMU V.04

Submitted by claudio (not verified) on Sat, 2011-09-17 10:49.

Hi fabio I download the file freeIMU V.04 the file is ready for use?

where is possible to do the smoll order printer ready circuit V.04?



Wii Motion plus success but match woes

Submitted by Mark Wilkie (not verified) on Sat, 2011-08-20 15:27.


First, thanks a ton for the great resource. It's really helped me so far get to where I am....which is:

1) I've successfully (I think) created a new library for the wii motion plus extension. (huge thanks to knuckles and of course wiibrew) You can find the code here under wmplus library directory.
2) I have added the HMC5883, BMA180, and the WM+ to a breadboard and am talking to all three via i2c with my uno.
3) I have aligned axis physically and have verified the following: gyro pitch (rotation around x) aligned with acc y, and gyro roll (rotation around y) with acc x. In addition, the gyro z axis rotation is aligned with mag z.
4) I have verified that my gyro rotation pos/neg aligns. That is, cw rotation around y is positive, ccw rotation around x is positive, and ccw around z is positive. When looking at the output graph, this indeed matches the acc output
5) I am getting values which are (kinda) meaningful from the FreeIMU_YawPitchRoll example.
6) I have verified that z axis output from the mag is stable. In fact, the heading is pretty close.

However, when using FreeIMU_Yaw_Pitch_Roll......

1) The amplitude for pitch and roll out of the FreeIMU library is much diminished (like 1/10) from the raw output.
2) Both pitch and roll go back to zero very quickly - even if the board is still angled and the acc data showed inclination.
3) Yaw does respond - but is not stable. That is to say, yaw moves negative fairly rapidly even when no motion is applied. That is to say, if left alone, yaw goes negative, wraps to 360 and repeats. This is despite mag and gyro outputs looking correct.

Any thoughts on my three problems? It feels like I'm really close - but missing something pretty basic. The basic issue here is that my math is very weak.



Cross posted to

Submitted by fabio on Mon, 2011-08-22 06:37.

4.0 progress

Submitted by apburner (not verified) on Fri, 2011-08-19 07:51.

Any progress on the 4.0 board. I have that
Senor on backorder also.

Still waiting for the sensors

Submitted by fabio on Fri, 2011-08-19 08:32.

Still waiting for the sensors to arrive. I've got a sample of 5 in shipping but it will take some time (more than a month) to have some v0.4 units available for shipping. Moreover, the MPU6050 is a new and untested sensor, meaning it is quite unknown from a software point of view... you may wanna get a v0.3.5_MS which is already supported in the software and will be available for shopping in some days. Check my blog for news about it.

Well I have in my possession

Submitted by Steve (not verified) on Tue, 2011-08-30 14:11.

Well I have in my possession a MPU6050. It just came in yesterday. I am still going to build a 0.3.0 because I have the board but am looking forward to the day that the 0.4.0 is built and tested. lol

Lucky you!

Submitted by fabio on Tue, 2011-08-30 14:26.

Lucky you!

Ah ok. Well I have some .3

Submitted by apburner (not verified) on Fri, 2011-08-19 10:34.

Ah ok. Well I have some .3 boards waiting to make
So I think I will play with them for a while.

Disabling internal pullup

Submitted by Winston (not verified) on Wed, 2011-08-17 14:09.

Disabling internal pullup resistors

Hi Fabio,

Thank you so much for sharing this great project!

I have a question on disabling the internal pullups resistors.
I read your notes on one of your other webpages about disabling the pullups inside twi.c, which I did by commenting out the code inside the init function. However on looking in FreeIMU.cpp I see that you disable the pullups inside the FreeIMU::init function. Given that I commented out the code in twi.c, will the FreeIMU code now re-enable them?

Nope, they will simply stay

Submitted by fabio on Wed, 2011-08-17 17:50.

Nope, they will simply stay disabled.

Ok Thanks

Submitted by Winston (not verified) on Wed, 2011-08-17 22:13.


Double Pull up resistor

Submitted by Fino (not verified) on Wed, 2012-02-01 15:54.

Hi all,
I am building a clone FreeIMU v0.2 but using and because I have no experience on SMD soldering.

Both of those boards have pull up resistors. If I combine them, there will be double pull up resistor on the I2C line from the IMU board and also form the PCA9306 board. Will those double pull up resistors cause any problems?


Simply do not use a logic

Submitted by fabio on Wed, 2012-02-01 17:11.

Simply do not use a logic voltage converter. It's useless if you disable the internal pullups.

Anyway, having 2 sets of pullups won't cause you problems.

Thank you Fabio!

Submitted by Fino (not verified) on Thu, 2012-02-02 06:12.

Thank you Fabio!

FreeIMU 0.3.5 accelerometer address select

Submitted by Luke (not verified) on Mon, 2011-08-15 21:54.

On the FreeIMU 0.3.5, pin 5 (CSB) of the BMA 180 can be wired to Vcc or Gnd via the Acc Ad solder switch on the backside of the board. However, pin 8 (SDO) is permanently wired to Gnd. The problem with this is that in order to use I2C mode, pin 5 (CSB) should be wired to Vcc and pin 8 (SDO) selects the last bit of the address by wiring it to Vcc (least significant bit of 7-bit I2C address is 1), or Gnd (least significant bit of 7-bit I2C address is 0). So, effectively the board is wired to select whether you want I2C or SPI, but you can't use it in SPI because SDO is hard wired to Gnd.

As a result, the Acc Ad middle switch should *always* be wired to Vcc, and any software you write to talk to this device, the 7-bit address is 0x40, and never 0x41. This translates to 0x80 for I2C writes and 0x81 for I2C reads.

Just a heads up.

Yes, this was a bug I had in

Submitted by fabio on Mon, 2011-08-15 23:31.

Yes, this was a bug I had in the first prototypes of FreeIMU v0.3.5. Current revision of FreeIMU v0.3.5_MS which is being produced in a big batch has this issue fixed.

Anyway, thanks for taking the time to study the design and report this issue.

FreeIMU board only for sale

Submitted by Steve (not verified) on Tue, 2011-08-09 01:31.

In case anyone is interested I had 3 FreeIMU boards I will not use anytime soon and will be selling them on eBay just like the femtoduino
boards. I am asking $4 each free shipping anywhere in USA.
Link is
I hope this helps someone

FreeIMU software working with SF 9DOF Razor IMU

Submitted by Ross (not verified) on Mon, 2011-08-08 17:10.

Thanks to Fabio for all his hard work. The current FreeIMU code works fine with the SparkFun Razor IMU (sku: SEN-10736). This unit appears to have the same sensor orientations as the FreeIMU boards. It does _not_ seem to require the orientation tweak that the 9DOF sensor stick needs (mentioned elsewhere in these comments).

The only change I had to make to get it running was to tweak FreeIMU.h to define #define FREEIMU_VER 3 so that it used the right sensor set (ADXL345, ITG3200, HMC5883L).

I also had to reduce the magnetometer gain in FreeIMU.cpp init() thusly:
magn.calibrate(4); // Use gain 1=default, valid 0-7, 7 not recommended.

But I think this depends on your sensor whether this is needed. I posted about that here:

In future it would be nice if FreeIMU auto-calibrated the magnetometer gain. There is a self-test procedure in the HMC5883L data sheet. Perhaps I will try to implement that.

I agree with you.. tho some small problems

Submitted by Iulian (not verified) on Thu, 2011-11-17 23:27.

Thanks for the great advice.. I also palyed with FreeIMU on Sparkfun razors latest 9D0F board. and it works!! Thats, for the code, very much appreciated, Once I get more familiar to the code I will stat using it more, and maybe we can collaborate.

There is a small problem, it kindly drifts sometimes.

Kind regards,

Similar idea - Mongoose 9DOF IMU with barometer

Submitted by Cory (not verified) on Fri, 2011-07-22 03:01.

This is great Fabio. We are also working on a open source IMU that uses the ITG-3200 gyro, ADXL345 accelerometer, HMC5883L magnetometer, BMP085 barometer and a atmega328P with lots of extra IO pins. One of our biggest challenges has been calibrating out all the hard and soft iron effects. It turns out the BMP085 contains both hard and soft iron. We are working on a detailed calibration procedure that I think will be usefull to anyone using a magnetometer. Right now we have AHRS firmware and a PC GUI and we are working on some more demo code.

In the link you posted, I

Submitted by fabio on Fri, 2011-07-22 09:25.

In the link you posted, I don't see any schematics/hardware sources for your IMU. I don't see how that could be defined as open source IMU if you don't actually provide any source for that.

Also, please do not cross post the same comment on multiple pages here.

Magnetometer Calibration

Submitted by Bo Xuan (not verified) on Wed, 2011-07-13 15:26.

Hello Fabio,

Great work in the FreeIMU. As you know, I recently got my IMU working, and have already implemented my own version of a quaternion attitude estimator which I intend to improve on (accuracy + computationally optimise + vibration resistance).

Sadly, my magnetometer needed some serious calibration. A few hours on Processing later, I got a nice program that plots a 3D scatter (based on using magnetometer data from Serial, calculates the offset and gain. Here're screenshots:

It rotates around the Z axis continuously to show the shape of the ovoid. What software do you use to calibrate yours?

Bo Xuan

Question about calibration

Submitted by Cory (not verified) on Fri, 2011-07-22 03:07.

Bo Xuan,

Does your calibration program have any functionality to help with calibrading out soft iron effects? From what you describe, it looks like your program only provides offsets to remove hard iron effects. I would also be interested in your code if you are willing to share it.



Submitted by Bo Xuan (not verified) on Fri, 2011-07-22 11:50.

Hello Cory,

Here's the code:

I haven't touched since I coded it, so the centroid and gain location methods are still overly simplistic (but works).

About the soft-iron corrections, the gains should at least alleviate the problem. Of course, these calibration values only work with distortion sources that are static relative to the magnetometer.

While the methods I use in this version are very rough, they should work well enough for general use. After all, the magnetometer is typically affected by many other sources during use and probably isn't the most reliable or accurate source of information.

Bo Xuan

It would be cool if you could

Submitted by fabio on Wed, 2011-07-13 16:53.

It would be cool if you could share your Processing code. Seems pretty cool.

Anyway, I'm not doing any fancy calibration on the magnetometer.. this has always been in the todo list but I never had the time (or need) to work on that.

So, I simply use the self test of the magnetometer to compute its offsets.. for my current applications (HCI) that's enough.

Sure. How do I tag code here

Submitted by Bo Xuan (not verified) on Wed, 2011-07-13 16:57.

Sure. How do I tag code here though? I only just wrote it so it's very rough and the offset and gain calculations are very simple.

Better not here

Submitted by fabio on Wed, 2011-07-13 17:00.

It's better not to post code as comment here. You can use a service like and post your code there. If you use something like you may also push your code there using git and periodically update it so that people will always get the most updated version.

Alright I'll test it a little

Submitted by Bo Xuan (not verified) on Wed, 2011-07-13 17:11.

Alright I'll test it a little more before posting. Perhaps use a more reliable method for finding centroid and gain.

For those using SF 9DOF Sensor Stick

Submitted by Edi (not verified) on Sat, 2011-06-25 19:39.

for those of you guys using the SF 9Dof Sensor Stick you need to align the
sensors in the program. This is very easy to do. All you have to do is go
to the FreeIMU.ccp file in the "getQ" function swap this line:

AHRSupdate(val[3] * M_PI/180, val[4] * M_PI/180, val[5] * M_PI/180, val[0], val[1], val[2], val[6], val[7], val[8]);

with this one:

AHRSupdate(val[3] * M_PI/180,val[4] * M_PI/180, val[5] * M_PI/180,val[0], val[1], val[2], val[7], -val[6], val[8]);

you will also need to un-comment a #def in the HMC library because you are using the HMC5843 and not the HMC5833

Thanks, Your revisions really

Submitted by Dennis Wai (not verified) on Mon, 2011-06-27 19:02.

Thanks, Your revisions really helped!

Axis aligment

Submitted by Tuomas (not verified) on Thu, 2011-06-16 16:54.


I'm still having issues and currently I'm suspecting that my magnetometer (or the Sparkfun 6DoF) isn't aligned as the FreeIMU class expects.

The IMU Guide in instructs how to check some of the axes but not all, especially the magnetometer is missing.

I tried to google but couldn't find anything meaningful, so do you happen to know if there is somewhere a checklist for making sure that all 9 axes are in the right direction for the FreeIMU class?


Check the various datasheets

Submitted by fabio on Thu, 2011-06-16 17:28.

Check the various datasheets of the sensors you are using, compare them to their placement on the board. FreeIMU library expect them to be all aligned. That's it.

Yeah, but..

Submitted by Tuomas (not verified) on Thu, 2011-06-16 17:55.

Part of the problem is the Sparkfun 6Dof. It has 3 axis accelerometer and 3x 1 axis gyroscope so I would like to verify that I get the axis I'm suspecting to get and that they are in the right direction (and not e.g. reversed).

E.g. the's IMU guide says that the Z accelerometer should read -1g while still on the table and I get +1g. The datasheet doesn't say anything about IMU guide..

The second part is the Sparkfun MicroMag magnetometer. For that I didn't even find the axis information.

And even if I did find it, I don't know how to map those with the accelerometer data. Should the magnetometer's X axis show the maximum value when the device's X axis is pointed to North? And likewise the accelerometer's X axis should show the maximum value when the device's X axis is pointed towards Earth center? Or should it be the minimum in the case of the accelerometer..


Submitted by fabio on Thu, 2011-06-16 19:18.

I would suggest you to use the accelerometer frame as reference. The MMA7260Q accelerometer used by the Sparkfun Atomic IMU 6Dof has his axis aligned this way: by looking the chip from the top with the case dot on the top left angle, you have the Z axis pointing your face, X goes on the right and Y goes top. This is explained in the MMA7260Q datasheet page 6.

As an accelerometer measures the normal force applied by the table on which it lies rather than gravity directly, it is perfectly normal that you read 1G reading when you leave it lying on the table. (for an explanation on why this is so, see my thesis section 5.1)

The next thing I would do is checking that the gyroscope axis are aligned with the accelerometer. Once you identified the XYZ axis of the accelerometer, you should rotate around each one of the accelerometer axis both positively and negatively (where positively and negatively follows the right-hand rule). A positive rotation on the accelerometer X axis should give a positive angular velocity on the X axis of the gyroscope (extend this example to negative rotation and to the Y and Z axis).

Once you did so you have to align the magnetometer to the other sensors axis.. unfortunately, I'm not able to find any documentation on your chip axis.. so you'll have to check it empirically. Pointing one axis to Earth North should give you a positive value of the biggest magnitude, pointing the same axis to Earth South should give you about the same magnitude but negative sign.

Magnetometer issues

Submitted by Tuomas (not verified) on Sat, 2011-06-18 16:13.

I don't understand the magnetometer output.

Everything seems to be more or less in order when I keep the sensor horizontally level (i.e. I get the biggest values when pointing to north and the smallest values when pointing to south).

But when I tilt the sensor I get much bigger values (about twice when pointing down compared to what it gives when just pointing north). I would have assumed that pointing 90 degrees down would be the same as pointing 90 degrees east/west and the value given by the sensor for the particular axis would be the same in east, west and down.

I guess I'm missing something?

Thanks again.

Answering myself about the down axis of a magnetometer

Submitted by Tuomas (not verified) on Sat, 2011-07-02 10:13.

It seems to be quite normal that the magnetometer shows biggest values when pointed down:

There's still something wrong my code as I get pretty similar results with the real values from the magnetometer and when I give zeros as the magnetometer value.

Problem with 9DOF IMU (FreeIMU library software)

Submitted by Aze (not verified) on Tue, 2011-06-14 06:43.

Hi fabio, for some reason the yaw on my IMU setup is a bit off. At some angles it seems to flip around 180 degrees. I've uploaded a video that may help. Thanks!

(I'm using the HMC5843 and have the code changed for it.)