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.
Fork of MMA8452_Test by
Diff: main.cpp
- 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