Driver for the LSM303D digital compass. Permits access to all LSM303D registers by name, including multi-byte register sets, and has convenience methods for floating-point accelerometer and magnetometer reads scaled according to the device settings. Written from scratch for Mbed 6.0

Dependents:   UoY-32C-lab8-exercise UoY-32C-lab5-lsm303d

Driver for the LSM303D digital compass

Permits access to all LSM303D registers by name, including multi-byte register sets. Convenience methods are included for sensor reads, including floating-point accelerometer and magnetometer reads scaled according to the device settings, and for the more common settings (data rates and scales).

I2C connection only. Written from scratch for Mbed 6.0.

The interface is subject to minor changes with each version. Deprecation warnings will be issued where possible.

Defaults

The class constructor checks that an LSM303D is present on the I2C bus, then enables all sensors. The accelerometer and magnetometer update rates are both set to 50Hz, and the scales are left at their device defaults of +-2g for the accelerometer and +-4gauss for the magnetometer.

Basic usage

Some usage examples

#include "lsm303d.h"

LSM303D lsm303d(D14, D15);  // SDA and SCL pins for I2C

lsm303d.setAccelScale(LSM303D::AccelScale::scale_4g); // set +-4g range

lsm303d.INT1_enable_DRDY_A(); // set DRDY_A bit in CTRL3 register (enable INT1 on accel data ready)

short rawX = lsm303d.getAccelX(); // returns 16-bit signed result, unscaled

float x, y, z;
lsm303d.getAccelInto(x, y, z); // overwrites parameters, values in g

