How to detect a persons fall with accelerometer?

Hi,

I am currently working on a school project which is about fall detection. I would like to use the spark internet button shield since it has an accelerometer on it. However, the standard range of it is set to 2G. After some search in the library I found
setRange(XL362_FILTER_FLAG_8G);. 8G should do just fine. But I can’t seem to set it properly. Because at 2G I get a max value of 128 by shaking it, and I also get 128 max in 8G modus by shaking it.

I am currently using this code


// This #include statement was automatically added by the Spark IDE.
#include "SparkButton/SparkButton.h"

/* Did you know that the SparkButton can detect if it's moving? It's true! 
Specifically it can read when it's being accelerated. Recall that gravity 
is a constant acceleration and this becomes very useful- you know the orientation!*/ 
    

SparkButton b = SparkButton();
ADXL362 c = ADXL362();
int xmax = 0;
int ymax = 0;
int zmax = 0;

void setup() {
    // Tell b to get everything ready to go
    b.begin();
    RGB.control(true);
    RGB.color(0,0,0);
    Serial.begin(9600);
    c.setRange(XL362_FILTER_FLAG_8G);

}

void loop(){
    
        //How much are you moving in the x direction? (look at the white text on the board)
    int xValue = b.readX();
    
    //How about in the y direction?
    int yValue = b.readY();
    
    //And the z!
    int zValue = b.readZ();
    
    if (abs(xValue) > xmax) { xmax =abs(xValue);}
    if (abs(yValue) > ymax) { ymax =abs(yValue);}
    if (abs(zValue) > zmax) { zmax =abs(zValue);}
    
    Serial.print("X: ");
    Serial.print(xmax);
    Serial.print(" Y: ");
    Serial.print(ymax);
    Serial.print(" Z: ");
    Serial.println(zmax);
    
    
}

How should I declare the 8G range? :smile:

2 Likes

