#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h> // For the ILI9341 TFT display
// Define the TFT and Buzzer pins
#define TFT_CS 5
#define TFT_RST 4
#define TFT_DC 2
#define BUZZER_PIN 12 // Pin for the buzzer
#define LED_PIN 14 // Pin for the LED
// Create display object
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Create MPU6050 object
Adafruit_MPU6050 mpu;
// Constants for seismograph graph
#define SEISMOGRAPH_START_X 10
#define SEISMOGRAPH_START_Y 180
#define SEISMOGRAPH_WIDTH 220
#define SEISMOGRAPH_HEIGHT 50
#define MAX_HISTORY SEISMOGRAPH_WIDTH
float xHistory[MAX_HISTORY];
float yHistory[MAX_HISTORY];
float zHistory[MAX_HISTORY];
int historyIndex = 0;
bool earthquakeDetected = false;
void setup() {
Serial.begin(115200);
// Initialize MPU6050
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) { delay(10); }
}
Serial.println("MPU6050 Found!");
// Set accelerometer and gyroscope ranges
mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
// Initialize TFT display
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
// Display static text (header)
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(10, 10);
// Initialize buzzer and LED pins
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW); // Start with buzzer off
digitalWrite(LED_PIN, LOW); // Start with LED off
// Labels for X, Y, Z accelerometer values
tft.setCursor(10, 40);
tft.print("Accel X: ");
tft.setCursor(10, 60);
tft.print("Accel Y: ");
tft.setCursor(10, 80);
tft.print("Accel Z: ");
// Labels for intensity and level
tft.setCursor(10, 120);
tft.print("Intensity: ");
tft.setCursor(10, 140);
tft.print("Level: ");
// Initialize history array
for (int i = 0; i < MAX_HISTORY; i++) {
xHistory[i] = 0;
yHistory[i] = 0;
zHistory[i] = 0;
}
}
String getIntensityLevel(float intensity) {
if (intensity < 1.0) {
return "No Activity";
} else if (intensity < 2.0) {
return "Light";
} else if (intensity < 3.0) {
return "Moderate";
} else if (intensity < 4.0) {
return "Strong";
} else {
return "Severe";
}
}
void plotSeismograph() {
int startX = SEISMOGRAPH_START_X;
int startY = SEISMOGRAPH_START_Y;
// Draw background rectangle for the seismograph
tft.drawRect(startX, startY, SEISMOGRAPH_WIDTH, SEISMOGRAPH_HEIGHT, ILI9341_WHITE);
// Check if all accelerations are zero
if (xHistory[historyIndex] == 0 && yHistory[historyIndex] == 0 && zHistory[historyIndex] == 0) {
// Draw a flat line at the center of the seismograph
int centerY = startY + SEISMOGRAPH_HEIGHT / 2;
tft.drawLine(startX, centerY, startX + SEISMOGRAPH_WIDTH, centerY, ILI9341_WHITE);
} else {
// Draw the X, Y, and Z graphs if there is activity
for (int i = 0; i < MAX_HISTORY - 1; i++) {
int x1 = startX + i;
int x2 = startX + i + 1;
// Map the acceleration to the height of the seismograph
int y1X = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(xHistory[i] * 5);
int y2X = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(xHistory[i + 1] * 5);
tft.drawLine(x1, y1X, x2, y2X, ILI9341_RED); // X axis in red
int y1Y = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(yHistory[i] * 5);
int y2Y = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(yHistory[i + 1] * 5);
tft.drawLine(x1, y1Y, x2, y2Y, ILI9341_YELLOW); // Y axis in yellow
int y1Z = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(zHistory[i] * 5);
int y2Z = startY + SEISMOGRAPH_HEIGHT / 2 - (int)(zHistory[i + 1] * 5);
tft.drawLine(x1, y1Z, x2, y2Z, ILI9341_BLUE); // Z axis in blue
}
}
}
void loop() {
// Get sensor event for accelerometer and gyroscope
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
// Capture the accelerometer values
float ax = a.acceleration.x;
float ay = a.acceleration.y;
float az = a.acceleration.z;
// Calculate total acceleration (Euclidean distance)
float totalAccel = sqrt(ax * ax + ay * ay + az * az);
// Compute intensity (can scale this if needed)
float intensity = totalAccel - 9.8; // Subtracting 9.8 to account for Earth's gravity
// Update accelerometer values without clearing the entire screen
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // Text with black background to overwrite
tft.setCursor(100, 40); tft.print(ax, 3); // Update X value
tft.setCursor(100, 60); tft.print(ay, 3); // Update Y value
tft.setCursor(100, 80); tft.print(az, 3); // Update Z value
// Update intensity and level
tft.setCursor(120, 120);
tft.print(intensity, 3); // Update intensity
String intensityLevel = getIntensityLevel(intensity);
tft.setCursor(80, 140);
tft.print(intensityLevel); // Update level
// Add current accelerometer readings to history for the seismograph
xHistory[historyIndex] = ax;
yHistory[historyIndex] = ay;
zHistory[historyIndex] = az;
historyIndex = (historyIndex + 1) % MAX_HISTORY; // Wrap around the history buffer
// Clear the previous seismograph area before redrawing it
tft.fillRect(SEISMOGRAPH_START_X + 1, SEISMOGRAPH_START_Y + 1, SEISMOGRAPH_WIDTH - 2, SEISMOGRAPH_HEIGHT - 2, ILI9341_BLACK);
// Plot the seismograph with the latest readings
plotSeismograph();
// Activate buzzer and LED if intensity is greater than or equal to 3
if (intensity >= 3.0) {
digitalWrite(BUZZER_PIN, HIGH); // Sound the buzzer
digitalWrite(LED_PIN, HIGH); // Turn on the LED
} else {
digitalWrite(BUZZER_PIN, LOW); // Turn off the buzzer
digitalWrite(LED_PIN, LOW); // Turn off the LED
}
// Serial debug (to check if the values are being read)
Serial.print("Accel X: "); Serial.println(ax);
Serial.print("Accel Y: "); Serial.println(ay);
Serial.print("Accel Z: "); Serial.println(az);
Serial.print("Intensity: "); Serial.println(intensity);
Serial.print("Level: "); Serial.println(getIntensityLevel(intensity));
delay(500); // Update every 500ms
}