3 axis accellerometer for pitch and roll on lcd and serial output

Dependencies:   mbed C12832

Revision:
1:8997a1b348dd
Parent:
0:7bc29a9ea016
Child:
2:a8e20db7901e
diff -r 7bc29a9ea016 -r 8997a1b348dd MMA7660.cpp
--- a/MMA7660.cpp	Sun Oct 14 08:02:53 2012 +0000
+++ b/MMA7660.cpp	Tue Oct 16 19:42:19 2012 +0000
@@ -4,7 +4,8 @@
 {
     _interrupt = interrupt;
     active = false;
-    samplerate = 120;
+    samplerate = 64;
+
 }
 
 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
@@ -37,6 +38,7 @@
     if (!active) {
         setActive(true);
         active = true;
+        wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
     }
 
     char temp[3];
@@ -55,6 +57,7 @@
     } while (alert);
 }
 
+
 void MMA7660::readData(float *data)
 {
     int intdata[3];
@@ -63,17 +66,115 @@
         data[i] = intdata[i]/MMA7660_SENSITIVITY;
 }
 
-float MMA7660::getX( void ) {
+float MMA7660::getX( void )
+{
     return getSingle(0);
+}
+
+float MMA7660::getY( void )
+{
+    return getSingle(1);
+}
+
+float MMA7660::getZ( void )
+{
+    return getSingle(2);
+}
+
+
+void MMA7660::setSampleRate(int samplerate)
+{
+    setActive(false);                               //Not allowed to be active to change anything
+    int rates[] = {120, 64, 32, 16, 8, 4, 2, 1};    //Alowed samplerates (and their number in array is also number required for MMA)
+    int sampleLoc = 0, sampleError = 10000, temp;
+    for (int i = 0; i<8; i++) {
+        temp = abs( rates[i] - samplerate );
+        if (temp<sampleError) {
+            sampleLoc = i;
+            sampleError=temp;
+        }
     }
 
-float MMA7660::getY( void ) {
-    return getSingle(1);
+    //Update the samplerate reg
+    temp = read(MMA7660_SR_R);
+    temp &= ~0x07;               //Awake sample rate are lowest 3 bit
+    temp |= sampleLoc;
+    write(MMA7660_SR_R, temp);
+    this->samplerate = rates[sampleLoc];
+    setActive(active);                              //Restore previous active state
+}
+
+MMA7660::Orientation MMA7660::getGlobalOrientation( void )
+{
+    int retval = MMA7660::Unknown;
+
+    int accelerations[3];
+    readData(accelerations);
+
+    //Check which side is up
+    int max = 0;
+    for (int i = 0; i<3; i++) {
+        if (-accelerations[i] > max) {
+            max = -accelerations[i];
+            retval = 2 * i;
+        }
+        if (accelerations[i] > max) {
+            max = accelerations[i];
+            retval = 2 * i + 1;
+        }
     }
+    return (MMA7660::Orientation)retval;
+
+
+}
+
+MMA7660::Orientation MMA7660::getSide( void )
+{
+    char tiltreg = read(MMA7660_TILT_R);
+
+    //We care about 2 LSBs
+    tiltreg &= 0x03;
+    if (tiltreg == 0x01)
+        return MMA7660::Front;
+    if (tiltreg == 0x02)
+        return MMA7660::Back;
+    return MMA7660::Unknown;
+}
+
+MMA7660::Orientation MMA7660::getOrientation( void )
+{
+    char tiltreg = read(MMA7660_TILT_R);
+
+    //We care about bit 2, 3 and 4 (counting from zero)
+    tiltreg &= 0x07<<2;
+    tiltreg >>= 2;
+    if (tiltreg == 0x01)
+        return MMA7660::Left;
+    if (tiltreg == 0x02)
+        return MMA7660::Right;
+    if (tiltreg == 0x05)
+        return MMA7660::Down;
+    if (tiltreg == 0x06)
+        return MMA7660::Up;
+    return MMA7660::Unknown;
+}
+
+bool MMA7660::isTapped( void )
+{
+    char tiltreg = read(MMA7660_TILT_R);
     
-float MMA7660::getZ( void ) {
-    return getSingle(2);
-    }        
+    //Tap is bit 5
+    tiltreg >>= 5;
+    tiltreg &= 0x01;
+    
+    return tiltreg==1;
+}
+    
+
+//////////////////////////////////////////////
+///////////////PRIVATE////////////////////////
+//////////////////////////////////////////////
+
 
 void MMA7660::write(char address, char data)
 {
@@ -103,6 +204,7 @@
     if (!active) {
         setActive(true);
         active = true;
+        wait(0.012 + 1/samplerate); //Wait until new sample is ready
     }
 
     signed char temp;