Library for driving the MMA8452 accelerometer over I2C
Dependents: MMA8452_Test MMA8452_Demo Dualing_Tanks IMU-Controlled_MP3_Player ... more
Here is a simple example:
#include "mbed.h" #include "MMA8452.h" int main() { Serial pc(USBTX,USBRX); pc.baud(115200); double x = 0, y = 0, z = 0; MMA8452 acc(p28, p27, 40000); acc.setBitDepth(MMA8452::BIT_DEPTH_12); acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G); acc.setDataRate(MMA8452::RATE_100); while(1) { if(!acc.isXYZReady()) { wait(0.01); continue; } acc.readXYZGravity(&x,&y,&z); pc.printf("Gravities: %lf %lf %lf\r\n",x,y,z); } }
An easy way to test that this actually works is to run the loop above and hold the MMA8452 parallel to the ground along the respective axis (and upsidedown in each axis). You will see 1G on the respective axis and 0G on the others.
Revision 21:a92a632a0cc7, committed 2014-03-07
- Comitter:
- ashleymills
- Date:
- Fri Mar 07 14:53:40 2014 +0000
- Parent:
- 20:d55e9d7eb17e
- Commit message:
- Improved doxygen.
Changed in this revision
MMA8452.cpp | Show annotated file Show diff for this revision Revisions of this file |
MMA8452.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r d55e9d7eb17e -r a92a632a0cc7 MMA8452.cpp --- a/MMA8452.cpp Fri Mar 07 11:55:30 2014 +0000 +++ b/MMA8452.cpp Fri Mar 07 14:53:40 2014 +0000 @@ -127,9 +127,9 @@ ); } -char MMA8452::getMaskedRegister(int reg, char mask) { +char MMA8452::getMaskedRegister(int addr, char mask) { char rval = 0; - if(readRegister(reg,&rval)) { + if(readRegister(addr,&rval)) { return 0; } return (rval&mask);
diff -r d55e9d7eb17e -r a92a632a0cc7 MMA8452.h --- a/MMA8452.h Fri Mar 07 11:55:30 2014 +0000 +++ b/MMA8452.h Fri Mar 07 14:53:40 2014 +0000 @@ -107,7 +107,10 @@ #define MMA8452_STATUS_ZDR_MASK 0x04 #define MMA8452_STATUS_YDR_MASK 0x02 #define MMA8452_STATUS_XDR_MASK 0x01 - + +/** + * Wrapper for the MMA8452 I2C driven accelerometer. + */ class MMA8452 { public: @@ -136,8 +139,7 @@ RATE_1_563, RATE_UNKNOWN }; - - + /** * Create an accelerometer object connected to the specified I2C pins. * @@ -162,84 +164,120 @@ * @return 0 on success, 1 on failure. */ int standby(); - - /** Initialization of device MMA8452 (required) - */ - void init(); /** * Read the device ID from the accelerometer (should be 0x2a) * - * @param pointer to store the ID + * @param dst pointer to store the ID * @return 0 on success, 1 on failure. */ int getDeviceID(char* dst); + /** + * Read the MMA8452 status register. + * + * @param dst pointer to store the register value. + * @ return 0 on success, 1 on failure. + */ int getStatus(char* dst); /** - * Read the x,y, and z registers of the MMA8452. + * Read the raw x, y, an z registers of the MMA8452 in one operation. + * All three registers are read sequentially and stored in the provided buffer. + * The stored values are signed 2's complement left-aligned 12 or 8 bit integers. * * @param dst The destination buffer. Note that this needs to be 3 bytes for * BIT_DEPTH_8 and 6 bytes for BIT_DEPTH_12. It is upto the caller to ensure this. * @return 0 for success, and 1 for failure + * @sa setBitDepth */ int readXYZRaw(char *dst); + /// Read the raw x register into the provided buffer. @sa readXYZRaw int readXRaw(char *dst); + /// Read the raw y register into the provided buffer. @sa readXYZRaw int readYRaw(char *dst); + /// Read the raw z register into the provided buffer. @sa readXYZRaw int readZRaw(char *dst); /** - * Read the x, y, and z counts of the MMA7452 axes. + * Read the x, y, and z signed counts of the MMA8452 axes. * * Count resolution is either 8 bits or 12 bits, and the range is either +-2G, +-4G, or +-8G - * depending on settings. + * depending on settings. The number of counts per G are 1024, 512, 256 for 2,4, and 8 G + * respectively at 12 bit resolution and 64, 32, 16 for 2, 4, and 8 G respectively at + * 8 bit resolution. * * This function queries the MMA8452 and returns the signed counts for each axes. * * @param x Pointer to integer to store x count * @param y Pointer to integer to store y count * @param z Pointer to integer to store z count - * @return 0 on success, 1 on failure + * @return 0 on success, 1 on failure. */ int readXYZCounts(int *x, int *y, int *z); + + /// Read the x axes signed count. @sa readXYZCounts int readXCount(int *x); + /// Read the y axes signed count. @sa readXYZCounts int readYCount(int *y); + /// Read the z axes signed count. @sa readXYZCounts int readZCount(int *z); + /** + * Read the x, y, and z accelerations measured in G. + * + * The measurement resolution is controlled via setBitDepth which can + * be 8 or 12, and by setDynamicRange, which can be +-2G, +-4G, or +-8G. + * + * @param x A pointer to the double to store the x acceleration in. + * @param y A pointer to the double to store the y acceleration in. + * @param z A pointer to the double to store the z acceleration in. + * + * @return 0 on success, 1 on failure. + */ int readXYZGravity(double *x, double *y, double *z); - int readXGravity(double *x); - int readYGravity(double *y); - int readZGravity(double *z); - /// Returns 1 if data has been internally sampled (is available) for the x-axis since last read, 0 otherwise. - int isXReady(); - - /// Returns 1 if data has been internally sampled (is available) for the y-axis since last read, 0 otherwise. - int isYReady(); - - /// Returns 1 if data has been internally sampled (is available) for the z-axis since last read, 0 otherwise. - int isZReady(); + /// Read the x gravity in G into the provided double pointer. @sa readXYZGravity + int readXGravity(double *x); + /// Read the y gravity in G into the provided double pointer. @sa readXYZGravity + int readYGravity(double *y); + /// Read the z gravity in G into the provided double pointer. @sa readXYZGravity + int readZGravity(double *z); /// Returns 1 if data has been internally sampled (is available) for all axes since last read, 0 otherwise. int isXYZReady(); + /// Returns 1 if data has been internally sampled (is available) for the x-axis since last read, 0 otherwise. + int isXReady(); + /// Returns 1 if data has been internally sampled (is available) for the y-axis since last read, 0 otherwise. + int isYReady(); + /// Returns 1 if data has been internally sampled (is available) for the z-axis since last read, 0 otherwise. + int isZReady(); /** - * Read from specified MMA8452 register. + * Reads a single byte from the specified MMA8452 register. * - * @param addr The internal registeraddress of the MMA8452 - * @return The value of the register + * @param addr The internal register address. + * @param dst The destination buffer address. + * @return 1 on success, 0 on failure. */ int readRegister(char addr, char *dst); + /** + * Reads n bytes from the specified MMA8452 register. + * + * @param addr The internal register address. + * @param dst The destination buffer address. + * @param nbytes The number of bytes to read. + * @return 1 on success, 0 on failure. + */ int readRegister(char addr, char *dst, int nbytes); /** * Write to the specified MMA8452 register. * * @param addr The internal register address - * @param data Data to write + * @param data Data byte to write */ int writeRegister(char addr, char data); @@ -247,15 +285,11 @@ * Write a data buffer to the specified MMA8452 register. * * @param addr The internal register address - * @param data Data buffer to write + * @param data Pointer to data buffer to write * @param nbytes The length of the data buffer to write */ int writeRegister(char addr, char *data, int nbytes); - int logicalANDRegister(char addr, char mask); - int logicalORRegister(char addr, char mask); - int logicalXORRegister(char addr, char mask); - int setDynamicRange(DynamicRange range, int toggleActivation=1); int setBitDepth(BitDepth depth, int toggleActivation=1); int setDataRate(DataRateHz dataRate, int toggleActivation=1); @@ -269,13 +303,34 @@ #endif private: - int readRaw(char src, char *dst, int len); + /** + * Reads the specified register, applies the mask with logical AND, logical ORs the value + * and writes back the result to the register. If toggleActivation is set to true then the + * device is put in standby before the operation, and activated at the end. + * Setting it to false is useful for setting options on a device that you want to keep in + * standby. + */ int maskAndApplyRegister(char reg, char mask, char value, int toggleActivation); + /// Reads the specified register, applies the mask with logical AND, and writes the result back. + int logicalANDRegister(char addr, char mask); + /// Reads the specified register, applies the mask with logical OR, and writes the result back. + int logicalORRegister(char addr, char mask); + /// Reads the specified register, applies the mask with logical XOR, and writes the result back. + int logicalXORRegister(char addr, char mask); + + /// Converts the 12-bit two's complement number in buf to a signed integer. Returns the integer. int twelveBitToSigned(char *buf); + /// Converts the 8-bit two's complement number in buf to a signed integer. Returns the integer. int eightBitToSigned(char *buf); + + /// Converts a count to a gravity using the supplied countsPerG. Returns the gravity. double convertCountToGravity(int count, int countsPerG); - char getMaskedRegister(int reg, char mask); + + /// Reads the register at addr, applies the mask with logical AND, and returns the result. + char getMaskedRegister(int addr, char mask); + + /// Get the counts per G for the current settings of bit depth and dynamic range. int getCountsPerG(); I2C _i2c; @@ -284,6 +339,5 @@ int _writeAddress; BitDepth _bitDepth; - DynamicRange _dynamicRange; - + DynamicRange _dynamicRange; }; \ No newline at end of file