Readings from 9 DOF IMU LSM30/L3GD20 (Accel/Mag/Gyro)

Hello,

I am using a 9 DOF IMU returning acceleration, magnetic and angular rates values. I am confidend about the connections (possible to see them in the attached picture). In order to get the aforementioned values, I use the script pitchrollheading from the Arduino 9DOF library (linked to Adafruit libraries). You can see the code I use bellow.
The problem is that it is specified that the provided heading varies from 0 to 360°. However, when I am measuring the values by rotating my IMU, my values do not vary from 0 to 360° at all. After rotating the IMU about 360°, the measurements indicate only a small variation of approximately 100° in between 210° to 290°.
I do not really understand why, I've read that it might be due to the disturbance of the electronic systems around. However, when I use my magnetic compass (that differs from my IMU), I have good measurements indeed in between 0 to 360° in the same room than the one where I also use the IMU.
Thanks for any help !

The used code:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>
#include <Adafruit_L3GD20_U.h>
#include <Adafruit_9DOF.h>

/* Assign a unique ID to the sensors */
Adafruit_9DOF dof = Adafruit_9DOF();
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(30302);

/* Update this with the correct SLP for accurate altitude measurements */
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;

//
/*!
@brief Initialises all the sensors used by this example
*/
/
/
void initSensors()
{
if(!accel.begin())
{
/* There was a problem detecting the LSM303 ... check your connections /
Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
while(1);
}
if(!mag.begin())
{
/
There was a problem detecting the LSM303 ... check your connections */
Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
while(1);
}
}

/**************************************************************************/
/*!

*/
/**************************************************************************/
void setup(void)
{
Serial.begin(115200);
Serial.println(F("Adafruit 9 DOF Pitch/Roll/Heading Example")); Serial.println("");

/* Initialise the sensors */
initSensors();
}

//
/*!
@brief Constantly check the roll/pitch/heading/altitude/temperature
*/
/
/
void loop(void)
{
sensors_event_t accel_event;
sensors_event_t mag_event;
sensors_vec_t orientation;

/* Calculate pitch and roll from the raw accelerometer data /
accel.getEvent(&accel_event);
if (dof.accelGetOrientation(&accel_event, &orientation))
{
/
'orientation' should have valid .roll and .pitch fields */
Serial.print(F("Roll: "));
Serial.print(orientation.roll);
Serial.print(F("; "));
Serial.print(F("Pitch: "));
Serial.print(orientation.pitch);
Serial.print(F("; "));
}

/* Calculate the heading using the magnetometer /
mag.getEvent(&mag_event);
if (dof.magGetOrientation(SENSOR_AXIS_Z, &mag_event, &orientation))
{
/
'orientation' should have valid .heading data now */
Serial.print(F("Heading: "));
Serial.print(orientation.heading);
Serial.print(F("; "));
}

Serial.println(F(""));
delay(1000);
}

One possible error could be that You rotated the item too fast. Try with a slow rotation, not advancing until You receive a value that reflects the last move.

And... please use code tags when posting code. How to? How to get the best out of this forum - Using Arduino / Project Guidance - Arduino Forum

IMUs must be calibrated before they can be used for 3D orientation measurements. The gyro and the magnetometer are most critical.

This is the best overview and tutorial on calibrating mangnetometers and accelerometers.

Thanks a lot for your answers. After going through your link jremington, I found out this following Arduino code for the calibration:

Then I launched the given code corresponding to my sensor (the second one: LSM303/LSM303DLH). But after that, I do not know what to do. Shall I run directly after the previous script to get the heading ? Or shall I merge the script making the calibration with the one that gets the actual measurements ?

Another thing: I tryed by curiosity to rotate my IMU not around the Z axis and horizontally, but by putting it perpendicular to the table (then rotate it aroud the horizontal axis), and the heading does vary from 0 to 360°... Maybe that I am wrong in my definition of the used axes that retreive the heading ?

Presumably, the code printed some results. What were those?

The next step is to calculate corrections to be applied to the magnetometer data, and use the corrected data in subsequent programs.

This forum post gives a complete example of calibrating and correcting magnetometer readings, for a severe case of "hard iron" distortion.