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.

Committer:
ashleymills
Date:
Wed Mar 05 15:04:45 2014 +0000
Revision:
1:e9981919b524
Parent:
0:0c17274c3b7c
Child:
2:0630128bdb32
Tests two's complement conversions and has gravity outputs.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:0c17274c3b7c 1 #include "mbed.h"
ashleymills 0:0c17274c3b7c 2 #include "MMA8452.h"
ashleymills 0:0c17274c3b7c 3
ashleymills 0:0c17274c3b7c 4 DigitalOut myled(LED1);
ashleymills 0:0c17274c3b7c 5
ashleymills 0:0c17274c3b7c 6 Serial pc(USBTX,USBRX);
ashleymills 0:0c17274c3b7c 7
ashleymills 0:0c17274c3b7c 8 #define LOG(...) pc.printf(__VA_ARGS__); pc.printf("\r\n");
ashleymills 0:0c17274c3b7c 9 #define LOGX(...) pc.printf(__VA_ARGS__);
ashleymills 0:0c17274c3b7c 10
ashleymills 0:0c17274c3b7c 11 void printByte(char b) {
ashleymills 0:0c17274c3b7c 12 LOG("%d%d%d%d%d%d%d%d",
ashleymills 0:0c17274c3b7c 13 (b&0x80)>>7,
ashleymills 0:0c17274c3b7c 14 (b&0x40)>>6,
ashleymills 0:0c17274c3b7c 15 (b&0x20)>>5,
ashleymills 0:0c17274c3b7c 16 (b&0x10)>>4,
ashleymills 0:0c17274c3b7c 17 (b&0x08)>>3,
ashleymills 0:0c17274c3b7c 18 (b&0x04)>>2,
ashleymills 0:0c17274c3b7c 19 (b&0x02)>>1,
ashleymills 0:0c17274c3b7c 20 (b&0x01)
ashleymills 0:0c17274c3b7c 21 );
ashleymills 0:0c17274c3b7c 22 }
ashleymills 0:0c17274c3b7c 23
ashleymills 1:e9981919b524 24 void sampleMMA8452Raw(MMA8452 *acc, int nsamples) {
ashleymills 0:0c17274c3b7c 25 int samples = 0;
ashleymills 0:0c17274c3b7c 26 int bufLen = 6;
ashleymills 0:0c17274c3b7c 27 char buffer[6];
ashleymills 0:0c17274c3b7c 28 memset(&buffer,0x00,bufLen);
ashleymills 0:0c17274c3b7c 29 while(samples<nsamples) {
ashleymills 0:0c17274c3b7c 30 if(!acc->isXYZReady()) {
ashleymills 0:0c17274c3b7c 31 wait(0.01);
ashleymills 0:0c17274c3b7c 32 continue;
ashleymills 0:0c17274c3b7c 33 }
ashleymills 0:0c17274c3b7c 34 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 35 acc->readXYZRaw(buffer);
ashleymills 0:0c17274c3b7c 36 LOGX("Sample %d of %d: ",samples,nsamples);
ashleymills 0:0c17274c3b7c 37 for(int i=0; i<bufLen; i++) {
ashleymills 0:0c17274c3b7c 38 LOGX("%.2x ",buffer[i]);
ashleymills 0:0c17274c3b7c 39 }
ashleymills 0:0c17274c3b7c 40 LOG(" ");
ashleymills 0:0c17274c3b7c 41 samples++;
ashleymills 0:0c17274c3b7c 42 }
ashleymills 0:0c17274c3b7c 43 }
ashleymills 0:0c17274c3b7c 44
ashleymills 1:e9981919b524 45 void sampleMMA8452Counts(MMA8452 *acc, int nsamples) {
ashleymills 1:e9981919b524 46 int samples = 0;
ashleymills 1:e9981919b524 47 int bufLen = 6;
ashleymills 1:e9981919b524 48 char buffer[6];
ashleymills 1:e9981919b524 49 int x = 0, y = 0, z = 0;
ashleymills 1:e9981919b524 50 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 51 while(samples<nsamples) {
ashleymills 1:e9981919b524 52 if(!acc->isXYZReady()) {
ashleymills 1:e9981919b524 53 wait(0.01);
ashleymills 1:e9981919b524 54 continue;
ashleymills 1:e9981919b524 55 }
ashleymills 1:e9981919b524 56 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 57 if(acc->readXYZCounts(&x,&y,&z)) {
ashleymills 1:e9981919b524 58 LOG("Error reading sample");
ashleymills 1:e9981919b524 59 break;
ashleymills 1:e9981919b524 60 }
ashleymills 1:e9981919b524 61 LOG("Sample %d of %d: %d, %d, %d",samples,nsamples,x,y,z);
ashleymills 1:e9981919b524 62 samples++;
ashleymills 1:e9981919b524 63 }
ashleymills 1:e9981919b524 64 }
ashleymills 1:e9981919b524 65
ashleymills 1:e9981919b524 66 void sampleMMA8452Gravities(MMA8452 *acc, int nsamples) {
ashleymills 1:e9981919b524 67 int samples = 0;
ashleymills 1:e9981919b524 68 int bufLen = 6;
ashleymills 1:e9981919b524 69 char buffer[6];
ashleymills 1:e9981919b524 70 double x = 0, y = 0, z = 0;
ashleymills 1:e9981919b524 71 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 72 while(samples<nsamples) {
ashleymills 1:e9981919b524 73 if(!acc->isXYZReady()) {
ashleymills 1:e9981919b524 74 wait(0.01);
ashleymills 1:e9981919b524 75 continue;
ashleymills 1:e9981919b524 76 }
ashleymills 1:e9981919b524 77 memset(&buffer,0x00,bufLen);
ashleymills 1:e9981919b524 78 if(acc->readXYZGravity(&x,&y,&z)) {
ashleymills 1:e9981919b524 79 LOG("Error reading sample");
ashleymills 1:e9981919b524 80 break;
ashleymills 1:e9981919b524 81 }
ashleymills 1:e9981919b524 82 LOG("Sample %d of %d: %lf, %lf, %lf",samples,nsamples,x,y,z);
ashleymills 1:e9981919b524 83 samples++;
ashleymills 1:e9981919b524 84 }
ashleymills 1:e9981919b524 85 }
ashleymills 1:e9981919b524 86
ashleymills 0:0c17274c3b7c 87 int test() {
ashleymills 0:0c17274c3b7c 88 MMA8452 acc(p28, p27, 40000);
ashleymills 0:0c17274c3b7c 89
ashleymills 0:0c17274c3b7c 90 acc.debugRegister(MMA8452_CTRL_REG_1);
ashleymills 0:0c17274c3b7c 91
ashleymills 0:0c17274c3b7c 92 LOG("Entering standby");
ashleymills 0:0c17274c3b7c 93 if(acc.standby()) {
ashleymills 0:0c17274c3b7c 94 LOG("Error putting MMA8452 in standby");
ashleymills 0:0c17274c3b7c 95 return false;
ashleymills 0:0c17274c3b7c 96 }
ashleymills 0:0c17274c3b7c 97
ashleymills 0:0c17274c3b7c 98 acc.debugRegister(MMA8452_CTRL_REG_1);
ashleymills 0:0c17274c3b7c 99
ashleymills 0:0c17274c3b7c 100 LOG("Activating MMA8452");
ashleymills 0:0c17274c3b7c 101 if(acc.activate()) {
ashleymills 0:0c17274c3b7c 102 LOG("Error activating MMA8452");
ashleymills 0:0c17274c3b7c 103 return false;
ashleymills 0:0c17274c3b7c 104 }
ashleymills 0:0c17274c3b7c 105
ashleymills 1:e9981919b524 106 char devID = 0;
ashleymills 1:e9981919b524 107 if(acc.getDeviceID(&devID)) {
ashleymills 1:e9981919b524 108 LOG("Error getting device ID");
ashleymills 1:e9981919b524 109 return false;
ashleymills 1:e9981919b524 110 }
ashleymills 1:e9981919b524 111 LOG("DeviceID: 0x%x",devID);
ashleymills 1:e9981919b524 112 if(devID!=0x2a) {
ashleymills 1:e9981919b524 113 LOG("Error, fetched device ID: 0x%x does not match expected 0x2a",devID);
ashleymills 1:e9981919b524 114 return false;
ashleymills 1:e9981919b524 115 } else {
ashleymills 1:e9981919b524 116 LOG("Device ID OK");
ashleymills 1:e9981919b524 117 }
ashleymills 1:e9981919b524 118
ashleymills 0:0c17274c3b7c 119 // test setting dynamic range
ashleymills 0:0c17274c3b7c 120 MMA8452::DynamicRange setRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
ashleymills 0:0c17274c3b7c 121 MMA8452::DynamicRange readRange = MMA8452::DYNAMIC_RANGE_UNKNOWN;
ashleymills 0:0c17274c3b7c 122 for(int i=0; i<=(int)MMA8452::DYNAMIC_RANGE_8G; i++) {
ashleymills 0:0c17274c3b7c 123 setRange = (MMA8452::DynamicRange)i;
ashleymills 0:0c17274c3b7c 124 if(acc.setDynamicRange(setRange)) {
ashleymills 0:0c17274c3b7c 125 LOG("Error setting dynamic range. Failing.");
ashleymills 0:0c17274c3b7c 126 return false;
ashleymills 0:0c17274c3b7c 127 }
ashleymills 0:0c17274c3b7c 128 readRange = acc.getDynamicRange();
ashleymills 0:0c17274c3b7c 129 if(readRange!=setRange) {
ashleymills 0:0c17274c3b7c 130 LOG("Read dynamic range: 0x%x does not match set: 0x%x",readRange,setRange);
ashleymills 0:0c17274c3b7c 131 return false;
ashleymills 0:0c17274c3b7c 132 }
ashleymills 0:0c17274c3b7c 133 LOG("Success on dynamic range %d",i);
ashleymills 0:0c17274c3b7c 134 }
ashleymills 0:0c17274c3b7c 135
ashleymills 0:0c17274c3b7c 136 // test setting data rate
ashleymills 0:0c17274c3b7c 137 for(int i=0; i<=(int)MMA8452::RATE_1_563; i++) {
ashleymills 0:0c17274c3b7c 138 if(acc.setDataRate((MMA8452::DataRateHz)i)) {
ashleymills 0:0c17274c3b7c 139 LOG("Error setting data rate. Failing.");
ashleymills 0:0c17274c3b7c 140 return false;
ashleymills 0:0c17274c3b7c 141 }
ashleymills 0:0c17274c3b7c 142 if(acc.getDataRate()!=(MMA8452::DataRateHz)i) {
ashleymills 0:0c17274c3b7c 143 LOG("Read data rate: 0x%x does not match set: 0x%x",acc.getDataRate(),(MMA8452::DataRateHz)i);
ashleymills 0:0c17274c3b7c 144 return false;
ashleymills 0:0c17274c3b7c 145 }
ashleymills 0:0c17274c3b7c 146 LOG("Success on data rate %d",i);
ashleymills 0:0c17274c3b7c 147 }
ashleymills 0:0c17274c3b7c 148
ashleymills 0:0c17274c3b7c 149 // set bit depth to 8 and read some values
ashleymills 0:0c17274c3b7c 150 LOG("Sampling at BIT_DEPTH_8");
ashleymills 0:0c17274c3b7c 151 acc.setBitDepth(MMA8452::BIT_DEPTH_8);
ashleymills 1:e9981919b524 152 sampleMMA8452Raw(&acc,10);
ashleymills 0:0c17274c3b7c 153
ashleymills 0:0c17274c3b7c 154 // set bit depth to 12 and read some values
ashleymills 0:0c17274c3b7c 155 LOG("Sampling at BIT_DEPTH_12");
ashleymills 0:0c17274c3b7c 156 acc.setDataRate(MMA8452::RATE_100);
ashleymills 0:0c17274c3b7c 157 acc.setBitDepth(MMA8452::BIT_DEPTH_12);
ashleymills 1:e9981919b524 158 sampleMMA8452Raw(&acc,10);
ashleymills 1:e9981919b524 159
ashleymills 1:e9981919b524 160 LOG("Sampling counts");
ashleymills 1:e9981919b524 161 acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_2G);
ashleymills 1:e9981919b524 162 sampleMMA8452Counts(&acc,100);
ashleymills 1:e9981919b524 163
ashleymills 1:e9981919b524 164 LOG("Samping gravities");
ashleymills 1:e9981919b524 165 sampleMMA8452Gravities(&acc,100);
ashleymills 0:0c17274c3b7c 166
ashleymills 0:0c17274c3b7c 167 return true;
ashleymills 0:0c17274c3b7c 168 }
ashleymills 0:0c17274c3b7c 169
ashleymills 0:0c17274c3b7c 170 void loop() {
ashleymills 0:0c17274c3b7c 171 while(1) {
ashleymills 0:0c17274c3b7c 172 wait(1);
ashleymills 0:0c17274c3b7c 173 }
ashleymills 0:0c17274c3b7c 174 }
ashleymills 0:0c17274c3b7c 175
ashleymills 1:e9981919b524 176 void u16d(uint16_t n) {
ashleymills 1:e9981919b524 177 int shift = 16;
ashleymills 1:e9981919b524 178 uint16_t mask = 0x8000;
ashleymills 1:e9981919b524 179 while(--shift>=0) {
ashleymills 1:e9981919b524 180 LOGX("%d",(n&mask)>>shift);
ashleymills 1:e9981919b524 181 mask >>= 1;
ashleymills 1:e9981919b524 182 }
ashleymills 1:e9981919b524 183 LOG(" ");
ashleymills 1:e9981919b524 184 }
ashleymills 1:e9981919b524 185
ashleymills 1:e9981919b524 186 int eightBitToSigned(char *buf) {
ashleymills 1:e9981919b524 187 return (int8_t)*buf;
ashleymills 1:e9981919b524 188 }
ashleymills 1:e9981919b524 189
ashleymills 1:e9981919b524 190 int twelveBitToSigned(char *buf) {
ashleymills 1:e9981919b524 191 //LOG("Doing twos complement conversion for 0x%x 0x%x",buf[0],buf[1]);
ashleymills 1:e9981919b524 192
ashleymills 1:e9981919b524 193 // cheat by using the int16_t internal type
ashleymills 1:e9981919b524 194 // all we need to do is convert to little-endian format and shift right
ashleymills 1:e9981919b524 195 int16_t x = 0;
ashleymills 1:e9981919b524 196 ((char*)&x)[1] = buf[0];
ashleymills 1:e9981919b524 197 ((char*)&x)[0] = buf[1];
ashleymills 1:e9981919b524 198 // note this only works because the below is an arithmetic right shift
ashleymills 1:e9981919b524 199 return x>>4;
ashleymills 1:e9981919b524 200
ashleymills 1:e9981919b524 201 // for reference, here is the full conversion, in case you port this somewhere where the above won't work
ashleymills 1:e9981919b524 202 /*
ashleymills 1:e9981919b524 203 uint16_t number = 0x0000;
ashleymills 1:e9981919b524 204 //u16d(number);
ashleymills 1:e9981919b524 205 int negative = false;
ashleymills 1:e9981919b524 206
ashleymills 1:e9981919b524 207 // bit depth 12, is spread over two bytes
ashleymills 1:e9981919b524 208 // put it into a uint16_t for easy manipulation
ashleymills 1:e9981919b524 209 number |= (buf[0]<<8);
ashleymills 1:e9981919b524 210 number |= buf[1];
ashleymills 1:e9981919b524 211
ashleymills 1:e9981919b524 212 // if this is a negative number take the twos complement
ashleymills 1:e9981919b524 213 if(number&0x8000) {
ashleymills 1:e9981919b524 214 negative = true;
ashleymills 1:e9981919b524 215 // flip all bits (doesn't matter about lower 4 bits)
ashleymills 1:e9981919b524 216 number ^= 0xFFFF;
ashleymills 1:e9981919b524 217
ashleymills 1:e9981919b524 218 // add 1 (but do so in a way that deals with overflow and respects our current leftwise shift)
ashleymills 1:e9981919b524 219 number += 0x0010;
ashleymills 1:e9981919b524 220 }
ashleymills 1:e9981919b524 221
ashleymills 1:e9981919b524 222 // shifting down the result by 4 bits gives us the absolute number
ashleymills 1:e9981919b524 223 number >>= 4;
ashleymills 1:e9981919b524 224
ashleymills 1:e9981919b524 225 int result = number;
ashleymills 1:e9981919b524 226 if(negative) {
ashleymills 1:e9981919b524 227 result *= -1;
ashleymills 1:e9981919b524 228 }
ashleymills 1:e9981919b524 229 return result;
ashleymills 1:e9981919b524 230 */
ashleymills 1:e9981919b524 231 }
ashleymills 1:e9981919b524 232
ashleymills 1:e9981919b524 233 int twosCompTest() {
ashleymills 1:e9981919b524 234 u16d((int16_t)5);
ashleymills 1:e9981919b524 235 u16d((int16_t)-5);
ashleymills 1:e9981919b524 236 // 12 bits of number gives 2048 steps
ashleymills 1:e9981919b524 237 int16_t i = -2047;
ashleymills 1:e9981919b524 238 while(1) {
ashleymills 1:e9981919b524 239 //LOG("number: %d",i);
ashleymills 1:e9981919b524 240 //u16d(number);
ashleymills 1:e9981919b524 241 uint16_t shiftedNumber = i<<4;
ashleymills 1:e9981919b524 242 //LOG("shifted:");
ashleymills 1:e9981919b524 243 //u16d(shiftedNumber);
ashleymills 1:e9981919b524 244 // ARM is little endian whereas 12 bit 2's comp rep is big endian
ashleymills 1:e9981919b524 245 uint16_t flippedNumber = 0x0000;
ashleymills 1:e9981919b524 246 //LOG("switching bytes");
ashleymills 1:e9981919b524 247 //u16d(flippedNumber);
ashleymills 1:e9981919b524 248 ((char*)&flippedNumber)[0] = ((char*)&shiftedNumber)[1];
ashleymills 1:e9981919b524 249
ashleymills 1:e9981919b524 250 //u16d(flippedNumber);
ashleymills 1:e9981919b524 251 ((char*)&flippedNumber)[1] = ((char*)&shiftedNumber)[0];
ashleymills 1:e9981919b524 252
ashleymills 1:e9981919b524 253 //u16d(flippedNumber);
ashleymills 1:e9981919b524 254 int value = twelveBitToSigned((char*)&flippedNumber);
ashleymills 1:e9981919b524 255 //LOG("%d converts to %d",i,value);
ashleymills 1:e9981919b524 256 if(i!=value) {
ashleymills 1:e9981919b524 257 return false;
ashleymills 1:e9981919b524 258 }
ashleymills 1:e9981919b524 259 if(i==2047) {
ashleymills 1:e9981919b524 260 break;
ashleymills 1:e9981919b524 261 }
ashleymills 1:e9981919b524 262 i++;
ashleymills 1:e9981919b524 263 }
ashleymills 1:e9981919b524 264
ashleymills 1:e9981919b524 265 int8_t n = -127;
ashleymills 1:e9981919b524 266 while(1) {
ashleymills 1:e9981919b524 267 int value = eightBitToSigned((char*)&n);
ashleymills 1:e9981919b524 268 //LOG("%d converts to %d",n,value);
ashleymills 1:e9981919b524 269 if(n!=value) {
ashleymills 1:e9981919b524 270 return false;
ashleymills 1:e9981919b524 271 }
ashleymills 1:e9981919b524 272 if(n==127) {
ashleymills 1:e9981919b524 273 break;
ashleymills 1:e9981919b524 274 }
ashleymills 1:e9981919b524 275 n++;
ashleymills 1:e9981919b524 276 }
ashleymills 1:e9981919b524 277
ashleymills 1:e9981919b524 278 return true;
ashleymills 1:e9981919b524 279 }
ashleymills 1:e9981919b524 280
ashleymills 0:0c17274c3b7c 281 int main() {
ashleymills 0:0c17274c3b7c 282 pc.baud(115200);
ashleymills 0:0c17274c3b7c 283 LOG("Begin");
ashleymills 1:e9981919b524 284 if(!twosCompTest()) {
ashleymills 1:e9981919b524 285 LOG("twos comp test failed");
ashleymills 1:e9981919b524 286 loop();
ashleymills 1:e9981919b524 287 }
ashleymills 1:e9981919b524 288 LOG("twos comp test passed");
ashleymills 1:e9981919b524 289 //loop();
ashleymills 0:0c17274c3b7c 290 for(int i=0; i<20; i++) {
ashleymills 0:0c17274c3b7c 291 LOG(" ");
ashleymills 0:0c17274c3b7c 292 }
ashleymills 0:0c17274c3b7c 293 if(!test()) {
ashleymills 0:0c17274c3b7c 294 LOG("FAIL.");
ashleymills 0:0c17274c3b7c 295 loop();
ashleymills 0:0c17274c3b7c 296 }
ashleymills 0:0c17274c3b7c 297 LOG("Tests passed");
ashleymills 0:0c17274c3b7c 298 loop();
ashleymills 0:0c17274c3b7c 299 }