Stephen Licht / MMA8452Q
Committer:
slicht_instructor
Date:
Sun Nov 28 15:17:01 2021 +0000
Revision:
0:bd5335862205
Accelerometer library for OCE360 final project.

Who changed what in which revision?

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