Programming ADXL335 Accelerometer to Track Falls

I'm using an ADXL335 Accelerometer as a sensor on a fall tracker I'm building. I'm having a little trouble programming it to be able to recognize a fall accurately. I'm currently calculating the magnitudes of the vectors the sensor is tracking but it doesn't seem like a good way to track a fall. Any advice on building a better accelerometer? I'm using an nRF24L01+ radio to communicate with a receiver wirelessly as well. My code is as following and thank you for any help:

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

RF24 radio(8,9);               
RF24Network network(radio);    

  byte ID=2;
 double val1=0;
 double val2=0;
 double val3=0;
 double sum=0;
    
const uint16_t home_node = 00;   
const uint16_t accel_node = 02; 

const long interval = 1333; 
unsigned long previousMillis = 0;

struct payload_t {            
byte ID;
  double val1;
  double val2;
  double val3;
};



void setup(void)
{
  Serial.begin(115200);      // sets the serial port to 9600
  //Serial.println("A C C E L E R O M E T E R");
   SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 92, /*node address*/ accel_node);

}

void loop()
{
   network.update();                          // Check the network regularly
  unsigned long currentMillis = millis();              // If it's time to send a message, send it!
  if ( currentMillis - previousMillis >= interval  )
  {
    previousMillis = currentMillis;
 



  val1 = analogRead(0);       // read analog input pin 0
  val2 = analogRead(1);       // read analog input pin 1
  val3 = analogRead(2);       // read analog input pin 2
  //Serial.print("accelerations are x, y, z: ");
  //Serial.print(val1);    // print the acceleration in the X axis
  //Serial.print(" ");       // prints a space between the numbers
  //Serial.print(val2);    // print the acceleration in the Y axis
  //Serial.print(" ");       // prints a space between the numbers
  //Serial.println(val3);  // print the acceleration in the Z axis
  double rootSumSquared = sqrt(val1*val1 + val2*val2 + val3*val3);
  double rootSum= sqrt(rootSumSquared);
  Serial.println(rootSum);
  sum = rootSum;
 
  
     if (val1>31)
     {   
    payload_t payload = {ID,sum};                           
    RF24NetworkHeader header(/*to node*/ home_node);
    bool ok = network.write(header,&payload,sizeof(payload));
    if (ok)
      Serial.println("ok.");
    else
      Serial.println("failed.");
      }
     
  }
}
1 Like

Free fall is detected by the absence of acceleration, i.e. the measured magnitude of the acceleration vector close to zero.

This is because the accelerometer measures the acceleration due to Earth's gravity in addition to those caused by other forces.

There is also an error in your program: you take the square root twice.

  double rootSumSquared = sqrt(val1*val1 + val2*val2 + val3*val3);
  double rootSum= sqrt(rootSumSquared);
1 Like

Good catch on my error! I didn't notice I had taken the square root twice. So in that case once I find the magnitude of the vector, instead of looking for something greater than a certain value, I should really be looking for something as close to 0 as possible? So I should be doing an if function check for less than 5 for example?

So I should be doing an if function check for less than 5 for example?

Yes, but you will have to determine the best value by experiment. Even in free fall, there will be some level of noise and the cutoff will need to be two or three times higher than that, at minimum.

The noise level can be estimated by taking a bunch of readings with the accelerometer sitting still on the table. The acceleration vector reported is 1 g, and the variation about that value (statistically, the standard deviation from the mean) is roughly the noise level.

Many accelerometers have a "free fall" interrupt output, intended for example to protect hard drives in laptops from falls. The ADXL335 does not, but check data sheets for other popular types to see how those work.

jremington:
Yes, but you will have to determine the best value by experiment. Even in free fall, there will be some level of noise and the cutoff will need to be two or three times higher than that, at minimum.

The noise level can be estimated by taking a bunch of readings with the accelerometer sitting still on the table. The acceleration vector reported is 1 g, and the variation about that value (statistically, the standard deviation from the mean) is roughly the noise level.

Many accelerometers have a "free fall" interrupt output, intended for example to protect hard drives in laptops from falls. The ADXL335 does not, but check data sheets for other popular types to see how those work.

Thanks for the input. I'll look into other accelerometers but for now since I'm working with the ADXL335, Ill see about determining that noise vector.