Problem with MMA8451 And Arduino Due

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Greetings:
I've been trying to get my Adafruit MMA8451 breakout to work with my Due using the Adafruit example code. If I hook the breakout up to my Uno, the example code works fine. If I then switch my IDE to Due, recompile & upload, I get "Couldnt start". I've tried hooking SCL and SDA up to A5 & A4, SCL & SDA, and SCL1 & SDA1. No luck with any of these. Any ideas? I'm sure it's probably some trivial error on my part, but I just can't get it to work.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

The MMA8451 library is written to work with SDA and SCL on pins 20 and 21. There is no I2C on A4 and A5. Using SDA1 and SCL1 requires modifications to the library. You also need to use pullup resistors with SDA1 and SCL1.

Unfortunately, I2C is kind of flaky on the Due. You may have to bite the bullet and try SDA1 and SCL1.

Edit Adafruit_MMA8451.cpp and add the following immediately below the line "#include <Adafruit_MMA8451.h>"

Code: Select all

#include <Adafruit_MMA8451.h>

#ifdef (_VARIANT_ARDUINO_DUE_X_)
  #define Wire Wire1
#endif
Attach 10K resistors between SDA1 and 3.3V, and between SCL1 and 3.3V. These are the pullup resistors. Attach the MMA8451 to SDA1 and SCL1

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

When I try this, I get the following errors on compile:

\build5849425541666072851.tmp\Adafruit MMA8451 Library\Adafruit_MMA8451.cpp.o

C:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451\Adafruit_MMA8451.cpp:32:8: error: macro names must be identifiers

#ifdef (_VARIANT_ARDUINO_DUE_X_)

^

Error compiling.

(Edit: Removed spurious error messages that were caused by a line-wrap problem with my editor)

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

There's nothing wrong with that line. The error must be on an earlier line. Post all the errors and also post the code. You may be missing a semicolon or something.

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Here is the full error report:

Code: Select all

Arduino: 1.7.6 (Windows 7), Board: "Arduino Due (Programming Port)"

Using library Wire in folder: C:\Program Files\Arduino\hardware\arduino\sam\libraries\Wire 

Using library Adafruit MMA8451 Library in folder: C:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451 

Using library Adafruit Unified Sensor in folder: C:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_Sensor 



C:\Program Files\Arduino/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-g++ -c -g -Os -w -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -MMD -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=10706 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM -D__SAM3X8E__ -mthumb -DUSB_VID=0x2a03 -DUSB_PID=0x003e -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due" -IC:\Program Files\Arduino\hardware\arduino\sam\system/libsam -IC:\Program Files\Arduino\hardware\arduino\sam\system/CMSIS/CMSIS/Include/ -IC:\Program Files\Arduino\hardware\arduino\sam\system/CMSIS/Device/ATMEL/ -IC:\Program Files\Arduino\hardware\arduino\sam\cores\arduino -IC:\Program Files\Arduino\hardware\arduino\sam\variants\arduino_due_x -IC:\Program Files\Arduino\hardware\arduino\sam\libraries\Wire -IC:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451 -IC:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_Sensor C:\Users\RE6C6~1.LEE\AppData\Local\Temp\build5849425541666072851.tmp\MMA8451demo.cpp -o C:\Users\RE6C6~1.LEE\AppData\Local\Temp\build5849425541666072851.tmp\MMA8451demo.cpp.o 

Using previously compiled file: C:\Users\RE6C6~1.LEE\AppData\Local\Temp\build5849425541666072851.tmp\Wire\Wire.cpp.o

C:\Program Files\Arduino/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/arm-none-eabi-g++ -c -g -Os -w -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -MMD -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=10706 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM -D__SAM3X8E__ -mthumb -DUSB_VID=0x2a03 -DUSB_PID=0x003e -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due" -IC:\Program Files\Arduino\hardware\arduino\sam\system/libsam -IC:\Program Files\Arduino\hardware\arduino\sam\system/CMSIS/CMSIS/Include/ -IC:\Program Files\Arduino\hardware\arduino\sam\system/CMSIS/Device/ATMEL/ -IC:\Program Files\Arduino\hardware\arduino\sam\cores\arduino -IC:\Program Files\Arduino\hardware\arduino\sam\variants\arduino_due_x -IC:\Program Files\Arduino\hardware\arduino\sam\libraries\Wire -IC:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451 -IC:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_Sensor -IC:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451\utility C:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451\Adafruit_MMA8451.cpp -o C:\Users\RE6C6~1.LEE\AppData\Local\Temp\build5849425541666072851.tmp\Adafruit MMA8451 Library\Adafruit_MMA8451.cpp.o 

