Library for driving the MMA8452 accelerometer over I2C

Dependents:   MMA8452_Test MMA8452_Demo Dualing_Tanks IMU-Controlled_MP3_Player ... more

Here is a simple example:

#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.

Revision:
1:ef026bf28798
Parent:
0:bcf2aa85d7f9
Child:
2:66db0f91b215
--- a/MMA8452.cpp	Fri Oct 04 14:48:02 2013 +0000
+++ b/MMA8452.cpp	Tue Oct 08 15:25:32 2013 +0000
@@ -27,7 +27,7 @@
 
 
 // Connect module at I2C address using I2C port pins sda and scl
-Accelerometer_MMA8452::Accelerometer_MMA8452(PinName sda, PinName scl,int frequency) : m_i2c(sda, scl): m_frequency(frequency):
+Accelerometer_MMA8452::Accelerometer_MMA8452(PinName sda, PinName scl,int frequency) : m_i2c(sda, scl) , m_frequency(frequency)
 {
     //m_i2c.frequency(m_frequency);
 }
@@ -42,19 +42,21 @@
 // Setting the control register bit 1 to true to activate the MMA8452
 int Accelerometer_MMA8452::activate()
 {
-    char mcu_address = (MMA8452_ADDRESS <1);
+    char mcu_address = (MMA8452_ADDRESS<<1);
     char init[2];
     init[0] = CTRL_REG_1;                 // control register 1
     init[1] = 0x01;                       // set to active
+    //while(m_i2c.write(mcu_address,init,2));
+    
     if(m_i2c.write(mcu_address,init,2) == 0)
     {
          // pc.printf("The initialisation worked");
-         return 0;
+         return 0;  // return 0 to indicate success
     }
     else
     {
         // pc.printf("The initialisation failed");
-        return 1;
+        return 1;   // crumbs it failed!!!
     }
          
 }
@@ -71,6 +73,44 @@
 }
 
 
+// Get device ID 
+int Accelerometer_MMA8452::Get_DeviceID(int *deviceID)
+{
+    char mcu_address = (MMA8452_ADDRESS<<1);
+    int z = 0;
+    m_i2c.start();
+    wait( 0.1);
+    if( m_i2c.write( mcu_address) == 0) 
+    {
+        //printf( "GetDeviceId NAK on writing address");
+        return 1;
+    }
+    wait( 0.1);
+    if( m_i2c.write( WHO_AM_I) == 0) 
+    {
+        //printf( "GetDeviceId NAK on writing register address");
+
+        return 1;
+    }
+    wait( 0.1);
+    m_i2c.start();
+    wait( 0.1);
+    if( m_i2c.write( mcu_address | 0x01) == 0)          // this is asking to read the slave address - even though it's a 'write' method!!! Crap API...
+    {
+        //printf( "GetDeviceId NAK on writing address");
+
+        return 1;
+    }
+    wait( 0.1);
+    //deviceID  = m_i2c.read(0);
+    z = m_i2c.read(0);
+    wait( 0.1);
+    m_i2c.stop();
+    return 0;
+
+}
+
+
 // Reads the tilt angle
 void Accelerometer_MMA8452::read_Tilt(float *x, float *y, float *z)
 {
@@ -92,17 +132,17 @@
 // Reads x data
 int Accelerometer_MMA8452::read_x()
 {
-    char mcu_address = (MMA8452_ADDRESS <1);
+    char mcu_address = (MMA8452_ADDRESS <<1);
 
-    m_i2c.start();                  // Start
-    m_i2c.write(mcu_address);              // A write to device 0x98
-    m_i2c.write(OUT_X_MSB);             // Register to read
+    m_i2c.start();                      // Start
+    m_i2c.write(mcu_address);           // A write to devic
+    m_i2c.write(OUT_X_LSB);             // Register to read
     m_i2c.start();                  
-    m_i2c.write(mcu_address);              // Read from device 0x99
-    char x = m_i2c.read(0);         // Read the data
+    m_i2c.write(mcu_address);           // Read from device
+    int x = m_i2c.read(0);             // Read the data
     m_i2c.stop();
     
-    return (int)x;  
+    return x;  
 
 }
 
@@ -110,17 +150,17 @@
 // Reads y data
 int Accelerometer_MMA8452::read_y()
 {
-    char mcu_address = (MMA8452_ADDRESS <1);
+    char mcu_address = (MMA8452_ADDRESS <<1);
 
     m_i2c.start();                  // Start
     m_i2c.write(mcu_address);              // A write to device 0x98
     m_i2c.write(OUT_Y_MSB);             // Register to read
     m_i2c.start();                  
     m_i2c.write(mcu_address);              // Read from device 0x99
-    char y = m_i2c.read(0);         // Read the data
+    int y = m_i2c.read(0);         // Read the data
     m_i2c.stop();
     
-    return (int)y; 
+    return y; 
 
 }
 
@@ -128,25 +168,52 @@
 // Reads z data
 int Accelerometer_MMA8452::read_z()
 {
-    char mcu_address = (MMA8452_ADDRESS <1);
+    char mcu_address = (MMA8452_ADDRESS <<1);
     
     m_i2c.start();                  // Start
     m_i2c.write(mcu_address);              // A write to device 0x98
     m_i2c.write(OUT_Z_MSB);             // Register to read
     m_i2c.start();                  
     m_i2c.write(mcu_address);              // Read from device 0x99
-    char z = m_i2c.read(0);         // Read the data
+    int z = m_i2c.read(0);         // Read the data
     m_i2c.stop();
     
-    return (int)z;
+    return z;
 
 }
 
 
 // Reads xyz
-
+int Accelerometer_MMA8452::read_xyz(char *x, char *y, char *z) 
+{
+    
+    
+    char mcu_address = (MMA8452_ADDRESS <<1);
+    char register_buffer[6] ={0,0,0,0,0,0};
+    const char Addr_X = OUT_X_MSB;
+    m_i2c.write(mcu_address);              // A write to device 0x98
+    m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1);         // Pointer to the OUT_X_MSB register
+    
+    if(m_i2c.write(mcu_address,&Addr_X,1) == 0)
+    {
+        if(m_i2c.read(mcu_address,register_buffer,6) == 0)
+        {
+            *x = register_buffer[1];
+            *y = register_buffer[3];
+            *z = register_buffer[5];
+            return 0;           // yahoooooo
+        }
+        else
+        {
+            return 1;           // failed oh nooo!
+        }    
+    }
+    else
+    {
+        return 1;               // failed oh nooo!
+    }
 
-
+}
 
         // Write register (The device must be placed in Standby Mode to change the value of the registers) 
 void Accelerometer_MMA8452::write_reg(char addr, char data)