Implementing a Quadcopter IMU
In order to determine the orientation of the quadcopter, we read data from the inertial measurement unit or IMU. The IMU is a collection of sensors and is typically comprised of at least a three-axis accelerometer and a 3-axis gyroscope and sometimes can employ magnetometers, barometers, and other sensors to supplement these.
We can use the output from these sensors to determine the angular position or attitude of the quadcopter. The accelerometer measures the acceleration forces (such as gravity) being applied to each axis. The gyroscope measures the rate of angular rotation for each axis. I picked up an AurduIMU v3 board from Sparkfun.
This board has an Invensense MPU-6000 MEMS 3-axis gyro and accelerometer as well the 3-axis I2C magnetometer HMC-5883L. There is an Arduino compatible Atmega328 microprocessor onboard that can be used to offload some of the sensor data processing from the main flight controller. There is also a port to connect an external GPS unit. The schematic is available here.
Note: Pin 13 is connected to the yellow LED, but it also connected to the SCK line of the MPU6000. This basically makes the yellow LED unusable unless you are willing to cut some traces.
Programming the Board
In order to program the ArduIMU v3 board, you need an FTDI Cable. An FTDI cable is a USB to Serial (TTL level) converter which allows for a simple way to connect TTL interface devices to USB. I have chosen to go with a breakout board rather than a cable simply because it is smaller.
This board is nice because it brings out the DTR pin as opposed to the RTS pin of the FTDI cable. The DTR pin allows an Arduino target to auto-reset when a new Sketch is downloaded. This is a really nice feature to have and allows a sketch to be downloaded without having to hit the reset button. This board will auto reset any Arduino board that has the reset pin brought out to a 6-pin connector. Also, there is a jumper on the back of the board that allows the board to be configured to either 3.3V or 5V (both power output and IO level).
Regarding The Official ArduIMU Code
Firstly, let me say that the ArduIMU code that is available on Google Code was not really was I needed. It is more of a full-blown auto-pilot system and there are many supported features that I didn’t need (GPS, Magnetometer, etc.). Also, it outputs a serial data stream in a format that is not really useful to me. I would rather just have the Flight Controller request IMU data as it needs. There were also many reported issues with the existing code outputting incorrect values etc.
Update: Although I didn’t know about it when building my quadcopter, the arduimu-v3-ahrs-improvements code looks promising. Check it out if you are thinking about using the ArduIMU board as a stand alone AHRS.
Reading Data From The Sensors
The MPU6000 has a Digital Motion Processor (hardware acceleration) onboard to obtain the Euler angles and/or Quaternions values from the MPU. This means it can derive roll, pitch and yaw without almost any drift. To read data from the accelerometer and gyro, you write to a register address and then read the values. Each value is two bytes for each sensor value. There are no A/D conversions performed on the ATMEGA328.
I came across some code on the diy drones site written by Martin Crown that was much closer to what I was trying to achieve with my IMU than the code that ships on the ArduIMU. His sketch is based on Jeff Rowberg’s MPU6050_DMP6_I2C library. The MPU6050 used in the original sketch however is the little brother of the MPU6000 and only supports I2C. Martin’s sketch is a port of Jeff’s sketch that also uses the DMP, but takes advantage of the SPI port instead of I2C.
Martin’s code remains compatible with the Teapot demo (a processing visualization sketch) which can be very useful for testing/debugging visually. To run the Teapot demo on the PC, you’ll need to have Processing installed and copy an additional toxiclibs library into Processing’s workspace’s libraries folder
I have adapted Martin’s code adding and removing as necessary. I am using I2C to communicate data between the flight controller and the IMU board. When ready, the flight controller board requests new data over I2C. This makes the flight controller code a little simpler and cleaner.
I’ve uploaded the source for this IMU implementation here.
The Teapot Demo
I’m not sure why they call it the Teapot demo. Probably the orignal Invensense demo displayed a Teapot. In any case, here is a video where I go over the IMU and show the output from the Teapot processing sketch.