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