Initializing Earthquake Monitoring System Dashboard
Connecting to hardware core...

Smart IoT-Based Earthquake Monitoring and Early Warning System

Developed by: Kshitiz Mishra
Visit Portfolio

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.

Hardware Connection Diagram