C:\Users\R. Lee Hawkins\Documents\Arduino\libraries\Adafruit_MMA8451\Adafruit_MMA8451.cpp:32:8: error: macro names must be identifiers

 #ifdef (_VARIANT_ARDUINO_DUE_X_)

        ^

Error compiling.
And here is the code with the suggested snippet inserted:

Code: Select all

/*********************************************************************
*****/
/*!
    @file     Adafruit_MMA8451.h
    @author   K. Townsend (Adafruit Industries)
    @license  BSD (see license.txt)

    This is a library for the Adafruit MMA8451 Accel breakout board
    ----> https://www.adafruit.com/products/2019

    Adafruit invests time and resources providing this open source
code,
    please support Adafruit and open-source hardware by purchasing
    products from Adafruit!

    @section  HISTORY

    v1.0  - First release
*/
/********************************************************************
******/

#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Wire.h>
#include <Adafruit_MMA8451.h>

#ifdef (_VARIANT_ARDUINO_DUE_X_)
  #define Wire Wire1
#endif

/********************************************************************
******/
/*!
    @brief  Abstract away platform differences in Arduino wire library
*/
/********************************************************************
******/
static inline uint8_t i2cread(void) {
  #if ARDUINO >= 100
  return Wire.read();
  #else
  return Wire.receive();
  #endif
}

static inline void i2cwrite(uint8_t x) {
  #if ARDUINO >= 100
  Wire.write((uint8_t)x);
  #else
  Wire.send(x);
  #endif
}


/********************************************************************
******/
/*!
    @brief  Writes 8-bits to the specified destination register
*/
/********************************************************************
******/
void Adafruit_MMA8451::writeRegister8(uint8_t reg, uint8_t value) {
  Wire.beginTransmission(_i2caddr);
  i2cwrite((uint8_t)reg);
  i2cwrite((uint8_t)(value));
  Wire.endTransmission();
}

/********************************************************************
******/
/*!
    @brief  Reads 8-bits from the specified register
*/
/********************************************************************
******/
uint8_t Adafruit_MMA8451::readRegister8(uint8_t reg) {
    Wire.beginTransmission(_i2caddr);
    i2cwrite(reg);
    Wire.endTransmission(false); // MMA8451 + friends uses repeated start!!

    Wire.requestFrom(_i2caddr, 1);
    if (! Wire.available()) return -1;
    return (i2cread());
}

/********************************************************************
******/
/*!
    @brief  Instantiates a new MMA8451 class in I2C mode
*/
/********************************************************************
******/
Adafruit_MMA8451::Adafruit_MMA8451(int32_t sensorID) {
  _sensorID = sensorID;
}

/********************************************************************
******/
/*!
    @brief  Setups the HW (reads coefficients values, etc.)
*/
/********************************************************************
******/
bool Adafruit_MMA8451::begin(uint8_t i2caddr) {
  Wire.begin();
  _i2caddr = i2caddr;

  /* Check connection */
  uint8_t deviceid = readRegister8(MMA8451_REG_WHOAMI);
  if (deviceid != 0x1A)
  {
    /* No MMA8451 detected ... return false */
    //Serial.println(deviceid, HEX);
    return false;
  }

  writeRegister8(MMA8451_REG_CTRL_REG2, 0x40); // reset

  while (readRegister8(MMA8451_REG_CTRL_REG2) & 0x40);

  // enable 4G range
  writeRegister8(MMA8451_REG_XYZ_DATA_CFG, MMA8451_RANGE_4_G);
  // High res
  writeRegister8(MMA8451_REG_CTRL_REG2, 0x02);
  // Low noise!
  writeRegister8(MMA8451_REG_CTRL_REG4, 0x01);
  // DRDY on INT1
  writeRegister8(MMA8451_REG_CTRL_REG4, 0x01);
  writeRegister8(MMA8451_REG_CTRL_REG5, 0x01);

  // Turn on orientation config
  writeRegister8(MMA8451_REG_PL_CFG, 0x40);

  // Activate!
  writeRegister8(MMA8451_REG_CTRL_REG1, 0x01); // active, max rate

  /*
  for (uint8_t i=0; i<0x30; i++) {
    Serial.print("$");
    Serial.print(i, HEX); Serial.print(" = 0x");
    Serial.println(readRegister8(i), HEX);
  }
  */

  return true;
}


