minIMU-9 with LPC1768

I am using a minIMU-9 as an AHRS for the MBED board (based on the LPC1768). I ported over the AHRS code for Arduino to the MBED with great success, have have been able to read from the board and monitor the data serially.
However I am having issues with the accuracy of the minIMU-9. When the roll or pitch is changed by less then 10 degrees the board immediately starts to calibrate back to 0, so when it should be reading 9 degrees it will read 0. I can then increase the roll another 9, and it will settle back to 0.
However when I move the board back to level it will recenter itself.

For large sudden changes (greater then 25 degrees) this issue is not experienced. I have re calibrated several times but this did not solve the problem.

CTRL_REG1_A for the LSM303DLM I wrote the value 0x24 which turns off X and Y axis, with it on my accuracy drops to +/-7 degrees on the x and y axis which is not acceptable. If this register does need to be 0x27 (x and y on) then I need to know how to make the readings have a smaller error range of +/- 1 degree.

Hello,

I’m afraid I don’t have any good suggestions for you other than to keep trying the magnetometer calibration, making sure that you are pointing the IMU in all possible directions and keeping it away from anything that could interfere with the magnetometer.

The reason an improperly calibrated magnetometer can cause problems is that the readings from the magnetometer in the LSM303 are often significantly off-center, meaning that the neutral reading is offset from 0. The sensitivity of each axis can often vary too. When you performing the calibration procedure, you try to correct for this by finding the minimum and maximum values for each axis, which can then be converted into a scaling factor and offset to normalize the raw readings, so it is very important to find the right values for the calibration constants so that the readings are corrected properly.

If you continue to have problems and want to try again with another IMU, we might be able to offer you a discount on a replacement if you contact us directly.

- Kevin

I calibrated it half a dozen times now and still have had no luck, it is still auto-centering back to 0 on smaller changes, and on larger changes on occasion it will just start racing away: ie move to a 45 degree angle and the board keeps going past 45 to 70+, and will come back down once the sensor is again level.

I really do not want to have to purchase another board. I am already on my second sensor and I am on a tight deadline…less then 4 weeks to have this up and running.

Have you set SENSOR_SIGN[9] (or your equivalent) correctly to match the orientation you are using your board in? Are you keeping the IMU level and stationary for a few seconds when the AHRS starts up?

- Kevin

The component side of the board is facing up, so I took the lines that are commented from the Arduino code. Based on my understanding this is the correct orientation, but to be thorough I have tried both orientations, and to be honest neither have a terribly large impact on the readings.
Whether I start it sitting on a breadboard on my floor, or on the application (biped), both are extremely level. I make sure the biped calibrates to level before the minIMU-9 starts up, I then make sure the bot does not move for 10 seconds (the start up sequence takes about 9.9), so I am sure that movement is not factor.
When I calibrated I fully extended my USB cable so it was approximately 4 feet away from any electronics. When testing I have tried both on the floor and on my desk with similar results.
I also noted that no matter what orientation I turn it too, the compass always seems to center back to a certain value. This value changes each time on start up, it seems like it is detecting the starting position of the compass and then having a fast drift back to that value. Where any movement will cause rapid drift(10+degrees/sec) in the x and y planes. Once moved back to level they immediately recenter.

To me, that definitely sounds like a problem with the magnetometer, which might still indicate a calibration problem. The AHRS program uses the gyro to measure relative rotation on a short timescale, then uses data from the accelerometer (for down on the roll/pitch axes) and the magnetometer (for north on the yaw axis) as absolute references to correct for gyro drift. If the yaw always drifts back to the same value, that indicates the program is not recognizing a heading change from the magnetometer for some reason.

Could you post your values for the calibration constants (M_X_MIN, etc) here? Also, could you change the line “#define PRINT_ANALOGS 0” to “#define PRINT_ANALOGS 1” and capture the output from the AHRS while you slowly rotate it through 360 degrees?

- Kevin

// Calibration values
#define M_X_MIN -600
#define M_Y_MIN -760
#define M_Z_MIN -493
#define M_X_MAX 502
#define M_Y_MAX 335
#define M_Z_MAX 673

I ran calibration probably close to a dozen times, each time I only modified values if the min got lower or the max got higher.

Still-minIMU9.txt (19.3 KB) This is the IMU absolutely still on a desk taking readings. Notice how it is jumping around like crazy despite absolutely no movement, this is after all the calibrations.

Y-minIMU9.txt (11.8 KB) This is the IMU started absolutely still then rotated on the Y axis by 360 degrees. Notice how it starts the rotation but then starts to try and center really after about a 40 degree rotation. Also notice how the X axis goes absolutely crazy, jumping all over the place

