49713 Designing for the Internet of Things
· 25 members
A hands-on introductory course exploring the Internet of Things and connected product experiences.
The fall detector will act as an emergency service in case the elderly person falls. It will send a notification to their loved ones enabling them to respond to the situation.
Falls are the leading cause of fatal and non-fatal injuries among elderly people. Adopting prevention techniques could reduce the frequency of falls, however, it is important to address the aftermath of a fall to ensure appropriate response and care.
The fall detector will act as an emergency service in case the elderly person suffers a fall. It will send a notification to their loved ones enabling them to respond to the situation.
The fall detector will also have an added feature of health tracking and monitoring that will enable the loved ones or the doctors to keep a follow up.
The first version of the device detected the position of a person. We found that for most of the daily movement of a person, the upper body of a person maintains an upright posture. But in the case of a fall, a person will lie on the ground eventually. This result in the posture change of the upper body. Our first algorithm was based on it.
The second version of the device deteced impact, in other words, a sudden increae of acceleration. This acceleration can be caused by fall as well as some daily movement. Hence, an algorithm to eliminate such noises are necessary. However, we found out that the movement of a human body was quite complex, and it was not just a matter of sensor sensitivity.
The third version of the device detected both impact and position change. We did many user tests to revise the code. These tests include walking, bending, going up/down stairs and so on. The final version of the fall detector passed all these activities. However, there was still some noises which could not be ultimately eliminated.
The fall detector had to meet the following requirements:
1. Daily activities of old people should not trigger the detector. These activities including walking, going up /down stairs, turning around, sitting down and standing up.
2. Falling down should trigger the detector.
3. In the case of trigger, the device should send notification to someone's mobile phone.
4. In the case of trigger, the device should use some signals to let the user know a falling has been detected.
5. In the case of false trigger, for example, a drop of the device, the user should be able to cancel the device before the notification is sent.
#include <math.h>
#include "neopixel.h"
#define PIXEL_COUNT 24
#define PIXEL_PIN D2
#define PIXEL_TYPE WS2812
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);
const int x_out = A1; /* connect x_out of module to A1 of Particle Photon board */
const int y_out = A2; /* connect y_out of module to A2 of Particle Photon board */
const int z_out = A3; /* connect z_out of module to A3 of Particle Photon board */
const int buzzer_pin = D0;
const int button_pin = D3;
unsigned long last_time = 0;
unsigned long current_time = 0;
int state = 0;
int bed_condition = 1;
int count = 0;
double prior_y_g_value = 0.0;
double y_change;
double prior_x_g_value = 0.0;
double x_change;
double prior_z_g_value = 0.0;
double z_change;
int brightness;
void setup() {
Serial.begin(9600);
Particle.subscribe("justgotinbedmyhomie", my_handler_inbed);
Particle.subscribe("justgotoutofbedfool", my_handler_outbed);
pinMode(buzzer_pin, OUTPUT);
pinMode(button_pin, INPUT_PULLUP);
strip.begin();
strip.show();
}
void loop() {
int x_adc_value, y_adc_value, z_adc_value;
double x_g_value, y_g_value, z_g_value, sum_g_value, delta_g_value;
double roll, pitch, yaw;
x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */
y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */
z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */
x_g_value = ( ( ( (double)(x_adc_value * 3.3)/4095) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */
y_g_value = ( ( ( (double)(y_adc_value * 3.3)/4095) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */
z_g_value = ( ( ( (double)(z_adc_value * 3.3)/4095) - 1.65 ) / 0.330 ); /* Acceleration in z-direction in g units */
y_change = y_g_value - prior_y_g_value; //Calculate the change of g value in y axis
prior_y_g_value = y_g_value;
x_change = x_g_value - prior_x_g_value; //Calculate the change of g value in x axis
prior_x_g_value = x_g_value;
z_change = z_g_value - prior_z_g_value; //Calculate the change of g value in x axis
prior_z_g_value = z_g_value;
sum_g_value = sqrt(pow(x_g_value,2) + pow(y_g_value,2) + pow(z_g_value,2)); //The sum of the square of x_g_value, y_g_value, z_g_value
delta_g_value = sqrt(pow(x_change,2) + pow(y_change,2) + pow(z_change,2));
//print in the Serial
Serial.print("x = ");
Serial.print(x_g_value);
Serial.print("\t\t");
Serial.print("y = ");
Serial.print(y_g_value);
Serial.print("\t\t");
Serial.print("z = ");
Serial.print(z_g_value);
Serial.print("\t\t");
Serial.print("sum_g_value = ");
Serial.print(sum_g_value);
Serial.print("\t\t");
Serial.print("delta_g_value = ");
Serial.print(delta_g_value);
Serial.print("\t\t");
// Serial.print("x_change = ");
// Serial.print(fabs(x_change));
// Serial.print("\t\t");
// Serial.print("y_change = ");
// Serial.print(fabs(y_change));
// Serial.print("\t\t");
// Serial.print("z_change = ");
// Serial.print(fabs(z_change));
// Serial.print("\t\t");
// delay(100);
roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
//yaw = ( ( (atan2(x_g_value,y_g_value) * 180) / 3.14 ) + 180 ); /* Formula for yaw */
/* Not possible to measure yaw using accelerometer. Gyroscope must be used if yaw is also required */
Serial.print("Roll = ");
Serial.print(roll);
Serial.print("\t");
Serial.print("Pitch = ");
Serial.print(pitch);
Serial.print("\n\n");
delay(100);
if(digitalRead(button_pin) == LOW){
count = 0;
}
if(bed_condition == 1){
if (digitalRead(button_pin) == LOW){//press the button to stop the buzzer and reset the system
noTone(buzzer_pin);
count = 0;
state = 0;
}
//detect whether there is a fall or not, state == 0 means current there is no fall detected && position_detector(x_change, y_change, z_change)==1
else if(delta_g_value > 3.5 && state == 0 ){
delay(1000);
x_adc_value = analogRead(x_out); /* Digital value of voltage on x_out pin */
y_adc_value = analogRead(y_out); /* Digital value of voltage on y_out pin */
z_adc_value = analogRead(z_out); /* Digital value of voltage on z_out pin */
x_g_value = ( ( ( (double)(x_adc_value * 3.3)/4095) - 1.65 ) / 0.330 ); /* Acceleration in x-direction in g units */
y_g_value = ( ( ( (double)(y_adc_value * 3.3)/4095) - 1.65 ) / 0.330 ); /* Acceleration in y-direction in g units */
z_g_value = ( ( ( (double)(z_adc_value * 3.3)/4095) - 1.65 ) / 0.330 );
roll = ( ( (atan2(y_g_value,z_g_value) * 180) / 3.14 ) + 180 ); /* Formula for roll */
pitch = ( ( (atan2(z_g_value,x_g_value) * 180) / 3.14 ) + 180 ); /* Formula for pitch */
Serial.println(roll);
Serial.println(pitch);
if(position_detector(roll, pitch) == 1){
Serial.println("fall detected");
state = 1;
buzzer();
}
}
else if(state == 1 ){//state == 1 means there is already a fall detected
Serial.println("signal has been sent");
publish_event();
tone(buzzer_pin, 2000);
delay(500);
noTone(buzzer_pin);
delay(2500);
}
}
delay(100);
}
void publish_event(){
current_time = millis();
if (current_time - last_time >= 30000){
Particle.publish("has/fall_detector");
last_time = current_time;
}
}
//handle the event that someone gets is bed, turn off the system
void my_handler_inbed(const char *event, const char *data){
Serial.println("gotinbed");
bed_condition = 0;
}
//hanlde the event that someone gets out of bed, turn on the system
void my_handler_outbed(const char *event, const char *data){
Serial.println("gotoutofbed");
bed_condition = 1;
}
//function to detect the g-change of three axis
bool position_detector(double roll, double pitch){
if( roll>150 && roll<190 ){
if( pitch>240 && pitch<300){
return 0;
}
}
else{
return 1;
}
}
//function for buzzer to ring
void buzzer(){
while (digitalRead(button_pin) == HIGH && count < 10){
tone(buzzer_pin, 2000);
delay(500);
Serial.println(count);
count ++;
}
if (digitalRead(button_pin) == LOW){
noTone(buzzer_pin);
count = 0;
}
else if (count >= 10){
state = 1;
}
}
void breathing(){
for(int num=0;num<strip.numPixels()-1;num++){
strip.setColorDimmed(num, 255, 0, 0, int(brightness));
}
for(double t=0.0;t<2000;t++){
brightness = sin(t)*200;
}
}
Click to Expand
⌃ 0
⌄
Click to Expand
During our research, we found that the industrial products of fall detector for old people use two kinds of sensors, accelerometers and highly sensitive barometric sensors. Our testing of the accelerometer completely understood the two kinds of data input. Normal activities of a person can cause many disturbances which will also trigger the fall detector. But when we set the sensor to be less sensitive, the whole code was backfiring. After several rounds of iteration of the algorithm, we finally derived our product that could be potentially used by elderly to stop worrying about falling down. This provides a subtle as well as effective solution at the same time.
A hands-on introductory course exploring the Internet of Things and connected product experiences.
The fall detector will act as an emergency service in case the elderly person falls. It will send a notification to their loved ones enabling them to respond to the situation.
March 9th, 2018