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.

Files at this revision

API Documentation at this revision

Comitter:
nherriot
Date:
Tue Oct 08 15:25:32 2013 +0000
Parent:
0:bcf2aa85d7f9
Child:
2:66db0f91b215
Commit message:
adding device id method detection

Changed in this revision

MMA8452.cpp Show annotated file Show diff for this revision Revisions of this file
MMA8452.h Show annotated file Show diff for this revision Revisions of this file
--- 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)
--- a/MMA8452.h	Fri Oct 04 14:48:02 2013 +0000
+++ b/MMA8452.h	Tue Oct 08 15:25:32 2013 +0000
@@ -89,7 +89,7 @@
 
 #define FF_MT_CFG 0X15                      // Type 'read/write' : Freefaul motion functional block configuration
 #define FF_MT_SRC 0X16                      // Type 'read' : Freefaul motion event source register
-#define FF_COUNT 0X17                       // Type 'read' : Freefaul motion threshold register
+#define FF_MT_THS 0X17                      // Type 'read' : Freefaul motion threshold register
 #define FF_COUNT 0X18                       // Type 'read' : Freefaul motion debouce counter
 
 #define ASLP_COUNT 0x29                     // Type 'read/write' : Counter setting for auto sleep
@@ -126,7 +126,8 @@
         * @param scl I2C8452 clock port
         * 
         */ 
-      Accelerometer_MMA8452(PinName sda, PinName scl);
+      Accelerometer_MMA8452(PinName sda, PinName scl, int frequency);
+      //Accelerometer_MMA8452(PinName sda, PinName scl);
        
        /** Destroys an MMA8452 object
         *
@@ -134,16 +135,23 @@
       ~Accelerometer_MMA8452();
       
       /** Activate the MMA8452 (required)
-       *
-       *
-       */
+        *   returns 0 for success in activating the chip
+        *   returns 1 for failure in activating the chip
+        *   -currrently no retries or waiting is done, this method tries 1 time the exits.
+      */
       int activate();
       
        /** Initialization of device MMA8452 (required)
-        *
         */
       void init();
     
+       /** Read the device ID from the accelerometer
+        *
+        * @param *deviceID Value of device - is should be 0x2A
+        * return 0 for success or
+        * return 1 for failure.
+        */        
+      int Get_DeviceID(int *deviceID);    
        /** Read the Tilt Angle using Three Axis
         *
         * @param *x Value of x tilt
@@ -169,6 +177,15 @@
         * @returns The value of z acceleration
         */
        int read_z();
+      
+      /** Read the x,y and z registers of the MMA8452
+       *
+       * takes a 2 byte char buffer to store the value
+       * for each axis.
+       * returns 0 for success, and 1 for failure
+       *
+       */ 
+      int read_xyz(char *x, char *y, char *z); 
             
         /** Read from specified MMA8452 register
          *
@@ -187,7 +204,7 @@
    
     private:
       I2C m_i2c;
-      int m_frequencey;
+      int m_frequency;
          
 };