Mbed driver for the Stmicroelectronics LIS2MDL sensor

Dependents:   itracker-mbed-os-example-lis2mdl

Introduction

The LIS2MDL is an ultra-low-power, high-performance 3-axis digital magnetic sensor.

The LIS2MDL has a magnetic field dynamic range of ±50 gauss.

The LIS2MDL includes an I2C serial bus interface that supports standard, fast mode, fast mode plus, and high-speed (100 kHz, 400 kHz, 1 MHz, and 3.4 MHz) and an SPI serial standard interface.

More details in datasheet here: http://www.st.com/resource/en/datasheet/lis2mdl.pdf

This driver assumes the user will deploy the sensor over I2C. SPI update will be committed soon :)

Sample Code:

LIS2mDL sample program

uint8_t MODR = MODR_100Hz;
int16_t temp[3] = {0, 0, 0};
float magBias[3] = {0,0,0}, magScale[3]  = {0,0,0};

// Attach interrupt to this pin if you want to use magnetometer sensor interrupt
// Before that make sure to set the correct interrupt value in the INT_CTRL_REG, INT_THS_L_REG and the INT_THS_H_REG (threshold value)
DigitalIn interruptPin(LIS2MDL_intPin);

// The itracker has the LIS2MDL sensor on the 13 and 11 I2C pins
I2C i2c(p13,p11);

// main() method. Runs in its own thread in the OS
int main()
{
    //Create LIS2MDL object
    LIS2MDL sensor(i2c, LIS2MDL_ADDRESS);
    
    //Reset the sensor to ensure correct starting config register values
    sensor.reset();
    wait(3);
    
    //Intialise the CHIP with the MODR value chosen
    sensor.init(MODR);
    
    //Test the Chip ID. Should return 64 (0x40)
    sensor.getChipID();
    
    // Calcaulte the offset bias to be used in future reading. See self check for example usage
    sensor.offsetBias(magBias, magScale);
    
    // Read the internal temp sensor
    sensor.readTemperature();

    //Get readings from the sensor;
    for(int i=0; i<60; i++) {
        int16_t temp[3] = {0, 0, 0};
        sensor.readData(temp);
        wait(0.1);
    }
}
Revision:
1:d7ea67f32b32
Parent:
0:d7138994c637
--- a/LIS2MDL.cpp	Mon Feb 12 04:59:47 2018 +0000
+++ b/LIS2MDL.cpp	Tue Feb 13 03:38:23 2018 +0000
@@ -7,7 +7,6 @@
 */
 
 #include "LIS2MDL.h"
-#include "SEGGER_RTT.h"
 
 LIS2MDL::LIS2MDL (I2C& p_i2c, uint8_t addr)
     : _i2c(p_i2c)
@@ -31,7 +30,6 @@
     int16_t mag_max[3] = {-32767, -32767, -32767}, mag_min[3] = {32767, 32767, 32767}, mag_temp[3] = {0, 0, 0};
     float _mRes = 0.0015f;
 
-    SEGGER_RTT_printf(0, "Calculate mag offset bias: move all around to sample the complete response surface!");
     wait(4);
 
     for (int ii = 0; ii < 4000; ii++) {
@@ -65,7 +63,6 @@
     dest2[1] = avg_rad/((float)mag_scale[1]);
     dest2[2] = avg_rad/((float)mag_scale[2]);
 
-    SEGGER_RTT_printf(0, "Mag Calibration done!");
 }
 
 
@@ -86,7 +83,6 @@
 uint8_t LIS2MDL::getChipID()
 {
     uint8_t c = readByte(LIS2MDL_ADDRESS, LIS2MDL_WHO_AM_I);
-    SEGGER_RTT_printf(0, "Address: %d  \n", c);
     return c;
 }
 
@@ -94,7 +90,6 @@
 {
     // Read the status register of the altimeter
     uint8_t temp = readByte(LIS2MDL_ADDRESS, LIS2MDL_STATUS_REG);
-    SEGGER_RTT_printf(0, "LIS2MDL status : %d \n", temp);
     return temp;
 }
 
@@ -107,7 +102,6 @@
     destination[1] = ((int16_t)rawData[3] << 8) | rawData[2] ;
     destination[2] = ((int16_t)rawData[5] << 8) | rawData[4] ;
 
-    SEGGER_RTT_printf(0, "x: %d y: %d z: %d \n", destination[0], destination[1], destination[2]);
 }
 
 int16_t LIS2MDL::readTemperature()
@@ -116,7 +110,6 @@
     readBytes(LIS2MDL_ADDRESS, (0x80 | LIS2MDL_TEMP_OUT_L_REG), 2, &rawData[0]);  // Read the 8 raw data registers into data array
 
     int16_t temp = ((int16_t)rawData[1] << 8) | rawData[0] ;       // Turn the MSB and LSB into a signed 16-bit value
-    SEGGER_RTT_printf(0, "LIS2MDL temp is : %d \n", temp);
     return temp;
 }
 
@@ -165,6 +158,7 @@
   writeByte(LIS2MDL_ADDRESS, LIS2MDL_CFG_REG_C, c); // return to previous settings/normal mode
   wait(0.1); // let mag respond
 
+  //replace with serial print statements for seeing the readings.
   /*SEGGER_RTT.printf(0, "Mag Self Test: \n");
   SEGGER_RTT.printf(0, "Mx results:"); 
   SEGGER_RTT.printf(0, " %f ", (magTest[0] - magNom[0]) * _mRes * 1000.0); 
@@ -190,14 +184,11 @@
     int ack = 0;
     _i2c.start();
     ack = _i2c.write(0x3C);
-    //SEGGER_RTT_printf(0, "address ACK: %d \n", ack);
     ack = _i2c.write(subAddress);
-    //SEGGER_RTT_printf(0, "sub address ACK: %d \n", ack);
     _i2c.start();
     ack = _i2c.write(0x3D);
     temp[0] = _i2c.read(0);
     _i2c.stop();
-    //SEGGER_RTT_printf(0, "readbyte read ACK: %d \n", ack);
     return temp[0];
 }
 
@@ -207,11 +198,8 @@
     int ack = 0;
     _i2c.start();
     ack = _i2c.write(0x3C);
-    //SEGGER_RTT_printf(0, "address ACK: %d \n", ack);
     ack = _i2c.write(subAddress);
-    //SEGGER_RTT_printf(0, "subaddr ACK: %d \n", ack);
     ack = _i2c.read(address, &dest[0], count);
-    //SEGGER_RTT_printf(0, "read ACK: %d \n", ack);
     _i2c.stop();
 }