float mX = lsm303d.getMagX(); // returns value in gauss
Committer:
ajp109
Date:
Wed Feb 17 13:13:13 2021 +0000
Revision:
11:0bb2931123d0
Parent:
lsm303d.cpp@10:392fa35ca17c
Capitalise filenames to match class name

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ajp109 11:0bb2931123d0 1 #include "LSM303D.h"
ajp109 0:b07c3d3e3d9c 2
ajp109 1:a74f8c175f6c 3 static unsigned char const accel_lookup[] = {2, 4, 6, 8, 16};
ajp109 1:a74f8c175f6c 4 static unsigned char const mag_lookup[] = {2, 4, 8, 12};
ajp109 1:a74f8c175f6c 5
ajp109 0:b07c3d3e3d9c 6 LSM303D::LSM303D(PinName sda, PinName scl, unsigned char i2c_addr) :
ajp109 1:a74f8c175f6c 7 i2c_(sda, scl), addr_8bit_(i2c_addr << 1),
ajp109 1:a74f8c175f6c 8 TEMP_OUT (*this, 0x05),
ajp109 1:a74f8c175f6c 9 STATUS_M (*this, 0x07),
ajp109 1:a74f8c175f6c 10 OUT_X_M (*this, 0x08),
ajp109 1:a74f8c175f6c 11 OUT_Y_M (*this, 0x0A),
ajp109 1:a74f8c175f6c 12 OUT_Z_M (*this, 0x0C),
ajp109 1:a74f8c175f6c 13 OUT_M (*this, 0x08),
ajp109 1:a74f8c175f6c 14 WHO_AM_I (*this, 0x0F),
ajp109 1:a74f8c175f6c 15 INT_CTRL_M (*this, 0x12),
ajp109 1:a74f8c175f6c 16 INT_SRC_M (*this, 0x13),
ajp109 1:a74f8c175f6c 17 INT_THS_M (*this, 0x14),
ajp109 1:a74f8c175f6c 18 OFFSET_X_M (*this, 0x16),
ajp109 1:a74f8c175f6c 19 OFFSET_Y_M (*this, 0x18),
ajp109 1:a74f8c175f6c 20 OFFSET_Z_M (*this, 0x1A),
ajp109 1:a74f8c175f6c 21 OFFSET_M (*this, 0x16),
ajp109 1:a74f8c175f6c 22 REFERENCE_X (*this, 0x1C),
ajp109 1:a74f8c175f6c 23 REFERENCE_Y (*this, 0x1D),
ajp109 1:a74f8c175f6c 24 REFERENCE_Z (*this, 0x1E),
ajp109 1:a74f8c175f6c 25 REFERENCE (*this, 0x1C),
ajp109 1:a74f8c175f6c 26 CTRL0 (*this, 0x1F),
ajp109 1:a74f8c175f6c 27 CTRL1 (*this, 0x20),
ajp109 1:a74f8c175f6c 28 CTRL2 (*this, 0x21),
ajp109 1:a74f8c175f6c 29 CTRL3 (*this, 0x22),
ajp109 1:a74f8c175f6c 30 CTRL4 (*this, 0x23),
ajp109 1:a74f8c175f6c 31 CTRL5 (*this, 0x24),
ajp109 1:a74f8c175f6c 32 CTRL6 (*this, 0x25),
ajp109 1:a74f8c175f6c 33 CTRL7 (*this, 0x26),
ajp109 1:a74f8c175f6c 34 STATUS_A (*this, 0x27),
ajp109 1:a74f8c175f6c 35 OUT_X_A (*this, 0x28),
ajp109 1:a74f8c175f6c 36 OUT_Y_A (*this, 0x2A),
ajp109 1:a74f8c175f6c 37 OUT_Z_A (*this, 0x2C),
ajp109 1:a74f8c175f6c 38 OUT_A (*this, 0x28),
ajp109 1:a74f8c175f6c 39 FIFO_CTRL (*this, 0x2E),
ajp109 1:a74f8c175f6c 40 FIFO_SRC (*this, 0x2F),
ajp109 1:a74f8c175f6c 41 IG_CFG1 (*this, 0x30),
ajp109 1:a74f8c175f6c 42 IG_SRC1 (*this, 0x31),
ajp109 1:a74f8c175f6c 43 IG_THS1 (*this, 0x32),
ajp109 1:a74f8c175f6c 44 IG_DUR1 (*this, 0x33),
ajp109 1:a74f8c175f6c 45 IG_CFG2 (*this, 0x34),
ajp109 1:a74f8c175f6c 46 IG_SRC2 (*this, 0x35),
ajp109 1:a74f8c175f6c 47 IG_THS2 (*this, 0x36),
ajp109 1:a74f8c175f6c 48 IG_DUR2 (*this, 0x37),
ajp109 1:a74f8c175f6c 49 CLICK_CFG (*this, 0x38),
ajp109 1:a74f8c175f6c 50 CLICK_SRC (*this, 0x39),
ajp109 1:a74f8c175f6c 51 CLICK_THS (*this, 0x3A),
ajp109 1:a74f8c175f6c 52 TIME_LIMIT (*this, 0x3B),
ajp109 1:a74f8c175f6c 53 TIME_LATENCY(*this, 0x3C),
ajp109 1:a74f8c175f6c 54 TIME_WINDOW (*this, 0x3D),
ajp109 1:a74f8c175f6c 55 Act_THS (*this, 0x3E),
ajp109 1:a74f8c175f6c 56 Act_DUR (*this, 0x3F),
ajp109 0:b07c3d3e3d9c 57
ajp109 1:a74f8c175f6c 58 accel_enableX (CTRL1, 0x01),
ajp109 1:a74f8c175f6c 59 accel_enableY (CTRL1, 0x02),
ajp109 1:a74f8c175f6c 60 accel_enableZ (CTRL1, 0x04),
ajp109 1:a74f8c175f6c 61 accel_enableAll (CTRL1, 0x07),
ajp109 1:a74f8c175f6c 62
ajp109 1:a74f8c175f6c 63 INT1_enable_BOOT (CTRL3, 0x80),
ajp109 1:a74f8c175f6c 64 INT1_enable_CLICK (CTRL3, 0x40),
ajp109 1:a74f8c175f6c 65 INT1_enable_IG1 (CTRL3, 0x20),
ajp109 1:a74f8c175f6c 66 INT1_enable_IG2 (CTRL3, 0x10),
ajp109 1:a74f8c175f6c 67 INT1_enable_IGM (CTRL3, 0x08),
ajp109 1:a74f8c175f6c 68 INT1_enable_DRDY_A (CTRL3, 0x04),
ajp109 1:a74f8c175f6c 69 INT1_enable_DRDY_M (CTRL3, 0x02),
ajp109 1:a74f8c175f6c 70 INT1_enable_EMPTY (CTRL3, 0x01),
ajp109 1:a74f8c175f6c 71
ajp109 1:a74f8c175f6c 72 temp_enable (CTRL5, 0x80),
ajp109 1:a74f8c175f6c 73 LIR1_enable (CTRL5, 0x01)
ajp109 1:a74f8c175f6c 74
ajp109 1:a74f8c175f6c 75 {
ajp109 0:b07c3d3e3d9c 76 // Check device responds correctly
ajp109 1:a74f8c175f6c 77 MBED_ASSERT(WHO_AM_I == 0x49);
ajp109 1:a74f8c175f6c 78
ajp109 0:b07c3d3e3d9c 79 // Grab current accelerometer and magnetometer scales from registers
ajp109 1:a74f8c175f6c 80 accel_scale_ = accel_lookup[(CTRL2 & 0x3E) >> 3];
ajp109 1:a74f8c175f6c 81 mag_scale_ = mag_lookup[(CTRL6 & 0x60) >> 5];
ajp109 0:b07c3d3e3d9c 82
ajp109 1:a74f8c175f6c 83 // Useful default config
ajp109 1:a74f8c175f6c 84 accel_enableAll();
ajp109 1:a74f8c175f6c 85 setAccelRate(AccelRate::rate_50Hz);
ajp109 1:a74f8c175f6c 86 temp_enable();
ajp109 1:a74f8c175f6c 87 setMagRate(MagRate::rate_50Hz);
ajp109 1:a74f8c175f6c 88 setMagMode(MagMode::continuous);
ajp109 0:b07c3d3e3d9c 89 }
ajp109 0:b07c3d3e3d9c 90
ajp109 0:b07c3d3e3d9c 91 void LSM303D::getRawAccelInto(short &x, short &y, short &z) {
ajp109 1:a74f8c175f6c 92 i16_3 xyz = OUT_A;
ajp109 0:b07c3d3e3d9c 93 x = xyz.x;
ajp109 0:b07c3d3e3d9c 94 y = xyz.y;
ajp109 0:b07c3d3e3d9c 95 z = xyz.z;
ajp109 0:b07c3d3e3d9c 96 }
ajp109 0:b07c3d3e3d9c 97
ajp109 0:b07c3d3e3d9c 98 void LSM303D::getAccelInto(float &x, float &y, float &z) {
ajp109 1:a74f8c175f6c 99 i16_3 xyz = OUT_A;
ajp109 0:b07c3d3e3d9c 100 float scale = accel_scale_ / 32768.0;
ajp109 0:b07c3d3e3d9c 101 x = xyz.x * scale;
ajp109 0:b07c3d3e3d9c 102 y = xyz.y * scale;
ajp109 0:b07c3d3e3d9c 103 z = xyz.z * scale;
ajp109 0:b07c3d3e3d9c 104 }
ajp109 0:b07c3d3e3d9c 105
ajp109 0:b07c3d3e3d9c 106 void LSM303D::getRawMagInto(short &x, short &y, short &z) {
ajp109 1:a74f8c175f6c 107 i16_3 xyz = OUT_M;
ajp109 0:b07c3d3e3d9c 108 x = xyz.x;
ajp109 0:b07c3d3e3d9c 109 y = xyz.y;
ajp109 0:b07c3d3e3d9c 110 z = xyz.z;
ajp109 0:b07c3d3e3d9c 111 }
ajp109 0:b07c3d3e3d9c 112
ajp109 0:b07c3d3e3d9c 113 void LSM303D::getMagInto(float &x, float &y, float &z) {
ajp109 1:a74f8c175f6c 114 i16_3 xyz = OUT_M;
ajp109 0:b07c3d3e3d9c 115 float scale = mag_scale_ / 32768.0;
ajp109 0:b07c3d3e3d9c 116 x = xyz.x * scale;
ajp109 0:b07c3d3e3d9c 117 y = xyz.y * scale;
ajp109 0:b07c3d3e3d9c 118 z = xyz.z * scale;
ajp109 0:b07c3d3e3d9c 119 }
ajp109 0:b07c3d3e3d9c 120
ajp109 1:a74f8c175f6c 121 void LSM303D::setAccelRate(AccelRate const &rate) {
ajp109 1:a74f8c175f6c 122 u8 set = static_cast<u8>(rate);
ajp109 1:a74f8c175f6c 123 CTRL1 = (CTRL1 & ~0xF0) | set;
ajp109 1:a74f8c175f6c 124 }
ajp109 1:a74f8c175f6c 125
ajp109 10:392fa35ca17c 126 void LSM303D::setAccelFilterFreq(AccelFilter const &freq) {
ajp109 10:392fa35ca17c 127 u8 set = static_cast<u8>(freq);
ajp109 10:392fa35ca17c 128 CTRL2 = (CTRL2 & ~0xC0) | set;
ajp109 10:392fa35ca17c 129 }
ajp109 10:392fa35ca17c 130
ajp109 1:a74f8c175f6c 131 void LSM303D::setAccelScale(AccelScale const &scale) {
ajp109 1:a74f8c175f6c 132 u8 set = static_cast<u8>(scale);
ajp109 1:a74f8c175f6c 133 CTRL2 = (CTRL2 & ~0x38) | set;
ajp109 1:a74f8c175f6c 134 accel_scale_ = accel_lookup[set >> 3];
ajp109 1:a74f8c175f6c 135 }
ajp109 1:a74f8c175f6c 136
ajp109 1:a74f8c175f6c 137 void LSM303D::setMagRes(MagRes const &res) {
ajp109 1:a74f8c175f6c 138 u8 set = static_cast<u8>(res);
ajp109 1:a74f8c175f6c 139 CTRL5 = (CTRL5 & ~0x60) | set;
ajp109 0:b07c3d3e3d9c 140 }
ajp109 0:b07c3d3e3d9c 141
ajp109 1:a74f8c175f6c 142 void LSM303D::setMagRate(MagRate const &rate) {
ajp109 1:a74f8c175f6c 143 u8 set = static_cast<u8>(rate);
ajp109 1:a74f8c175f6c 144 CTRL5 = (CTRL5 & ~0x1C) | set;
ajp109 0:b07c3d3e3d9c 145 }
ajp109 0:b07c3d3e3d9c 146
ajp109 1:a74f8c175f6c 147 void LSM303D::setMagScale(MagScale const &scale) {
ajp109 1:a74f8c175f6c 148 u8 set = static_cast<u8>(scale);
ajp109 1:a74f8c175f6c 149 CTRL6 = (CTRL6 & ~0x60) | set;
ajp109 1:a74f8c175f6c 150 mag_scale_ = mag_lookup[set >> 5];
ajp109 0:b07c3d3e3d9c 151 }
ajp109 1:a74f8c175f6c 152
ajp109 1:a74f8c175f6c 153 void LSM303D::setMagMode(MagMode const &mode) {
ajp109 1:a74f8c175f6c 154 u8 set = static_cast<u8>(mode);
ajp109 1:a74f8c175f6c 155 CTRL7 = (CTRL7 & ~0x03) | set;
ajp109 1:a74f8c175f6c 156 }