Library for Freescale MMA8452 Accelerometer

Dependents:   acce_ChenZhengyang mbed_ProjectC_Accelerometer AccelerometerProject mbed_Accelerometer ... more

Committer:
eencae
Date:
Sun Mar 08 15:31:02 2015 +0000
Revision:
0:df3b9e41edf3
Library for Freescale MMA8452 accelerometer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eencae 0:df3b9e41edf3 1 /**
eencae 0:df3b9e41edf3 2 @file MMA8452.cpp
eencae 0:df3b9e41edf3 3
eencae 0:df3b9e41edf3 4 @brief Member functions implementations
eencae 0:df3b9e41edf3 5
eencae 0:df3b9e41edf3 6 */
eencae 0:df3b9e41edf3 7 #include "mbed.h"
eencae 0:df3b9e41edf3 8 #include "MMA8452.h"
eencae 0:df3b9e41edf3 9
eencae 0:df3b9e41edf3 10 MMA8452:: MMA8452(PinName sdaPin, PinName sclPin)
eencae 0:df3b9e41edf3 11 {
eencae 0:df3b9e41edf3 12 i2c = new I2C(sdaPin,sclPin); // create new I2C instance and initialise
eencae 0:df3b9e41edf3 13 i2c->frequency(400000); // I2C Fast Mode - 400kHz
eencae 0:df3b9e41edf3 14 leds = new BusOut(LED4,LED3,LED2,LED1); // for debug
eencae 0:df3b9e41edf3 15 }
eencae 0:df3b9e41edf3 16
eencae 0:df3b9e41edf3 17 void MMA8452::init()
eencae 0:df3b9e41edf3 18 {
eencae 0:df3b9e41edf3 19
eencae 0:df3b9e41edf3 20 i2c->frequency(400000); // set Fast Mode I2C frequency (5.10 datasheet)
eencae 0:df3b9e41edf3 21
eencae 0:df3b9e41edf3 22 char data = readByteFromRegister(WHO_AM_I); // p18 datasheet
eencae 0:df3b9e41edf3 23 if (data != 0x2A) { // if correct ID not found, hand and flash error message
eencae 0:df3b9e41edf3 24 error();
eencae 0:df3b9e41edf3 25 }
eencae 0:df3b9e41edf3 26
eencae 0:df3b9e41edf3 27 // put into STANDBY while configuring
eencae 0:df3b9e41edf3 28 data = readByteFromRegister(CTRL_REG1); // get current value of register
eencae 0:df3b9e41edf3 29 data &= ~(1<<0); // clear bit 0 (p37 datasheet)
eencae 0:df3b9e41edf3 30 sendByteToRegister(data,CTRL_REG1);
eencae 0:df3b9e41edf3 31
eencae 0:df3b9e41edf3 32 // Set output data rate, default is 800 Hz, will set to 100 Hz (clear b5, set b4/b3 - p37 datasheet)
eencae 0:df3b9e41edf3 33 data = readByteFromRegister(CTRL_REG1);
eencae 0:df3b9e41edf3 34 data &= ~(1<<5);
eencae 0:df3b9e41edf3 35 data |= (1<<4);
eencae 0:df3b9e41edf3 36 data |= (1<<3);
eencae 0:df3b9e41edf3 37 sendByteToRegister(data,CTRL_REG1);
eencae 0:df3b9e41edf3 38
eencae 0:df3b9e41edf3 39 //// Can also change default 2g range to 4g or 8g (p22 datasheet)
eencae 0:df3b9e41edf3 40 data = readByteFromRegister(XYZ_DATA_CFG);
eencae 0:df3b9e41edf3 41 data |= (1<<0); // set bit 0 - 4g range
eencae 0:df3b9e41edf3 42 sendByteToRegister(data,XYZ_DATA_CFG);
eencae 0:df3b9e41edf3 43
eencae 0:df3b9e41edf3 44 // set ACTIVE
eencae 0:df3b9e41edf3 45 data = readByteFromRegister(CTRL_REG1);
eencae 0:df3b9e41edf3 46 data |= (1<<0); // set bit 0 in CTRL_REG1
eencae 0:df3b9e41edf3 47 sendByteToRegister(data,CTRL_REG1);
eencae 0:df3b9e41edf3 48
eencae 0:df3b9e41edf3 49 }
eencae 0:df3b9e41edf3 50
eencae 0:df3b9e41edf3 51 // read acceleration data from device
eencae 0:df3b9e41edf3 52 Acceleration MMA8452::readValues()
eencae 0:df3b9e41edf3 53 {
eencae 0:df3b9e41edf3 54 // acceleration data stored in 6 registers (0x01 to 0x06)
eencae 0:df3b9e41edf3 55 // device automatically increments register, so can read 6 bytes starting from OUT_X_MSB
eencae 0:df3b9e41edf3 56 char data[6];
eencae 0:df3b9e41edf3 57 readBytesFromRegister(OUT_X_MSB,6,data);
eencae 0:df3b9e41edf3 58
eencae 0:df3b9e41edf3 59 char x_MSB = data[0]; // extract MSB and LSBs for x,y,z values
eencae 0:df3b9e41edf3 60 char x_LSB = data[1];
eencae 0:df3b9e41edf3 61 char y_MSB = data[2];
eencae 0:df3b9e41edf3 62 char y_LSB = data[3];
eencae 0:df3b9e41edf3 63 char z_MSB = data[4];
eencae 0:df3b9e41edf3 64 char z_LSB = data[5];
eencae 0:df3b9e41edf3 65
eencae 0:df3b9e41edf3 66 // [0:7] of MSB are 8 MSB of 12-bit value , [7:4] of LSB are 4 LSB's of 12-bit value
eencae 0:df3b9e41edf3 67 // need to type-cast as numbers are in signed (2's complement) form (p20 datasheet)
eencae 0:df3b9e41edf3 68 int x = (int16_t) (x_MSB << 8) | x_LSB; // combine bytes
eencae 0:df3b9e41edf3 69 x >>= 4; // are left-aligned, so shift 4 places right to right-align
eencae 0:df3b9e41edf3 70 int y = (int16_t) (y_MSB << 8) | y_LSB;
eencae 0:df3b9e41edf3 71 y >>= 4;
eencae 0:df3b9e41edf3 72 int z = (int16_t) (z_MSB << 8) | z_LSB;
eencae 0:df3b9e41edf3 73 z >>= 4;
eencae 0:df3b9e41edf3 74
eencae 0:df3b9e41edf3 75 // sensitivity is 1024 counts/g in 2g mode (pg 9 datasheet)
eencae 0:df3b9e41edf3 76 // " " 512 " 4g "
eencae 0:df3b9e41edf3 77 // " " 256 " 8g "
eencae 0:df3b9e41edf3 78 Acceleration acc;
eencae 0:df3b9e41edf3 79
eencae 0:df3b9e41edf3 80 acc.x = x/512.0;
eencae 0:df3b9e41edf3 81 acc.y = y/512.0;
eencae 0:df3b9e41edf3 82 acc.z = z/512.0;
eencae 0:df3b9e41edf3 83
eencae 0:df3b9e41edf3 84 return acc;
eencae 0:df3b9e41edf3 85 }
eencae 0:df3b9e41edf3 86
eencae 0:df3b9e41edf3 87 // reads a byte from a specific register
eencae 0:df3b9e41edf3 88 char MMA8452::readByteFromRegister(char reg)
eencae 0:df3b9e41edf3 89 {
eencae 0:df3b9e41edf3 90 int nack = i2c->write(MMA8452_W_ADDRESS,&reg,1,true); // send the register address to the slave
eencae 0:df3b9e41edf3 91 // true as need to send repeated start condition (5.10.1 datasheet)
eencae 0:df3b9e41edf3 92 // http://www.i2c-bus.org/repeated-start-condition/
eencae 0:df3b9e41edf3 93 if (nack)
eencae 0:df3b9e41edf3 94 error(); // if we don't receive acknowledgement, flash error message
eencae 0:df3b9e41edf3 95
eencae 0:df3b9e41edf3 96 char rx;
eencae 0:df3b9e41edf3 97 nack = i2c->read(MMA8452_R_ADDRESS,&rx,1); // read a byte from the register and store in buffer
eencae 0:df3b9e41edf3 98 if (nack)
eencae 0:df3b9e41edf3 99 error(); // if we don't receive acknowledgement, flash error message
eencae 0:df3b9e41edf3 100
eencae 0:df3b9e41edf3 101 return rx;
eencae 0:df3b9e41edf3 102 }
eencae 0:df3b9e41edf3 103
eencae 0:df3b9e41edf3 104 // reads a series of bytes, starting from a specific register
eencae 0:df3b9e41edf3 105 void MMA8452::readBytesFromRegister(char reg,int numberOfBytes,char bytes[])
eencae 0:df3b9e41edf3 106 {
eencae 0:df3b9e41edf3 107
eencae 0:df3b9e41edf3 108 int nack = i2c->write(MMA8452_W_ADDRESS,&reg,1,true); // send the slave write address and the configuration register address
eencae 0:df3b9e41edf3 109 // true as need to send repeated start condition (5.10.1 datasheet)
eencae 0:df3b9e41edf3 110 // http://www.i2c-bus.org/repeated-start-condition/
eencae 0:df3b9e41edf3 111
eencae 0:df3b9e41edf3 112 if (nack)
eencae 0:df3b9e41edf3 113 error(); // if we don't receive acknowledgement, flash error message
eencae 0:df3b9e41edf3 114
eencae 0:df3b9e41edf3 115 nack = i2c->read(MMA8452_R_ADDRESS,bytes,numberOfBytes); // read bytes
eencae 0:df3b9e41edf3 116 if (nack)
eencae 0:df3b9e41edf3 117 error(); // if we don't receive acknowledgement, flash error message
eencae 0:df3b9e41edf3 118
eencae 0:df3b9e41edf3 119 }
eencae 0:df3b9e41edf3 120
eencae 0:df3b9e41edf3 121 // sends a byte to a specific register
eencae 0:df3b9e41edf3 122 void MMA8452::sendByteToRegister(char byte,char reg)
eencae 0:df3b9e41edf3 123 {
eencae 0:df3b9e41edf3 124 char data[2];
eencae 0:df3b9e41edf3 125 data[0] = reg;
eencae 0:df3b9e41edf3 126 data[1] = byte;
eencae 0:df3b9e41edf3 127 // send the register address, followed by the data
eencae 0:df3b9e41edf3 128 int nack = i2c->write(MMA8452_W_ADDRESS,data,2);
eencae 0:df3b9e41edf3 129 if (nack)
eencae 0:df3b9e41edf3 130 error(); // if we don't receive acknowledgement, flash error message
eencae 0:df3b9e41edf3 131
eencae 0:df3b9e41edf3 132 }
eencae 0:df3b9e41edf3 133
eencae 0:df3b9e41edf3 134 void MMA8452::error()
eencae 0:df3b9e41edf3 135 {
eencae 0:df3b9e41edf3 136 while(1) {
eencae 0:df3b9e41edf3 137 leds->write(15);
eencae 0:df3b9e41edf3 138 wait(0.1);
eencae 0:df3b9e41edf3 139 leds->write(0);
eencae 0:df3b9e41edf3 140 wait(0.1);
eencae 0:df3b9e41edf3 141 }
eencae 0:df3b9e41edf3 142 }