@TheHawk1337, I guess you`ve set (or it’s default in the library) the output resolution to 8bit which only gives you a range -128 to +127 for the whole range - 12bit would be the sensors native resolution.
So when you’ve set it to measure -2g to +2g the -128 stands for -2g and the +127 for +2g and in the same manner -8g to +8g has to mapped into the same output range of 8bit.

And it’s also not too surprising that you get max. readings when you shake the sensor violently enough.
The acceleration when changing direction on either end of your movement will quite easily exceed 8g.

For instance a professional shot-put athlete exceeds 10g when pushing the ball or
some HDDs have built-in shock protection that triggers well above 40g - some even beyond 100g.
If you do the physics calculations you’ll see that an impact on a hard surface will create decelleration forces well beyond that range, too.

Have look here:
http://en.wikipedia.org/wiki/Orders_of_magnitude_(acceleration)

2 Likes

Hi,

That makes sense, I obviously need a way to reliably test the G forces. Thanks! :smile:

I think you have to assess your expected “normal” measures and set a detection threshold according to them correctly, before you can make any further decissions.

Can you give some more detail what kind of fall you want do detect and for what purpose these detected events will serve?

Well the assignment is to detect if an elderly person fell. If so, there needs to be an alarm to warn anybody in the surroundings. I figured that the spark core could also be used to publish something on a webpage which then uses IFTTT to send a notification to an android device for instance. But the main goal is to detect a person’s fall and if possible how it fell exactly (face first, on his/her side, etc).
This is just project based so it doesn’t have to be ultra fancy integrated stuff, just some proof of concept is enough.

I see.

But in this case you might not actually want to look for an one-of acceleration event but rather some unexpected changes in orientation of the persons upper body.
You’d have to look for a place on the persons body that keeps fairly stable in orientation and monitor its change of orientation over some periode of time, to average out normal movement and then look out for events when the change of orientation (vertical change weighted higher than horizontal) leaves the “comfort zone”.

Edit: I’ve been so cheeky to change your topic to better reflect the “new” purpose.

5 Likes

That is a good idea, I discussed it with my group mates and they seem to like that idea too. :smile:
We will start working things out now, sadly we have to do a lot of paperwork during these projects too so that takes most of the time. Thanks for the help :smile: I will report back when I have some basic things working

1 Like

This paper breaks down a fall into discrete events that could be a state machine: weightlessness/impact/aftermath/ etc.
Probably way more info than you need but an interesting read.
Analog Devices paper

2 Likes

It’s not just the absolute magnitude of the acceleration that matters but its duration. As you have discovered and others have pointed out, the vulnerable person just banging the fall detection device on the hard arm of a chair would be enough to exceed many G, momentarily. If the device is worn on the belt then there will only be a 1.1 metre displacement to detect and a G-meter doesn’t detect displacement but acceleration. It’s the combination of (lack of) acceleration over some time that constiitutes a fall. You need the G-meter to read zero or low values (free fall in the earth’s gravity) for enough time for s=g/(2t^2) to give you s = 1metre or whatever distance a fall is deemed to be. g being acceleration due to gravity. Solving for t you need t >= 0.5 secs for a displacement of 1.1 metre. The orientation of the person cannot be assumed so you need to sum the x y and z accel thus: a = sqrt(x^2+y^2+z^2)

In summary you are looking for low absolute values from your G-meter over a period of half a second - that is what constitutes a fall.

6 Likes

@bobh that indeed is very interesting, very usefull! Thanks! :smile:

@psb777

I indeed came to a conclusion similar to your suggestion as well after prototyping a bit today.
I currently do it as following:

I put the measurements if the x,y and z into 3 different arrays (each axis his own array). The arrays contain 128 values. when it’s full I calculate the average of those arrays and put those averages into the ‘averages array’ which contains 64 averages. Then the total average of the measurements is the average of the ‘averages array’. This makes smooth data come out whilst the standard readX(); can still be used to detect highs and lows for further calculation.

After detecting a high value, which is a value of 50(random value, needs testing) higher than the average of the axis it is measured on, the detection sequence starts. For a period of 5 seconds all axis are compared to the average of them. If the values are suddenly lower (the person is in a completely different position -> fell) and they differ more from the average than a threshold, the alarm activates.

It works reasonably well for something made in a couple of hours but indeed, measurements could be much better if the freefalling method is applied, which is the next thing I will do. Thanks @psb777 :smile:

Small question though, you state that the orientation can be calculated by using the sum of x,y and z. But this gives me only the length of the total vector, not the direction. Or am I missing your point? :dizzy_face:

Perhaps an argument can be made for adding direction, but I am not sure it is worth the effort.

OK, it’s interesting to be able to generate a text message to the emergency services which says “Jo Brown fell backwards and, of all the fallen people in the area, she is the one lying on her right side” but I think really you just want to detect the fall.

Cartesian components (i.e. x, y & z) are just one way of describing the direction and magnitude of the acceleration, but we know the direction of a fall, it is down, and we detect it by the absence of acceleration (due to gravity). I.e. all three readings, x, y & z, must be small because the value in any direction must be small.

I am suggesting we need not know the orientation of the sensor.

The magnitude of the acceleration is sqrt(x^2 + y^2 + z^2). Pseudo code to detect a 500ms fall:

# fall detected if over moving average of acceleration
# during any 500ms (50 loops of 10ms)
# is less than 1/10th what you would expect
const float fall_threshold = 1.0 # if sensor retums m/s^2
#const float fall_threshold = 0.1 # if sensor returns g
float free_fall = 1000.0 # this will decay down
while free_fall > fall_threshold
  sleep_milliseconds(10)
  (x,y,z) = read_accelerometer()
  free_fall = (free_fall * 49.0 + sqrt(x^2+y^2+z^2)) / 50.0
end-while
SoundAlarm();

Actually that is lazy. I have coded an exponential moving average. Best to store the 50 values in an array, discarding the oldest, each time.

1 Like

Sorry for the late reply, I was quite busy the last few days :smile:

I will test your code, thanks a lot! :smile:

@TheHawk1337 Any word on how this turned out? Seems like a cool project with lots of potential.

1 Like

Yes ofcourse,

During the last week we used the example @psb777 explained above. We implemented it and it was working standalone, not attached to the human body. So if we would just drop the spark core it would detect it.

Today we went to a gym and did tests with the device strapped to our body. We found out that placing it on an arm is a bad idea since reflexes makes you move and because of that the accelero sensor isn’t really seeing a freefall. So there has to be some analyzing of the movement that if there suddenly is a lot of movement and the person is suddenly in a different position, the person fell. But that needs further investigation. But so far we are really happy with the results ! :smile:

Good to see that it’s working so far. Have you considered hanging it around your neck on some sort of lanyard? This way, those people could also use it to issue some instructions using the pushbuttons. Also, your torso wont flex as much as your arms would during a falling reflex. Even if it moves a bit, the general direction would still be downwards, unlike your arms, which you can move upward, effectively zeroing out the drop.

Yes, we are currently experimenting with different positions on the body. During the tests yesterday we also had another sensor, called a Shimmer sensor. They basicly are recording accelerometers. We used 3 on different places of our body. We can use the recorded data in matlab to test our code so we wont have to keep falling to test it :smile:

1 Like

Great project! I look forward to hearing more about your progress.

I think part of the problem is that you’re not normally going to see a true “freefall” when a person is falling down (unless perhaps they faint, and their knees just collapse). The person is probably falling in an arc (imagine the sensor on top of a tree that’s chopped down, moving in a circular arc towards the ground). Also, they are probably doing what they can to fight against the fall, grabbing nearby furniture or whatnot for support, sticking an arm out to cushion their fall as they hit the ground, twisting to a position to minimize injury, etc.

I would think having the sensor on the hip/waist might help reduce those motion factors a little, but it’s still a complex thing to understand with only a few variables to go on, like acceleration and gyroscopic orientation.

Recording real-world data of various types of falls and analyzing them for patterns seems like a great thing to do. You can watch for rate-of-change in the 3 axes individually, in combination with each other, and in individual and combined magnitudes, and maybe spot some common cases.

Good luck!

For those wondering about the status of this project :

This was a school project, the time for it was 8 weeks in which you mostly research and build a prototype. It is not mandatory to end up with a working product but if you don’t, you need to have solid arguments why not.

So after 8 weeks we kindof finished the research, we rented a gym and did a total of 400 falls to have some data to use and calibrate with. We did end up with code that could detect a fall, but the amount of false positives was way too high to call it functional. So we ran out of time to implement more factors to more accurately detect a fall.
The teachers were pleased with the results and we all passed the ‘course’. This was by far the most detailed and difficult project the teachers had seen in a while so they were excited during the presentation haha. To put this project into perspective, 1 group made an ‘amplifier’ that managed to drop 350 volts to 220 with a linear regulator, they had no idea why their pcb was turning black :wink:

Thanks for all the help guys! :slight_smile:

PS: I can share some project documents if you are interested in them

4 Likes

Very impressive project. I would definitely be interested in anything you would be willing to share.

1 Like

I will edit this post with the links in a bit :slight_smile:

@techbutler @peekay123

Here are the relevant project documents. https://www.dropbox.com/s/0czk16ruzmvpe9v/spark%20core%20fall%20detection.zip?dl=0

Please keep in mind that it’s not finished, some things have to be still implemented. I can help with some things ofcourse :smile:

3 Likes