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