X-minIMU9.txt (15.7 KB) This is the IMU starting still then rotated 360 degrees in the x direction. This appears slightly more accurate but it was reading level (0 degrees) by the time I still had about 20-30 degrees of rotation left to actually reach level.

Z-minIMU9.txt (17.9 KB) This is full rotation in Z 360 degrees. These numbers make no sense and are not even close at any time…

Uploaded separately because of the 3 post maximum

In your readings from the IMU when it is sitting still, the raw readings from the sensor seem fairly consistent, but the output angles are changing a lot. This makes me think that there is a problem somwhere in your mbed port of the program. Do you happen to have an Arduino you can use for comparison to test the original Arduino AHRS program with the IMU?

If you post all of your mbed code (or email it to us), I can try to run it on an mbed here, although I can’t make any promises about when I will be able to look at it or whether I will be able to make it work any better.

- Kevin

So from what you can see you would guess that something is wrong with the math? I did not really change the math in the slightest for fear of messing it up haha. I attached a zip of my converted file, I made it OO and changed it to take advantage of the i2c mbed library.
If you have time to take a look that would be much appreciated! So as far as you can tell it looks like the Analog values are correct? That would lead me to believe there is an error somewhere else, not in my L3G2400D or LSM303 libraries…

DCM_AHRS.zip (15.1 KB)

Could you also post your main .cpp file (the one that contains the main() function), along with anything else I would need to reproduce the output you captured?

- Kevin

See below for my main, I cut out anything that does not have anything to do with the minIMU9

#include "mbed.h"
#include "rtos.h"
#include "DCM_AHRS/minimu9.h"

#define DEBUG_MODE 0

// Create a serial interface (debug only)
#if DEBUG_MODE == 0
Serial pc(USBTX, USBRX);
#endif

/*
 * Constantly monitor angle data
 */
void update_sensor( void const *argument ){
    DigitalOut myled(LED1);

    minimu9 move_sensor;
    float x, y, z;
    bool status;
    while( 1 ) {
        myled = 1;
        status = move_sensor.get_data();
        x = move_sensor.get_roll();
        y = move_sensor.get_pitch();
        z = move_sensor.get_yaw();
        // Only update if the values have been changed
        if( true == status ) {
            body->set_angles( x, y, z );
        }
    }
}

int main() {
    // Starting up minIMU9
    Thread monitor_angles( update_sensor );
    pc.printf( "Sensor initialization started..." );
    wait( 10 );
   // Do stuff
} // End main

Hi Prediluted,

I ported the code to the LPCXpresso LPC-1769 had had a small issue with the math…

This is from a previos post of mine:

I did have one small problem that I though was an I2C issue but turned out to be a casting problem. The LPC-1769 compiler has 32-bit int’s and the code that converts the sensor low and high bytes had to be modified. For example this had to be changed:

AN[0] = (gxh << 8 | gxl);

To this:

AN[0] = (short int)(gxh << 8 | gxl);

Here is a lint to the thread: minIMU-9 with NXP LPCXpresso (ARM Cortex M3) or STM32

Mike

The accelerometer readings from the LSM303DLM are 12-bit left-justified values (the lowest 4 bits in the low register are not meaningful), so our Arduino LSM303 library combines the two 8-bit registers and then shifts the result right by 4 bits:

	a.x = (xha << 8 | xla) >> 4;
	a.y = (yha << 8 | yla) >> 4;
	a.z = (zha << 8 | zla) >> 4;

You were not doing this in your code, on line 154 of LSM303.cpp, which makes the accelerometer values too large by a factor of 16:

            acc[i] = ( short( _bytes[2*i] ) | short(_bytes[2*i+1]) << 8 );

I changed this line to:

            acc[i] = short( short( _bytes[2*i] ) | short(_bytes[2*i+1]) << 8 ) >> 4;

and it seemed to make the output behave better. (It didn’t seem to work without the extra “short” cast.) Does that solve your problem?

- Kevin

I came across this error on Tuesday night ha. I was so frustrated with the results that I threw out a good chunk of the code that I got for the LSM303 and the L3G4200D (I did not port that over, I got it from someone else) and re-wrote it. As I was rewriting it I noticed the shift difference, I should have posted it but the next day I was out of town. It does appear this fixes stability issues.

Thank you for taking the time to trouble shoot for me! If I come across anything else I will be sure to update my progress here.

I am glad to hear you figured it out. Thanks for the update.

- Kevin