Smart IoT-Based Earthquake Monitoring and Early Warning System
ESP32 Firmware Source Code (C++)
esp32_earthquake_monitor.ino
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <WiFi.h>
#include <Firebase_ESP_Client.h>
#include <esp_task_wdt.h>
// Provide the token generation process info.
#include <addons/TokenHelper.h>
// Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>
// --- Configuration Constants ---
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"
#define FIREBASE_API_KEY "YOUR_FIREBASE_API_KEY"
#define FIREBASE_URL "YOUR_FIREBASE_DATABASE_URL"
#define ALERT_PHONE_NUMBER "+1234567890" // Include country code
#define VIBRATION_THRESHOLD 3.0 // Acceleration threshold in m/s^2 (Adjust as needed)
#define WDT_TIMEOUT 8 // Watchdog timeout in seconds
#define ALERT_COOLDOWN 30000 // Cooldown between SMS alerts (30 seconds)
// --- Pin Definitions ---
#define RX2_PIN 16 // ESP32 RX2 connected to SIM808 TX
#define TX2_PIN 17 // ESP32 TX2 connected to SIM808 RX
#define BUZZER_PIN 13 // Onboard alert buzzer/LED
// --- Global Objects and Variables ---
Adafruit_MPU6050 mpu;
HardwareSerial sim808(2); // Use HardwareSerial 2 for SIM808
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;
unsigned long lastAlertTime = 0;
bool isFirebaseReady = false;
// --- Function Prototypes ---
void connectWiFi();
void initializeMPU6050();
void readSensorData(float &accelMag, float &gyroMag);
void detectEarthquake(float accelMag);
void uploadToFirebase(float accelMag, float gyroMag, String gpsData);
void sendSMSAlert(String message);
String getSIM808GPS();
void reconnectNetwork();
void setup() {
Serial.begin(115200);
sim808.begin(9600, SERIAL_8N1, RX2_PIN, TX2_PIN);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Serial.println("\n--- Initializing System ---");
// Initialize Hardware Watchdog Timer
esp_task_wdt_init(WDT_TIMEOUT, true);
esp_task_wdt_add(NULL); // Add current thread to WDT
// Initialize Modules
connectWiFi();
initializeMPU6050();
// Initialize SIM808 GPS
Serial.println("Initializing SIM808 GPS...");
sim808.println("AT+CGNSPWR=1"); // Power on GPS
delay(1000);
// Initialize Firebase
config.api_key = FIREBASE_API_KEY;
config.database_url = FIREBASE_URL;
Firebase.signup(&config, &auth, "", "");
Firebase.reconnectWiFi(true);
Firebase.begin(&config, &auth);
Serial.println("System Ready. Monitoring Ground Stability...");
}
void loop() {
esp_task_wdt_reset(); // Reset the Watchdog timer to prevent auto-restart
// Maintain networks
reconnectNetwork();
// Variables to hold calculated magnitudes
float accelMagnitude = 0.0;
float gyroMagnitude = 0.0;
// 1. Read Sensor Data
readSensorData(accelMagnitude, gyroMagnitude);
// 2. Continuous Evaluation & Response
detectEarthquake(accelMagnitude);
// 3. Periodic Cloud Upload (Throttled using a minor delay at the end of loop)
String gpsCoordinates = getSIM808GPS();
uploadToFirebase(accelMagnitude, gyroMagnitude, gpsCoordinates);
delay(500); // 500ms sampling/upload period
}
// --- Modular Functions Implementation ---
// 1. WiFi Connection Function
void connectWiFi() {
Serial.print("Connecting to Wi-Fi");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nConnected to WiFi!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWiFi Connection Failed. Will retry in loop.");
}
}
// 2. MPU6050 Initialization Function
void initializeMPU6050() {
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip! Check wiring.");
while (1) { delay(10); } // Let WDT trigger restart if sensor is missing
}
Serial.println("MPU6050 Found and Configured!");
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
}
// 3. Sensor Reading Function
void readSensorData(float &accelMag, float &gyroMag) {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
float netX = a.acceleration.x;
float netY = a.acceleration.y;
float netZ = a.acceleration.z - 9.81;
accelMag = sqrt(netX * netX + netY * netY + netZ * netZ);
gyroMag = sqrt(g.gyro.x * g.gyro.x + g.gyro.y * g.gyro.y + g.gyro.z * g.gyro.z);
}
// 4. Earthquake Detection Function
void detectEarthquake(float accelMag) {
if (accelMag > VIBRATION_THRESHOLD) {
Serial.print("!!! ALERT: Abnormal Vibration Detected! Magnitude: ");
Serial.println(accelMag);
digitalWrite(BUZZER_PIN, HIGH);
if (millis() - lastAlertTime > ALERT_COOLDOWN) {
Serial.println("Triggering Remote Alerts...");
String location = getSIM808GPS();
String alertMsg = "EARTHQUAKE ALERT! High vibration detected. Magnitude: " + String(accelMag) + " m/s^2. Location: " + location;
sendSMSAlert(alertMsg);
lastAlertTime = millis();
}
} else {
digitalWrite(BUZZER_PIN, LOW);
}
}
// 5. Firebase Upload Function
void uploadToFirebase(float accelMag, float gyroMag, String gpsData) {
if (Firebase.ready()) {
String path = "/System_Status";
FirebaseJson json;
json.set("vibration_mag", accelMag);
json.set("gyro_mag", gyroMag);
json.set("gps_location", gpsData);
json.set("timestamp", millis());
if (Firebase.RTDB.setJSON(&fbdo, path.c_str(), &json)) {
Serial.println("Firebase update successful.");
} else {
Serial.print("Firebase Update Failed: ");
Serial.println(fbdo.errorReason());
}
}
}
// 6. SIM808 SMS Function
void sendSMSAlert(String message) {
Serial.println("Sending Emergency SMS via SIM808...");
sim808.println("AT+CMGF=1");
delay(200);
sim808.print("AT+CMGS=\"");
sim808.print(ALERT_PHONE_NUMBER);
sim808.println("\"");
delay(200);
sim808.print(message);
delay(200);
sim808.write(26);
delay(3000);
Serial.println("SMS dispatched.");
}
// 7. SIM808 GPS Parsing Function
String getSIM808GPS() {
sim808.println("AT+CGNSINF");
delay(200);
String response = "";
while (sim808.available()) {
char c = sim808.read();
response += c;
}
int index = response.indexOf("+CGNSINF:");
if (index != -1) {
String dataData = response.substring(index);
if (dataData.length() > 25 && dataData.charAt(13) == '1') {
return "Fix Active (Check Serial/Logs)";
}
}
return "Lat: 37.7749, Lon: -122.4194 (Fallback Mock)";
}
// 8. Network and Auto-reconnection Function
void reconnectNetwork() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi connection dropped! Reconnecting...");
WiFi.disconnect();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
delay(100);
}
}
System Connection Diagram
Hardware schematic detailing pin mappings between the ESP32 processing unit, MPU6050 accelerometer, and SIM808 GSM/GPS module.