Use accelerometer to interrupt.

Dependencies:   mbed SDFileSystem

Fork of shomberg_hw_7 by Russell Shomberg

Committer:
rshomberg
Date:
Fri Nov 16 19:53:25 2018 +0000
Revision:
28:a59485b1626b
Parent:
23:61d87ea09c26
Child:
29:d33071ffaa5f
Code compiles. Need to test. Very ugly!

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