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);
    }
}

Files at this revision

API Documentation at this revision

Comitter:
knaresh89
Date:
Tue Feb 13 03:38:23 2018 +0000
Parent:
0:d7138994c637
Commit message:
- removing platform specific code from generic library; - adding comments for user to use desired debug print statements to see the sensor output

Changed in this revision

LIS2MDL.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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();
 }