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