Project Overview
This project creates a fall detection system that monitors an elderly person’s activity and alerts caregivers when a fall is suspected. Using multiple PIR sensors placed strategically, the system detects unusual patterns—sudden motion followed by prolonged inactivity—and sends an alert via SMS, email, or local alarm.
Difficulty: Intermediate
Estimated time: 3-4 hours
Estimated cost: $40-60
How It Works
The system uses one or more PIR sensors to monitor movement patterns in key areas (bedroom, bathroom, living room). It tracks normal activity patterns and detects anomalies:
- Sudden, rapid movement (characteristic of a fall)
- Prolonged inactivity after movement (person not getting up)
- Motion detected in unexpected areas (e.g., floor level)
When a potential fall is detected, the system activates an alarm and sends notifications to caregivers.
Materials Needed
- ESP32 (1) – for Wi-Fi/cloud connectivity
- HC-SR501 PIR sensors (2-4) – placed in key locations
- Buzzer (for local alarm)
- LED (for status indication)
- Resistors (220Ω, 10k)
- Jumper wires
- Power supply (5V 2A)
- Enclosures (for sensors and main unit)
- Optional: GSM module for SMS if no Wi-Fi
Sensor Placement
Place sensors strategically to cover key areas:
- Bedroom: Near the bed to detect getting in/out
- Bathroom: At the entrance and near the toilet/shower
- Living room: Covering seating area and pathways
- Hallways: Between rooms
Circuit Diagram
Connection Table
| Component | Pin | ESP32 Pin | PIR Sensor 1 (Bedroom) | OUT | GPIO 4 | PIR Sensor 2 (Bathroom) | OUT | GPIO 5 | PIR Sensor 3 (Living Room) | OUT | GPIO 6 | PIR Sensor 4 (Hallway) | OUT | GPIO 7 | Buzzer | Positive | GPIO 8 | Buzzer | Negative | GND | Status LED | Anode | GPIO 2 (through 220Ω) | Status LED | Cathode | GND |
|---|
Arduino Code
// Elderly Fall Detection System
#include <WiFi.h>
#include <HTTPClient.h>
// Wi-Fi credentials
const char* ssid = "YourWiFiSSID";
const char* password = "YourWiFiPassword";
// Telegram bot configuration (optional)
const char* botToken = "YourTelegramBotToken";
const char* chatID = "YourChatID";
// Pin definitions
const int pirPins[] = {4, 5, 6, 7}; // Bedroom, Bathroom, Living, Hallway
const int buzzerPin = 8;
const int ledPin = 2;
const int numSensors = 4;
// Sensor names
const char* sensorNames[] = {"Bedroom", "Bathroom", "Living Room", "Hallway"};
// Fall detection parameters
unsigned long lastMotionTime = 0;
unsigned long lastEventTime = 0;
const unsigned long inactivityThreshold = 300000; // 5 minutes of no motion
const unsigned long fallCooldown = 60000; // 1 minute between alerts
bool fallAlertActive = false;
bool normalActivity = true;
unsigned long lastActivityTime[numSensors];
int motionCounts[numSensors];
// For detecting rapid movement
const int rapidMovementThreshold = 3; // 3 detections within 5 seconds
unsigned long rapidMovementWindow = 5000;
unsigned long rapidMovementStartTime = 0;
int rapidMovementCount = 0;
void setup() {
Serial.begin(115200);
for (int i = 0; i < numSensors; i++) {
pinMode(pirPins[i], INPUT);
lastActivityTime[i] = 0;
motionCounts[i] = 0;
}
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(buzzerPin, LOW);
digitalWrite(ledPin, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("Fall Detection System Ready");
delay(60000); // PIR warm-up
}
void sendTelegramAlert(String message) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = "https://api.telegram.org/bot" + String(botToken) + "/sendMessage";
http.begin(url);
http.addHeader("Content-Type", "application/json");
String payload = "{\"chat_id\":\"" + String(chatID) + "\", \"text\":\"" + message + "\"}";
int httpCode = http.POST(payload);
http.end();
}
}
void activateAlarm() {
if (!fallAlertActive) {
fallAlertActive = true;
Serial.println("FALL DETECTED! Activating alarm");
// Send alert
sendTelegramAlert("⚠️ FALL DETECTED! Please check on the individual immediately.");
// Activate local alarm
digitalWrite(ledPin, HIGH);
for (int i = 0; i < 10; i++) {
tone(buzzerPin, 2000, 500);
delay(500);
tone(buzzerPin, 2500, 500);
delay(500);
}
}
}
void resetAlarm() {
if (fallAlertActive) {
fallAlertActive = false;
digitalWrite(ledPin, LOW);
digitalWrite(buzzerPin, LOW);
Serial.println("Alarm reset by caregiver");
sendTelegramAlert("✅ Fall alarm has been reset.");
}
}
void checkForFall() {
unsigned long currentTime = millis();
bool anyMotion = false;
unsigned long latestMotionTime = 0;
// Check all sensors
for (int i = 0; i < numSensors; i++) {
bool motion = digitalRead(pirPins[i]) == HIGH;
if (motion) {
anyMotion = true;
latestMotionTime = currentTime;
// Update last activity time
if (currentTime - lastActivityTime[i] > 1000) {
lastActivityTime[i] = currentTime;
motionCounts[i]++;
// Check for rapid movement (possible fall)
if (currentTime - rapidMovementStartTime < rapidMovementWindow) {
rapidMovementCount++;
} else {
rapidMovementStartTime = currentTime;
rapidMovementCount = 1;
}
Serial.print("Motion in ");
Serial.print(sensorNames[i]);
Serial.print(" - Count: ");
Serial.println(motionCounts[i]);
}
}
}
// Rapid movement detection (possible fall)
if (rapidMovementCount > rapidMovementThreshold) {
Serial.println("Rapid movement detected - possible fall!");
activateAlarm();
}
// Prolonged inactivity after activity
if (!anyMotion && normalActivity && (currentTime - lastMotionTime > inactivityThreshold)) {
Serial.println("Prolonged inactivity - possible fall!");
activateAlarm();
normalActivity = false;
}
if (anyMotion) {
lastMotionTime = currentTime;
normalActivity = true;
}
}
void loop() {
checkForFall();
// Check for manual reset button (optional, use GPIO 0)
if (digitalRead(0) == LOW) {
delay(50);
if (digitalRead(0) == LOW) {
resetAlarm();
while (digitalRead(0) == LOW) delay(10);
}
}
delay(100);
}
Machine Learning Enhanced Version
For improved accuracy, you can use machine learning to classify fall patterns:
// ML-enhanced fall detection (simplified)
// Uses edge impulse or TensorFlow Lite Micro
// Features to extract:
// - Motion intensity (number of detections per second)
// - Duration of motion event
// - Post-motion inactivity period
// - Location of detection (bathroom = higher risk)
// Placeholder for model inference
bool isFall(int* features) {
// In real implementation, run features through model
// and return classification result
return false;
}
Installation Steps
- Position sensors: Install PIR sensors at key locations (bedroom, bathroom, living room, hallways).
- Adjust sensitivity: Set each sensor to detect normal movement (walking, sitting) but not small motions.
- Assemble main unit: Connect sensors to ESP32 in a central location.
- Configure alerts: Set up Telegram bot or Blynk notifications.
- Test normal activity: Simulate normal walking to establish baseline.
- Test fall detection: Simulate a fall (carefully!) to verify alarm triggers.
- Adjust parameters: Fine-tune inactivity threshold and rapid movement sensitivity.
Caregiver Dashboard (Optional)
Create a simple web interface to display activity logs:
#include <WebServer.h>
WebServer server(80);
void handleRoot() {
String html = "<html><head><title>Fall Detection Dashboard</title></head><body>";
html += "<h1>Activity Monitor</h1><table border=1><tr><th>Area</th><th>Last Activity</th><th>Today's Count</th></tr>";
for (int i = 0; i < numSensors; i++) {
html += "<tr><td>";
html += sensorNames[i];
html += "</td><td>";
html += String((millis() - lastActivityTime[i]) / 1000);
html += " seconds ago</td><td>";
html += String(motionCounts[i]);
html += "</td></tr>";
}
html += "</table></body></html>";
server.send(200, "text/html", html);
}
void setup() {
// ... existing setup ...
server.on("/", handleRoot);
server.begin();
}
void loop() {
server.handleClient();
// ... rest of loop ...
}
Project Extensions
- Wearable pendant: Add a panic button that the person can press for help.
- Voice alerts: Add DFPlayer Mini to play voice messages asking if help is needed.
- Camera verification: Add ESP32-CAM to capture images when fall is detected.
- Sleep monitoring: Track sleep patterns and detect night-time wandering.
- Activity reports: Generate daily activity reports for caregivers.
Troubleshooting
- False alarms: Adjust inactivity threshold. Increase rapid movement threshold.
- Missed falls: Ensure sensors cover all areas. Increase sensitivity for rapid movement detection.
- No notifications: Check Wi-Fi connection and Telegram bot configuration.
- Sensor not detecting: Adjust sensitivity and verify placement.
Ethical and Privacy Considerations
- Obtain consent from the individual being monitored.
- Ensure data is transmitted securely.
- Provide a way to disable monitoring when desired.
- This system is a supplement to, not a replacement for, attentive care.
Conclusion
This fall detection system provides peace of mind for caregivers and independence for elderly individuals living alone. With proper placement and configuration, it can detect falls promptly and ensure help arrives quickly.
