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

Committer:
ashleymills
Date:
Wed Mar 05 16:48:41 2014 +0000
Revision:
3:2a8e59a590db
Parent:
2:0630128bdb32
Child:
5:756f9b157319
Updated child, cleaned something.

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 2:0630128bdb32 165 acc.setBitDepth(MMA8452::BIT_DEPTH_8);
ashleymills 2:0630128bdb32 166 acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_4G);
ashleymills 2:0630128bdb32 167 sampleMMA8452Gravities(&acc,2000);
ashleymills 0:0c17274c3b7c 168
ashleymills 0:0c17274c3b7c 169 return true;
ashleymills 0:0c17274c3b7c 170 }
ashleymills 0:0c17274c3b7c 171
ashleymills 0:0c17274c3b7c 172 void loop() {
ashleymills 0:0c17274c3b7c 173 while(1) {
ashleymills 0:0c17274c3b7c 174 wait(1);
ashleymills 0:0c17274c3b7c 175 }
ashleymills 0:0c17274c3b7c 176 }
ashleymills 0:0c17274c3b7c 177
ashleymills 1:e9981919b524 178 void u16d(uint16_t n) {
ashleymills 1:e9981919b524 179 int shift = 16;
ashleymills 1:e9981919b524 180 uint16_t mask = 0x8000;
ashleymills 1:e9981919b524 181 while(--shift>=0) {
ashleymills 1:e9981919b524 182 LOGX("%d",(n&mask)>>shift);
ashleymills 1:e9981919b524 183 mask >>= 1;
ashleymills 1:e9981919b524 184 }
ashleymills 1:e9981919b524 185 LOG(" ");
ashleymills 1:e9981919b524 186 }
ashleymills 1:e9981919b524 187
ashleymills 1:e9981919b524 188 int eightBitToSigned(char *buf) {
ashleymills 1:e9981919b524 189 return (int8_t)*buf;
ashleymills 1:e9981919b524 190 }
ashleymills 1:e9981919b524 191
ashleymills 1:e9981919b524 192 int twelveBitToSigned(char *buf) {
ashleymills 1:e9981919b524 193 //LOG("Doing twos complement conversion for 0x%x 0x%x",buf[0],buf[1]);
ashleymills 1:e9981919b524 194
ashleymills 1:e9981919b524 195 // cheat by using the int16_t internal type
ashleymills 1:e9981919b524 196 // all we need to do is convert to little-endian format and shift right
ashleymills 1:e9981919b524 197 int16_t x = 0;
ashleymills 1:e9981919b524 198 ((char*)&x)[1] = buf[0];
ashleymills 1:e9981919b524 199 ((char*)&x)[0] = buf[1];
ashleymills 1:e9981919b524 200 // note this only works because the below is an arithmetic right shift
ashleymills 1:e9981919b524 201 return x>>4;
ashleymills 1:e9981919b524 202
ashleymills 1:e9981919b524 203 // for reference, here is the full conversion, in case you port this somewhere where the above won't work
ashleymills 1:e9981919b524 204 /*
ashleymills 1:e9981919b524 205 uint16_t number = 0x0000;
ashleymills 1:e9981919b524 206 //u16d(number);
ashleymills 1:e9981919b524 207 int negative = false;
ashleymills 1:e9981919b524 208
ashleymills 1:e9981919b524 209 // bit depth 12, is spread over two bytes
ashleymills 1:e9981919b524 210 // put it into a uint16_t for easy manipulation
ashleymills 1:e9981919b524 211 number |= (buf[0]<<8);
ashleymills 1:e9981919b524 212 number |= buf[1];
ashleymills 1:e9981919b524 213
ashleymills 1:e9981919b524 214 // if this is a negative number take the twos complement
ashleymills 1:e9981919b524 215 if(number&0x8000) {
ashleymills 1:e9981919b524 216 negative = true;
ashleymills 1:e9981919b524 217 // flip all bits (doesn't matter about lower 4 bits)
ashleymills 1:e9981919b524 218 number ^= 0xFFFF;
ashleymills 1:e9981919b524 219
ashleymills 1:e9981919b524 220 // add 1 (but do so in a way that deals with overflow and respects our current leftwise shift)
ashleymills 1:e9981919b524 221 number += 0x0010;
ashleymills 1:e9981919b524 222 }
ashleymills 1:e9981919b524 223
ashleymills 1:e9981919b524 224 // shifting down the result by 4 bits gives us the absolute number
ashleymills 1:e9981919b524 225 number >>= 4;
ashleymills 1:e9981919b524 226
ashleymills 1:e9981919b524 227 int result = number;
ashleymills 1:e9981919b524 228 if(negative) {
ashleymills 1:e9981919b524 229 result *= -1;
ashleymills 1:e9981919b524 230 }
ashleymills 1:e9981919b524 231 return result;
ashleymills 1:e9981919b524 232 */
ashleymills 1:e9981919b524 233 }
ashleymills 1:e9981919b524 234
ashleymills 1:e9981919b524 235 int twosCompTest() {
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 }