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