The main.cpp program below demonstrates a simple way to interface with the MMA8452 accelerometer. The function reads in the acceleration data in the X, Y, and Z directions and displays them through a serial com port on a PC. The Putty Output figure below shows the output of the accelerometer using Putty. The program also dims or brightens the mbed LEDs 1-3 based on whether or not they are at 'level'( 0 Gs) or above respectively. The video below previews the code in action.

Dependencies:   MMA8452 mbed

Fork of MMA8452_Test by Ashley Mills

Revision:
5:756f9b157319
Parent:
3:2a8e59a590db
Child:
6:e3100f66ed6a
--- a/main.cpp	Wed Mar 05 17:04:27 2014 +0000
+++ b/main.cpp	Thu Mar 06 18:07:58 2014 +0000
@@ -21,7 +21,135 @@
    );
 }
 
-void sampleMMA8452Raw(MMA8452 *acc, int nsamples) {
+enum SampleType {
+   SAMPLE_RAW=0,
+   SAMPLE_COUNT,
+   SAMPLE_GRAVITY
+};
+
+void sampleTypeToString(SampleType t, char *dst) {
+   switch(t) {
+      case SAMPLE_RAW:
+         sprintf(dst,"SAMPLE_RAW");
+      break;
+      case SAMPLE_COUNT:
+         sprintf(dst,"SAMPLE_COUNT");
+      break;
+      case SAMPLE_GRAVITY:
+         sprintf(dst,"SAMPLE_GRAVITY");
+      break;
+   };
+}
+
+int testSampleTaking(MMA8452 *acc, int nsamples, SampleType sampleType) {
+   int samples = 0;
+   int bufLen = 6;
+   
+   // buffers for multi and single raw sampling
+   char bufferMulti[6];
+   char bufferSingle[6];
+   memset(&bufferMulti,0x00,bufLen);
+   memset(&bufferSingle,0x00,bufLen);
+   
+   // variables for multi and single count sampling
+   int xCountM = 0, yCountM = 0, zCountM = 0;
+   int xCountS = 0, yCountS = 0, zCountS = 0;
+   
+   // variables for multi and single gravity sampling
+   double xGravityM = 0, yGravityM = 0, zGravityM = 0;
+   double xGravityS = 0, yGravityS = 0, zGravityS = 0;
+   
+   // keep track of errors
+   int error = 0;
+   // mismatches between multi and single read calls are inevitable
+   // since the MMA8452 has an internal sampling mechanism which is
+   // not synchronous to this test routine. At low internal sampling
+   // rates, these mismatches should be rare, so keep track to
+   // check that this is sane
+   int mismatchCount = 0;
+   
+   // take samples
+   while(samples<nsamples) {
+      // wait for device to be ready
+      if(!acc->isXYZReady()) {
+         wait(0.01);
+         continue;
+      }
+      
+      switch(sampleType) {
+         case SAMPLE_RAW:
+            // read raw data via multi and single calls
+            memset(&bufferMulti,0x00,bufLen);
+            memset(&bufferSingle,0x00,bufLen);
+            error = 0;
+            error += acc->readXYZRaw((char*)&bufferMulti);
+            error += acc->readXRaw((char*)&bufferSingle[0]);
+            error += acc->readYRaw((char*)&bufferSingle[2]);
+            error += acc->readZRaw((char*)&bufferSingle[4]);
+            if(error) {
+               LOG("Error reading raw accelerometer data. Fail.");
+               return false;
+            }
+            // compare multi and single samples for equivalence
+            // note that this is bound to fail for high data rates
+            if(acc->getBitDepth()==MMA8452::BIT_DEPTH_12) {
+               if(memcmp(bufferMulti,bufferSingle,bufLen)) {
+                  LOG("Multi and single sampling mismatch");
+                  LOG("Multi: %x %x %x %x %x %x",
+                     bufferMulti[0],bufferMulti[1],
+                     bufferMulti[2],bufferMulti[3],
+                     bufferMulti[4],bufferMulti[5]
+                  );
+                  LOG("Single: %x %x %x %x %x %x",
+                     bufferSingle[0],bufferSingle[1],
+                     bufferSingle[2],bufferSingle[3],
+                     bufferSingle[4],bufferSingle[5]
+                  ); 
+                  mismatchCount++;
+               }
+               LOG("Sample %d of %d: %x %x %x %x %x %x",
+                  samples,nsamples,
+                  bufferMulti[0],bufferMulti[1],
+                  bufferMulti[2],bufferMulti[3],
+                  bufferMulti[4],bufferMulti[5]
+               );
+            } else {
+               if(bufferMulti[0]!=bufferSingle[0]||
+                  bufferMulti[1]!=bufferSingle[2]||
+                  bufferMulti[2]!=bufferSingle[4]) {
+                  LOG("Multi and single sampling mismatch");
+                  mismatchCount++;
+               }
+               LOG("Sample %d of %d: %x %x %x",
+                  samples,nsamples,
+                  bufferMulti[0],bufferMulti[1],bufferMulti[2]
+               );
+            }
+         break;
+         case SAMPLE_COUNT:
+            error = 0;
+            error += acc->readXYZCounts(&xCountM,&yCountM,&zCountM);
+            if(error) {
+               LOG("Error reading signed counts. Fail.");
+               break;
+            }
+         break;
+         case SAMPLE_GRAVITY:
+            error = 0;
+            error += acc->readXYZGravity(&xGravityM,&yGravityM,&zGravityM);
+            if(error) {
+               LOG("Error reading gravities. Fail.");
+               break;
+            }
+         break;
+      }
+      samples++;
+   }
+   LOG("mismatches %d/%d",mismatchCount,nsamples);
+   return true;
+}
+
+int sampleMMA8452Raw(MMA8452 *acc, int nsamples) {
    int samples = 0;
    int bufLen = 6;
    char buffer[6];
@@ -40,9 +168,10 @@
       LOG(" ");
       samples++;
    }
+   return true;
 }
 
