Use accelerometer to interrupt.

Dependencies:   mbed SDFileSystem

Fork of shomberg_hw_7 by Russell Shomberg

Committer:
rshomberg
Date:
Sun Nov 18 19:24:26 2018 +0000
Revision:
29:d33071ffaa5f
Parent:
28:a59485b1626b
working code. Tested. Works well.; Doesn't have ability to change interrupt.

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