MECH478

Committer:
daroldkellyjr
Date:
Thu May 12 15:26:25 2022 +0000
Revision:
0:26f36d63a397
Committed;

Who changed what in which revision?

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