Sensing change of direction of repeating movement (MMA8452Q sensor)

Hello everybody,

I am quite new to the world of arduino and for a project, I would like to sense (and afterwards play a beeping sound) when an object changes its direction during a repeating cycle (the cycle varies a little every time). A local electronics shop advised me to use an accelerometer (type Velleman Accelerometer).

I can indeed read out acceleration values, but I don't seem to be able to "detect" the moment when the sensor movement changes to the opposite direction.

The movements are (simplified):

  • 1 cm left-right movement
  • 1-2 cm back-front movement
  • 1-3 cm up-down movement

Anyone got some advise for this problem?

Thanks in advance!

Are you comparing the last value(S) read by the accelerometer to the newest reading to look for a change ala the state change detection method? That is for a button but the idea is the same.

Post your code and we can better help. Read the how to use this forum-please read sticky to see how to post code.

I would like to sense (and afterwards play a beeping sound) when an object changes its direction during a repeating cycle (the cycle varies a little every time). A local electronics shop advised me to use an accelerometer

Does that mean the object moving is carrying the Arduino?

I can indeed read out acceleration values, but I don't seem to be able to "detect" the moment when the sensor movement changes to the opposite direction.

You should see small spikes at the moment of the direction change.

The movements are (simplified):

1 cm left-right movement
1-2 cm back-front movement
1-3 cm up-down movement

The centimeters are not that relevant, but how fast is the object moving? Is the direction change abrupt?

Can you tell us what kind of object we're talking about?

Please describe what causes the object to move, and how it does that.

An accelerometer cannot detect, for example, when a ball thrown upwards begins its descent. The acceleration due to gravity is constant.

pylon:
Does that mean the object moving is carrying the Arduino?

You should see small spikes at the moment of the direction change.

The centimeters are not that relevant, but how fast is the object moving? Is the direction change abrupt?

Can you tell us what kind of object we're talking about?

The object is the human jaw. For example: I want to be able to detect when the jaw starts opening/closing, or when the jaw is moving from left to right when doing that specific motion.

That may be possible. Hook up an accelerometer to someone's jaw (presumably you will ask permission) and see what you get.

jremington:
Please describe what causes the object to move, and how it does that.

An accelerometer cannot detect, for example, when a ball thrown upwards begins its descent. The acceleration due to gravity is constant.

A jaw when performing e.g. only closing/opening of the mouth.

groundFungus:
Are you comparing the last value(S) read by the accelerometer to the newest reading to look for a change ala the state change detection method? That is for a button but the idea is the same.

Post your code and we can better help. Read the how to use this forum-please read sticky to see how to post code.

This my code. It is based on the starting example of the sensor and it doesn't contain code yet for automatic "peek" detection because the acceleration differences during direction change seem very little...

/******************************************************************************
MMA8452Q_Basic.ino
SFE_MMA8452Q Library Basic Example Sketch
https://github.com/sparkfun/MMA8452_Accelerometer

This sketch uses the SFE_MMA8452Q library to initialize the
accelerometer, and stream values from it.

Hardware hookup:
  Arduino --------------- MMA8452Q Breakout
    3.3V  ---------------     3.3V
    GND   ---------------     GND
  SDA (A4) --\/330 Ohm\/--    SDA
  SCL (A5) --\/330 Ohm\/--    SCL

The MMA8452Q is a 3.3V max sensor, so you'll need to do some 
level-shifting between the Arduino and the breakout. Series
resistors on the SDA and SCL lines should do the trick.

Development environment specifics:
  IDE: Arduino 1.0.5
  Hardware Platform: Arduino Uno
******************************************************************************/

#include <Wire.h> // Must include Wire library for I2C
#include <SFE_MMA8452Q.h> // Includes the SFE_MMA8452Q library

MMA8452Q accel;

void setup()
{
  Serial.begin(9600);
  Serial.println("MMA8452Q Test!");
  

  //     Initialize with FULL-SCALE and DATA RATE setting. Control how fast the accelerometer produces
  //     data by using one of the following options in the second param:
  //     ODR_800, ODR_400, ODR_200, ODR_100, ODR_50, ODR_12,
  //     ODR_6, or ODR_1. 
  //     Sets to 800, 400, 200, 100, 50, 12.5, 6.25, or 1.56 Hz. See http://www.jneurosci.org/content/19/20/9073 for G-forces during speech
  accel.init(SCALE_4G, ODR_12);
}

void loop()
{
  if (accel.available())
  {
    accel.read();
    printCalculatedAccels();    
    Serial.println(); // Print new line every time.
  }
}

void printCalculatedAccels()
{ 
  Serial.print(accel.cx, 3);
  Serial.print("\t");
  Serial.print(accel.cy, 3);
  Serial.print("\t");
  Serial.print(accel.cz, 3);
  Serial.print("\t");
  
  float Xsquare = 0, Ysquare = 0, Zsquare = 0, XYZsum = 0, RootXYZ = 0;
  Xsquare = pow(accel.cx, 2);
  Ysquare = pow(accel.cy, 2);
  Zsquare = pow(accel.cz, 2);
  XYZsum = Xsquare + Ysquare + Zsquare;
  RootXYZ = sqrt(XYZsum);
  Serial.print(RootXYZ, 3);
  Serial.print("\t");
}

Please post some of the results you get.

There are a number of potential problems with your approach.

  1. you are printing way too much and way too slowly, so your sample rate is very low. You don't need to print out the individual X,Y,Z accelerations, and you should change the serial Baud rate to something much higher, like 115200.

  2. Don't use pow() to compute squares. Do the following instead for all three variables.

  Xsquare = float(accel.cx)*float(accel.cx);
  1. Is is pointless to select the +/- 4 g sensitivity range when you are trying to measure small accelerations. Change this to +/- 2 g.

  2. The comment below suggests that you are using series resistors rather than a level shifter for 5V/3.3V I2C communications. While that may work, it is an extremely bad idea. It is hard to believe that Sparkfun employees were so unprofessional as to recommend it. Use one of these or similar.

  SDA (A4) --\/330 Ohm\/--    SDA
  SCL (A5) --\/330 Ohm\/--    SCL


The MMA8452Q is a 3.3V max sensor, so you'll need to do some
level-shifting between the Arduino and the breakout. Series
resistors on the SDA and SCL lines should do the trick.