MEMS sensor drivers and tilt-compensated compass using the STEVAL-MKI124V1 header board: LPS331 pressure sensor, LSM303DLHC magnetometer/accelerometer and L3GD20 gyroscope.

Dependencies:   mbed

I used a header board for an STM MEMS evaluation kit in order to take a look at some common MEMS sensors:

  • LPS301: Pressure and temperature sensor
  • LG3D20: Gyroscope
  • LSM303DLHC: Accelerometer and magnetometer

The header was an STEVAL-MKI124V1 which is designed to work with an STM motherboard evaluation system. I took a shortcut and used it with an LPC1768 MBED over I2C

Hook-up was trivial:

/media/uploads/liamg/setup2.png

The schematic is here:

http://www.st.com/web/en/catalog/tools/PF253482

The orientation of the sensors on the board is like this:

/media/uploads/liamg/board_shot.png

The code sets up each of the sensors and then provides a continuous output of temperature, pressure and orientation. Rather than optimize for performance or efficiency, the code here is intended to show clearly how to access the sensors.

An interesting twist was to use the linear accelerometer to find the vector of the earth's gravitational field (i.e. down) and to use that to make a tilt-adjusted compass. Algorithm came from ST Apps note AN3192.

The sensors do need some calibration. Here is a scatter plot of the raw output of X and Y values from the magnetometer:

/media/uploads/liamg/calibration.png

The chart should be a perfect circle around the origin (allowing for distortion on Excel charting).

  • Blue points are the raw data
  • Red is offset-corrected
  • Green is offset and soft-iron corrected

As you can see, there is an offset error but also and X:Y ratio term. The latter is a soft iron error and is well described in a great article here:

http://www.sensorsmag.com/sensors/motion-velocity-displacement/compensating-tilt-hard-iron-and-soft-iron-effects-6475

