MECH478
Revision 0:26f36d63a397, committed 2022-05-12
- Comitter:
- daroldkellyjr
- Date:
- Thu May 12 15:26:25 2022 +0000
- Commit message:
- Committed;
Changed in this revision
MMA8452Q.cpp | Show annotated file Show diff for this revision Revisions of this file |
MMA8452Q.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 26f36d63a397 MMA8452Q.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA8452Q.cpp Thu May 12 15:26:25 2022 +0000 @@ -0,0 +1,175 @@ +// Library for our MMA8452Q 3-axis accelerometer +// Based on the MMA8452Q Arduino Library by Jim Lindblom (SparkFun Electronics) + +#include "mbed.h" +#include "MMA8452Q.h" + +// Constructor +MMA8452Q::MMA8452Q(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) +{ + // Initialize members + scale = DEFAULT_FSR; +} + +// Destructor +MMA8452Q::~MMA8452Q() +{ + +} + +// Initialization +bool MMA8452Q::init() +{ + // Check to make sure the chip's ID matches the factory ID + uint8_t c = readRegister(REG_WHO_AM_I); + if( c != FACTORY_ID ) { + return false; + } + + // Set default scale and data rate + standby(); + setScale(DEFAULT_FSR); + setODR(DEFAULT_ODR); + active(); + + return true; +} + +// Set the full-scale range for x, y, and z data +void MMA8452Q::setScale(uint8_t fsr) +{ + uint8_t config = readRegister(REG_XYZ_DATA_CFG); + scale = fsr; + config &= 0xFC; // Mask out FSR bits + fsr = fsr >> 2; // Trick to translate scale to FSR bits + fsr &= 0x03; // Mask out acceptable FSRs + config |= fsr; // Write FSR bits to config byte + writeRegister(REG_XYZ_DATA_CFG, config); // Write config back to register +} + +// Set the Output Data Rate +void MMA8452Q::setODR(uint8_t odr) +{ + uint8_t ctrl = readRegister(REG_CTRL_REG1); + ctrl &= 0xCF; // Mask out data rate bits + odr &= 0x07; // Mask out acceptable ODRs + ctrl |= (odr << 3); // Write ODR bits to control byte + writeRegister(REG_CTRL_REG1, ctrl); // Write control back to register +} + +// Set accelerometer into standby mode +void MMA8452Q::standby() +{ + uint8_t c = readRegister(REG_CTRL_REG1); + c &= ~(0x01); // Clear bit 0 to go into standby + writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register +} + +// Set accelerometer into active mode +void MMA8452Q::active() +{ + uint8_t c = readRegister(REG_CTRL_REG1); + c |= 0x01; // Set bit 0 to go into active mode + writeRegister(REG_CTRL_REG1, c); // Write back to CONTROL register +} + +// Read X registers +float MMA8452Q::readX() +{ + int16_t x = 0; + float cx = 0; + + // Read MSB and LSB from X registers + x = readRegister(OUT_X_MSB); + x = x << 8; + x |= readRegister(OUT_X_LSB); + x = x >> 4; + + // Calculate human readable X + cx = (float)x / (float)2048 * (float)(scale); + + return cx; +} + +// Read Y registers +float MMA8452Q::readY() +{ + int16_t y = 0; + float cy = 0; + + // Read MSB and LSB from Y registers + y = readRegister(OUT_Y_MSB); + y = y << 8; + y |= readRegister(OUT_Y_LSB); + y = y >> 4; + + // Calculate human readable Y + cy = (float)y / (float)2048 * (float)(scale); + + return cy; +} + +// Read Z registers +float MMA8452Q::readZ() +{ + int16_t z = 0; + float cz = 0; + + // Read MSB and LSB from Z registers + z = readRegister(OUT_Z_MSB); + z = z << 8; + z |= readRegister(OUT_Z_LSB); + z = z >> 4; + + // Calculate human readable Z + cz = (float)z / (float)2048 * (float)(scale); + + return cz; +} + +// Raw read register over I2C +uint8_t MMA8452Q::readRegister(uint8_t reg) +{ + uint8_t dev_addr; + uint8_t data; + + // I2C address are bits [6..1] in the transmitted byte, so we shift by 1 + dev_addr = m_addr << 1; + + // Write device address with a trailing 'write' bit + m_i2c.start(); + m_i2c.write(dev_addr & 0xFE); + + // Write register address + m_i2c.write(reg); + + // Write a start bit and device address with a trailing 'read' bit + m_i2c.start(); + m_i2c.write(dev_addr | 0x01); + + // Read single byte from I2C device + data = m_i2c.read(0); + m_i2c.stop(); + + return data; +} + +// Raw write data to a register over I2C +void MMA8452Q::writeRegister(uint8_t reg, uint8_t data) +{ + uint8_t dev_addr; + + // I2C address are bits [6..1] in the transmitted byte, so we shift by 1 + dev_addr = m_addr << 1; + + // Write device address with a trailing 'write' bit + m_i2c.start(); + m_i2c.write(dev_addr & 0xFE); + + // Write register address + m_i2c.write(reg); + + // Write the data to the register + m_i2c.write(data); + m_i2c.stop(); +}
diff -r 000000000000 -r 26f36d63a397 MMA8452Q.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA8452Q.h Thu May 12 15:26:25 2022 +0000 @@ -0,0 +1,68 @@ +// Library for our MMA8452Q 3-axis accelerometer +// Based on the MMA8452Q Arduino Library by Jim Lindblom (SparkFun Electronics) + +#ifndef MMA8452Q_H +#define MMA8452Q_H + +#include "mbed.h" + +// Register definitions +#define REG_STATUS 0x00 +#define OUT_X_MSB 0x01 +#define OUT_X_LSB 0x02 +#define OUT_Y_MSB 0x03 +#define OUT_Y_LSB 0x04 +#define OUT_Z_MSB 0x05 +#define OUT_Z_LSB 0x06 +#define REG_WHO_AM_I 0x0D +#define REG_XYZ_DATA_CFG 0x0E +#define REG_CTRL_REG1 0x2A + +// WHO_AM_I check +#define FACTORY_ID 0x2A + +// Scale definitions +#define SCALE_2G 2 +#define SCALE_4G 4 +#define SCALE_8G 8 + +// Data rates +#define ODR_800HZ 0 +#define ODR_400HZ 1 +#define ODR_200HZ 2 +#define ODR_100HZ 3 +#define ODR_50HZ 4 +#define ODR_12_5HZ 5 +#define ODR_6_25HZ 6 +#define ODR_1_56HZ 7 + +// Init values +#define DEFAULT_FSR SCALE_2G +#define DEFAULT_ODR ODR_800HZ + + +// Class declaration +class MMA8452Q +{ + public: + MMA8452Q(PinName sda, PinName scl, int addr); + ~MMA8452Q(); + bool init(); + uint8_t available(); + void setScale(uint8_t fsr); + void setODR(uint8_t odr); + void standby(); + void active(); + float readX(); + float readY(); + float readZ(); + uint8_t readRegister(uint8_t reg); + void writeRegister(uint8_t reg, uint8_t data); + + private: + I2C m_i2c; + int m_addr; + int scale; +}; + +#endif