void Adafruit_MMA8451::read(void) {
  // read x y z at once
  Wire.beginTransmission(_i2caddr);
  i2cwrite(MMA8451_REG_OUT_X_MSB);
  Wire.endTransmission(false); // MMA8451 + friends uses repeated start!!

  Wire.requestFrom(_i2caddr, 6);
  x = Wire.read(); x <<= 8; x |= Wire.read(); x >>= 2;
  y = Wire.read(); y <<= 8; y |= Wire.read(); y >>= 2;
  z = Wire.read(); z <<= 8; z |= Wire.read(); z >>= 2;


  uint8_t range = getRange();
  uint16_t divider = 1;
  if (range == MMA8451_RANGE_8_G) divider = 1024;
  if (range == MMA8451_RANGE_4_G) divider = 2048;
  if (range == MMA8451_RANGE_2_G) divider = 4096;

  x_g = (float)x / divider;
  y_g = (float)y / divider;
  z_g = (float)z / divider;

}

/********************************************************************
******/
/*!
    @brief  Read the orientation: 
    Portrait/Landscape + Up/Down/Left/Right + Front/Back
*/
/********************************************************************
******/
uint8_t Adafruit_MMA8451::getOrientation(void) {
  return readRegister8(MMA8451_REG_PL_STATUS) & 0x07;
}

/********************************************************************
******/
/*!
    @brief  Sets the g range for the accelerometer
*/
/********************************************************************
******/
void Adafruit_MMA8451::setRange(mma8451_range_t range)
{
  // lower bits are range
  writeRegister8(MMA8451_REG_CTRL_REG1, 0x00); // deactivate
  writeRegister8(MMA8451_REG_XYZ_DATA_CFG, range & 0x3);
  writeRegister8(MMA8451_REG_CTRL_REG1, 0x01); // active, max rate
}

/********************************************************************
******/
/*!
    @brief  Sets the g range for the accelerometer
*/
/********************************************************************
******/
mma8451_range_t Adafruit_MMA8451::getRange(void)
{
  /* Read the data format register to preserve bits */
  return (mma8451_range_t)(readRegister8(MMA8451_REG_XYZ_DATA_CFG) &
0x03);
}

/********************************************************************
******/
/*!
    @brief  Sets the data rate for the MMA8451 (controls power
consumption)
*/
/********************************************************************
******/
void Adafruit_MMA8451::setDataRate(mma8451_dataRate_t dataRate)
{
  uint8_t ctl1 = readRegister8(MMA8451_REG_CTRL_REG1);
  ctl1 &= ~(0x28); // mask off bits
  ctl1 |= (dataRate << 3);
  writeRegister8(MMA8451_REG_CTRL_REG1, ctl1);
}

/********************************************************************
******/
/*!
    @brief  Sets the data rate for the MMA8451 (controls power
consumption)
*/
/********************************************************************
******/
mma8451_dataRate_t Adafruit_MMA8451::getDataRate(void)
{
  return (mma8451_dataRate_t)((readRegister8(MMA8451_REG_CTRL_REG1)
>> 3)& 0x07);
}

/********************************************************************
******/
/*! 
    @brief  Gets the most recent sensor event
*/
/********************************************************************
******/
bool Adafruit_MMA8451::getEvent(sensors_event_t *event) {
  /* Clear the event */
  memset(event, 0, sizeof(sensors_event_t));

  event->version   = sizeof(sensors_event_t);
  event->sensor_id = _sensorID;
  event->type      = SENSOR_TYPE_ACCELEROMETER;
  event->timestamp = 0;

  read();

  event->acceleration.x = x_g;
  event->acceleration.y = y_g;
  event->acceleration.z = z_g;
  
  return true;
}

