MECH478

Files at this revision

API Documentation at this revision

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
--- /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();
+}
--- /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