-void sampleMMA8452Counts(MMA8452 *acc, int nsamples) {
+int sampleMMA8452Counts(MMA8452 *acc, int nsamples) {
    int samples = 0;
    int bufLen = 6;
    char buffer[6];
@@ -61,9 +190,10 @@
       LOG("Sample %d of %d: %d, %d, %d",samples,nsamples,x,y,z);
       samples++;
    }
+   return true;
 }
 
-void sampleMMA8452Gravities(MMA8452 *acc, int nsamples) {
+int sampleMMA8452Gravities(MMA8452 *acc, int nsamples) {
    int samples = 0;
    int bufLen = 6;
    char buffer[6];
@@ -82,6 +212,61 @@
       LOG("Sample %d of %d: %lf, %lf, %lf",samples,nsamples,x,y,z);
       samples++;
    }
+   return true;
+}
+
+void bitDepthToString(MMA8452::BitDepth d, char *dst) {
+   switch(d) {
+       case MMA8452::BIT_DEPTH_12:
+          sprintf(dst,"BIT_DEPTH_12");
+       break;
+       case MMA8452::BIT_DEPTH_8:
+          sprintf(dst,"BIT_DEPTH_8");
+       break;
+    }
+}
+
+void dynamicRangeToString(MMA8452::DynamicRange r, char *dst) {
+   switch(r) {
+      case MMA8452::DYNAMIC_RANGE_2G:
+         sprintf(dst,"DYNAMIC_RANGE_2G");
+      break;
+      case MMA8452::DYNAMIC_RANGE_4G:
+         sprintf(dst,"DYNAMIC_RANGE_4G");
+      break;
+      case MMA8452::DYNAMIC_RANGE_8G:
+         sprintf(dst,"DYNAMIC_RANGE_8G");
+      break;
+   }
+}
+
+void dataRateToString(MMA8452::DataRateHz r, char *dst) {
+   switch(r) {
+       case MMA8452::RATE_800:
+          sprintf(dst,"RATE_800");
+       break;
+       case MMA8452::RATE_400:
+          sprintf(dst,"RATE_400");
+       break;
+       case MMA8452::RATE_200:
+          sprintf(dst,"RATE_200");
+       break;
+       case MMA8452::RATE_100:
+          sprintf(dst,"RATE_100");
+       break;
+       case MMA8452::RATE_50:
+          sprintf(dst,"RATE_50");
+       break;
+       case MMA8452::RATE_12_5:
+          sprintf(dst,"RATE_12_5");
+       break;
+       case MMA8452::RATE_6_25:
+          sprintf(dst,"RATE_6_25");
+       break;
+       case MMA8452::RATE_1_563:
+          sprintf(dst,"RATE_1_563");
+       break;
+    }
 }
 
 int test() {
@@ -146,9 +331,49 @@
        LOG("Success on data rate %d",i);
     }
     
+    char depthString[32], rangeString[32], rateString[32], sampleTypeString[32];
+    // draw some samples at each bit depth, rate, and dynamic range
+    for(int depth=0; depth<=(int)MMA8452::BIT_DEPTH_8; depth++) {
+       bitDepthToString((MMA8452::BitDepth)depth,(char*)&depthString);
+       LOG("Setting bit depth to %s",depthString);
+       if(acc.setBitDepth((MMA8452::BitDepth)depth)) {
+          LOG("Error setting bit depth to %s. Fail.",depthString);
+          return false;
+       }
+       for(int range=0; range<=(int)MMA8452::DYNAMIC_RANGE_8G; range++) {
+          dynamicRangeToString((MMA8452::DynamicRange)range,(char*)&rangeString);
+          LOG("Setting dynamic range to %s",rangeString);
+          if(acc.setDynamicRange((MMA8452::DynamicRange)range)) {
+             LOG("Error setting dynamic range to %s. Fail.",rangeString);
+             return false;
+          }
+          for(int rate=0; rate<=(int)MMA8452::RATE_1_563; rate++) {
+             dataRateToString((MMA8452::DataRateHz)rate,(char*)&rateString);
+             LOG("Setting data rate to %s",rateString);
+             if(acc.setDataRate((MMA8452::DataRateHz)rate)) {
+                LOG("Error setting data rate to %s",rateString);
+                return false;
+             }
+             // take samples
+             for(int sampleType=0; sampleType<=(int)SAMPLE_GRAVITY; sampleType++) {
+                sampleTypeToString((SampleType)sampleType,sampleTypeString);
+                LOG("Setting sample type to %s",sampleTypeString);
+                if(testSampleTaking(&acc, 10, (SampleType)sampleType)!=true) {
+                  LOG("Sample taking failed for %s, %s, %s, %s",sampleTypeString,depthString,rangeString,rateString);
+                  return false;
+                }
+             }
+          }
+       }
+    }
+    return true;
+    
     // set bit depth to 8 and read some values
     LOG("Sampling at BIT_DEPTH_8");
-    acc.setBitDepth(MMA8452::BIT_DEPTH_8);
+    if(acc.setBitDepth(MMA8452::BIT_DEPTH_8)) {
+       LOG("Error setting bit depth. Fail.");
+       return false;
+    }
     sampleMMA8452Raw(&acc,10);
     
     // set bit depth to 12 and read some values