Community project

Tsunami Detection Alarm

gautam biju

Published August 11, 2026

ESP327 components5 assembly steps
Remix this project
Photo of Tsunami Detection AlarmGenerated with AI

This project builds a detection system that monitors for rapid water level changes and ground vibrations, two key indicators of tsunami activity. The ESP32 microcontroller combines an ultrasonic distance sensor to track water height, a vibration sensor to detect seismic activity, and audio-visual alerts (buzzer and LED) to warn of potential danger.

The guide provides a complete wiring diagram, parts list, and step-by-step assembly instructions for connecting all components safely to the ESP32. The included firmware continuously samples the distance sensor with noise filtering, triggers an alarm when water levels shift suddenly or vibrations are detected, and maintains the alert for a set duration to ensure the warning is noticed.

Wiring diagram

Interactive · read-only
Wiring diagram for Tsunami Detection Alarm

Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.

Parts list

Bill of materials
ComponentQtyNotes
SW-420 Vibration Sensor ModuleSW-420 module1Non-directional vibration detection module based on the SW-420 vibration switch and LM393 voltage comparator. Outputs a digital HIGH/LOW signal on the DO pin when vibration or movement is detected. Sensitivity is adjustable via an on-board 10 kΩ potentiometer. Operates at 3.3 V or 5 V, making it fully compatible with the Raspberry Pi Pico's 3.3 V logic. No external library is required — standard digitalRead() calls are sufficient.
HC-SR04HC-SR041Ultrasonic distance measurement sensor
Yellow 5 mm LEDYellow1A yellow light that turns on while the vibration sensor reports movement.
220 ohm Resistor220 Ω1The small part that limits current so the yellow LED is not damaged.
1 kΩ Resistor1 kΩ1The upper resistor of the Echo voltage divider, reducing the HC-SR04 5 V signal safely.
2 kΩ Resistor2 kΩ1The lower resistor of the Echo voltage divider, taking the divider junction to ground.
Buzzer3.3 V active buzzer1Piezo buzzer for sound output

Assembly

5 steps
  1. Make shared power rows

    Place the ESP32 beside the breadboard. Use one jumper from ESP32 3V3 to a positive breadboard row and one from ESP32 GND to a ground row. Use another jumper from ESP32 VIN/5V to a separate 5 V row for the ultrasonic sensor. Every ground row used by the parts must connect back to ESP32 GND.

    • Tip: Keep the 3.3 V and 5 V rows separate; label them with tape if that helps.
    • Do not join the ESP32 3V3 row to the 5 V row — 5 V on an ESP32 signal or 3.3 V pin can damage the board.
  2. Wire the vibration warning light

    Connect the SW-420 VCC pin to 3V3 (power), GND to GND (ground), and DO to GPIO32 (signal). Put the yellow LED across the breadboard center gap: its long leg goes to one end of the 220 Ω resistor, the other resistor end goes to GPIO26 (signal), and its short leg/flat-side leg goes to GND (ground).

    • Tip: Turn the small screw on the SW-420 module later if normal table movement does not switch the yellow LED on and off.
    • Make sure the LED long and short legs are not swapped — reversed LEDs do not light.
  3. Wire the water-distance sensor safely

    Connect HC-SR04 VCC to the separate 5 V row (power), GND to GND (ground), and TRIG to GPIO25 (signal). Connect HC-SR04 ECHO to one end of the 1 kΩ resistor. Join the other end of that 1 kΩ resistor, one end of the 2 kΩ resistor, and GPIO33 in the same breadboard row (signal). Connect the free end of the 2 kΩ resistor to GND (ground).

    • Tip: The two resistors make a safe meeting point: 1 kΩ comes from ECHO, 2 kΩ goes to ground, and GPIO33 joins that meeting point.
    • Never connect the HC-SR04 ECHO pin straight to an ESP32 pin — its 5 V signal can damage the ESP32. Keep the sensor facing down toward still water and keep its electronics dry.
  4. Wire the alarm buzzer

    Connect the buzzer SIGNAL or + pin to GPIO27 (signal) and its GND or − pin to GND (ground). If it is an unmarked two-leg buzzer, use the leg marked + for GPIO27 and the other leg for GND.

    • Tip: This design expects a small 3.3 V active buzzer. An active buzzer makes a sound when it receives a steady on signal.
    • Do not use a larger high-current buzzer directly from GPIO27; it can overload the ESP32 pin.
  5. Position and test the sensors

    Mount the HC-SR04 above the water so its two round openings point straight down and have a clear path to the water surface. Keep the ESP32, breadboard, SW-420 board, LED, and buzzer dry and away from splash zones. Connect the ESP32 to USB, then press Deploy in Schematik. After it starts, the first distance is the reference; move the water surface or sensor by at least 3 cm to hear the 10-second alarm.

    • Tip: A ruler is useful: raise or lower the water by at least 3 cm between one-second readings. The yellow LED should follow vibration separately from the water alarm.
    • This breadboard project is an educational local water-level-change alarm, not a certified tsunami-warning instrument. Keep mains electricity and the USB connection away from water.

Pin assignments

