Library to interface MMA8451Q sensor

Dependents:   LELEC_2811_Accelerometer_2 LELEC_2811_Multiple_Sensors LELEC_2811_acquiring_data LELEC_2811_acquiring_data_working

Committer:
martlefebvre94
Date:
Sat Sep 22 23:15:49 2018 +0000
Revision:
0:2a71c4ec3ee2
Child:
1:51c9ede6bb48
First code to interface the MMA8451Q accelerometer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
martlefebvre94 0:2a71c4ec3ee2 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
martlefebvre94 0:2a71c4ec3ee2 2 *
martlefebvre94 0:2a71c4ec3ee2 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
martlefebvre94 0:2a71c4ec3ee2 4 * and associated documentation files (the "Software"), to deal in the Software without
martlefebvre94 0:2a71c4ec3ee2 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
martlefebvre94 0:2a71c4ec3ee2 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
martlefebvre94 0:2a71c4ec3ee2 7 * Software is furnished to do so, subject to the following conditions:
martlefebvre94 0:2a71c4ec3ee2 8 *
martlefebvre94 0:2a71c4ec3ee2 9 * The above copyright notice and this permission notice shall be included in all copies or
martlefebvre94 0:2a71c4ec3ee2 10 * substantial portions of the Software.
martlefebvre94 0:2a71c4ec3ee2 11 *
martlefebvre94 0:2a71c4ec3ee2 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
martlefebvre94 0:2a71c4ec3ee2 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
martlefebvre94 0:2a71c4ec3ee2 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
martlefebvre94 0:2a71c4ec3ee2 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
martlefebvre94 0:2a71c4ec3ee2 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
martlefebvre94 0:2a71c4ec3ee2 17 */
martlefebvre94 0:2a71c4ec3ee2 18
martlefebvre94 0:2a71c4ec3ee2 19 #include "MMA8451Q.h"
martlefebvre94 0:2a71c4ec3ee2 20
martlefebvre94 0:2a71c4ec3ee2 21 #define REG_WHO_AM_I 0x0D
martlefebvre94 0:2a71c4ec3ee2 22 #define REG_CTRL_REG_1 0x2A
martlefebvre94 0:2a71c4ec3ee2 23 #define REG_OUT_X_MSB 0x01
martlefebvre94 0:2a71c4ec3ee2 24 #define REG_OUT_Y_MSB 0x03
martlefebvre94 0:2a71c4ec3ee2 25 #define REG_OUT_Z_MSB 0x05
martlefebvre94 0:2a71c4ec3ee2 26 #define REG_XYZ_DATA_CFG 0x0E
martlefebvre94 0:2a71c4ec3ee2 27
martlefebvre94 0:2a71c4ec3ee2 28 #define UINT14_MAX 16383
martlefebvre94 0:2a71c4ec3ee2 29
martlefebvre94 0:2a71c4ec3ee2 30 MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
martlefebvre94 0:2a71c4ec3ee2 31
martlefebvre94 0:2a71c4ec3ee2 32 // Place the peripheral in standby mode to configure the full scale range
martlefebvre94 0:2a71c4ec3ee2 33 uint8_t data[2] = {REG_CTRL_REG_1, 0x00};
martlefebvre94 0:2a71c4ec3ee2 34 writeRegs(data, 2);
martlefebvre94 0:2a71c4ec3ee2 35
martlefebvre94 0:2a71c4ec3ee2 36 // Set the scale
martlefebvre94 0:2a71c4ec3ee2 37 uint8_t fsr = 0x02;
martlefebvre94 0:2a71c4ec3ee2 38 setScale(fsr);
martlefebvre94 0:2a71c4ec3ee2 39
martlefebvre94 0:2a71c4ec3ee2 40 // Activate the peripheral
martlefebvre94 0:2a71c4ec3ee2 41 data[0] = REG_CTRL_REG_1;
martlefebvre94 0:2a71c4ec3ee2 42 data[1] = 0x01;
martlefebvre94 0:2a71c4ec3ee2 43 writeRegs(data, 2);
martlefebvre94 0:2a71c4ec3ee2 44 }
martlefebvre94 0:2a71c4ec3ee2 45
martlefebvre94 0:2a71c4ec3ee2 46 MMA8451Q::~MMA8451Q() { }
martlefebvre94 0:2a71c4ec3ee2 47
martlefebvre94 0:2a71c4ec3ee2 48 uint8_t MMA8451Q::getWhoAmI() {
martlefebvre94 0:2a71c4ec3ee2 49 uint8_t who_am_i = 0;
martlefebvre94 0:2a71c4ec3ee2 50 readRegs(REG_WHO_AM_I, &who_am_i, 1);
martlefebvre94 0:2a71c4ec3ee2 51 return who_am_i;
martlefebvre94 0:2a71c4ec3ee2 52 }
martlefebvre94 0:2a71c4ec3ee2 53
martlefebvre94 0:2a71c4ec3ee2 54 float MMA8451Q::getAccX() {
martlefebvre94 0:2a71c4ec3ee2 55 return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
martlefebvre94 0:2a71c4ec3ee2 56 }
martlefebvre94 0:2a71c4ec3ee2 57
martlefebvre94 0:2a71c4ec3ee2 58 float MMA8451Q::getAccY() {
martlefebvre94 0:2a71c4ec3ee2 59 return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
martlefebvre94 0:2a71c4ec3ee2 60 }
martlefebvre94 0:2a71c4ec3ee2 61
martlefebvre94 0:2a71c4ec3ee2 62 float MMA8451Q::getAccZ() {
martlefebvre94 0:2a71c4ec3ee2 63 return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
martlefebvre94 0:2a71c4ec3ee2 64 }
martlefebvre94 0:2a71c4ec3ee2 65
martlefebvre94 0:2a71c4ec3ee2 66 void MMA8451Q::getAccAllAxis(float * res) {
martlefebvre94 0:2a71c4ec3ee2 67 res[0] = getAccX();
martlefebvre94 0:2a71c4ec3ee2 68 res[1] = getAccY();
martlefebvre94 0:2a71c4ec3ee2 69 res[2] = getAccZ();
martlefebvre94 0:2a71c4ec3ee2 70 }
martlefebvre94 0:2a71c4ec3ee2 71
martlefebvre94 0:2a71c4ec3ee2 72 int16_t MMA8451Q::getAccAxis(uint8_t addr) {
martlefebvre94 0:2a71c4ec3ee2 73 int16_t acc;
martlefebvre94 0:2a71c4ec3ee2 74 uint8_t res[2];
martlefebvre94 0:2a71c4ec3ee2 75 readRegs(addr, res, 2);
martlefebvre94 0:2a71c4ec3ee2 76
martlefebvre94 0:2a71c4ec3ee2 77 acc = (res[0] << 6) | (res[1] >> 2);
martlefebvre94 0:2a71c4ec3ee2 78 if (acc > UINT14_MAX/2)
martlefebvre94 0:2a71c4ec3ee2 79 acc -= UINT14_MAX;
martlefebvre94 0:2a71c4ec3ee2 80
martlefebvre94 0:2a71c4ec3ee2 81 return acc;
martlefebvre94 0:2a71c4ec3ee2 82 }
martlefebvre94 0:2a71c4ec3ee2 83
martlefebvre94 0:2a71c4ec3ee2 84 void MMA8451Q::setScale(uint8_t fsr)
martlefebvre94 0:2a71c4ec3ee2 85 {
martlefebvre94 0:2a71c4ec3ee2 86 // Read register
martlefebvre94 0:2a71c4ec3ee2 87 uint8_t cfg;
martlefebvre94 0:2a71c4ec3ee2 88 readRegs(REG_XYZ_DATA_CFG, &cfg, 8);
martlefebvre94 0:2a71c4ec3ee2 89
martlefebvre94 0:2a71c4ec3ee2 90 // Mask out scale bits
martlefebvre94 0:2a71c4ec3ee2 91 cfg = cfg & 0xFC;
martlefebvre94 0:2a71c4ec3ee2 92 cfg = cfg | fsr; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
martlefebvre94 0:2a71c4ec3ee2 93
martlefebvre94 0:2a71c4ec3ee2 94 // Write the configuration register
martlefebvre94 0:2a71c4ec3ee2 95 uint8_t data[2] = {REG_XYZ_DATA_CFG, cfg};
martlefebvre94 0:2a71c4ec3ee2 96 writeRegs(data, 8);
martlefebvre94 0:2a71c4ec3ee2 97 }
martlefebvre94 0:2a71c4ec3ee2 98
martlefebvre94 0:2a71c4ec3ee2 99 void MMA8451Q::readRegs(int addr, uint8_t * data, int len) {
martlefebvre94 0:2a71c4ec3ee2 100 char t[1] = {addr};
martlefebvre94 0:2a71c4ec3ee2 101 m_i2c.write(m_addr, t, 1, true);
martlefebvre94 0:2a71c4ec3ee2 102 m_i2c.read(m_addr, (char *)data, len);
martlefebvre94 0:2a71c4ec3ee2 103 }
martlefebvre94 0:2a71c4ec3ee2 104
martlefebvre94 0:2a71c4ec3ee2 105 void MMA8451Q::writeRegs(uint8_t * data, int len) {
martlefebvre94 0:2a71c4ec3ee2 106 m_i2c.write(m_addr, (char *)data, len);
martlefebvre94 0:2a71c4ec3ee2 107 }