Friday, May 5, 2023

0000 0000 1100 1000

The Dirty Dozen - Part Five - 3 axes accelerometer as Fall Detector

Those of us who fall off things may want immediate help or maybe even notifications sent to relevant authorities. Perhaps you have a relative or friend, prone to falling, who needs some gentle silicon monitoring?

The LIS3DH Triaxial Acceleration Temperature Sensor might be just the ticket. When I pulled it out of the Dirty Dozen box I thought immediately that if I could talk to the thing and get some sense out of it then I'd take a crack at a fall detector.

The theory is that if there is sudden acceleration of the module (or the object in which it is contained) then the device would output, in three dimensions, the magnitude of that "overall" event.

To characterise it as a single event I thought I might use a virtual 3D box and plot values from the ideal position (no acceleration for zero) to a calculated threshold value (found in my case by experimentation).


That High School math sure does come in handy some days!

I went looking for all sorts of information on this module only to discover that I think it's a cheap knockoff of an existing product (surprise!).

Using a fair amount of optomistic pixie dust I sprinkled in some code from the legitimate product found here at this link.

After successfully "talking" to the module with the legit code and library, I then embarked upon coding the fake version. It took a bit longer than expected as my perfection gene kicked in halfway through the coding process.

/*
   based on code by Marshall Taylor @ SparkFun Electronics
   https://github.com/sparkfun/LIS3DH_Breakout
   https://github.com/sparkfun/SparkFun_LIS3DH_Arduino_Library

   OneCircuit https://www.youtube.com/@onecircuit-as
   Tue 18 Apr 2023 14:03:27 AEST
*/

#include "SparkFunLIS3DH.h"
#include "Wire.h"
#include "SPI.h"

#define alarmLED 4

float xmove = 0;
float ymove = 0;
float zmove = 0;
float falldetect = 0;   // how hard is fall?
boolean fell = false;
float biggestfall = 0;
int falltrigger = 300;  // how hard to fall?
long timer = 0;
long currenttime = 0;
long bigfalltime = 5000;
LIS3DH myIMU(I2C_MODE, 0x19);

void setup() {
  Serial.begin(57600);
  pinMode(alarmLED, OUTPUT);

  myIMU.settings.adcEnabled = 1;
  myIMU.settings.tempEnabled = 0;
  // in Hz: 0,1,10,25,50,100,200,400,1600,5000
  myIMU.settings.accelSampleRate = 200;
  // Max G force: 2, 4, 8, 16
  myIMU.settings.accelRange = 16;
  myIMU.settings.xAccelEnabled = 1;
  myIMU.settings.yAccelEnabled = 1;
  myIMU.settings.zAccelEnabled = 1;

  myIMU.begin();
  delay(1000); // settle petal

}

// here is where you would txt, email or call for help
void raisealarm() {
  digitalWrite(alarmLED, HIGH);
  fell = true;
  timer = millis();
}

void loop()
{
  // time at start of loop
  currenttime = millis();

  // measure and convert each axis
  xmove = abs(myIMU.readFloatAccelX() * 100);
  ymove = abs(myIMU.readFloatAccelY() * 100) - 5;
  zmove = abs(myIMU.readFloatAccelZ() * 100) - 93;

  // has the device fallen?
  falldetect = sqrt(xmove * xmove + ymove * ymove + zmove * zmove);
  if (falldetect > falltrigger) {
    raisealarm();
  }

  Serial.print(xmove);
  Serial.print(",");
  Serial.print(ymove);
  Serial.print(",");
  Serial.print(zmove);
  Serial.print(",");
  Serial.print(falldetect);
  Serial.print(",");
  Serial.println(biggestfall);

  if (falldetect > biggestfall) {
    biggestfall = falldetect;
  }

  if (((currenttime - timer) > bigfalltime) && fell) {
    digitalWrite(alarmLED, LOW);
    fell = false;
    biggestfall = 0;
    timer = 0;
  }

  delay(20);
}

The results were, I don't mind saying, pretty impressive! I'd like to maybe further develop this project to include an "IoT" twist - such that maybe fall detection is accompanied by a text or email message.

Your thoughts, as always, appreciated!



No comments:

Post a Comment