Hi everyone, I'm currently working on a project with an accelerometer, and the "task" that I have is detecting when the sensor is moving up or down. I'm using IMU6050 and I'm reading Z axis values for the movement. My problem now is that I need to detect when is the sensor moving up, and when is it moving down. It doesn't have to be super accurate but the way I did it now is with "if" statements. When I detect a threshold I react on it, but the thought of writing bunch of "if" statements is killing me. Another problem with accelerometer is, for example, when you move the sensor up, it's having positive values, but when you stop the movement the values go into negative direction. So my question is, would any of you know a way of detecting when is the value rising and when is it falling, with eliminating the after values after movement in the opposite direction.
Karlo69:
but the thought of writing bunch of "if" statements is killing me.
Don't really see how that's going to be more then two if's... Especially without code. One for up, one for down.
Karlo69:
Another problem with accelerometer is, for example, when you move the sensor up, it's having positive values, but when you stop the movement the values go into negative direction.
I would not really expect that but might be a bit of overshoot. Is it a short burst? Not familiar with the IMU6050. Otherwise you can (high pass) filter the signal. Or implement a time threshold.
As you can see on this picture, I have made Z axis, represent the values in the graph. Maybe this will help with what I'm trying to do and explain?
Ahh, yeah.
Think I would simply use two thresholds and a small time threshold. And only react to passing a threshold if the signal was a minimal time 0 (aka, between the thresholds) before calling it up of down.
Maybe this will help with what I'm trying to do and explain?
Not really. The data from the Z axis of the accelerometer would plot as a line, not as two shaded regions.
The points you have labeled moving up and moving down are where the motion changes from moving up to moving down, and where the motion changes from moving down to moving up.
The sign of the value tells you whether the motion is up or down. Detecting the time when the sign changes value is something else.
What ARE you really trying to determine?
Well, in the picture you can see "moving up", it means motion has started from the strait line and made a rise to the top, when it has reached the top value, the motion has been stopped and so the accelerometer is still in motion inside the sensor, which crates the negative so to speak rise.
The short answer is that you can't decide if you are moving up or down using acceleration sign (positive = moving up, negative = moving down).
That's because acceleration is the variation in velocity, so, for example, if you are moving in the up direction with a velocity v0 and you slow down to a velocity v1 < v0, with v1 > 0, you will measure a negative acceleration, but you will continue to move in the up direction.
What you need is the movement's velocity in the up or down direction: if velocity is positive in the up direction you are moving up, if is negative you are moving down.
Because the acceleration is the derivative of velocity, you can obtain the velocity by integrating the acceleration values.
Here is a more detailed explanation with some math included:
http://www.chrobotics.com/library/accel-position-velocity
In a simplified case, where the accelerometer Z axis is exactly aligned with the up direction and you measure the acceleration every T seconds, you can use the equation
v(i+1) = v(i) + (a(i) - g) * T
where
v(i+1) is the velocity calculated at the iteration i+1;
v(i) is the velocity calculated at the iteration i
a(i) is the acceleration measured at the iteration i
g is the gravity acceleration
T is the time interval between consecutive acceleration measures
Note that this method will be not very precise, see the link for some error values.
Angular positions using accelerometers:
//Roll & Pitch Equations from accelerometers only
// float roll2 = (atan2(-_ay, _az)*180.0)/M_PI;
// float pitch2 = (atan2(_ax, sqrt(_ay*_ay + _az*_az))*180.0)/M_PI;
next, after finding those angles are noisy you'll look into using a some type of filter. So you might look for " complementary low pass filter Arduino" using those words in your favorite search engine. Filtering beyond a complementary filter would be a bit intensive for a UNO.
Here is a link to some great code info: onehorse | Mbed