accelerometer library

Fork of MMA8452Q by Stephen Licht

Committer:
rsean10
Date:
Thu Dec 07 15:23:07 2017 +0000
Revision:
1:a63e41016132
Parent:
0:b3305e3c9e73
this works i think;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
slicht 0:b3305e3c9e73 1 // Library for our MMA8452Q 3-axis accelerometer
slicht 0:b3305e3c9e73 2 // Based on the MMA8452Q Arduino Library by Jim Lindblom (SparkFun Electronics)
slicht 0:b3305e3c9e73 3
slicht 0:b3305e3c9e73 4 #include "mbed.h"
slicht 0:b3305e3c9e73 5 #include "MMA8452Q.h"
slicht 0:b3305e3c9e73 6
slicht 0:b3305e3c9e73 7 // Constructor
slicht 0:b3305e3c9e73 8 MMA8452Q::MMA8452Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr)
slicht 0:b3305e3c9e73 9 {
slicht 0:b3305e3c9e73 10 // Initialize members
slicht 0:b3305e3c9e73 11 scale = DEFAULT_FSR;
slicht 0:b3305e3c9e73 12 }
slicht 0:b3305e3c9e73 13
slicht 0:b3305e3c9e73 14 // Destructor
slicht 0:b3305e3c9e73 15 MMA8452Q::~MMA8452Q()
slicht 0:b3305e3c9e73 16 {
slicht 0:b3305e3c9e73 17
slicht 0:b3305e3c9e73 18 }
slicht 0:b3305e3c9e73 19
slicht 0:b3305e3c9e73 20 // Initialization
slicht 0:b3305e3c9e73 21 bool MMA8452Q::init()
slicht 0:b3305e3c9e73 22 {
slicht 0:b3305e3c9e73 23 // Check to make sure the chip's ID matches the factory ID
slicht 0:b3305e3c9e73 24 uint8_t c = readRegister(REG_WHO_AM_I);
slicht 0:b3305e3c9e73 25 if( c != FACTORY_ID ) {
slicht 0:b3305e3c9e73 26 return false;
slicht 0:b3305e3c9e73 27 }
slicht 0:b3305e3c9e73 28
slicht 0:b3305e3c9e73 29 // Set default scale and data rate
slicht 0:b3305e3c9e73 30 standby();
slicht 0:b3305e3c9e73 31 setScale(DEFAULT_FSR);
slicht 0:b3305e3c9e73 32 setODR(DEFAULT_ODR);
rsean10 1:a63e41016132 33 //freefall(); //enable freefall
slicht 0:b3305e3c9e73 34 active();
slicht 0:b3305e3c9e73 35
slicht 0:b3305e3c9e73 36 return true;
slicht 0:b3305e3c9e73 37 }
slicht 0:b3305e3c9e73 38
slicht 0:b3305e3c9e73 39 // Set the full-scale range for x, y, and z data
slicht 0:b3305e3c9e73 40 void MMA8452Q::setScale(uint8_t fsr)
slicht 0:b3305e3c9e73 41 {
slicht 0:b3305e3c9e73 42 uint8_t config = readRegister(REG_XYZ_DATA_CFG);
slicht 0:b3305e3c9e73 43 scale = fsr;
slicht 0:b3305e3c9e73 44 config &= 0xFC; // Mask out FSR bits
slicht 0:b3305e3c9e73 45 fsr = fsr >> 2; // Trick to translate scale to FSR bits
slicht 0:b3305e3c9e73 46 fsr &= 0x03; // Mask out acceptable FSRs
slicht 0:b3305e3c9e73 47 config |= fsr; // Write FSR bits to config byte
slicht 0:b3305e3c9e73 48 writeRegister(REG_XYZ_DATA_CFG, config); // Write config back to register
slicht 0:b3305e3c9e73 49 }
slicht 0:b3305e3c9e73 50
slicht 0:b3305e3c9e73 51 // Set the Output Data Rate
slicht 0:b3305e3c9e73 52 void MMA8452Q::setODR(uint8_t odr)
slicht 0:b3305e3c9e73 53 {
slicht 0:b3305e3c9e73 54 uint8_t ctrl = readRegister(REG_CTRL_REG1);
slicht 0:b3305e3c9e73 55 ctrl &= 0xCF; // Mask out data rate bits
slicht 0:b3305e3c9e73 56 odr &= 0x07; // Mask out acceptable ODRs
slicht 0:b3305e3c9e73 57 ctrl |= (odr << 3); // Write ODR bits to control byte
slicht 0:b3305e3c9e73 58 writeRegister(REG_CTRL_REG1, ctrl); // Write control back to register
slicht 0:b3305e3c9e73 59 }
slicht 0:b3305e3c9e73 60
slicht 0:b3305e3c9e73 61 // Set accelerometer into standby mode
slicht 0:b3305e3c9e73 62 void MMA8452Q::standby()
slicht 0:b3305e3c9e73 63 {
slicht 0:b3305e3c9e73 64 uint8_t c = readRegister(REG_CTRL_REG1);
slicht 0:b3305e3c9e73 65 c &= ~(0x01); // Clear bit 0 to go into standby
slicht 0:b3305e3c9e73 66 writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register
slicht 0:b3305e3c9e73 67 }
slicht 0:b3305e3c9e73 68
slicht 0:b3305e3c9e73 69 // Set accelerometer into active mode
slicht 0:b3305e3c9e73 70 void MMA8452Q::active()
slicht 0:b3305e3c9e73 71 {
slicht 0:b3305e3c9e73 72 uint8_t c = readRegister(REG_CTRL_REG1);
slicht 0:b3305e3c9e73 73 c |= 0x01; // Set bit 0 to go into active mode
slicht 0:b3305e3c9e73 74 writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register
slicht 0:b3305e3c9e73 75 }
slicht 0:b3305e3c9e73 76
rsean10 1:a63e41016132 77 //Enabe Freefall interrupt
rsean10 1:a63e41016132 78 void MMA8452Q::freefall(uint8_t interrupt,uint8_t threshold)
rsean10 1:a63e41016132 79 {
rsean10 1:a63e41016132 80 writeRegister(FF_CONFIG,0x38); // Configure for freefall
rsean10 1:a63e41016132 81 writeRegister(FF_THS,threshold); // Configure for threshold <"thresh"g
rsean10 1:a63e41016132 82 writeRegister(FF_COUNT,0x64); // Set debounce counter for 125ms
rsean10 1:a63e41016132 83 writeRegister(REG_CTRL_REG4,0x04); // enable interrupt in control register
rsean10 1:a63e41016132 84 writeRegister(REG_CTRL_REG5,interrupt); // set interrupt to hardware pin
rsean10 1:a63e41016132 85 }
rsean10 1:a63e41016132 86
slicht 0:b3305e3c9e73 87 // Read X registers
slicht 0:b3305e3c9e73 88 float MMA8452Q::readX()
slicht 0:b3305e3c9e73 89 {
slicht 0:b3305e3c9e73 90 int16_t x = 0;
slicht 0:b3305e3c9e73 91 float cx = 0;
slicht 0:b3305e3c9e73 92
slicht 0:b3305e3c9e73 93 // Read MSB and LSB from X registers
slicht 0:b3305e3c9e73 94 x = readRegister(OUT_X_MSB);
slicht 0:b3305e3c9e73 95 x = x << 8;
slicht 0:b3305e3c9e73 96 x |= readRegister(OUT_X_LSB);
slicht 0:b3305e3c9e73 97 x = x >> 4;
slicht 0:b3305e3c9e73 98
slicht 0:b3305e3c9e73 99 // Calculate human readable X
slicht 0:b3305e3c9e73 100 cx = (float)x / (float)2048 * (float)(scale);
slicht 0:b3305e3c9e73 101
slicht 0:b3305e3c9e73 102 return cx;
slicht 0:b3305e3c9e73 103 }
slicht 0:b3305e3c9e73 104
slicht 0:b3305e3c9e73 105 // Read Y registers
slicht 0:b3305e3c9e73 106 float MMA8452Q::readY()
slicht 0:b3305e3c9e73 107 {
slicht 0:b3305e3c9e73 108 int16_t y = 0;
slicht 0:b3305e3c9e73 109 float cy = 0;
slicht 0:b3305e3c9e73 110
slicht 0:b3305e3c9e73 111 // Read MSB and LSB from Y registers
slicht 0:b3305e3c9e73 112 y = readRegister(OUT_Y_MSB);
slicht 0:b3305e3c9e73 113 y = y << 8;
slicht 0:b3305e3c9e73 114 y |= readRegister(OUT_Y_LSB);
slicht 0:b3305e3c9e73 115 y = y >> 4;
slicht 0:b3305e3c9e73 116
slicht 0:b3305e3c9e73 117 // Calculate human readable Y
slicht 0:b3305e3c9e73 118 cy = (float)y / (float)2048 * (float)(scale);
slicht 0:b3305e3c9e73 119
slicht 0:b3305e3c9e73 120 return cy;
slicht 0:b3305e3c9e73 121 }
slicht 0:b3305e3c9e73 122
slicht 0:b3305e3c9e73 123 // Read Z registers
slicht 0:b3305e3c9e73 124 float MMA8452Q::readZ()
slicht 0:b3305e3c9e73 125 {
slicht 0:b3305e3c9e73 126 int16_t z = 0;
slicht 0:b3305e3c9e73 127 float cz = 0;
slicht 0:b3305e3c9e73 128
slicht 0:b3305e3c9e73 129 // Read MSB and LSB from Z registers
slicht 0:b3305e3c9e73 130 z = readRegister(OUT_Z_MSB);
slicht 0:b3305e3c9e73 131 z = z << 8;
slicht 0:b3305e3c9e73 132 z |= readRegister(OUT_Z_LSB);
slicht 0:b3305e3c9e73 133 z = z >> 4;
slicht 0:b3305e3c9e73 134
slicht 0:b3305e3c9e73 135 // Calculate human readable Z
slicht 0:b3305e3c9e73 136 cz = (float)z / (float)2048 * (float)(scale);
slicht 0:b3305e3c9e73 137
slicht 0:b3305e3c9e73 138 return cz;
slicht 0:b3305e3c9e73 139 }
slicht 0:b3305e3c9e73 140
slicht 0:b3305e3c9e73 141 // Raw read register over I2C
slicht 0:b3305e3c9e73 142 uint8_t MMA8452Q::readRegister(uint8_t reg)
slicht 0:b3305e3c9e73 143 {
slicht 0:b3305e3c9e73 144 uint8_t dev_addr;
slicht 0:b3305e3c9e73 145 uint8_t data;
slicht 0:b3305e3c9e73 146
slicht 0:b3305e3c9e73 147 // I2C address are bits [6..1] in the transmitted byte, so we shift by 1
slicht 0:b3305e3c9e73 148 dev_addr = m_addr << 1;
slicht 0:b3305e3c9e73 149
slicht 0:b3305e3c9e73 150 // Write device address with a trailing 'write' bit
slicht 0:b3305e3c9e73 151 m_i2c.start();
slicht 0:b3305e3c9e73 152 m_i2c.write(dev_addr & 0xFE);
slicht 0:b3305e3c9e73 153
slicht 0:b3305e3c9e73 154 // Write register address
slicht 0:b3305e3c9e73 155 m_i2c.write(reg);
slicht 0:b3305e3c9e73 156
slicht 0:b3305e3c9e73 157 // Write a start bit and device address with a trailing 'read' bit
slicht 0:b3305e3c9e73 158 m_i2c.start();
slicht 0:b3305e3c9e73 159 m_i2c.write(dev_addr | 0x01);
slicht 0:b3305e3c9e73 160
slicht 0:b3305e3c9e73 161 // Read single byte from I2C device
slicht 0:b3305e3c9e73 162 data = m_i2c.read(0);
slicht 0:b3305e3c9e73 163 m_i2c.stop();
slicht 0:b3305e3c9e73 164
slicht 0:b3305e3c9e73 165 return data;
slicht 0:b3305e3c9e73 166 }
slicht 0:b3305e3c9e73 167
slicht 0:b3305e3c9e73 168 // Raw write data to a register over I2C
slicht 0:b3305e3c9e73 169 void MMA8452Q::writeRegister(uint8_t reg, uint8_t data)
slicht 0:b3305e3c9e73 170 {
slicht 0:b3305e3c9e73 171 uint8_t dev_addr;
slicht 0:b3305e3c9e73 172
slicht 0:b3305e3c9e73 173 // I2C address are bits [6..1] in the transmitted byte, so we shift by 1
slicht 0:b3305e3c9e73 174 dev_addr = m_addr << 1;
slicht 0:b3305e3c9e73 175
slicht 0:b3305e3c9e73 176 // Write device address with a trailing 'write' bit
slicht 0:b3305e3c9e73 177 m_i2c.start();
slicht 0:b3305e3c9e73 178 m_i2c.write(dev_addr & 0xFE);
slicht 0:b3305e3c9e73 179
slicht 0:b3305e3c9e73 180 // Write register address
slicht 0:b3305e3c9e73 181 m_i2c.write(reg);
slicht 0:b3305e3c9e73 182
slicht 0:b3305e3c9e73 183 // Write the data to the register
slicht 0:b3305e3c9e73 184 m_i2c.write(data);
slicht 0:b3305e3c9e73 185 m_i2c.stop();
slicht 0:b3305e3c9e73 186 }