Board wiring reference
PinConnectionType
3V3vibration_sensor VCCpower
GNDvibration_sensor GNDground
VINultrasonic_sensor VCCpower
GNDultrasonic_sensor GNDground
GPIO 25ultrasonic_sensor TRIGdigital
EXTultrasonic_sensor ECHO1 kΩ Resistor End 1digital
GNDecho_resistor_bottom End 2ground
GPIO 26led_resistor End 1digital
EXTled_resistor End 2Yellow 5 mm LED Anodedigital
GNDyellow_led Cathodeground
GPIO 27alarm_buzzer SIGNALdigital
GNDalarm_buzzer GNDground
GPIO 32vibration_sensor DOdigital
GPIO 33echo_resistor_top End 2digital
EXTecho_resistor_bottom End 11 kΩ Resistor End 2digital

Firmware

ESP32
main.cppDeploy to device
#include <Arduino.h>


// Forward declarations
float readDistanceCm();
float medianOfThreeDistances();
void setBuzzer(bool enabled);

const int VIBRATION_PIN = 32;
const int TRIG_PIN = 25;
const int ECHO_PIN = 33;
const int YELLOW_LED_PIN = 26;
const int BUZZER_PIN = 27;

const unsigned long SAMPLE_INTERVAL_MS = 1000;
const unsigned long ALARM_DURATION_MS = 10000;
const float CHANGE_THRESHOLD_CM = 3.0f;
const int BUZZER_CHANNEL = 0;
const int BUZZER_FREQUENCY_HZ = 2000;

float previousDistanceCm = -1.0f;
unsigned long lastSampleMs = 0;
unsigned long alarmUntilMs = 0;

float readDistanceCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(3);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  unsigned long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  if (duration == 0) {
    return -1.0f;
  }

  float distance = (duration * 0.0343f) / 2.0f;
  if (distance < 2.0f || distance > 400.0f) {
    return -1.0f;
  }
  return distance;
}

float medianOfThreeDistances() {
  float readings[3];
  int validCount = 0;

  for (int i = 0; i < 3; i++) {
    float reading = readDistanceCm();
    if (reading > 0.0f) {
      readings[validCount++] = reading;
    }
    delay(60);
  }

  if (validCount == 0) {
    return -1.0f;
  }
  if (validCount == 1) {
    return readings[0];
  }
  if (validCount == 2) {
    return (readings[0] + readings[1]) / 2.0f;
  }

  if (readings[0] > readings[1]) {
    float temp = readings[0];
    readings[0] = readings[1];
    readings[1] = temp;
  }
  if (readings[1] > readings[2]) {
    float temp = readings[1];
    readings[1] = readings[2];
    readings[2] = temp;
  }
  if (readings[0] > readings[1]) {
    float temp = readings[0];
    readings[0] = readings[1];
    readings[1] = temp;
  }
  return readings[1];
}

void setBuzzer(bool enabled) {
  if (enabled) {
    ledcWriteTone(BUZZER_CHANNEL, BUZZER_FREQUENCY_HZ);
  } else {
    ledcWriteTone(BUZZER_CHANNEL, 0);
  }
}

void setup() {
  Serial.begin(115200);

  pinMode(VIBRATION_PIN, INPUT);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  digitalWrite(YELLOW_LED_PIN, LOW);

  ledcSetup(BUZZER_CHANNEL, BUZZER_FREQUENCY_HZ, 8);
  ledcAttachPin(BUZZER_PIN, BUZZER_CHANNEL);
  setBuzzer(false);

  Serial.println("Tsunami detector started. Waiting for first water-level reading.");
}

void loop() {
  // Most SW-420 modules output HIGH while the sensor is vibrating.
  bool vibrationDetected = digitalRead(VIBRATION_PIN) == HIGH;
  digitalWrite(YELLOW_LED_PIN, vibrationDetected ? HIGH : LOW);

  unsigned long now = millis();
  if (now - lastSampleMs >= SAMPLE_INTERVAL_MS) {
    lastSampleMs = now;
    float currentDistanceCm = medianOfThreeDistances();

    if (currentDistanceCm > 0.0f) {
      if (previousDistanceCm > 0.0f) {
        float changeCm = fabsf(currentDistanceCm - previousDistanceCm);
        Serial.print("Water surface distance: ");
        Serial.print(currentDistanceCm, 1);
        Serial.print(" cm; change: ");
        Serial.print(changeCm, 1);
        Serial.println(" cm");

        if (changeCm >= CHANGE_THRESHOLD_CM) {
          alarmUntilMs = now + ALARM_DURATION_MS;
          Serial.println("Water-level alarm: 3 cm or greater change detected.");
        }
      } else {
        Serial.print("Reference water-surface distance: ");
        Serial.print(currentDistanceCm, 1);
        Serial.println(" cm");
      }
      previousDistanceCm = currentDistanceCm;
    } else {
      Serial.println("No usable ultrasonic reading; check that the sensor faces the water.");
    }
  }

  bool alarmActive = (long)(alarmUntilMs - now) > 0;
  setBuzzer(alarmActive);
}

“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik