Go Down

Topic: Accelerometer counting lifts ($10 REWARD) (Read 484 times) previous topic - next topic

sagepath

I'm trying to grasp the way an accelerometer needs to be programed in order to count how many times an object has been lifted. For example in the gym it would be useful to count how many times a bench press bar has been lifted (reps the user does). 

I know that Math is involved to calculate this but I have very limited knowledge on that unfortunately. I have followed a tutorial on making a pedometer but that did not bring me closer to solving my problem. I did learn that this equation was key to count the steps:

totvect = sqrt(((xaccl-xavg)* (xaccl-xavg))+ ((yaccl - yavg)*(yaccl - yavg)) + ((zval - zavg)*(zval - zavg)));


I think I need an equation that counts upward movement then downward.

Pedometer tutorial I followed link:
http://www.instructables.com/id/Simple-Easy-and-Cheap-DIY-Pedometer-with-Arduino/


I own these accelerometers: GY-521 MPU-6050, GY-61 ADXL335.

A direction for me to head towards would be appreciated. Please dumb down the info for me as much as possible.

I'm willing to pay $10 via PayPal if someone has made a program like this and it works. 


mugambi

What is your hardware set up like? where do you want your data displayed? the instructables example uses LED's

PaulMurrayCbr

#2
Sep 04, 2017, 07:41 am Last Edit: Sep 04, 2017, 07:42 am by PaulMurrayCbr
Will the object maintain one orientation? If so, you only need the value of the vertically oriented accelerometer. If not, then you need to take the vector length as per your math. Will it be lifted evenly by a machine, or will it be all over the shop (lifted by a human)?

When an object is being lifted, at the start of the lift the total acceleration in the object is somewhat greater than g. At the end of the lift, the acceleration is less than g - you can experience this in an elevator. If you want to to work that way, then you don't want to be subtracting the average acceleration from the sensed acceleration. If you subtract the average acceleration, you will be able to sense the top and the bottom of the lift, but you won't know which is which (because mathematically, a start and a stop are both simply accelerations).

The difficulty is that at the start of a drop, the total is less than g and at the end of a drop the total is greater than g. So to sense a lift, you need to sense a >g followed by a <g. Furthermore, if the object is being lifted unevenly you can get spurious events.

You could try using acelleration to plot an absolute position … but the data will be noisy and inaccurate and it's really not going to work.

I would approach this by logging the data from the acellerometers during a series of lifts, dumping the data into excel, and seeing if I can formulate some sort of rule in excel that correctly senses a lift. Then I'd translate that rule into a sketch.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

sagepath

Thank you this was very helpful. Now I will try to figure out the rule that detects a lift. I predict an issue will be random accelerometer noise that I need to filter out from the rule somehow.

PaulMurrayCbr

#4
Sep 05, 2017, 10:23 am Last Edit: Sep 05, 2017, 10:24 am by PaulMurrayCbr
predict an issue will be random accelerometer noise that I need to filter out from the rule somehow.
The main method I use for filterng out noise is this:

Code: [Select]

double filteredData;

loop() {
  if it's time to take another sample {
    newSample = read_some_data();
    filteredData = .75 * filteredData + .25 * newSample;
  }
}


This implememnts a software low-pass filter. As the sample changes, "filteredData" slowly follows along after it - the speed at which it does so is determined by those floating-point numbers. It's important to use millis() or micros() to sample the data at a predictable, known rate. Note also that I use a float for the filtered reading, as it is a statistical artifact and not an actual digital reading.

This example is one of the simplest type of recursive filters. Much more compicated things are possible. In particular, it's possible to devise digital filters that reject particular frequencies, This can be handy if your setup tends to oscillate at certain frequencies that you want to ignore. However, there's rather a lot of math involved, and I personally wouldn't know how to write such a thing.

The low-pass filter works very well. One trick I sometimes use is to have a low-pass filter with a short response time and one with a long response time, and to compare the two. This have detect jerks and jumps, which might be ideal for your application.

Code: [Select]

double slowFilter;
double fastFilter;

loop() {
  if it's time to take another sample {
    newSample = read_some_data();
    slowFilter = .99 * slowFilter + .01 * newSample;
    fastFilter = .75 * fastFilter + .25 * newSample;

    double jerk = fastFilter - slowfilter;
  }
}



You may also want to look at 'PID' control theory.
http://paulmurraycbr.github.io/ArduinoTheOOWay.html

MarkT

When its being lifted its moving.  When its put down its stationary.  So you need to spot the
transitions between stationary <-> moving, which ought to simply be a matter of thresholding a
low-pass filtered version of the velocity vector magnitude.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

PaulS

Quote
So you need to spot the
transitions between stationary <-> moving
However, the number of times the thing is moved up and down while it is moving is what OP want to count, not that the thing was picked up and then put down.
The art of getting good answers lies in asking good questions.

sagepath

Thanks for the help everyone. The filtering method is greatly appreciated. This is my plan on detecting the correct pattern (a lift): I will count a certain number of downward points until a upward point is detected so count those upward points to.

For example if 10 downward points and 10 upwards points are found then that is a lift (will fiddle with the numbers).  Just have to smooth out the data using the filtering method first. At the moment the data is to erratic.

Go Up