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:
Fri Oct 04 14:48:02 2013 +0000
Revision:
0:bcf2aa85d7f9
Child:
1:ef026bf28798
Initial commit fro mma8452

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 0:bcf2aa85d7f9 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 0:bcf2aa85d7f9 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 0:bcf2aa85d7f9 49 if(m_i2c.write(mcu_address,init,2) == 0)
nherriot 0:bcf2aa85d7f9 50 {
nherriot 0:bcf2aa85d7f9 51 // pc.printf("The initialisation worked");
nherriot 0:bcf2aa85d7f9 52 return 0;
nherriot 0:bcf2aa85d7f9 53 }
nherriot 0:bcf2aa85d7f9 54 else
nherriot 0:bcf2aa85d7f9 55 {
nherriot 0:bcf2aa85d7f9 56 // pc.printf("The initialisation failed");
nherriot 0:bcf2aa85d7f9 57 return 1;
nherriot 0:bcf2aa85d7f9 58 }
nherriot 0:bcf2aa85d7f9 59
nherriot 0:bcf2aa85d7f9 60 }
nherriot 0:bcf2aa85d7f9 61
nherriot 0:bcf2aa85d7f9 62
nherriot 0:bcf2aa85d7f9 63 // Device initialization
nherriot 0:bcf2aa85d7f9 64 void Accelerometer_MMA8452::init()
nherriot 0:bcf2aa85d7f9 65 {
nherriot 0:bcf2aa85d7f9 66
nherriot 0:bcf2aa85d7f9 67 write_reg(INTSU_STATUS, 0x10); // automatic interrupt after every measurement
nherriot 0:bcf2aa85d7f9 68 write_reg(SR_STATUS, 0x00); // 120 Samples/Second
nherriot 0:bcf2aa85d7f9 69 write_reg(MODE_STATUS, 0x01); // Active Mode
nherriot 0:bcf2aa85d7f9 70
nherriot 0:bcf2aa85d7f9 71 }
nherriot 0:bcf2aa85d7f9 72
nherriot 0:bcf2aa85d7f9 73
nherriot 0:bcf2aa85d7f9 74 // Reads the tilt angle
nherriot 0:bcf2aa85d7f9 75 void Accelerometer_MMA8452::read_Tilt(float *x, float *y, float *z)
nherriot 0:bcf2aa85d7f9 76 {
nherriot 0:bcf2aa85d7f9 77
nherriot 0:bcf2aa85d7f9 78 const char Addr_X = OUT_X_MSB;
nherriot 0:bcf2aa85d7f9 79 char buf[3] = {0,0,0};
nherriot 0:bcf2aa85d7f9 80
nherriot 0:bcf2aa85d7f9 81 m_i2c.write(MMA8452_ADDRESS, &Addr_X, 1); // Pointer to the OUT_X_MSB register
nherriot 0:bcf2aa85d7f9 82 m_i2c.read(MMA8452_ADDRESS, buf, 3); // Read register content into buffer with 6bit
nherriot 0:bcf2aa85d7f9 83
nherriot 0:bcf2aa85d7f9 84 // returns the x, y, z coordinates transformed into full degrees
nherriot 0:bcf2aa85d7f9 85 *x = TILT_XY[(int)buf[0]];
nherriot 0:bcf2aa85d7f9 86 *y = TILT_XY[(int)buf[1]];
nherriot 0:bcf2aa85d7f9 87 *z = TILT_Z[(int)buf[2]];
nherriot 0:bcf2aa85d7f9 88
nherriot 0:bcf2aa85d7f9 89 }
nherriot 0:bcf2aa85d7f9 90
nherriot 0:bcf2aa85d7f9 91
nherriot 0:bcf2aa85d7f9 92 // Reads x data
nherriot 0:bcf2aa85d7f9 93 int Accelerometer_MMA8452::read_x()
nherriot 0:bcf2aa85d7f9 94 {
nherriot 0:bcf2aa85d7f9 95 char mcu_address = (MMA8452_ADDRESS <1);
nherriot 0:bcf2aa85d7f9 96
nherriot 0:bcf2aa85d7f9 97 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 98 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 99 m_i2c.write(OUT_X_MSB); // Register to read
nherriot 0:bcf2aa85d7f9 100 m_i2c.start();
nherriot 0:bcf2aa85d7f9 101 m_i2c.write(mcu_address); // Read from device 0x99
nherriot 0:bcf2aa85d7f9 102 char x = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 103 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 104
nherriot 0:bcf2aa85d7f9 105 return (int)x;
nherriot 0:bcf2aa85d7f9 106
nherriot 0:bcf2aa85d7f9 107 }
nherriot 0:bcf2aa85d7f9 108
nherriot 0:bcf2aa85d7f9 109
nherriot 0:bcf2aa85d7f9 110 // Reads y data
nherriot 0:bcf2aa85d7f9 111 int Accelerometer_MMA8452::read_y()
nherriot 0:bcf2aa85d7f9 112 {
nherriot 0:bcf2aa85d7f9 113 char mcu_address = (MMA8452_ADDRESS <1);
nherriot 0:bcf2aa85d7f9 114
nherriot 0:bcf2aa85d7f9 115 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 116 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 117 m_i2c.write(OUT_Y_MSB); // Register to read
nherriot 0:bcf2aa85d7f9 118 m_i2c.start();
nherriot 0:bcf2aa85d7f9 119 m_i2c.write(mcu_address); // Read from device 0x99
nherriot 0:bcf2aa85d7f9 120 char y = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 121 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 122
nherriot 0:bcf2aa85d7f9 123 return (int)y;
nherriot 0:bcf2aa85d7f9 124
nherriot 0:bcf2aa85d7f9 125 }
nherriot 0:bcf2aa85d7f9 126
nherriot 0:bcf2aa85d7f9 127
nherriot 0:bcf2aa85d7f9 128 // Reads z data
nherriot 0:bcf2aa85d7f9 129 int Accelerometer_MMA8452::read_z()
nherriot 0:bcf2aa85d7f9 130 {
nherriot 0:bcf2aa85d7f9 131 char mcu_address = (MMA8452_ADDRESS <1);
nherriot 0:bcf2aa85d7f9 132
nherriot 0:bcf2aa85d7f9 133 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 134 m_i2c.write(mcu_address); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 135 m_i2c.write(OUT_Z_MSB); // Register to read
nherriot 0:bcf2aa85d7f9 136 m_i2c.start();
nherriot 0:bcf2aa85d7f9 137 m_i2c.write(mcu_address); // Read from device 0x99
nherriot 0:bcf2aa85d7f9 138 char z = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 139 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 140
nherriot 0:bcf2aa85d7f9 141 return (int)z;
nherriot 0:bcf2aa85d7f9 142
nherriot 0:bcf2aa85d7f9 143 }
nherriot 0:bcf2aa85d7f9 144
nherriot 0:bcf2aa85d7f9 145
nherriot 0:bcf2aa85d7f9 146 // Reads xyz
nherriot 0:bcf2aa85d7f9 147
nherriot 0:bcf2aa85d7f9 148
nherriot 0:bcf2aa85d7f9 149
nherriot 0:bcf2aa85d7f9 150
nherriot 0:bcf2aa85d7f9 151 // Write register (The device must be placed in Standby Mode to change the value of the registers)
nherriot 0:bcf2aa85d7f9 152 void Accelerometer_MMA8452::write_reg(char addr, char data)
nherriot 0:bcf2aa85d7f9 153 {
nherriot 0:bcf2aa85d7f9 154
nherriot 0:bcf2aa85d7f9 155 char cmd[2] = {0, 0};
nherriot 0:bcf2aa85d7f9 156
nherriot 0:bcf2aa85d7f9 157 cmd[0] = MODE_STATUS;
nherriot 0:bcf2aa85d7f9 158 cmd[1] = 0x00; // Standby Mode on
nherriot 0:bcf2aa85d7f9 159 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 160
nherriot 0:bcf2aa85d7f9 161 cmd[0] = addr;
nherriot 0:bcf2aa85d7f9 162 cmd[1] = data; // New value of the register
nherriot 0:bcf2aa85d7f9 163 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 164
nherriot 0:bcf2aa85d7f9 165 cmd[0] = MODE_STATUS;
nherriot 0:bcf2aa85d7f9 166 cmd[1] = 0x01; // Active Mode on
nherriot 0:bcf2aa85d7f9 167 m_i2c.write(MMA8452_ADDRESS, cmd, 2);
nherriot 0:bcf2aa85d7f9 168
nherriot 0:bcf2aa85d7f9 169 }
nherriot 0:bcf2aa85d7f9 170
nherriot 0:bcf2aa85d7f9 171
nherriot 0:bcf2aa85d7f9 172
nherriot 0:bcf2aa85d7f9 173 // Read from specified MMA7660FC register
nherriot 0:bcf2aa85d7f9 174 char Accelerometer_MMA8452::read_reg(char addr)
nherriot 0:bcf2aa85d7f9 175 {
nherriot 0:bcf2aa85d7f9 176
nherriot 0:bcf2aa85d7f9 177 m_i2c.start(); // Start
nherriot 0:bcf2aa85d7f9 178 m_i2c.write(0x98); // A write to device 0x98
nherriot 0:bcf2aa85d7f9 179 m_i2c.write(addr); // Register to read
nherriot 0:bcf2aa85d7f9 180 m_i2c.start();
nherriot 0:bcf2aa85d7f9 181 m_i2c.write(0x99); // Read from device 0x99
nherriot 0:bcf2aa85d7f9 182 char c = m_i2c.read(0); // Read the data
nherriot 0:bcf2aa85d7f9 183 m_i2c.stop();
nherriot 0:bcf2aa85d7f9 184
nherriot 0:bcf2aa85d7f9 185 return c;
nherriot 0:bcf2aa85d7f9 186
nherriot 0:bcf2aa85d7f9 187 }
nherriot 0:bcf2aa85d7f9 188
nherriot 0:bcf2aa85d7f9 189
nherriot 0:bcf2aa85d7f9 190
nherriot 0:bcf2aa85d7f9 191
nherriot 0:bcf2aa85d7f9 192
nherriot 0:bcf2aa85d7f9 193