A test program for the MMA8452 accelerometer

Dependencies:   MMA8452 mbed

The test program runs a bunch of tests for the MMA8452 accelerometer.

What is below is not the test program, but an example to whet your appetite about the library.

#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:
Thu Mar 06 18:07:58 2014 +0000
Parent:
4:936b60956489
Child:
6:e3100f66ed6a
Commit message:
Adding independent query tests

Changed in this revision

MMA8452.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/MMA8452.lib	Wed Mar 05 17:04:27 2014 +0000
+++ b/MMA8452.lib	Thu Mar 06 18:07:58 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/ashleymills/code/MMA8452/#27d839e6dc0e
+http://mbed.org/users/ashleymills/code/MMA8452/#4d6cd7140a71
--- 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