This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1290NCPDT: Need desperate help with I2C communication with MMA8452Q in Energia

Part Number: TM4C1290NCPDT
Other Parts Discussed in Thread: ENERGIA

Hi, I'm currently doing a project involving the MMA8452Q accelerometer inside Energia, but for some reason it won't work and it won't even read 0x2A out of the WHO_AM_I register.

Need desperate help T.T Thanks a lot!

I'm using I2C module 0 (PB2 and PB3) and below is my code!

Inside my loop I'm supposed to read the x y z data but in order to test the WHO_AM_I register I have some dummy code there.

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

#define SA0 1
#if SA0
#define MMA8452_ADDRESS 0x1D  // SA0 is high, 0x1C if low
#else
#define MMA8452_ADDRESS 0x1C
#endif

//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.

volatile byte value;

void setup()
{
  Serial.begin(115200);
  Serial.println("MMA8452 Basic Example");
  Wire.setModule(0);
  delay(10);
  Wire.begin(); //Join the bus as a master
  delay(10);
  Serial.println(readRegister(WHO_AM_I));
  initMMA8451(); //Test and intialize the MMA8451
}

void loop()
{  
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write((byte) 0x0D);
  Wire.endTransmission(false);
  Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default
  while(!Wire.available()) ; //Wait for the data to come back
  value = (byte) Wire.read();
  Serial.println(value);
  delay(1000);  // 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

  short x = ((short)(rawData[0]<<8 | rawData[1])) >> 4;
  short y = ((short)(rawData[2]<<8 | rawData[3])) >> 4;
  short z = ((short)(rawData[4]<<8 | rawData[5])) >> 4;

  Serial.println(x);
  delay(1000);
  Serial.println(y);
  delay(1000);
  Serial.println(z);
  delay(1000);

//  // 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
//  }
}


void initMMA8451()
{
  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
  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(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection active

  Wire.requestFrom(MMA8452_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(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  delay(10);
  Wire.endTransmission(false);

  Wire.requestFrom(MMA8452_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(MMA8452_ADDRESS);
  Wire.write(addressToWrite);
  Wire.write(dataToWrite);
  Wire.endTransmission(); //Stop transmitting
}

  • Feel your pain - and commend you for avoiding the (so off-putting) "Urgent" or "Expecting" we (few) forum users to, "Drop what we're doing" and rush to those "uber - privileged" posters' (immediate - if not sooner) NEEDS! (all of them)

    Your choice of, "Desperate" well defines (your) condition - while not imposing itself (as much) upon hapless helper crüe, here.

    Troubleshooting (any) such serial interface ALWAYS is greatly, "Speeded, Eased, Enhanced" thru use of a Scope - which quickly reveals if ANY Signals escape from the MCU.     Alas - you make "No mention."

    Pull-Up resistors - 4K7 - 10K ARE Required (please do not debate) and should appear upon EACH of the 2 I2C signal lines.    (Data & Clock)    Are those present?    Do both signal lines "return to near 3V3" when you are NOT transacting via I2C?

    Few here (this forum) know - or even "care" about, "L0-energia" - have you directed similar "desperation" to that forum or help provider?

    Firm/I believe (very much) in "KISS" and for your (assumed) first action w/I2C you've chosen a TALL Mountain - have you not?     KISS - which best leads you to success - dictates that you START w/a far easier, small capacity, I2C based, EEProm.     Your more complex device simply presents "too many variables" - is wildly inappropriate for, ANY "First Time Attack!"     (even though - and especially though - tacitly encouraged by those who (surely) "know better.")

    Have you seriously reviewed Lo-energia - surely someone there has posted (something) "claimed as working."    

    Again - feeling your pain does not enable a quick/eased solution - when tasked w/so complex a device - and a "Series of BAD, Overly Optimistic Choices" have led to your "desperation" - is that not so?    And - one must ask - WHY is that?     

    Lesson Learned - Start EARLY - (even when fearful - especially when fearful!)      YELL for help EARLY & OFTEN - to Stakeholders - who best may assist.     "Reality is a (sometimes) cruel teacher - yet (some) lessons must "cause pain" - to lead to, "Improved future efforts..."

  • Hello Xujia,

    As far as the software you posted goes, we don't have any Energia experience to review your code and offer any feedback in terms of any possible errors. You will need to go to the Energia forums to get assistance with that, the link for the forums is: https://forum.43oh.com/forum/125-energia-tivaccc3xxx/

    cb1 made some good suggestions about the hardware though, please do follow up with your findings about his advice pertaining the hardware aspects like the pull-up resistors. At least on a hardware level we can help give some confidence that your setup is okay, and then you can focus on the software via the Energia forums noted above.