#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1 // not used for I2C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_MPU6050 mpu;
// Buzzer pin
#define BUZZER_PIN 19
// Fall detection thresholds
const float fallThreshold = 3.0; // Lower for testing in Wokwi
void setup() {
Serial.begin(115200);
Wire.begin();
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 failed");
while (1);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Initializing...");
display.display();
// Initialize MPU6050
if (!mpu.begin()) {
Serial.println("MPU6050 open failed");
while (1);
}
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
display.clearDisplay();
display.setCursor(0, 0);
display.println("Fall Detection Active");
display.display();
delay(1000);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float ax = a.acceleration.x;
float ay = a.acceleration.y;
float az = a.acceleration.z;
float magnitude = sqrt(ax * ax + ay * ay + az * az);
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.print("Ax: "); display.println(ax, 2);
display.print("Ay: "); display.println(ay, 2);
display.print("Az: "); display.println(az, 2);
display.print("Mag: "); display.println(magnitude, 2);
if (magnitude > fallThreshold) {
display.setTextSize(2);
display.setCursor(0, 40);
display.println("FALL!");
display.display();
// Buzz for 200ms
digitalWrite(BUZZER_PIN, HIGH);
delay(200);
digitalWrite(BUZZER_PIN, LOW);
} else {
display.display();
}
delay(200);
}