Committer:
liamg
Date:
Tue Mar 18 17:29:44 2014 +0000
Revision:
2:2ef63ab235bf
Parent:
0:91b1274ec397
#ifdef fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
liamg 0:91b1274ec397 1 // Defines for the MEMS sensors on the STEVAL-MKI124V1 board
liamg 0:91b1274ec397 2 // Liam Goudge. March 2014
liamg 0:91b1274ec397 3
liamg 0:91b1274ec397 4 // LPS331AP MEMS pressure and temperature sensor
liamg 0:91b1274ec397 5 #define LPS331addr 0xBA // I2C address of the sensor for writes (line SAO is tied high on this board so bit 1=1. Note this may not work on other boards).
liamg 0:91b1274ec397 6
liamg 0:91b1274ec397 7 #define pWHO_AM_I 0x0F // "ping" register. Device will respond even when in sleep mode
liamg 0:91b1274ec397 8 #define pRES_CONF 0x10 // Reset value is 0x7A (512 pressure samples and 128 temperature samples)
liamg 0:91b1274ec397 9 #define pCTRL_REG1 0x20
liamg 0:91b1274ec397 10 #define pCTRL_REG2 0x21
liamg 0:91b1274ec397 11 #define pCTRL_REG3 0x22
liamg 0:91b1274ec397 12 #define pPRESS_OUT_XL 0x28
liamg 0:91b1274ec397 13 #define pPRESS_OUT_L 0x29
liamg 0:91b1274ec397 14 #define pPRESS_OUT_H 0x2A
liamg 0:91b1274ec397 15 #define pTEMP_OUT_L 0x2B // Temperature data. 2's complement. Device will respond when in sleep mode
liamg 0:91b1274ec397 16 #define pTEMP_OUT_H 0x2C
liamg 0:91b1274ec397 17
liamg 0:91b1274ec397 18 // LSM303DLHC MEMS ascceleratometer, magnetometer and temperature sensor
liamg 0:91b1274ec397 19 #define LSM303_m 0x3C // I2C base address of the magnetometer sensor
liamg 0:91b1274ec397 20 #define LSM303_a 0x32 // I2C base address of the accelerometer sensor
liamg 0:91b1274ec397 21
liamg 0:91b1274ec397 22 // Magnetometer registers
liamg 0:91b1274ec397 23 #define mCRA_REG_M 0x00 // Magnetic sensor configuration register A
liamg 0:91b1274ec397 24 #define mCRB_REG_M 0x01 // Magnetic sensor configuration register B
liamg 0:91b1274ec397 25 #define mMR_REG_M 0x02 // Magnetometer mode register
liamg 0:91b1274ec397 26 #define mOUT_X_H_M 0x03 // X-axis magnetic field data High byte
liamg 0:91b1274ec397 27 #define mOUT_X_L_M 0x04 // X-axis magnetic field data Low byte
liamg 0:91b1274ec397 28 #define mOUT_Z_H_M 0x05 // Z-axis magnetic field data High byte
liamg 0:91b1274ec397 29 #define mOUT_Z_L_M 0x06 // Z-axis magnetic field data Low byte
liamg 0:91b1274ec397 30 #define mOUT_Y_H_M 0x07 // Y-axis magnetic field data High byte
liamg 0:91b1274ec397 31 #define mOUT_Y_L_M 0x08 // Y-axis magnetic field data Low byte
liamg 0:91b1274ec397 32 #define mSR_REG_M 0x09 // Magnetometer status register
liamg 0:91b1274ec397 33 #define mIRA_REG_M 0x0A // ID register A. Should read 0x48
liamg 0:91b1274ec397 34 #define mCTRL_REG1_A 0x20
liamg 0:91b1274ec397 35 #define mTEMP_OUT_H_M 0x31 // Magnetometer temperature register High byte
liamg 0:91b1274ec397 36 #define mTEMP_OUT_L_M 0x32 // Magnetometer temperature register Low byte
liamg 0:91b1274ec397 37
liamg 0:91b1274ec397 38 // Accelerometer registers
liamg 0:91b1274ec397 39 #define aCTRL_REG1_A 0x20 // Accelerometer output data rate ODR, low power modes etc
liamg 0:91b1274ec397 40 #define aCTRL_REG4_A 0x23 // Accelerometer full scale selection etc
liamg 0:91b1274ec397 41 #define aOUT_X_L_A 0x28 // Accelerometer X axis low byte
liamg 0:91b1274ec397 42 #define aOUT_X_H_A 0x29 // Accelerometer X axis high byte
liamg 0:91b1274ec397 43 #define aOUT_Y_L_A 0x2A // Accelerometer Y axis low byte
liamg 0:91b1274ec397 44 #define aOUT_Y_H_A 0x2B // Accelerometer Y axis high byte
liamg 0:91b1274ec397 45 #define aOUT_Z_L_A 0x2C // Accelerometer Z axis low byte
liamg 0:91b1274ec397 46 #define aOUT_Z_H_A 0x2D // Accelerometer Z axis high byte
liamg 0:91b1274ec397 47
liamg 0:91b1274ec397 48 // L3GD20 MEMS gyro. 3 axis angular rate sensor
liamg 0:91b1274ec397 49 #define L3GD20_ADDR 0xD6 // I2C base address of the gyro
liamg 0:91b1274ec397 50
liamg 0:91b1274ec397 51 #define gWHO_AM_I 0x0F // Ping register. Response is 0xD4. Responds even when device is off
liamg 0:91b1274ec397 52 #define gCTRL_REG1 0x20 // Sets Output Data Rate, Bandwidth and Power mode
liamg 0:91b1274ec397 53 #define gCTRL_REG4 0x23 //
liamg 0:91b1274ec397 54 #define gOUT_TEMP 0x26 // Temperature data. 8 bit resolution
liamg 0:91b1274ec397 55 #define gOUT_X_L 0x28 // X-axis angular rate low byte expressed as 2's complement
liamg 0:91b1274ec397 56 #define gOUT_X_H 0x29 // X-axis angular rate high byte
liamg 0:91b1274ec397 57 #define gOUT_Y_L 0x2A
liamg 0:91b1274ec397 58 #define gOUT_Y_H 0x2B
liamg 0:91b1274ec397 59 #define gOUT_Z_L 0x2C
liamg 0:91b1274ec397 60 #define gOUT_Z_H 0x2D
liamg 0:91b1274ec397 61
liamg 0:91b1274ec397 62
liamg 0:91b1274ec397 63 // Structs
liamg 0:91b1274ec397 64 typedef struct{
liamg 0:91b1274ec397 65 float pitch;
liamg 0:91b1274ec397 66 float roll;
liamg 0:91b1274ec397 67 float Xrotation;
liamg 0:91b1274ec397 68 float Yrotation;
liamg 0:91b1274ec397 69 float Zrotation;
liamg 0:91b1274ec397 70 float heading;
liamg 0:91b1274ec397 71 float tempC;
liamg 0:91b1274ec397 72 float pressuremB;
liamg 0:91b1274ec397 73 } SensorState_t;
liamg 0:91b1274ec397 74
liamg 0:91b1274ec397 75
liamg 0:91b1274ec397 76
liamg 0:91b1274ec397 77