/********************************************************************
******/
/*! 
    @brief  Gets the sensor_t data
*/
/********************************************************************
******/
void Adafruit_MMA8451::getSensor(sensor_t *sensor) {
  /* Clear the sensor_t object */
  memset(sensor, 0, sizeof(sensor_t));

  /* Insert the sensor name in the fixed length char array */
  strncpy (sensor->name, "MMA8451", sizeof(sensor->name) - 1);
  sensor->name[sizeof(sensor->name)- 1] = 0;
  sensor->version     = 1;
  sensor->sensor_id   = _sensorID;
  sensor->type        = SENSOR_TYPE_ACCELEROMETER;
  sensor->min_delay   = 0;
  sensor->max_value   = 0;             
  sensor->min_value   = 0;
  sensor->resolution  = 0;             
}
Last edited by adafruit_support_rick on Tue Sep 01, 2015 8:33 am, edited 1 time in total.
Reason: please use Code tags when posting code (</> button)

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Just tried inserting that snippet into a fresh copy of Adafruit_MMA8451.cpp, and I get the exact same error messages on compile...

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

Sorry - my mistake. :(

Remove the parens from around _VARIANT_ARDUINO_DUE_X_

Code: Select all

#ifdef _VARIANT_ARDUINO_DUE_X_
  #define Wire Wire1
#endif

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

Oh - wait! You're using Arduino 1.7.6. That doesn't define that symbol. Change it to _SAM3X8E__:

Code: Select all

#ifdef _SAM3X8E__
  #define Wire Wire1
#endif

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Ok, now the code compiles fine. However, I'm still getting "Couldnt start".

Here's how things are connected:

10k resistors from 3.3V on the Due to SDA1 and SCL1 on the Due
3.3V on the Due to VIn on the MMA8451
SDA on the MMA8451 to SDA1 on the Due
SCL on the MMA8451 to SCL1 on the Due
GND on the Due to GND on the MMA8451

Running Arduino 1.7.6, and communicating through the Programming USB port

Any further ideas?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

Try it with Arduino 1.6.5. 1.7.6 is from Arduino srl, which has splintered off from Arduino.
https://www.arduino.cc/en/Main/Software

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Nope, no joy with this scenario either. I first tried going back to 1.6.5 on SCL1 & SDA1 with the 10k pullups. Before compiling, I changed the additional lines back to:

#ifdef _VARIANT_ARDUINO_DUE_X_
#define Wire Wire1
#endif

Still get "Couldnt start"

I then commented those lines out, removed the pullups, recompiled, and moved to SDA & SCL on the Due. Also no joy.

Just checked again. Still working fine on my Uno.

I've got to believe this is some deeper problem with the library for the MM8451.

Has anyone actually run this breakout with a Due?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: Problem with MMA8451 And Arduino Due

Post by adafruit_support_rick »

The MMA8451 library works with calls to the Wire library, which is part of the Arduino distribution. The problem is going to be with the Due itself, or with the Arduino Wire library. As I mentioned before, I2C is flaky on the Due.

I don't have an MMA8451, so I haven't tried it. I can get one. It will take a few days.

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

I have other boards, notably a Freetronics barometer breakout, that work fine on the Due SCL/SDA..

User avatar
hawkinsrl
 
Posts: 10
Joined: Thu Aug 27, 2015 3:41 pm

Re: Problem with MMA8451 And Arduino Due

Post by hawkinsrl »

Just tried this with my backup MMA8451, and I get the same symptoms as with the original breakout. Since other boards work fine with the Due, it seems to me that this has to either be a problem with the design of the MMA8451 breakout or with its library.

User avatar
adafruit2
 
Posts: 22187
Joined: Fri Mar 11, 2005 7:36 pm

Re: Problem with MMA8451 And Arduino Due

Post by adafruit2 »

Yep the library just hasnt been tested with Due, which is a completely different chipset than the UNO. could be something different about the way it does i2c that makes it not work with that sensor.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”