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.
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.
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?
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.
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.
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");
}
There are a number of potential problems with your approach.
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.
Don't use pow() to compute squares. Do the following instead for all three variables.
Xsquare = float(accel.cx)*float(accel.cx);
Is is pointless to select the +/- 4 g sensitivity range when you are trying to measure small accelerations. Change this to +/- 2 g.
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.