Reliability Test: Uno R3 + Grove Accelerometer MMA7660FC (±1.5g)+ Grove Chainable RGB LED

Written by  on April 28, 2014 

* A log of reliability tests and subsequent findings when working with the Uno R3, Grove Accelerometer MMA7660FC and Grove Chainable RGB LED *

Setup:
Arduino IDE 1.5.6-r2
Arduino Uno r3
Grove base shield 1.3
Grove Accelerometer MMA7660FC (±1.5g) on I2C
3 x Grove Chainable RGB LED on digital pins 2,3

Attached but not used:
Arduino Wifi shield updated with the firmware that comes with Arduino IDE 1.5.6-r2

Test A: MMA7660FC reporting over serial while the LEDs scroll through colours.

– Results 1
Briefly froze on loading serial monitor
Then ran for a little while
Then froze again. Going to put a count in it.

– Results 2
With runcount, let it run for a little while before I invoked the serial monitor
Froze after about 30 sec. Opening serial monitor made it reset. –
Moving the acc around generally worked but occasionally made it print garbage. Till eventually it froze.
Reckon maybe the acc library is bad and its freezing because it gives it garbage.
Give it one more go.

– Results 3
Shook the acc around for ages, put garbage in the serial occasionally but didn’t freeze,
Then randomly froze at runcount 773

– Result 4
Just left it alone, froze at runcount 13

– Result 5
Left it alone. Froze at 936. No garbage in serial monitor

!! Change: Higher baud on serial, 19200

– Result 6
Left it alone, ran till 809. No garbage in serial monitor

!! Change: Tried changing sample rate to 32 times a second on MAA (not documented well in grove stuff, hints found here http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA7660FC)
note that 20 times a second is equiv to us pulling the data every 50ms.

!! Learning the hard way: looking in the .cpp file the MMA init function sets the mode to stand by, sets the sample rate to ‘AUTO SLEEP 32’ and then sets the mode to active. Looking in the .h file auto_sleep_32 is a sample rate, with auto sleep obviously. What are the other modes? Confusing because it looks like the call takes an unsigned integer, not AUTO_SLEEP_32 which is a register reference.
Ok, no way to turn off auto sleep. The only alternative is auto wake.
Ok, looks like the unsigned integer is the hex address reference that AUTO_SLEEP_32 refers to. You can’t just pass it any integer to be the sample rate.
Ok, so that means it’s already sampling at 32 times a second. Left it alone.

– Result 7
Moved the acc, froze almost straight away, runcount 60

– Result 8
Froze at 27. If anything this is more unstable than before.

!! Change: Tried changing sample rate to AUTO_SLEEP_16

– Result 9
Moved it around, froze at 597. Some garbage in the monitor

– Result 10
Left it alone, froze at 259

—- Conclusion
Have had RGB running overnight before, so prob not that code. Almost def MMA code. OR interaction between MMA and RGB code.

Final Sketch:

 /*
Reliability test, Grove Chainable RGB LEDs in a colour scroll plus Grove Accelerometer +-1.5 MMA7660FC reporting over serial.
Requires the Grove libraries for chainable LED and MMA7660 which you can find in their wiki.
*/

//Acc include and create
#include <Wire.h>
#include "MMA7660.h"
MMA7660 accelemeter;

//RGB include and create
#include <ChainableLED.h>
#define NUM_LEDS  3
ChainableLED leds(2, 3, NUM_LEDS);
byte pos = 0;
long runcount = 0;

void setup()
{
  //Acc setup
	accelemeter.init();  
  //Serial setup 
	Serial.begin(19200);
}

void loop()
{
  runcount = runcount++; 

  //acc business
	int8_t x;
	int8_t y;
	int8_t z;
	float ax,ay,az;
	accelemeter.getXYZ(&x,&y,&z);
	
	Serial.print("x = ");
    Serial.println(x); 
    Serial.print("y = ");
    Serial.println(y);   
    Serial.print("z = ");
    Serial.println(z);
	
	accelemeter.getAcceleration(&ax,&ay,&az);
    Serial.println("accleration of X/Y/Z: ");
	Serial.print(ax);
	Serial.println(" g");
	Serial.print(ay);
	Serial.println(" g");
	Serial.print(az);
	Serial.println(" g");
	Serial.println("*************");

Serial.print("runcount =");
Serial.println(runcount);
	
//rgb business

for (byte i=0; i<NUM_LEDS; i++)
  {
    if (i==pos)
      leds.setColorRGB(i, 255, 0, 0);  
    else
      leds.setColorRGB(i, 0, 0, 255); 
  }
  
   pos = (pos+1) % NUM_LEDS;
  
  delay(50);
  
 


}

Test B: Take the MMA example code from Grove (https://github.com/Seeed-Studio/DigitalAccelerometer_MMA7660FC) , upgrade it to be fast (delay 32) and give me a runcount. NO led code although LEDS and wifi shield still attached physically. (Note left MMA with default sample rate of init AUTO_SLEEP_32)

– Result 1
Moving acc around, no garbage, made it to runcount 400.

– Result 2
Left it alone, froze at runcount 150

!! Change – detatched LEDs physically so they draw no power

– Result 3
Moving it around, froze at runcount 180

!! Change – slowed delay to 50

– Result 4
Moving it around, froze at runcount 70

– Result 5
Left it alone, froze at runcount 188

!! Change – tried a brand new UNO (uB), different USB port.

– Result 6
Left it alone, froze at runcount 206

– Result 7
Left it alone, froze at runcount 77

– Result 8
Left it alone, froze at runcount 183

!! Change – tried slowing it back to original demo delay speed, 500

– Result 9
Left it alone, froze at runcount 393

—- Conclusion
Either:
The Grove MAA7660FC hardware is unreliable
The Grove MMA7660FC software is unreliable (latest one on github at 29.4.14)
The Grove MMA7660FC I have is bad. No second unit to test.

NOTE TO SELF: Do reliability tests with a devices own example code before writing your own.

What now:
I’m going to swap out the MMA7660FC and test the other grove accelormeter I have at hand, the ADXL345 +-16g
See the results here.

Final Sketch:

/*
Reliability test of Grove MMA7660FC with fast sampling and runcount.
Required Grove MMA7660FC library
*/ 

#include <Wire.h>
#include "MMA7660.h"
MMA7660 accelemeter;
long runcount = 0; 

void setup()
{
	accelemeter.init();  
	Serial.begin(9600);
}
void loop()
{
        runcount = runcount ++; 
        
	int8_t x;
	int8_t y;
	int8_t z;
	float ax,ay,az;
	accelemeter.getXYZ(&x,&y,&z);
	
	Serial.print("x = ");
    Serial.println(x); 
    Serial.print("y = ");
    Serial.println(y);   
    Serial.print("z = ");
    Serial.println(z);
	
	accelemeter.getAcceleration(&ax,&ay,&az);
    Serial.println("accleration of X/Y/Z: ");
	Serial.print(ax);
	Serial.println(" g");
	Serial.print(ay);
	Serial.println(" g");
	Serial.print(az);
	Serial.println(" g");
	Serial.println("*************");

        Serial.print("Runcount = ");
	Serial.println(runcount);



	delay(50);
}