1 /* 2 * Author: Brendan Le Foll<brendan.le.foll@intel.com> 3 * Copyright (c) 2014 Intel Corporation. 4 * 5 * Code based on LSM303DLH sample by Jim Lindblom SparkFun Electronics 6 * and the CompensatedCompass.ino by Frankie Chu from SeedStudio 7 * 8 * Further modifications to port to the LSM303d by <bruce.j.beare@intel.com> 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining 11 * a copy of this software and associated documentation files (the 12 * "Software"), to deal in the Software without restriction, including 13 * without limitation the rights to use, copy, modify, merge, publish, 14 * distribute, sublicense, and/or sell copies of the Software, and to 15 * permit persons to whom the Software is furnished to do so, subject to 16 * the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be 19 * included in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 */ 29 #pragma once 30 31 #include <string.h> 32 #include <mraa/i2c.hpp> 33 #include <math.h> 34 35 namespace upm { 36 /** 37 * @brief LSM303d Accelerometer/Compass library 38 * @defgroup lsm303d libupm-lsm303d 39 * @ingroup seeed adafruit i2c accelerometer compass 40 */ 41 42 /** 43 * @library lsm303d 44 * @sensor lsm303d 45 * @comname LSM303d Accelerometer & Compass 46 * @altname Grove 6-Axis Accelerometer & Compass 47 * @type accelerometer compass 48 * @man seeed adafruit 49 * @web http://www.seeedstudio.com/wiki/Grove_-_6-Axis_Accelerometer%26Compass 50 * @con i2c 51 * 52 * @brief API for the LSM303d Accelerometer & Compass 53 * 54 * This module defines the LSM303d 3-axis magnetometer/3-axis accelerometer. 55 * This module was tested with the Seeed Studio* Grove 6-Axis Accelerometer & Compass 56 * version 2.0 module used over I2C. The magnometer and acceleromter are accessed 57 * at two seperate I2C addresses. 58 * 59 * @image html lsm303d.jpeg 60 * @snippet lsm303d.cxx Interesting 61 */ 62 class LSM303d { 63 public: 64 65 /* Address definitions for the grove 6DOF v2.0 */ 66 typedef enum { 67 LSM303d_ADDR = 0x1E 68 } GROVE_6DOF_ADDRS_T; 69 70 typedef enum { 71 LM303D_SCALE_2G = 2, 72 LM303D_SCALE_4G = 4, 73 LM303D_SCALE_6G = 6, 74 LM303D_SCALE_8G = 8, 75 LM303D_SCALE_16G = 16 76 } LSM303D_SCALE_T; 77 78 typedef enum { 79 X = 0, 80 Y = 1, 81 Z = 2 82 } XYZ_T; 83 84 /** 85 * Instantiates an LSM303d object 86 * 87 * @param i2c bus 88 * @param addr Magnetometer 89 * @param addr Accelerometer 90 */ 91 LSM303d (int bus, 92 int addr=LSM303d_ADDR, 93 int accScale=LM303D_SCALE_4G); 94 95 /** 96 * LSM303d object destructor 97 * where is no more need for this here - I2c connection will be stopped 98 * automatically when m_i2c variable will go out of scope 99 * ~LSM303d (); 100 **/ 101 102 /** 103 * Gets the current heading; headings <0 indicate an error has occurred 104 * 105 * @return float 106 */ 107 float getHeading(); 108 109 /** 110 * Gets the coordinates in the XYZ order 111 */ 112 mraa::Result getCoordinates(); 113 114 /** 115 * Gets accelerometer values 116 * Should be called before other "get" functions for acceleration 117 */ 118 mraa::Result getAcceleration(); 119 120 /** 121 * Gets raw coordinate data; it is updated when getCoordinates() is called 122 */ 123 int16_t* getRawCoorData(); 124 125 /** 126 * Gets the X component of the coordinates data 127 */ 128 int16_t getCoorX(); 129 130 /** 131 * Gets the Y component of the coordinates data 132 */ 133 int16_t getCoorY(); 134 135 /** 136 * Gets the Z component of the coordinates data 137 */ 138 int16_t getCoorZ(); 139 140 /** 141 * Gets raw accelerometer data; it is updated when getAcceleration() is called 142 */ 143 int16_t* getRawAccelData(); 144 145 /** 146 * Gets the X component of the acceleration data 147 */ 148 int16_t getAccelX(); 149 150 /** 151 * Gets the Y component of the acceleration data 152 */ 153 int16_t getAccelY(); 154 155 /** 156 * Gets the Z component of the acceleration data 157 */ 158 int16_t getAccelZ(); 159 160 private: 161 162 /* LSM303d Register definitions */ 163 typedef enum { 164 STATUS_M = 0x7, 165 OUT_X_L_M = 0x8, 166 OUT_X_H_M = 0x9, 167 OUT_Y_L_M = 0xA, 168 OUT_Y_H_M = 0xB, 169 OUT_Z_L_M = 0xC, 170 OUT_Z_H_M = 0xD, 171 172 CTRL_REG0 = 0x1f, 173 CTRL_REG1 = 0x20, 174 CTRL_REG2 = 0x21, 175 CTRL_REG3 = 0x22, 176 CTRL_REG4 = 0x23, 177 CTRL_REG5 = 0x24, 178 CTRL_REG6 = 0x25, 179 CTRL_REG7 = 0x26, 180 181 STATUS_REGA = 0x27, 182 183 OUT_X_L_A = 0x28, 184 OUT_X_H_A = 0x29, 185 OUT_Y_L_A = 0x2A, 186 OUT_Y_H_A = 0x2B, 187 OUT_Z_L_A = 0x2C, 188 OUT_Z_H_A = 0x2D, 189 190 FIFO_CTRL = 0x2E, 191 FIFO_SRC = 0x2F, 192 193 IG_CFG1 = 0x30, 194 IG_SRC1 = 0x31, 195 IG_THS1 = 0x32, 196 IG_DUR1 = 0x33, 197 198 IG_CFG2 = 0x34, 199 IG_SRC2 = 0x35, 200 IG_THS2 = 0x36, 201 IG_DUR2 = 0x37, 202 203 CLICK_CFG = 0x38, 204 CLICK_SRC = 0x39, 205 CLICK_THS = 0x3A, 206 207 TIME_LIMIT = 0x3B, 208 TIME_LATEN = 0x3C, 209 TIME_WINDO = 0x3D, 210 211 ACT_THS = 0x3E, 212 ACT_DUR = 0x3F, 213 } LSM303d_REGS_T; 214 215 int writeThenRead(uint8_t reg); 216 mraa::Result setRegisterSafe(uint8_t slave, uint8_t sregister, uint8_t data); 217 218 mraa::I2c m_i2c; 219 int m_addr; 220 221 uint8_t buf[6]; 222 int16_t coor[3]; 223 int16_t accel[3]; 224 }; 225 226 } 227