MSP430LaunchPad

MMA8451 Accelerometer on the Launchpad with Energia

Note: This article is a blurb. Help expand it.

Tags

Tutorial

The following procedure will show you how to set up your launchpad with Energia and the MMA8451 Accelerometer and should work for both the MSP-430F5529 and the MSP-430G2553.

Where to Get Parts

The parts in this tutorial can be acquired:


Advertisement


Hardware

I will be using the Triple-axis 14-bit MMA8451 Accelerometer - from Adafruit.

Breakout-Board Assembly

Assemble the board, by soldering the connector pins:

Circuit

  • The F5529 board uses the P3.0 (SDA0) and P3.1 (SCL) pins for I2C communication. For more information, see the F5529 board pinout here.
  • The G2553 board uses the P1.7 (SDA0) and P1.6 (SCL) pins for I2C communication. For more information, see the G2553 board pinout here.

Connect the Launchpad and the accelerometer breakout board according to the following diagram:

The accelerometer is powered by the 3.3 volt line. The A pin is not connected in this tutorial, but can be used to change the I2C address to 0x1D if connected to 3.3 Volt. The SDA and the SCA pins are connected through a 1.8 kΩ pull-up resistor each to the P3.0 and P3.1 pins on the MSPF5529 board, respectively.

Software

Energia Installation

  1. Download the latest Energia version from here(in my case I used the Windows Binary release).
  2. Extract the .zip file into a working folder.

Accelerometer Library Installation

The Adafruit MMA8451 library did not work well with the Launchpad. I was not able to modify it to get it to work.

Sketch Creation

  1. The following sketch shows an example of how to read the accelerometer values in the X, Y, and Z directions. The sketch was modified from the Sparkfun Basic Example to work with the MSP430 Launchpad. You can just copy and paste the following sketch, or you can download the sketch here.

Notes

  • The GSCALE variable can be set to 2, 4, or 8, which will set the maximum acceleration measured. Setting the variable to 8, will allow you to measure up to 8g, but will reduce your resolution.
 
/*

MMA8451 Basic Example Code
  Nikolai Kummer
  Edison Developers http://edisondev.net/
  September 22, 2014


Modified by EdisonDev from:
 Nathan Seidle
 SparkFun Electronics
 November 5, 2012

 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

 This example code shows how to read the X/Y/Z accelerations and basic functions of the MMA5841. It leaves out
 all the neat features this IC is capable of (tap, orientation, and inerrupts) and just displays X/Y/Z. See 
 the advanced example code to see more features.

 Hardware setup:
 MMA8451 Breakout (Adafruit) ------------ MSP430F5529
 3.3V --------------------- 3.3V
 SDA -------^^(1.8k)^^------- P3.0
 SCL -------^^(1.8k)^^------- P3.1
 GND ---------------------- GND

Connect the SDA and SCL lines via a 1.8kOhm pull-up resistor to the 3.3Volt line and the P3.0 and P3.1 pins

 The MMA8451 has built in pull-up resistors for I2C so you do not need additional pull-ups.
 */

#include <Wire.h> // Used for I2C

//This example uses the Adafruit breakout board
#define MMA8451_ADDRESS 0x1D  // 0x1D if A pin is high, 0x1C if low (connected to GND)

//Define a few of the registers that we will be accessing on the MMA8451
#define OUT_X_MSB 0x01
#define XYZ_DATA_CFG  0x0E
#define WHO_AM_I   0x0D
#define CTRL_REG1  0x2A

#define GSCALE 4 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.

void setup()
{
  Serial.begin(9600);
  Serial.println("MMA8451 Basic Example");

  Wire.begin(); //Join the bus as a master

  initMMA8451(); //Test and intialize the MMA8451
}

void loop()
{  
  int accelCount[3];  // Stores the 14-bit signed value
  readAccelData(accelCount);  // Read the x/y/z adc values

  // Now we'll calculate the accleration value into actual g's
  float accelG[3];  // Stores the real accel value in g's
  for (int i = 0 ; i < 3 ; i++)
  {
    accelG[i] = (float) accelCount[i] / ((1<<14)/(2*GSCALE));  // get actual g value, this depends on scale being set //ed (12 to 14)
  }

  // Print out values
  for (int i = 0 ; i < 3 ; i++)
  {
    Serial.print(accelG[i], 4);  // Print g values
    Serial.print("\t");  // tabs in between axes
  }
  Serial.println();

  delay(100);  // Delay here for visibility
}

void readAccelData(int *destination)
{
  byte rawData[6];  // x/y/z accel register data stored here

  readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array

  // Loop to calculate 12-bit ADC and g value for each axis
  for(int i = 0; i < 3 ; i++)
  {
    int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
    gCount >>= 2; //The registers are left align, here we right align the 14-bit integer

    // If the number is negative, we have to make it so manually (no 12-bit data type)
    if (rawData[i*2] > 0x7F)
    {  
      gCount = ~gCount + 1;
      gCount *= -1;  // Transform into negative 2's complement #
    }

    destination[i] = gCount; //Record this gCount into the 3 int array
  }
}

// Initialize the MMA8451 registers 
// See the many application notes for more info on setting all of these registers:
// http://www.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
void initMMA8451()
{
  byte c = readRegister(WHO_AM_I);  // Read WHO_AM_I register
  if (c == 0x1A) // WHO_AM_I should always be 0x1A for MMA8451            //EDISON_DEV_modified
  {  
    Serial.println("MMA8451 is online...");
  }
  else
  {
    Serial.print("Could not connect to MMA8451: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }

  MMA8451Standby();  // Must be in standby to change registers

  // Set up the full scale range to 2, 4, or 8g.
  byte fsr = GSCALE;
  if(fsr > 8) fsr = 8; //Easy error check
  fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
  writeRegister(XYZ_DATA_CFG, fsr);

  //The default data rate is 800Hz and we don't modify it in this example code

  MMA8451Active();  // Set to active to start reading
}

// Sets the MMA8451 to standby mode. It must be in standby to change most register settings
void MMA8451Standby()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
}

// Sets the MMA8451 to active mode. Needs to be in this mode to output data
void MMA8451Active()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
}

// Read bytesToRead sequentially, starting at addressToRead into the dest byte array
void readRegisters(byte addressToRead, int bytesToRead, byte * dest)
{
  Wire.beginTransmission(MMA8451_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

  Wire.requestFrom(MMA8451_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default

  while(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect

  for(int x = 0 ; x < bytesToRead ; x++)
    dest[x] = Wire.read();    
}

// Read a single byte from addressToRead and return it as a byte
byte readRegister(byte addressToRead)
{
  Wire.beginTransmission(MMA8451_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

  Wire.requestFrom(MMA8451_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default

  while(!Wire.available()) ; //Wait for the data to come back
  return Wire.read(); //Return this one byte
}

// Writes a single byte (dataToWrite) into addressToWrite
void writeRegister(byte addressToWrite, byte dataToWrite)
{
  Wire.beginTransmission(MMA8451_ADDRESS);
  Wire.write(addressToWrite);
  Wire.write(dataToWrite);
  Wire.endTransmission(); //Stop transmitting
}

Uploading Sketch

First select the appropriate board (here MSP430F5529) and COM port in Energia. Click upload and the sketch should compile without problems. The Serial Monitor output can be accessed by pressing [Ctrl]+[Shift]+[M] and should show something like this:

Each entry per line shows the accelerations in the X, Y, and Z directions, respectively.

Conclusion

In this tutorial you were shown how to interface the MMA8451 Accelerometer with the MSP430F5529 board. The example shows you how to communicate with the sensor and how to read the acceleration values from the accelerometer.


Advertisement