![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Driving
Dependencies: FSR LIS3DH USBDevice mbed
Fork of MMA8452_Demo by
Diff: main.cpp
- Revision:
- 1:e9981919b524
- Parent:
- 0:0c17274c3b7c
- Child:
- 2:0630128bdb32
--- a/main.cpp Tue Mar 04 17:51:27 2014 +0000 +++ b/main.cpp Wed Mar 05 15:04:45 2014 +0000 @@ -21,7 +21,7 @@ ); } -void sampleMMA8452(MMA8452 *acc, int nsamples) { +void sampleMMA8452Raw(MMA8452 *acc, int nsamples) { int samples = 0; int bufLen = 6; char buffer[6]; @@ -32,7 +32,7 @@ continue; } memset(&buffer,0x00,bufLen); - acc->readRawXYZ(buffer); + acc->readXYZRaw(buffer); LOGX("Sample %d of %d: ",samples,nsamples); for(int i=0; i<bufLen; i++) { LOGX("%.2x ",buffer[i]); @@ -42,6 +42,48 @@ } } +void sampleMMA8452Counts(MMA8452 *acc, int nsamples) { + int samples = 0; + int bufLen = 6; + char buffer[6]; + int x = 0, y = 0, z = 0; + memset(&buffer,0x00,bufLen); + while(samples<nsamples) { + if(!acc->isXYZReady()) { + wait(0.01); + continue; + } + memset(&buffer,0x00,bufLen); + if(acc->readXYZCounts(&x,&y,&z)) { + LOG("Error reading sample"); + break; + } + LOG("Sample %d of %d: %d, %d, %d",samples,nsamples,x,y,z); + samples++; + } +} + +void sampleMMA8452Gravities(MMA8452 *acc, int nsamples) { + int samples = 0; + int bufLen = 6; + char buffer[6]; + double x = 0, y = 0, z = 0; + memset(&buffer,0x00,bufLen); + while(samples<nsamples) { + if(!acc->isXYZReady()) { + wait(0.01); + continue; + } + memset(&buffer,0x00,bufLen); + if(acc->readXYZGravity(&x,&y,&z)) { + LOG("Error reading sample"); + break; + } + LOG("Sample %d of %d: %lf, %lf, %lf",samples,nsamples,x,y,z); + samples++; + } +} + int test() { MMA8452 acc(p28, p27, 40000); @@ -61,6 +103,19 @@ return false; } + char devID = 0; + if(acc.getDeviceID(&devID)) { + LOG("Error getting device ID"); + return false; + } + LOG("DeviceID: 0x%x",devID); + if(devID!=0x2a) { + LOG("Error, fetched device ID: 0x%x does not match expected 0x2a",devID); + return false; + } else { + LOG("Device ID OK"); + } + // test setting dynamic range MMA8452::DynamicRange setRange = MMA8452::DYNAMIC_RANGE_UNKNOWN; MMA8452::DynamicRange readRange = MMA8452::DYNAMIC_RANGE_UNKNOWN; @@ -94,13 +149,20 @@ // set bit depth to 8 and read some values LOG("Sampling at BIT_DEPTH_8"); acc.setBitDepth(MMA8452::BIT_DEPTH_8); - sampleMMA8452(&acc,10); + sampleMMA8452Raw(&acc,10); // set bit depth to 12 and read some values LOG("Sampling at BIT_DEPTH_12"); acc.setDataRate(MMA8452::RATE_100); acc.setBitDepth(MMA8452::BIT_DEPTH_12); - sampleMMA8452(&acc,10); + sampleMMA8452Raw(&acc,10); + + LOG("Sampling counts"); + acc.setDynamicRange(MMA8452::DYNAMIC_RANGE_2G); + sampleMMA8452Counts(&acc,100); + + LOG("Samping gravities"); + sampleMMA8452Gravities(&acc,100); return true; } @@ -111,9 +173,120 @@ } } +void u16d(uint16_t n) { + int shift = 16; + uint16_t mask = 0x8000; + while(--shift>=0) { + LOGX("%d",(n&mask)>>shift); + mask >>= 1; + } + LOG(" "); +} + +int eightBitToSigned(char *buf) { + return (int8_t)*buf; +} + +int twelveBitToSigned(char *buf) { + //LOG("Doing twos complement conversion for 0x%x 0x%x",buf[0],buf[1]); + + // cheat by using the int16_t internal type + // all we need to do is convert to little-endian format and shift right + int16_t x = 0; + ((char*)&x)[1] = buf[0]; + ((char*)&x)[0] = buf[1]; + // note this only works because the below is an arithmetic right shift + return x>>4; + + // for reference, here is the full conversion, in case you port this somewhere where the above won't work + /* + uint16_t number = 0x0000; + //u16d(number); + int negative = false; + + // bit depth 12, is spread over two bytes + // put it into a uint16_t for easy manipulation + number |= (buf[0]<<8); + number |= buf[1]; + + // if this is a negative number take the twos complement + if(number&0x8000) { + negative = true; + // flip all bits (doesn't matter about lower 4 bits) + number ^= 0xFFFF; + + // add 1 (but do so in a way that deals with overflow and respects our current leftwise shift) + number += 0x0010; + } + + // shifting down the result by 4 bits gives us the absolute number + number >>= 4; + + int result = number; + if(negative) { + result *= -1; + } + return result; + */ +} + +int twosCompTest() { + u16d((int16_t)5); + u16d((int16_t)-5); + // 12 bits of number gives 2048 steps + int16_t i = -2047; + while(1) { + //LOG("number: %d",i); + //u16d(number); + uint16_t shiftedNumber = i<<4; + //LOG("shifted:"); + //u16d(shiftedNumber); + // ARM is little endian whereas 12 bit 2's comp rep is big endian + uint16_t flippedNumber = 0x0000; + //LOG("switching bytes"); + //u16d(flippedNumber); + ((char*)&flippedNumber)[0] = ((char*)&shiftedNumber)[1]; + + //u16d(flippedNumber); + ((char*)&flippedNumber)[1] = ((char*)&shiftedNumber)[0]; + + //u16d(flippedNumber); + int value = twelveBitToSigned((char*)&flippedNumber); + //LOG("%d converts to %d",i,value); + if(i!=value) { + return false; + } + if(i==2047) { + break; + } + i++; + } + + int8_t n = -127; + while(1) { + int value = eightBitToSigned((char*)&n); + //LOG("%d converts to %d",n,value); + if(n!=value) { + return false; + } + if(n==127) { + break; + } + n++; + } + + return true; +} + int main() { pc.baud(115200); LOG("Begin"); + if(!twosCompTest()) { + LOG("twos comp test failed"); + loop(); + } + LOG("twos comp test passed"); + //loop(); for(int i=0; i<20; i++) { LOG(" "); }