Arduino and MMA8653 accelerometer example

The NXP® MMA8653FC 10-bit accelerometer has industry leading performance in a small DFN package. Packed with embedded functions that include:

Flexible user-programmable options and two configurable interrupt pins
Overall power savings through inertial wake-up interrupt signals that monitor events and remain in a low-power mode during periods of inactivity

Features

Low-profile 2 x 2 x 1.0 mm DFN package
High sensitivity: 1 mg per LSB
Low noise: 150 micro g per root Hertz (independent of resolution)
Low-power mode: 7 micro amps
Interrupt and IIC interface supply: 1.62 to 3.6 V
Supply voltage : 1.95 to 3.6 V
Output data rate: 1.5 to 800 Hz

Connection

You need to use 3.3v for this device, the rest is easy Gnd and I2C

Code

 

[codesyntax lang=”cpp”]

#include <Wire.h>

// I2C BUS: already defined in "wire" librairy
// SDA: PIN 2 with pull up 4.7K to 3.3V on arduino Micro
// SCL: PIN 3 with pull up 4.7K to 3.3V on arduino Micro
// Accelerometer connected to +3.3V of arduino DO NOT CONNECT TO 5V (this will destroy the accelerometer!)
// all GND Pin of accelerometer connected to gnd of arduino

/********************ACCELEROMETER DATAS************/
// adresss of accelerometer
int adress_acc=0X1D; // MMA8653FC and MMA8652FC
// adress of registers for MMA8653FC
int ctrl_reg1 = 0x2A;
int ctrl_reg2 = 0x2B;
int ctrl_reg3 = 0x2C;
int ctrl_reg4 = 0x2D;
int ctrl_reg5 = 0x2E;
int int_source = 0x0C;
int status_ = 0x00;
int f_setup = 0x09;
int out_x_msb = 0x01;
int out_y_msb = 0x03;
int out_z_msb = 0x05;
int sysmod = 0x0B;
int xyz_data_cfg = 0x0E;

/******PROGRAM DATAS**********/
int result [3];
int axeXnow ;
int axeYnow ;
int axeZnow ;


void setup(){
Wire.begin(); // start of the i2c protocol
Serial.begin(9600); // start serial for output
ACC_INIT(); // initialize the accelerometer by the i2c bus. enter the sub to adjust the range (2g, 4g, 8g), and the data rate (800hz to 1,5Hz)
}

//------------------------------------------------------------------

void loop()
{
I2C_READ_ACC(0x00);
Serial.print(axeXnow); 
Serial.print(";");
Serial.print(axeYnow); 
Serial.print(";");
Serial.print(axeZnow); 
Serial.print(";");
Serial.println();
delay(500);
}

//------------------------------------------------------------------

void ACC_INIT()
{
I2C_SEND(ctrl_reg1 ,0X00); // standby to be able to configure
delay(10);

I2C_SEND(xyz_data_cfg ,B00000000); // 2G full range mode
delay(1);
// I2C_SEND(xyz_data_cfg ,B00000001); // 4G full range mode
// delay(1);
// I2C_SEND(xyz_data_cfg ,B00000010); // 8G full range mode
// delay(1);

I2C_SEND(ctrl_reg1 ,B00000001); // Output data rate at 800Hz, no auto wake, no auto scale adjust, no fast read mode
delay(1);
// I2C_SEND(ctrl_reg1 ,B00100001); // Output data rate at 200Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1);
// I2C_SEND(ctrl_reg1 ,B01000001); // Output data rate at 50Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1);
// I2C_SEND(ctrl_reg1 ,B01110001); // Output data rate at 1.5Hz, no auto wake, no auto scale adjust, no fast read mode
// delay(1); 
}

//------------------------------------------------------------------

void I2C_SEND(unsigned char REG_ADDRESS, unsigned char DATA) //SEND data to MMA7660
{

Wire.beginTransmission(adress_acc);
Wire.write(REG_ADDRESS);
Wire.write(DATA);
Wire.endTransmission();
}

//------------------------------------------------------------------

void I2C_READ_ACC(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
byte REG_ADDRESS[7];
int accel[4];
int i=0; 
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // store the register to read in the buffer of the wire library
Wire.endTransmission(); // actually send the data on the bus -note: returns 0 if transmission OK-
Wire.requestFrom(adress_acc,7); // read a number of byte and store them in wire.read (note: by nature, this is called an "auto-increment register adress")

for(i=0; i<7; i++) // 7 because on datasheet p.19 if FREAD=0, on auto-increment, the adress is shifted
{
REG_ADDRESS[i]=Wire.read(); //each time you read the write.read it gives you the next byte stored. The couter is reset on requestForm
}

for (i=1;i<7;i=i+2)
{
accel[0] = (REG_ADDRESS[i+1]|((int)REG_ADDRESS[i]<<8))>>6; // X
if (accel[0]>0x01FF) {accel[1]=(((~accel[0])+1)-0xFC00);} // note: with signed int, this code is optional
else {accel[1]=accel[0];} // note: with signed int, this code is optional
switch(i){
case 1: axeXnow=accel[1];
break;
case 3: axeYnow=accel[1];
break;
case 5: axeZnow=accel[1];
break;
}
}

}

//------------------------------------------------------------------

void I2C_READ_REG(int ctrlreg_address) //READ number data from i2c slave ctrl-reg register and return the result in a vector
{
unsigned char REG_ADDRESS;
int i=0; 
Wire.beginTransmission(adress_acc); //=ST + (Device Adress+W(0)) + wait for ACK
Wire.write(ctrlreg_address); // register to read
Wire.endTransmission();
Wire.requestFrom(adress_acc,1); // read a number of byte and store them in write received
}

[/codesyntax]

 

 

Output

107;-65281;191;
-65488;511;89;
-65387;15;87;
-65491;511;-65443;
-65364;-65423;-65470;
229;74;-65269;
237;-65511;64;
-65355;-65347;73;
-65360;132;14;
-65481;-65263;-65323;
-65453;228;-65448;
-65354;94;215;
55;-65464;276;

Links

Related posts

Arduino and GY-21P readings on a web page

MPL3115A2 sensor readings displayed on a web page

Adafruit Neopixel shield examples