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.

Committer:
nherriot
Date:
Tue Oct 08 15:25:32 2013 +0000
Revision:
1:ef026bf28798
Parent:
0:bcf2aa85d7f9
Child:
2:66db0f91b215
adding device id method detection

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nherriot 0:bcf2aa85d7f9 1 // Author: Nicholas Herriot
nherriot 0:bcf2aa85d7f9 2 /* Copyright (c) 2013 Vodafone, MIT License
nherriot 0:bcf2aa85d7f9 3 *
nherriot 0:bcf2aa85d7f9 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
nherriot 0:bcf2aa85d7f9 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
nherriot 0:bcf2aa85d7f9 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
nherriot 0:bcf2aa85d7f9 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
nherriot 0:bcf2aa85d7f9 8 * furnished to do so, subject to the following conditions:
nherriot 0:bcf2aa85d7f9 9 *
nherriot 0:bcf2aa85d7f9 10 * The above copyright notice and this permission notice shall be included in all copies or
nherriot 0:bcf2aa85d7f9 11 * substantial portions of the Software.
nherriot 0:bcf2aa85d7f9 12 *
nherriot 0:bcf2aa85d7f9 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
nherriot 0:bcf2aa85d7f9 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
nherriot 0:bcf2aa85d7f9 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
nherriot 0:bcf2aa85d7f9 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
nherriot 0:bcf2aa85d7f9 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
nherriot 0:bcf2aa85d7f9 18 */
nherriot 0:bcf2aa85d7f9 19
nherriot 0:bcf2aa85d7f9 20 # include "MMA8452.h"
nherriot 0:bcf2aa85d7f9 21
nherriot 0:bcf2aa85d7f9 22
nherriot 0:bcf2aa85d7f9 23
nherriot 0:bcf2aa85d7f9 24 float TILT_XY[64] = {0, 2.69, 5.38, 8.08, 10.81, 13.55, 16.33, 19.16, 22.02, 24.95, 27.95, 31.04, 34.23, 37.54, 41.01, 44.68, 48.59, 52.83, 57.54, 62.95, 69.64, 79.86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -79.86, -69.64, -62.95, -57.54, -52.83, -48.59, -44.68, -41.01, -37.54, -34.23, -31.04, -27.95, -24.95, -22.02, -19.16, -16.33, -13.55, -10.81, -8.08, -5.38, -2.69};
nherriot 0:bcf2aa85d7f9 25 float TILT_Z[64] = {90.00, 87.31, 84.62, 81.92, 79.19, 76.45, 73.67, 70.84, 67.98, 65.05, 62.05, 58.96, 55.77, 52.46, 48.99, 45.32, 41.41, 37.17, 32.46, 27.05, 20.36, 10.14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10.14, -20.36, -27.05, -32.46, -37.17, -41.41, -45.32, -48.99, -52.46, -55.77, -58.96, -62.05, -65.05, -67.98, -70.84, -73.67, -76.45, -79.19, -81.92, -84.62};
nherriot 0:bcf2aa85d7f9 26
nherriot 0:bcf2aa85d7f9 27
nherriot 0:bcf2aa85d7f9 28
nherriot 0:bcf2aa85d7f9 29 // Connect module at I2C address using I2C port pins sda and scl
nherriot 1:ef026bf28798 30 Accelerometer_MMA8452::Accelerometer_MMA8452(PinName sda, PinName scl,int frequency) : m_i2c(sda, scl) , m_frequency(frequency)
nherriot 0:bcf2aa85d7f9 31 {
nherriot 0:bcf2aa85d7f9 32 //m_i2c.frequency(m_frequency);
nherriot 0:bcf2aa85d7f9 33 }
nherriot 0:bcf2aa85d7f9 34
nherriot 0:bcf2aa85d7f9 35
nherriot 0:bcf2aa85d7f9 36 // Destroys instance
nherriot 0:bcf2aa85d7f9 37 Accelerometer_MMA8452::~Accelerometer_MMA8452()
nherriot 0:bcf2aa85d7f9 38 {
nherriot 0:bcf2aa85d7f9 39
nherriot 0:bcf2aa85d7f9 40 }
nherriot 0:bcf2aa85d7f9 41
nherriot 0:bcf2aa85d7f9 42 // Setting the control register bit 1 to true to activate the MMA8452
nherriot 0:bcf2aa85d7f9 43 int Accelerometer_MMA8452::activate()
nherriot 0:bcf2aa85d7f9 44 {
nherriot 1:ef026bf28798 45 char mcu_address = (MMA8452_ADDRESS<<1);
nherriot 0:bcf2aa85d7f9 46 char init[2];
nherriot 0:bcf2aa85d7f9 47 init[0] = CTRL_REG_1; // control register 1
nherriot 0:bcf2aa85d7f9 48 init[1] = 0x01; // set to active
nherriot 1:ef026bf28798 49 //while(m_i2c.write(mcu_address,init,2));
nherriot 1:ef026bf28798 50
nherriot 0:bcf2aa85d7f9 51 if(m_i2c.write(mcu_address,init,2) == 0)
nherriot 0:bcf2aa85d7f9 52 {
nherriot 0:bcf2aa85d7f9 53 // pc.printf("The initialisation worked");
nherriot 1:ef026bf28798 54 return 0; // return 0 to indicate success
nherriot 0:bcf2aa85d7f9 55 }
nherriot 0:bcf2aa85d7f9 56 else
nherriot 0:bcf2aa85d7f9 57 {
nherriot 0:bcf2aa85d7f9 58 // pc.printf("The initialisation failed");
nherriot 1:ef026bf28798 59 return 1; // crumbs it failed!!!
nherriot 0:bcf2aa85d7f9 60 }
nherriot 0:bcf2aa85d7f9 61
nherriot 0:bcf2aa85d7f9 62 }
nherriot 0:bcf2aa85d7f9 63
nherriot 0:bcf2aa85d7f9 64
nherriot 0:bcf2aa85d7f9 65 // Device initialization
nherriot 0:bcf2aa85d7f9 66 void Accelerometer_MMA8452::init()
nherriot 0:bcf2aa85d7f9 67 {
nherriot 0:bcf2aa85d7f9 68
nherriot 0:bcf2aa85d7f9 69 write_reg(INTSU_STATUS, 0x10); // automatic interrupt after every measurement
nherriot 0:bcf2aa85d7f9 70 write_reg(SR_STATUS, 0x00); // 120 Samples/Second
nherriot 0:bcf2aa85d7f9 71 write_reg(MODE_STATUS, 0x01); // Active Mode
nherriot 0:bcf2aa85d7f9 72
nherriot 0:bcf2aa85d7f9 73 }
nherriot 0:bcf2aa85d7f9 74
nherriot 0:bcf2aa85d7f9 75
nherriot 1:ef026bf28798 76 // Get device ID
nherriot 1:ef026bf28798 77 int Accelerometer_MMA8452::Get_DeviceID(int *deviceID)
nherriot 1:ef026bf28798 78 {
nherriot 1:ef026bf28798 79 char mcu_address = (MMA8452_ADDRESS<<1);
nherriot 1:ef026bf28798 80 int z = 0;
nherriot 1:ef026bf28798 81 m_i2c.start();
nherriot 1:ef026bf28798 82 wait( 0.1);
nherriot 1:ef026bf28798 83 if( m_i2c.write( mcu_address) == 0)
nherriot 1:ef026bf28798 84 {
nherriot 1:ef026bf28798 85 //printf( "GetDeviceId NAK on writing address");
nherriot 1:ef026bf28798 86 return 1;
nherriot 1:ef026bf28798 87 }
nherriot 1:ef026bf28798 88 wait( 0.1);
nherriot 1:ef026bf28798 89 if( m_i2c.write( WHO_AM_I) == 0)
nherriot 1:ef026bf28798 90 {
nherriot 1:ef026bf28798 91 //printf( "GetDeviceId NAK on writing register address");
nherriot 1:ef026bf28798 92
nherriot 1:ef026bf28798 93 return 1;
nherriot 1:ef026bf28798 94 }
nherriot 1:ef026bf28798 95 wait( 0.1);
nherriot 1:ef026bf28798 96 m_i2c.start();
nherriot 1:ef026bf28798 97 wait( 0.1);
nherriot 1:ef026bf28798 98 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...
nherriot 1:ef026bf28798 99 {
nherriot 1:ef026bf28798 100 //printf( "GetDeviceId NAK on writing address");
nherriot 1:ef026bf28798 101
nherriot 1:ef026bf28798 102 return 1;
nherriot 1:ef026bf28798 103 }
nherriot 1:ef026bf28798 104 wait( 0.1);
nherriot 1:ef026bf28798 105 //deviceID = m_i2c.read(0);
nherriot 1:ef026bf28798 106 z = m_i2c.read(0);
nherriot 1:ef026bf28798 107 wait( 0.1);
nherriot 1:ef026bf28798 108 m_i2c.stop();
nherriot 1:ef026bf28798 109 return 0;
nherriot 1:ef026bf28798 110
nherriot 1:ef026bf28798 111 }
nherriot 1:ef026bf28798 112
nherriot 1:ef026bf28798 113
nherriot 0:bcf2aa85d7f9 114 // Reads the tilt angle
nherriot 0:bcf2aa85d7f9 115 void Accelerometer_MMA8452::read_Tilt(float *x, float *y, float *z)
nherriot 0:bcf2aa85d7f9 116 {
nherriot 0:bcf2aa85d7f9 117
nherriot 0:bcf2aa85d7f9 118 const char Addr_X = OUT_X_MSB;
nherriot 0:bcf2aa85d7f9 119 char buf[3] = {0,0,0};
nherriot 0:bcf2aa85d7f9 120
nherriot 0:bcf2aa85d7f9 121 m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register
nherriot 0:bcf2aa85d7f9 122 m_i2c.read(MMA8452_ADDRESS, buf, 3); // Read register content into buffer with 6bit
nherriot 0:bcf2aa85d7f9 123
nherriot 0:bcf2aa85d7f9 124 // returns the x, y, z coordinates transformed into full degrees
nherriot 0:bcf2aa85d7f9 125 *x = TILT_XY[(int)buf[0]];
nherriot 0:bcf2aa85d7f9 126 *y = TILT_XY[(int)buf[1]];
nherriot 0:bcf2aa85d7f9 127 *z = TILT_Z[(int)buf[2]];
nherriot 0:bcf2aa85d7f9 128
nherriot 0:bcf2aa85d7f9 129 }
nherriot 0:bcf2aa85d7f9 130
nherriot 0:bcf2aa85d7f9 131
nherriot 0:bcf2aa85d7f9 132 // Reads x data
nherriot 0:bcf2aa85d7f9 133 int Accelerometer_MMA8452::read_x()
nherriot 0:bcf2aa85d7f9 134 {
nherriot 1:ef026bf28798 135 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 0:bcf2aa85d7f9 136
nherriot 1:ef026bf28798 137 m_i2c.start(); // Start
nherriot 1:ef026bf28798 138 m_i2c.write(mcu_address); // A write to devic
nherriot 1:ef026bf28798 139 m_i2c.write(OUT_X_LSB); // Register to read
nherriot 0:bcf2aa85d7f9 140 m_i2c.start();
nherriot 1:ef026bf28798 141 m_i2c.write(mcu_address); // Read from device
nherriot 1:ef026bf28798 142 int x = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 143 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 144
nherriot 1:ef026bf28798 145 return x;
nherriot 0:bcf2aa85d7f9 146
nherriot 0:bcf2aa85d7f9 147 }
nherriot 0:bcf2aa85d7f9 148
nherriot 0:bcf2aa85d7f9 149
nherriot 0:bcf2aa85d7f9 150 // Reads y data
nherriot 0:bcf2aa85d7f9 151 int Accelerometer_MMA8452::read_y()
nherriot 0:bcf2aa85d7f9 152 {
nherriot 1:ef026bf28798 153 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 0:bcf2aa85d7f9 154
nherriot 0:bcf2aa85d7f9 155 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 156 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 157 m_i2c.write(OUT_Y_MSB); // Register to read
nherriot 0:bcf2aa85d7f9 158 m_i2c.start();
nherriot 0:bcf2aa85d7f9 159 m_i2c.write(mcu_address); // Read from device 0x99
nherriot 1:ef026bf28798 160 int y = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 161 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 162
nherriot 1:ef026bf28798 163 return y;
nherriot 0:bcf2aa85d7f9 164
nherriot 0:bcf2aa85d7f9 165 }
nherriot 0:bcf2aa85d7f9 166
nherriot 0:bcf2aa85d7f9 167
nherriot 0:bcf2aa85d7f9 168 // Reads z data
nherriot 0:bcf2aa85d7f9 169 int Accelerometer_MMA8452::read_z()
nherriot 0:bcf2aa85d7f9 170 {
nherriot 1:ef026bf28798 171 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 0:bcf2aa85d7f9 172
nherriot 0:bcf2aa85d7f9 173 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 174 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 175 m_i2c.write(OUT_Z_MSB); // Register to read
nherriot 0:bcf2aa85d7f9 176 m_i2c.start();
nherriot 0:bcf2aa85d7f9 177 m_i2c.write(mcu_address); // Read from device 0x99
nherriot 1:ef026bf28798 178 int z = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 179 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 180
nherriot 1:ef026bf28798 181 return z;
nherriot 0:bcf2aa85d7f9 182
nherriot 0:bcf2aa85d7f9 183 }
nherriot 0:bcf2aa85d7f9 184
nherriot 0:bcf2aa85d7f9 185
nherriot 0:bcf2aa85d7f9 186 // Reads xyz
nherriot 1:ef026bf28798 187 int Accelerometer_MMA8452::read_xyz(char *x, char *y, char *z)
nherriot 1:ef026bf28798 188 {
nherriot 1:ef026bf28798 189
nherriot 1:ef026bf28798 190
nherriot 1:ef026bf28798 191 char mcu_address = (MMA8452_ADDRESS <<1);
nherriot 1:ef026bf28798 192 char register_buffer[6] ={0,0,0,0,0,0};
nherriot 1:ef026bf28798 193 const char Addr_X = OUT_X_MSB;
nherriot 1:ef026bf28798 194 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 1:ef026bf28798 195 m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register
nherriot 1:ef026bf28798 196
nherriot 1:ef026bf28798 197 if(m_i2c.write(mcu_address,&Addr_X,1) == 0)
nherriot 1:ef026bf28798 198 {
nherriot 1:ef026bf28798 199 if(m_i2c.read(mcu_address,register_buffer,6) == 0)
nherriot 1:ef026bf28798 200 {
nherriot 1:ef026bf28798 201 *x = register_buffer[1];
nherriot 1:ef026bf28798 202 *y = register_buffer[3];
nherriot 1:ef026bf28798 203 *z = register_buffer[5];
nherriot 1:ef026bf28798 204 return 0; // yahoooooo
nherriot 1:ef026bf28798 205 }
nherriot 1:ef026bf28798 206 else
nherriot 1:ef026bf28798 207 {
nherriot 1:ef026bf28798 208 return 1; // failed oh nooo!
nherriot 1:ef026bf28798 209 }
nherriot 1:ef026bf28798 210 }
nherriot 1:ef026bf28798 211 else
nherriot 1:ef026bf28798 212 {
nherriot 1:ef026bf28798 213 return 1; // failed oh nooo!
nherriot 1:ef026bf28798 214 }
nherriot 0:bcf2aa85d7f9 215
nherriot 1:ef026bf28798 216 }
nherriot 0:bcf2aa85d7f9 217
nherriot 0:bcf2aa85d7f9 218 // Write register (The device must be placed in Standby Mode to change the value of the registers)
nherriot 0:bcf2aa85d7f9 219 void Accelerometer_MMA8452::write_reg(char addr, char data)
nherriot 0:bcf2aa85d7f9 220 {
nherriot 0:bcf2aa85d7f9 221
nherriot 0:bcf2aa85d7f9 222 char cmd[2] = {0, 0};
nherriot 0:bcf2aa85d7f9 223
nherriot 0:bcf2aa85d7f9 224 cmd[0] = MODE_STATUS;
nherriot 0:bcf2aa85d7f9 225 cmd[1] = 0x00; // Standby Mode on
nherriot 0:bcf2aa85d7f9 226 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 227
nherriot 0:bcf2aa85d7f9 228 cmd[0] = addr;
nherriot 0:bcf2aa85d7f9 229 cmd[1] = data; // New value of the register
nherriot 0:bcf2aa85d7f9 230 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 231
nherriot 0:bcf2aa85d7f9 232 cmd[0] = MODE_STATUS;
nherriot 0:bcf2aa85d7f9 233 cmd[1] = 0x01; // Active Mode on
nherriot 0:bcf2aa85d7f9 234 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 235
nherriot 0:bcf2aa85d7f9 236 }
nherriot 0:bcf2aa85d7f9 237
nherriot 0:bcf2aa85d7f9 238
nherriot 0:bcf2aa85d7f9 239
nherriot 0:bcf2aa85d7f9 240 // Read from specified MMA7660FC register
nherriot 0:bcf2aa85d7f9 241 char Accelerometer_MMA8452::read_reg(char addr)
nherriot 0:bcf2aa85d7f9 242 {
nherriot 0:bcf2aa85d7f9 243
nherriot 0:bcf2aa85d7f9 244 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 245 m_i2c.write(0x98); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 246 m_i2c.write(addr); // Register to read
nherriot 0:bcf2aa85d7f9 247 m_i2c.start();
nherriot 0:bcf2aa85d7f9 248 m_i2c.write(0x99); // Read from device 0x99
nherriot 0:bcf2aa85d7f9 249 char c = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 250 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 251
nherriot 0:bcf2aa85d7f9 252 return c;
nherriot 0:bcf2aa85d7f9 253
nherriot 0:bcf2aa85d7f9 254 }
nherriot 0:bcf2aa85d7f9 255
nherriot 0:bcf2aa85d7f9 256
nherriot 0:bcf2aa85d7f9 257
nherriot 0:bcf2aa85d7f9 258
nherriot 0:bcf2aa85d7f9 259
nherriot 0:bcf2aa85d7f9 260