Use accelerometer to interrupt.

Dependencies:   mbed SDFileSystem

Fork of shomberg_hw_7 by Russell Shomberg

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?

UserRevisionLine numberNew 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 }