#include <Wire.h>
#include <MPU6050.h>
//#include <NMEAGPS.h> // Include NeoGPS library for handling GPS data
//#include <GPSport.h> // Include your GPS port configuration file
MPU6050 mpu;
NMEAGPS gps; // Create a GPS object
gps_fix fix; // Create a fix object to store the GPS data
const int buzzerPin = 2; // Pin for the buzzer
const float angleThreshold = 60.0; // Threshold angle for detecting a fall
const float netAccelThreshold = 1.1; // Threshold for net acceleration (in g's, adjust as necessary)
const float k = 0.1; // Steepness of the curve for logistic regression
void setup() {
Serial.begin(115200);
Wire.begin();
mpu.initialize();
gpsPort.begin(9600); // Initialize GPS port at 9600 baud
pinMode(buzzerPin, OUTPUT); // Initialize the buzzer pin as an output
// Check MPU6050 connection
if (!mpu.testConnection()) {
Serial.println("MPU6050 connection failed");
while (1);
}
Serial.println("MPU6050 connection successful");
}
void loop() {
// Get angle data from MPU6050
int16_t ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
// Convert raw accelerometer data to 'g' (assuming 16-bit data with range ±2g)
float ax_g = ax / 16384.0;
float ay_g = ay / 16384.0;
float az_g = az / 16384.0;
// Calculate pitch (angle in degrees)
float angle = atan2(ax_g, sqrt(ay_g * ay_g + az_g * az_g)) * 180.0 / PI;
// Calculate net acceleration (in g's)
float netAccel = sqrt(ax_g * ax_g + ay_g * ay_g + az_g * az_g);
// Calculate fall probability using a simple logistic regression approximation
float fallProbability = calculateFallProbability(angle);
// Print the angle, net acceleration, and probability
Serial.print("Angle: ");
Serial.print(angle);
Serial.print(" degrees, Net Acceleration: ");
Serial.print(netAccel);
Serial.print(" g, Fall Probability: ");
Serial.println(fallProbability);
// Trigger an alert if the probability exceeds 60% and net acceleration threshold is met
if (fallProbability > 0.6 && netAccel > netAccelThreshold) {
Serial.println("Fall detected! Triggering alert...");
triggerBuzzer();
getGPSData(); // Call function to read GPS data
} else {
digitalWrite(buzzerPin, LOW);
}
delay(5000); // Delay for 5 seconds
}
float calculateFallProbability(float angle) {
// Using a simple logistic regression approximation
float probability = 1.0 / (1.0 + exp(-k * (angle - angleThreshold)));
return probability;
}
void triggerBuzzer() {
digitalWrite(buzzerPin, HIGH);
delay(500);
digitalWrite(buzzerPin, LOW);
delay(500);
}
void getGPSData() {
if (gps.available(gpsPort)) { // Check if GPS data is available
fix = gps.read(); // Read the GPS data
// Check if GPS fix is valid
if (fix.valid.location) {
Serial.print("Latitude: ");
Serial.println(fix.latitude(), 6); // Print latitude with 6 decimal places
Serial.print("Longitude: ");
Serial.println(fix.longitude(), 6); // Print longitude with 6 decimal places
} else {
Serial.println("GPS fix not available.");
}
} else {
Serial.println("No GPS data available.");
}
}