Arduino Fall Alarm Code
Arduino Fall Alarm Code
To create a fall detection alarm using an MPU6050 (accelerometer and gyroscope) with an
Arduino Uno, you can detect a sudden change in acceleration or orientation that could
indicate a fall. Here’s a basic code that sets up the MPU6050 and triggers an alarm when a
fall is detected.
You'll need:
An Arduino Uno
An MPU6050 sensor
Wiring:
1. Connect the MPU6050 to the Arduino using I2C:
VCC → 5V
GND → GND
SDA → A4
SCL → A5
Arduino Code:
cpp
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
int buzzerPin = 9; // Pin for the buzzer/LED
void setup() {
1/34
Wire.begin();
Serial.begin(115200);
void loop() {
int16_t ax, ay, az; // Acceleration values
int16_t gx, gy, gz; // Gyroscope values
// Fall detection threshold (example: if the total acceleration falls below 0.5G)
if (totalAccel < 0.5) {
// Trigger alarm (turn on the buzzer or LED)
digitalWrite(buzzerPin, HIGH);
Serial.println("Fall detected!");
} else {
// Turn off the alarm
digitalWrite(buzzerPin, LOW);
2/34
}
Explanation:
1. MPU6050 Initialization: The MPU6050 sensor is initialized using I2C communication.
2. Acceleration Reading: The code reads acceleration in the X, Y, and Z axes. The values are
converted into G-forces (1G ≈ 9.8 m/s²).
3. Fall Detection: A fall is detected when the total acceleration is below a certain threshold,
indicating a free fall or impact. In this case, a threshold of 0.5G is used, but you can
adjust this depending on your application.
Let me know if you'd like to adjust the fall sensitivity or add additional features!
cpp
void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(115200); // Start the serial communication at 115200 baud rate for
debugging
3/34
Serial.println("Initializing MPU6050...");
mpu.initialize(); // Call the function to initialize the MPU6050 sensor
void loop() {
int16_t ax, ay, az; // Declare variables for the raw acceleration values (X, Y,
Z)
int16_t gx, gy, gz; // Declare variables for the raw gyroscope values (X, Y, Z)
4/34
} else {
// If no fall is detected, turn off the buzzer or LED
digitalWrite(buzzerPin, LOW); // Deactivate buzzer or LED
}
delay(200); // Wait for 200 milliseconds before taking the next reading
}
2. Setup:
3. Loop:
Would you like to modify the code further or adjust specific values?
To display both the live acceleration (in G-force) and angular velocity (in degrees per second)
values in the Serial Monitor of the Arduino IDE, you need to extract the gyroscope data along
with the accelerometer data and print them out. Here's how to modify the code to achieve
this:
5/34
Modified Arduino Code:
cpp
void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(115200); // Start the serial communication at 115200 baud rate for
debugging
void loop() {
int16_t ax, ay, az; // Declare variables for the raw acceleration values (X, Y,
Z)
int16_t gx, gy, gz; // Declare variables for the raw gyroscope values (X, Y, Z)
6/34
// Convert raw acceleration values (ax, ay, az) to G-forces
float accelX = ax / 16384.0; // Convert raw X-axis acceleration to G-force
float accelY = ay / 16384.0; // Convert raw Y-axis acceleration to G-force
float accelZ = az / 16384.0; // Convert raw Z-axis acceleration to G-force
// Convert raw gyroscope values (gx, gy, gz) to degrees per second
float gyroX = gx / 131.0; // Convert raw X-axis gyroscope data to degrees/sec
float gyroY = gy / 131.0; // Convert raw Y-axis gyroscope data to degrees/sec
float gyroZ = gz / 131.0; // Convert raw Z-axis gyroscope data to degrees/sec
delay(200); // Wait for 200 milliseconds before taking the next reading
}
Key Changes:
1. Gyroscope Data:
7/34
Raw gyroscope data ( gx , gy , gz ) is retrieved from the MPU6050.
The raw values are converted into degrees per second by dividing by 131 (the
sensitivity scale factor in +/-250 degrees/sec mode).
2. Serial Output:
Added Serial.print statements to display the acceleration values (in G-force) and
gyroscope values (in degrees per second) for the X, Y, and Z axes.
Separated acceleration and gyroscope readings with labels and a separator line for
readability in the Serial Monitor.
markdown
This shows real-time acceleration in G-force and angular velocity in degrees per second for
all three axes.
Yes, the MPU6050 sensor typically benefits from calibration to improve the accuracy of the
accelerometer and gyroscope readings. Calibration compensates for sensor biases such as
offsets, which can cause the sensor to return non-zero values even when the device is
stationary.
8/34
slightly different values because of small manufacturing imperfections or environmental
conditions.
Gyroscope: When the sensor is stationary, the gyroscope should ideally read 0°/s on all
three axes (X, Y, Z). Any non-zero readings are considered bias or drift.
2. Gyroscope Calibration: When the sensor is stationary, the gyroscope output should be
zero on all axes. The offsets for the gyroscope are subtracted from the raw values to
ensure accurate angular velocity measurements.
You can either hard-code the offsets in your Arduino program, or dynamically calculate them
during setup. Below is an example of how to perform a basic calibration and apply offsets in
your code.
cpp
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
int buzzerPin = 9; // Pin for the buzzer or LED
void setup() {
Wire.begin();
Serial.begin(115200);
9/34
if (mpu.testConnection()) {
Serial.println("MPU6050 connection successful");
} else {
Serial.println("MPU6050 connection failed");
while (1);
}
pinMode(buzzerPin, OUTPUT);
// Perform calibration
calibrateSensor();
}
void loop() {
int16_t ax, ay, az; // Raw acceleration values
int16_t gx, gy, gz; // Raw gyroscope values
10/34
Serial.print("Accel (G) -> X: "); Serial.print(accelX);
Serial.print(" Y: "); Serial.print(accelY);
Serial.print(" Z: "); Serial.println(accelZ);
Serial.println("---------------------------");
axSum += ax;
aySum += ay;
azSum += az;
gxSum += gx;
gySum += gy;
gzSum += gz;
11/34
gyroY_offset = (gySum / numReadings) / 131.0;
gyroZ_offset = (gzSum / numReadings) / 131.0;
Serial.println("Calibration complete");
}
It calculates offsets for the accelerometer and gyroscope, which are subtracted from
the raw sensor data during the main loop to correct for biases.
For the Z-axis of the accelerometer, the offset accounts for the presence of 1G due to
gravity.
2. Application of Offsets:
The offsets are subtracted from the raw accelerometer and gyroscope readings in
the main loop before converting them to G-forces and degrees per second, ensuring
that the readings are more accurate.
How to Use:
1. Ensure that the MPU6050 is stationary (e.g., place it flat on a table) when performing
calibration.
3. After calibration, the sensor should output more accurate acceleration and angular
velocity values.
Here's a standalone code for calibrating the MPU6050 sensor. This code will calculate and
print the calibration offsets for both the accelerometer and gyroscope, which you can use
later in your project.
12/34
cpp
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
void setup() {
Wire.begin();
Serial.begin(115200);
// Perform calibration
calibrateSensor();
}
void loop() {
// Calibration runs once in setup, no need to repeat in loop
}
void calibrateSensor() {
int numReadings = 1000; // Number of readings for calibration
long axSum = 0, aySum = 0, azSum = 0;
long gxSum = 0, gySum = 0, gzSum = 0;
axSum += ax;
aySum += ay;
13/34
azSum += az;
gxSum += gx;
gySum += gy;
gzSum += gz;
2. Calibration:
It reads the sensor 1000 times to compute an average for each axis (X, Y, Z) for both
the accelerometer and gyroscope.
3. Calibration Results: Prints out the accelerometer and gyroscope offsets. These values
can be used in your main code to adjust the raw sensor readings.
14/34
How to Use:
1. Upload this code to your Arduino while keeping the MPU6050 stationary (on a flat
surface).
3. After calibration is complete, the offsets will be printed. These offsets should be
subtracted from your sensor readings in future programs for better accuracy.
If you don't have access to the Serial Monitor to view the calibration values, you can modify
the code to use LEDs or a buzzer to signal the completion of calibration. While you won't be
able to see the exact calibration values directly, you can at least know when the calibration is
finished, and then use pre-calculated or hardcoded calibration offsets in your main code.
2. Hardcode the offsets into your final project code, so calibration doesn't need to be
repeated every time.
Since you mentioned not having a Serial Monitor, here's how to modify the calibration code
to signal calibration completion with a buzzer or LED:
cpp
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
int buzzerPin = 9; // Pin for the buzzer or LED
15/34
void setup() {
Wire.begin();
// Perform calibration
calibrateSensor();
}
void loop() {
// Nothing needed here, as we only calibrate once during setup
}
axSum += ax;
aySum += ay;
azSum += az;
gxSum += gx;
gySum += gy;
gzSum += gz;
16/34
delay(2); // Small delay between readings
}
Key Changes:
1. No Serial Monitor: The Serial Monitor code is removed, and a buzzer or LED signals
when the MPU6050 is connected and when calibration is complete.
2. Buzzer Indications:
A short tone (1 kHz for 500ms) plays if the MPU6050 is successfully connected.
After the calibration is complete, a longer tone (1 kHz for 1 second) plays to signal
that the process has finished.
You can replace the placeholder values ( accelX_offset , gyroX_offset , etc.) with
actual offsets that you obtain from another run where you have access to the Serial
Monitor.
How to Use:
1. Run Once with Serial Monitor: Obtain the calibration offsets by running the code on a
device that supports the Serial Monitor.
17/34
2. Hardcode Offsets: Replace the calibration offsets in the code with the values you obtain.
3. Final Setup: Upload the modified code to your device, and the buzzer will notify you
when calibration is complete. You won't need the Serial Monitor anymore.
void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(115200); // Start the serial communication at
115200 baud rate for debugging
18/34
void loop() {
int16_t ax, ay, az; // Declare variables for the raw
acceleration values (X, Y, Z)
int16_t gx, gy, gz; // Declare variables for the raw
gyroscope values (X, Y, Z)
19/34
delay(200); // Wait for 200 milliseconds before taking the
next reading
} also include a switch to restart detecting
You can add a push-button switch to reset or restart the fall detection process. When the
button is pressed, it can either reset the fall alarm (by turning off the buzzer) or restart the
detection logic.
void setup() {
Wire.begin(); // Initialize the I2C communication
Serial.begin(115200); // Start the serial communication at 115200 baud rate for
debugging
20/34
pinMode(buzzerPin, OUTPUT); // Set the buzzer/LED pin as an output pin
pinMode(switchPin, INPUT_PULLUP); // Set the switch pin as input with an internal
pull-up resistor
}
void loop() {
// Check if the reset button is pressed
if (digitalRead(switchPin) == LOW) {
// If the button is pressed, reset the fall detection alarm
fallDetected = false; // Reset the fall detection flag
digitalWrite(buzzerPin, LOW); // Turn off the buzzer
Serial.println("Fall alarm reset.");
delay(500); // Debounce the button press
}
21/34
// Print acceleration values for debugging purposes (optional)
Serial.print("AccelX: "); Serial.print(accelX);
Serial.print(" AccelY: "); Serial.print(accelY);
Serial.print(" AccelZ: "); Serial.println(accelZ);
delay(200); // Wait for 200 milliseconds before taking the next reading
}
}
Key Changes:
1. Switch Pin Setup: The switch is connected to pin 8 and uses the internal pull-up resistor
( INPUT_PULLUP ). When the button is pressed, it grounds the pin and registers a LOW
signal.
A flag fallDetected is used to keep track of whether a fall has already been
detected.
Once a fall is detected, the buzzer stays on, and the program will stop checking for
new falls until the button is pressed.
Hardware Connections:
1. Buzzer or LED: Connect the buzzer or LED to pin 9 and ground.
2. Button: Connect one side of the button to pin 8 and the other side to ground (since
we're using INPUT_PULLUP mode).
#include<Wire.h>
#include<MPU6050.h>
22/34
MPU6050 mpu;
void setup() {
Serial.begin(115200);
Serial.println("Initialize MPU6050");
while(!mpu.begin(MPU6050_SCALE_2000DPS,
MPU6050_RANGE_2G)){
Serial.println("Could not find a valid MPU6050 sensor,
check wiring!");
delay(500);
}
checkSettings();
}
void checkSettings()
{
Serial.println();
23/34
case MPU6050_CLOCK_PLL_ZGYRO: Serial.println("PLL
with Z axis gyroscope reference"); break;
case MPU6050_CLOCK_PLL_YGYRO: Serial.println("PLL
with Y axis gyroscope reference"); break;
case MPU6050_CLOCK_PLL_XGYRO: Serial.println("PLL
with X axis gyroscope reference"); break;
case MPU6050_CLOCK_INTERNAL_8MHZ:
Serial.println("Internal 8MHz oscillator"); break;
}
Serial.println();
}
void loop() {
Vector rawAccel = mpu.readRawAccel();
Vector normAccel = mpu.readNormalizeAccel();
24/34
Serial.println(rawAccel.ZAxis);
Serial.print(" Xnorm = ");
Serial.print(normAccel.XAxis);
Serial.print(" Ynorm = ");
Serial.print(normAccel.YAxis);
Serial.print(" Znorm = ");
Serial.println(normAccel.ZAxis);
delay(10);
} code is showing errors
The code you provided seems to use functions and methods that are likely part of a different
MPU6050 library. The library you're using in your code appears to be different from the
common MPU6050 library typically used in Arduino projects.
To fix the issues, we need to ensure you're using the correct library and its functions. Based
on your code, it looks like you're mixing function calls from different libraries (e.g.,
mpu.begin is from a different library than mpu.getClockSource() ).
1. Check the Library: Make sure you are using the correct library for the MPU6050. There
are a couple of different ones, and the function calls differ between them. You might be
mixing them up.
2. Correct the Code: Here’s a working version of the code that uses the correct MPU6050
library (you can install it through the Library Manager in the Arduino IDE by searching
for "MPU6050" by Jeff Rowberg).
cpp
#include <Wire.h>
#include <MPU6050.h> // Make sure to install this library by Jeff Rowberg
MPU6050 mpu;
void setup() {
Serial.begin(115200);
25/34
Wire.begin(); // Start I2C communication
Serial.println("Initializing MPU6050...");
void checkSettings() {
Serial.println();
26/34
case MPU6050_CLOCK_PLL_XGYRO: Serial.println("PLL with X axis gyroscope
reference"); break;
case MPU6050_CLOCK_INTERNAL_8MHZ: Serial.println("Internal 8MHz oscillator");
break;
}
Serial.println();
}
void loop() {
// Variables for raw accelerometer data
int16_t ax, ay, az;
27/34
Serial.print(accelY); Serial.print(" Znorm = "); Serial.println(accelZ);
delay(100);
}
Key Changes:
1. Library and Functions:
This code assumes you’re using the MPU6050 library by Jeff Rowberg, which can be
installed through the Arduino Library Manager.
2. Serial Output:
The code will now output the raw acceleration data as well as the normalized G-
forces for each axis.
This should resolve the issues you're facing with the code. Let me know if you encounter any
further problems!
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino: In
function 'void checkSettings()':
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:41:10:
error: 'MPU6050_CLOCK_EXTERNAL_19MHZ' was not
declared in this scope
case MPU6050_CLOCK_EXTERNAL_19MHZ:
Serial.println("PLL with external 19.2MHz reference"); break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
28/34
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:41:10:
note: suggested alternative: 'MPU6050_CLOCK_INTERNAL'
case MPU6050_CLOCK_EXTERNAL_19MHZ:
Serial.println("PLL with external 19.2MHz reference"); break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
MPU6050_CLOCK_INTERNAL
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:42:10:
error: 'MPU6050_CLOCK_EXTERNAL_32KHZ' was not
declared in this scope
case MPU6050_CLOCK_EXTERNAL_32KHZ:
Serial.println("PLL with external 32.768kHz reference");
break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:42:10:
note: suggested alternative: 'MPU6050_CLOCK_INTERNAL'
case MPU6050_CLOCK_EXTERNAL_32KHZ:
Serial.println("PLL with external 32.768kHz reference");
break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
MPU6050_CLOCK_INTERNAL
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:46:10:
error: 'MPU6050_CLOCK_INTERNAL_8MHZ' was not
declared in this scope
case MPU6050_CLOCK_INTERNAL_8MHZ:
Serial.println("Internal 8MHz oscillator"); break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\uditm_27jdw1v\AppData\Local\Temp\.arduinoIDE-
unsaved2024822-1096-
b9e7m8.w059q\sketch_sep22a\sketch_sep22a.ino:46:10:
note: suggested alternative: 'MPU6050_CLOCK_INTERNAL'
case MPU6050_CLOCK_INTERNAL_8MHZ:
Serial.println("Internal 8MHz oscillator"); break;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
MPU6050_CLOCK_INTERNAL
Multiple libraries were found for "MPU6050.h"
Used:
29/34
C:\Users\uditm_27jdw1v\Documents\Arduino\libraries\MP
U6050-1.3.1
Not used:
C:\Users\uditm_27jdw1v\Documents\Arduino\libraries\Ard
uino-MPU6050-master
exit status 1
Steps to Fix:
1. Use Supported Constants: Remove the unsupported constants and use only the
available ones.
2. Simplify Clock Source Checking: The MPU6050 library typically supports the following
clock sources:
MPU6050_CLOCK_KEEP_RESET
MPU6050_CLOCK_PLL_XGYRO
MPU6050_CLOCK_PLL_YGYRO
MPU6050_CLOCK_PLL_ZGYRO
MPU6050_CLOCK_INTERNAL
cpp
#include <Wire.h>
#include <MPU6050.h> // Make sure to install this library by Jeff Rowberg
MPU6050 mpu;
void setup() {
Serial.begin(115200);
Wire.begin(); // Start I2C communication
30/34
Serial.println("Initializing MPU6050...");
void checkSettings() {
Serial.println();
31/34
// Check accelerometer range
Serial.print(" * Accelerometer: ");
switch (mpu.getFullScaleAccelRange()) {
case MPU6050_ACCEL_FS_2: Serial.println("+/- 2 g"); break;
case MPU6050_ACCEL_FS_4: Serial.println("+/- 4 g"); break;
case MPU6050_ACCEL_FS_8: Serial.println("+/- 8 g"); break;
case MPU6050_ACCEL_FS_16: Serial.println("+/- 16 g"); break;
}
Serial.println();
}
void loop() {
// Variables for raw accelerometer data
int16_t ax, ay, az;
delay(100);
}
32/34
Key Changes:
Removed unsupported clock sources ( MPU6050_CLOCK_EXTERNAL_19MHZ ,
MPU6050_CLOCK_EXTERNAL_32KHZ , MPU6050_CLOCK_INTERNAL_8MHZ ).
This code should now compile correctly with the library you're using. Let me know if you have
further issues!
To connect the MPU6050 sensor to the Arduino, you will use the I2C protocol. Here are the
steps for wiring:
Connections:
1. MPU6050 Pin Layout:
GND: Ground.
VCC: Connect this to the 5V pin on the Arduino (or 3.3V if your MPU6050 operates at
3.3V).
Detailed Wiring:
MPU6050 Pin Arduino Pin
VCC 5V or 3.3V
GND GND
SCL A5 (SCL)
SDA A4 (SDA)
33/34
Diagram:
MPU6050 VCC → Arduino 5V/3.3V
After wiring, ensure the correct library is installed and upload the code to test the setup.
34/34