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.

Files at this revision

API Documentation at this revision

Comitter:
ashleymills
Date:
Fri Mar 07 11:55:30 2014 +0000
Parent:
19:4d6cd7140a71
Child:
21:a92a632a0cc7
Commit message:
Independent read methods present.

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
--- a/MMA8452.cpp	Thu Mar 06 18:07:43 2014 +0000
+++ b/MMA8452.cpp	Fri Mar 07 11:55:30 2014 +0000
@@ -244,34 +244,51 @@
    return 0;
 }
 
-int readXCount(int *x) {
+int MMA8452::readXCount(int *x) {
    char buf[2];
    if(readXRaw((char*)&buf)) {
        return 1;
    }
    if(_bitDepth==BIT_DEPTH_12) {
      *x = twelveBitToSigned(&buf[0]);
-     *y = twelveBitToSigned(&buf[2]);
-     *z = twelveBitToSigned(&buf[4]);
    } else {
      *x = eightBitToSigned(&buf[0]);
-     *y = eightBitToSigned(&buf[1]);
-     *z = eightBitToSigned(&buf[2]);
+   }
+   return 0;
+}
+
+int MMA8452::readYCount(int *y) {
+   char buf[2];
+   if(readYRaw((char*)&buf)) {
+       return 1;
+   }
+   if(_bitDepth==BIT_DEPTH_12) {
+     *y = twelveBitToSigned(&buf[0]);
+   } else {
+     *y = eightBitToSigned(&buf[0]);
    }
-   
+   return 0;
+}
+
+int MMA8452::readZCount(int *z) {
+   char buf[2];
+   if(readZRaw((char*)&buf)) {
+       return 1;
+   }
+   if(_bitDepth==BIT_DEPTH_12) {
+     *z = twelveBitToSigned(&buf[0]);
+   } else {
+     *z = eightBitToSigned(&buf[0]);
+   }
+   return 0;
 }
 
 double MMA8452::convertCountToGravity(int count, int countsPerG) {
    return (double)count/(double)countsPerG;
 }
 
-int MMA8452::readXYZGravity(double *x, double *y, double *z) {
-   int xCount = 0, yCount = 0, zCount = 0;
-   if(readXYZCounts(&xCount,&yCount,&zCount)) {
-      return 1;
-   }
-   
-   // assume starting with DYNAMIC_RANGE_2G and BIT_DEPTH_12
+int MMA8452::getCountsPerG() {
+ // assume starting with DYNAMIC_RANGE_2G and BIT_DEPTH_12
    int countsPerG = 1024;
    if(_bitDepth==BIT_DEPTH_8) {
       countsPerG = 64;
@@ -284,6 +301,15 @@
          countsPerG /= 4;
       break;
    }
+   return countsPerG;
+}
+
+int MMA8452::readXYZGravity(double *x, double *y, double *z) {
+   int xCount = 0, yCount = 0, zCount = 0;
+   if(readXYZCounts(&xCount,&yCount,&zCount)) {
+      return 1;
+   }
+   int countsPerG = getCountsPerG();
    
    *x = convertCountToGravity(xCount,countsPerG);
    *y = convertCountToGravity(yCount,countsPerG);
@@ -291,6 +317,39 @@
    return 0;
 }
 
+int MMA8452::readXGravity(double *x) {
+   int xCount = 0;
+   if(readXCount(&xCount)) {
+      return 1;
+   }
+   int countsPerG = getCountsPerG();
+   
+   *x = convertCountToGravity(xCount,countsPerG);
+   return 0;
+}
+
+int MMA8452::readYGravity(double *y) {
+   int yCount = 0;
+   if(readYCount(&yCount)) {
+      return 1;
+   }
+   int countsPerG = getCountsPerG();
+   
+   *y = convertCountToGravity(yCount,countsPerG);
+   return 0;
+}
+
+int MMA8452::readZGravity(double *z) {
+   int zCount = 0;
+   if(readZCount(&zCount)) {
+      return 1;
+   }
+   int countsPerG = getCountsPerG();
+   
+   *z = convertCountToGravity(zCount,countsPerG);
+   return 0;
+}
+
 // apply an AND mask to a register. read register value, apply mask, write it back
 int MMA8452::logicalANDRegister(char addr, char mask) {
    char value = 0;
--- a/MMA8452.h	Thu Mar 06 18:07:43 2014 +0000
+++ b/MMA8452.h	Fri Mar 07 11:55:30 2014 +0000
@@ -35,37 +35,37 @@
 #endif
 
 // Register descriptions found in section 6 of pdf
-#define MMA8452_STATUS 0x00                 // Type 'read' : Status of the data registers
-#define MMA8452_OUT_X_MSB 0x01              // Type 'read' : x axis - MSB of 2 byte sample
-#define MMA8452_OUT_X_LSB 0x02              // Type 'read' : x axis - LSB of 2 byte sample
-#define MMA8452_OUT_Y_MSB 0x03              // Type 'read' : y axis - MSB of 2 byte sample
-#define MMA8452_OUT_Y_LSB 0x04              // Type 'read' : y axis - LSB of 2 byte sample
-#define MMA8452_OUT_Z_MSB 0x05              // Type 'read' : z axis - MSB of 2 byte sample
-#define MMA8452_OUT_Z_LSB 0x06              // Type 'read' : z axis - LSB of 2 byte sample
+#define MMA8452_STATUS 0x00        // Type 'read' : Status of the data registers
+#define MMA8452_OUT_X_MSB 0x01     // Type 'read' : x axis - MSB of 2 byte sample
+#define MMA8452_OUT_X_LSB 0x02     // Type 'read' : x axis - LSB of 2 byte sample
+#define MMA8452_OUT_Y_MSB 0x03     // Type 'read' : y axis - MSB of 2 byte sample
+#define MMA8452_OUT_Y_LSB 0x04     // Type 'read' : y axis - LSB of 2 byte sample
+#define MMA8452_OUT_Z_MSB 0x05     // Type 'read' : z axis - MSB of 2 byte sample
+#define MMA8452_OUT_Z_LSB 0x06     // Type 'read' : z axis - LSB of 2 byte sample
 
 // register definitions
 #define MMA8452_XYZ_DATA_CFG 0x0E
 
-#define MMA8452_SYSMOD 0x0B                         // Type 'read' : This tells you if device is active, sleep or standy 0x00=STANDBY 0x01=WAKE 0x02=SLEEP
-#define MMA8452_WHO_AM_I 0x0D                       // Type 'read' : This should return the device id of 0x2A
+#define MMA8452_SYSMOD 0x0B        // Type 'read' : This tells you if device is active, sleep or standy 0x00=STANDBY 0x01=WAKE 0x02=SLEEP
+#define MMA8452_WHO_AM_I 0x0D      // Type 'read' : This should return the device id of 0x2A
 
-#define MMA8452_PL_STATUS 0x10                      // Type 'read' : This shows portrait landscape mode orientation
-#define MMA8452_PL_CFG 0x11                         // Type 'read/write' : This allows portrait landscape configuration
-#define MMA8452_PL_COUNT 0x12                       // Type 'read' : This is the portraint landscape debounce counter
-#define MMA8452_PL_BF_ZCOMP 0x13                    // Type 'read' :
-#define MMA8452_PL_THS_REG 0x14                     // Type 'read' :
+#define MMA8452_PL_STATUS 0x10     // Type 'read' : This shows portrait landscape mode orientation
+#define MMA8452_PL_CFG 0x11        // Type 'read/write' : This allows portrait landscape configuration
+#define MMA8452_PL_COUNT 0x12      // Type 'read' : This is the portraint landscape debounce counter
+#define MMA8452_PL_BF_ZCOMP 0x13   // Type 'read' :
+#define MMA8452_PL_THS_REG 0x14    // Type 'read' :
 
-#define MMA8452_FF_MT_CFG 0X15                      // Type 'read/write' : Freefaul motion functional block configuration
-#define MMA8452_FF_MT_SRC 0X16                      // Type 'read' : Freefaul motion event source register
-#define MMA8452_FF_MT_THS 0X17                      // Type 'read' : Freefaul motion threshold register
-#define MMA8452_FF_COUNT 0X18                       // Type 'read' : Freefaul motion debouce counter
+#define MMA8452_FF_MT_CFG 0X15     // Type 'read/write' : Freefaul motion functional block configuration
+#define MMA8452_FF_MT_SRC 0X16     // Type 'read' : Freefaul motion event source register
+#define MMA8452_FF_MT_THS 0X17     // Type 'read' : Freefaul motion threshold register
+#define MMA8452_FF_COUNT 0X18      // Type 'read' : Freefaul motion debouce counter
 
-#define MMA8452_ASLP_COUNT 0x29                     // Type 'read/write' : Counter settings for auto sleep
-#define MMA8452_CTRL_REG_1 0x2A                     // Type 'read/write' :
-#define MMA8452_CTRL_REG_2 0x2B                     // Type 'read/write' :
-#define MMA8452_CTRL_REG_3 0x2C                     // Type 'read/write' :
-#define MMA8452_CTRL_REG_4 0x2D                     // Type 'read/write' :
-#define MMA8452_CTRL_REG_5 0x2E                     // Type 'read/write' :
+#define MMA8452_ASLP_COUNT 0x29    // Type 'read/write' : Counter settings for auto sleep
+#define MMA8452_CTRL_REG_1 0x2A    // Type 'read/write' :
+#define MMA8452_CTRL_REG_2 0x2B    // Type 'read/write' :
+#define MMA8452_CTRL_REG_3 0x2C    // Type 'read/write' :
+#define MMA8452_CTRL_REG_4 0x2D    // Type 'read/write' :
+#define MMA8452_CTRL_REG_5 0x2E    // Type 'read/write' :
 
 // Defined in table 13 of the Freescale PDF
 /// xxx these all need to have better names
@@ -108,8 +108,8 @@
 #define MMA8452_STATUS_YDR_MASK 0x02
 #define MMA8452_STATUS_XDR_MASK 0x01
  
-class MMA8452         
-{        
+class MMA8452 {
+            
     public:
     
        enum DynamicRange {
@@ -209,7 +209,9 @@
       int readZCount(int *z);
       
       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();
@@ -274,6 +276,7 @@
       int eightBitToSigned(char *buf);
       double convertCountToGravity(int count, int countsPerG);
       char getMaskedRegister(int reg, char mask);
+      int getCountsPerG();
     
       I2C _i2c;
       int _frequency;