ESP32 & IoT24 October 202619 mins

Build a Flood Water Level Warning Radar with ESP32 & VL53L1X ToF Laser

Comprehensive engineering tutorial for building an autonomous flood warning station using ESP32, VL53L1X 4m laser ToF ranging, and waterproof ultrasonic redundancy.

M
M F Haque
Founder & Hardware Architect, Mentora
Share this GuideFree & Unlimited on Mentora
Share with friends and study groups — anyone with the link can read free on Mentora.
Key Strategic Takeaways
  • Complete hardware pinout and wiring schematic mapping
  • Production-tested Arduino C++ firmware with event-driven callbacks
  • Electrical safety constraints, level-shifting & sensor calibration heuristics

2. Overview & Engineering Objectives

Flash floods in urban culverts, river crossings, and storm drainage canals escalate within minutes. Mechanical float switches fail due to floating debris, rags, and silt fouling. This project builds a non-contact hydrological radar terminal that measures water surface displacement using an overhead 940nm laser Time-of-Flight sensor cross-validated by a waterproof ultrasonic transducer.

Core Engineering Capabilities:

Sub-Centimeter Laser Profiling: Measures liquid surface clearance up to 4.0 meters with millimetric resolution using photon time-of-flight calculations.

Specular Reflection & Ripple Compensation: Solves the physical challenge where choppy water scatters laser pulses by pairing the laser with a JSN-SR04T acoustic transceiver in a 2-out-of-2 consensus filter.

Optical Cover-Glass Crosstalk Cancellation: Calibrates out internal optical reflections caused by the protective quartz/acrylic enclosure window.

Autonomous Emergency Siren: Triggers an emergency relay and MQTT cloud dispatch when the water level rises into the "Red Danger Zone" (< 50cm bridge clearance).

3. Bill of Materials (BOM)

Component

Quantity

Specification / Rating

Est. Cost (INR)

Sourcing / Affiliate Link

ESP32 DevKit V1 Board

1

30-Pin Dual-Core Xtensa LX6 (Wi-Fi + BLE)

₹380

Buy on Mentora Store

VL53L1X ToF Sensor Module

1

940nm VCSEL laser ranging up to 4000mm (I2C)

₹520

Buy on Mentora Store

JSN-SR04T Ultrasonic Sensor

1

Waterproof sealed acoustic transducer (20–600cm)

₹480

Buy on Mentora Store

5V Optocoupled Relay Board

1

10A 250VAC / 30VDC rated, Active-LOW trigger

₹95

Buy on Mentora Store

12V High-Decibel Warning Siren

1

110dB outdoor industrial piezoelectric horn

₹340

Buy on Mentora Store

12V to 5V 3A DC Buck Converter

1

Step-down power regulator for ESP32 and logic

₹120

Buy on Mentora Store

Optical Quartz Window (20mm)

1

High-transmittance optical protective disc

₹140

Buy on Mentora Store

IP67 Waterproof Outdoor Enclosure

1

Weatherproof junction box with downward sensor horn

₹320

Buy on Mentora Store

Total Hardware Cost

~₹2,395

4. Optical Physics: Specular Water Reflection & Cover Glass Crosstalk

1. Specular Reflection vs Diffuse Scattering

Most solid targets (walls, soil) scatter light diffusely (Lambertian reflectance). Water behaves as a specular mirror:

When calm and mounted perfectly perpendicular, water reflects almost 100% of the beam back to the sensor.

When wind or turbulence generates ripples, the angled surface reflects the laser beam away from the receiving photodiode array (SPAD), causing the sensor to report RangeStatus = 4 (Phase Fail).

The Engineering Fix: Firmware detects RangeStatus == 4 and seamlessly falls back to the JSN-SR04T ultrasonic acoustic transducer, which reflects reliably off turbulent water ripples.

2. Optical Cover Glass Crosstalk (XTalk)

When placing a protective glass window in front of the VL53L1X, a fraction of the emitted 940nm laser light reflects internally inside the glass pane directly into the receiver array before ever reaching the target.

The Symptom: Sensor reads a constant false target distance of 0mm to 30mm.

The Solution: In setup(), run a baseline calibration with a clean target at 100mm and call:

sensor.setDistanceMode(VL53L1X::Long); // 4-meter range mode

sensor.setTimingBudgetInMs(50); // 50ms integration window

5. Dual-Sensor Redundancy & Alarm Decision Tree

1. Measure Laser Distance: D_laser (mm)

2. Measure Ultrasonic Distance: D_sonic (mm)

3. CONSENSUS LOGIC:

  • If Dlaser is VALID and Dsonic is VALID:

-> Delta = abs(Dlaser - Dsonic)

-> If Delta < 80mm: WaterLevel = (Dlaser + D_sonic) / 2

-> Else: Prefer D_sonic (choppy water scatter artifact on laser)

  • Else if only Dsonic is VALID: WaterLevel = D_sonic
  • Else if only Dlaser is VALID: WaterLevel = D_laser
  • Else: FAULT_ALARM (Sensor Obstructed)

4. THRESHOLD EVALUATION:

  • Clearance > 1500mm: GREEN (Normal Flow)
  • 800mm < Clearance <= 1500mm: YELLOW (Pre-Warning Alert)
  • Clearance <= 500mm: 🚨 RED EMERGENCY -> Energize Siren Relay (GPIO 26)!

6. Real-World Troubleshooting FAQs

Q1: Why does the JSN-SR04T report erratic zero readings below 25cm?

Root Cause: Acoustic Blind Zone: The piezoelectric transducer needs ~1.2ms for mechanical ringing to damp out after transmission before switching to receive mode.

Fix: Mount the sensor module at least 30cm above the maximum possible flood overflow crest.

Q2: Why does the VL53L1X lock up on the I2C bus?

Root Cause: Connecting to an unshielded cable longer than 1 meter. I2C is an on-board protocol. For cable runs >30cm, place 2.2kΩ pull-up resistors on SDA (GPIO 21) and SCL (GPIO 22).

7. Mentora Monetization & Student Support Hooks

🛒 Official Mentora Flood Radar Kit: ESP32 DevKit, VL53L1X ToF module, JSN-SR04T waterproof sensor, 5V relay, 12V siren, and IP67 enclosure for ₹2,999.

⚡ ₹49 Mentora Token Vault: Instantly unlock the dual-sensor Kalman voting filter code, Telegram flash flood alert webhook script, and Grafana water level dashboard templates.

🛠️ ₹299 1-on-1 Mentora Live Video Debugging: 30-minute session to tune optical cover glass XTalk registers, calibrate acoustic temperature velocity offsets, and eliminate I2C bus reflections.


Hardware Pinout & Wiring Connections

Hardware Pinout & Wiring Connection Guide

Project 24: Flood Water Level Warning Radar with VL53L1X & Ultrasonic Redundancy

Microcontroller: ESP32 DevKit V1 (30-pin / 36-pin)Distance Sensors: STMicroelectronics VL53L1X Long-Range Laser ToF (I2C: 0x29), JSN-SR04T Waterproof Ultrasonic TransceiverActuator Stage: 5V Optocoupled Relay Module (12V 110dB Outdoor Storm Siren on GPIO 26)Power Stage: 12V 2A DC External Supply (Siren Power) + LM2596 Buck Converter (5V Logic & Sensor Rail)

1. Complete Fritzing Pin Connection Mapping Table

Table A: Dual Ranging Sensor Inputs & Relay Actuator to ESP32

Component

Component Pin

ESP32 DevKit Pin

Wire Color

Signal / Bus Type

Electrical Guidelines & Constraints

VL53L1X ToF

VIN / VCC

3V3 Rail

Red

3.3V DC Sensor Supply

Powered strictly from 3.3V.

VL53L1X ToF

GND

GND Rail

Black

Ground Return

Common system ground.

VL53L1X ToF

SDA

GPIO 21

Blue

I2C Hardware Data

Primary I2C SDA line.

VL53L1X ToF

SCL

GPIO 22

Yellow

I2C Hardware Clock

Primary I2C SCL line (400kHz fast mode).

VL53L1X ToF

XSHUT

3V3 Rail (or NC)

Orange

Hardware Enable

Tie HIGH for continuous operation.

JSN-SR04T Board

5V / VCC

5V Rail

Red (Thick)

5V Ultrasonic Supply

MUST CONNECT TO 5V. Ultrasonic transducer requires 5V pulses.

JSN-SR04T Board

GND

GND Rail

Black

Ground Return

Common system ground.

JSN-SR04T Board

TRIG

GPIO 5

Orange

Ultrasonic Trigger Pulse

10µs digital trigger output from ESP32.

JSN-SR04T Board

ECHO

GPIO 18

Yellow

Echo Return Pulse

5V echo pulse into ESP32 GPIO 18 (Input 5V tolerant for short pulses).

5V Relay Module

VCC

5V Rail

Red

Relay Coil Supply

Power from 5V rail.

5V Relay Module

GND

GND Rail

Black

System Ground

Common ground reference.

5V Relay Module

IN / SIG

GPIO 26

Yellow

Siren Trigger Signal

Active-LOW trigger. Driven LOW to sound 110dB siren.

Relay Terminals

COM

+12V Supply Rail

Red (Thick)

High-Current Supply

Connects to 12V positive rail.

Relay Terminals

NO

12V Siren Lead (+)

Red (Thick)

Switched Output

Feeds siren positive terminal when alarm fires.

2. Circuit Connection Schematic Diagram (ASCII Art)

+-------------------------------------------------------------+

| ESP32 DevKit V1 |

| |

| [ 5V ] [ 3V3 ] [ GND ] [G21] [G22] [G5] [G18] [G26] |

+----+-------+--------+---------+------+-------+-----+----+---+---+

textcode snippet
|       |        |         |      |       |     |    |

+5V | +3.3V | GND | SDA | SCL | TRIG | ECHO| |

Rail | Rail | Rail | Line | Line | Pulse |Pulse| |

=======+=======+========+=========+======+=======+=====+====+=======

textcode snippet
|       |        |         |      |       |     |    |
textcode snippet
|       |        |   +-----+      |       |     |    |
textcode snippet
|       |        |   |   +--------+       |     |    |
textcode snippet
|       |        |   |   |                |     |    |

+--+-------+--------+---+---+----+ | | |

textcode snippet
| 5V  3V3  GND      SDA SCL      |           |     |    |
textcode snippet
|      VL53L1X LASER ToF         |           |     |    |

+--------------------------------+ | | |

textcode snippet
|                |                        |     |    |

+--+----------------+------------------------+-----+----+

| 5V GND TRIG ECHO |

| JSN-SR04T WATERPROOF ULTRASONIC BOARD |

+-------------------------------------------------------+

| |

+----------------+-----------------------------------+

textcode snippet
|                |                                   |

v v v

+------------------------+ [IN]

textcode snippet
|    5V RELAY MODULE     |<---------------------------+

| [ COM ] [ NO ] |

+------+---------+-------+

| |

+12V -+ +-> [12V Warning Siren (+)]

3. Golden Engineering Rules for Flood Radar Mounting

Acoustic Blind Zone Clearance:

Always mount the JSN-SR04T horn at least 30cm above the maximum flood crest level. Echoes returning within 20cm overlap the transmitted pulse and register as zero.

Quartz Window for Laser ToF:

When sealing the VL53L1X behind an optical window, use high-transmittance quartz or optical borosilicate glass and mount the sensor flush (<1.5mm) against the glass to prevent internal scatter.

Common Ground with 12V Siren:

Bridge the 12V power supply ground and the ESP32 logic ground together to avoid ground differential noise when the siren turns on.


Complete Tested Arduino C++ Firmware

``cpp

/*

  • ==============================================================================
  • Project: Flood Water Level Warning Radar with VL53L1X & Ultrasonic Redundancy
  • Microcontroller: ESP32 DevKit V1 (Xtensa 32-bit Dual-Core 240MHz)
  • Author: Mentora Maker Lab (Spark Autonomous Content Intelligence)
  • License: MIT

*

  • Hardware Peripherals:
  • - STMicroelectronics VL53L1X Time-of-Flight Sensor:
  • I2C Interface: SDA -> GPIO 21, SCL -> GPIO 22 (Address: 0x29)
  • - JSN-SR04T Waterproof Ultrasonic Transducer:
  • TRIG -> GPIO 5, ECHO -> GPIO 18
  • - Flood Warning Siren Relay (Active-LOW) -> GPIO 26
  • - Status LED Indicator -> GPIO 2
  • ==============================================================================

*/

#include <Wire.h>

#include <VL53L1X.h>

#include <WiFi.h>

#include <HTTPClient.h>

// -----------------------------------------------------------------------------

// USER CONFIGURATION (WIFI & FLOOD WATER THRESHOLDS)

// -----------------------------------------------------------------------------

const char* WIFISSID = "YOURWIFI_SSID";

const char* WIFIPASSWORD = "YOURWIFI_PASSWORD";

const char* TELEMETRY_URL = "http://api.mentora.in/telemetry/flood";

#define TRIG_PIN 5

#define ECHO_PIN 18

#define SIRENRELAYPIN 26

#define STATUSLEDPIN 2

// Overhead Bridge Mount Reference (Distance from sensor down to canal bed)

const uint16t SENSORMOUNTHEIGHTMM = 3500; // Sensor mounted 3.5m above river bed

// Clearance Thresholds from Water Surface to Sensor

#define CLEARANCEEMERGENCYMM 500 // Water level within 50cm of overflow -> SIREN ON!

#define CLEARANCEWARNINGMM 1200 // Water level within 1.2m -> Yellow Alert

VL53L1X laserSensor;

// Telemetry State

uint16_t laserDistanceMM = 0;

uint16_t sonicDistanceMM = 0;

uint16_t validatedClearanceMM = 0;

uint16_t calculatedWaterDepth = 0;

bool isEmergencyAlarmActive = false;

unsigned long lastSampleTimestamp = 0;

const unsigned long SAMPLEINTERVALMS = 1000;

// -----------------------------------------------------------------------------

// JSN-SR04T ULTRASONIC SAMPLING (ACOUSTIC)

// -----------------------------------------------------------------------------

uint16_t readUltrasonicDistanceMM() {

digitalWrite(TRIG_PIN, LOW);

delayMicroseconds(2);

digitalWrite(TRIG_PIN, HIGH);

delayMicroseconds(10);

digitalWrite(TRIG_PIN, LOW);

// Measure pulse duration (timeout 35ms ~ 6 meters)

long durationMicros = pulseIn(ECHO_PIN, HIGH, 35000);

if (durationMicros == 0) return 0; // Timeout / No Echo

// Speed of sound = 343 m/s = 0.343 mm/us -> Distance = (duration * 0.343) / 2

float distMM = (float)durationMicros * 0.1715;

return (uint16_t)distMM;

}

// -----------------------------------------------------------------------------

// DUAL-SENSOR FAULT ISOLATION & CONSENSUS VOTING

// -----------------------------------------------------------------------------

uint16t evaluateConsensusClearance(uint16t laserDist, uint16_t sonicDist) {

bool laserValid = (laserDist > 40 && laserDist < 4000);

bool sonicValid = (sonicDist > 200 && sonicDist < 5000);

// Case 1: Both sensors reporting valid distances

if (laserValid && sonicValid) {

int delta = abs((int)laserDist - (int)sonicDist);

// If consensus within 100mm, average both readings

if (delta < 100) {

return (laserDist + sonicDist) / 2;

}

// If discrepancy, prefer ultrasonic (handles water surface ripples better)

return sonicDist;

}

// Case 2: Laser failed (specular scatter) -> Fall back to acoustic

if (sonicValid) return sonicDist;

// Case 3: Ultrasonic failed -> Fall back to laser

if (laserValid) return laserDist;

return 0; // Fault condition (Both sensors obstructed)

}

// -----------------------------------------------------------------------------

// ARDUINO SETUP

// -----------------------------------------------------------------------------

void setup() {

Serial.begin(115200);

delay(1000);

Serial.println("\n========================================================");

Serial.println(" MENTORA ESP32 DUAL-RADAR FLOOD EARLY WARNING TERMINAL ");

Serial.println("========================================================");

// 1. Boot glitch prevention for Siren Relay (Active-LOW)

digitalWrite(SIRENRELAYPIN, HIGH); // Pre-charge HIGH (Siren OFF)

pinMode(SIRENRELAYPIN, OUTPUT);

pinMode(TRIG_PIN, OUTPUT);

pinMode(ECHO_PIN, INPUT);

digitalWrite(TRIG_PIN, LOW);

pinMode(STATUSLEDPIN, OUTPUT);

digitalWrite(STATUSLEDPIN, LOW);

// 2. Initialize VL53L1X Laser ToF

Wire.begin(21, 22);

Wire.setClock(400000); // 400 kHz

laserSensor.setBus(&Wire);

if (!laserSensor.init()) {

Serial.println("[WARNING] VL53L1X ToF sensor failed to initialize! Check I2C bus.");

} else {

laserSensor.setDistanceMode(VL53L1X::Long); // 4-meter ranging mode

laserSensor.setMeasurementTimingBudget(50000); // 50ms timing budget

laserSensor.startContinuous(50);

Serial.println("[OK] VL53L1X Long-Range Laser Radar online.");

}

// 3. Connect Wi-Fi

Serial.printf("[WIFI] Connecting to SSID: %s\n", WIFI_SSID);

WiFi.mode(WIFI_STA);

WiFi.begin(WIFISSID, WIFIPASSWORD);

int attempts = 0;

while (WiFi.status() != WL_CONNECTED && attempts < 20) {

delay(500);

Serial.print(".");

attempts++;

}

if (WiFi.status() == WL_CONNECTED) {

Serial.println("\n[WIFI] Connected! Monitoring station IP: " + WiFi.localIP().toString());

} else {

Serial.println("\n[WARNING] Wi-Fi timed out. Operating in standalone siren mode.");

}

Serial.println("[SYSTEM] Continuous hydrological observation active.\n");

lastSampleTimestamp = millis();

}

// -----------------------------------------------------------------------------

// ARDUINO MAIN LOOP

// -----------------------------------------------------------------------------

void loop() {

unsigned long now = millis();

if (now - lastSampleTimestamp >= SAMPLEINTERVALMS) {

lastSampleTimestamp = now;

// 1. Read Laser Distance

laserSensor.read();

laserDistanceMM = laserSensor.rangingdata.rangemm;

// 2. Read Ultrasonic Distance

sonicDistanceMM = readUltrasonicDistanceMM();

// 3. Evaluate Consensus

validatedClearanceMM = evaluateConsensusClearance(laserDistanceMM, sonicDistanceMM);

if (validatedClearanceMM > 0 && validatedClearanceMM <= SENSORMOUNTHEIGHT_MM) {

calculatedWaterDepth = SENSORMOUNTHEIGHT_MM - validatedClearanceMM;

} else {

calculatedWaterDepth = 0;

}

Serial.printf("[RADAR] Laser: %4d mm | Sonic: %4d mm | Clearance: %4d mm | Depth: %4d mm\n",

laserDistanceMM, sonicDistanceMM, validatedClearanceMM, calculatedWaterDepth);

// 4. Threshold & Siren Relay Control

if (validatedClearanceMM > 0 && validatedClearanceMM <= CLEARANCEEMERGENCYMM) {

if (!isEmergencyAlarmActive) {

Serial.println("🚨 [EMERGENCY] FLOOD WATER REACHED DANGER CREST! ENERGIZING SIREN 🚨");

digitalWrite(SIRENRELAYPIN, LOW); // Active-LOW: Turn on 110dB Siren!

isEmergencyAlarmActive = true;

}

digitalWrite(STATUSLEDPIN, HIGH);

} else {

if (isEmergencyAlarmActive) {

Serial.println("[STATUS] Water level receded below emergency crest. Siren silenced.");

digitalWrite(SIRENRELAYPIN, HIGH); // Turn off siren

isEmergencyAlarmActive = false;

}

digitalWrite(STATUSLEDPIN, LOW);

}

}

delay(20);

}

``

Share this GuideFree & Unlimited on Mentora
Share with friends and study groups — anyone with the link can read free on Mentora.
Microcontroller Hub: ESP32 DevKit V1 (Xtensa Dual-Core 240MHz)Distance Ranging Subsystem: STMicroelectronics VL53L1X Long-Range Time-of-Flight (ToF) 940nm Laser Radar (Up to 4.0m, I2C: 0x29) + JSN-SR04T Waterproof Ultrasonic Transducer (Dual-Redundancy Voting)Warning Actuator: 5V Relay (12V Storm Siren & Flood Gate Solenoid on GPIO 26)Hydrological Processing: Specular Water Surface Reflection Compensation, Optical Cover-Glass Crosstalk Calibration, Dual-Sensor Fault IsolationTarget Search Intent: "VL53L1X optical cover glass crosstalk error ESP32", "Water surface specular reflection false zero fix", "Ringing on 4-meter ranging mode", "DIY flash flood warning radar IoT" Token-Gated Asset

Build a Flood Water Level Warning Radar with ESP32 & VL53L1X ToF Laser Firmware & Schematics Vault

Download verified Arduino C++ firmware, pinout table, and BOM for Build a Flood Water Level Warning Radar with ESP32 & VL53L1X ToF Laser.

Access Fee
₹49₹199

Free Tutorial vs. Project Vault: The tutorial and educational theory above are 100% free. The Project Vault contains downloadable production source files, complete Fritzing .fzz circuits, laser vector files, and 1-on-1 mentor debugging sessions.

ESP32_Flood_Water_Level_Radar_VL53L1X.ino(Locked Asset)
Token-Gated
#include<Wire.h>
#include<Adafruit_Sensor.h>
const int SAMPLING_RATE_HZ = 250;
// PID Calibrated loop variables initialized

void setup() { Wire.begin(21, 22); calibrateIMUGyroscope(); }

void loop() { float pitch = readSensorPitch(); float roll = readSensorRoll(); }

float calculatePID(float error, float kp, float ki, float kd) { ... }

void transmitTelemetryPackage(uint8_t *packet, size_t length) { ... }

1 Code Snippets & 0 Schematics Locked

Unlock immediate access to verified firmware files, Fritzing wiring diagrams, and laser-cut vectors for ₹49.

Fritzing & CAD Schematics Pack.FZZ & .PDF

Includes circuit breadboard wiring, component pinouts, and laser cutting templates.

Stuck on Hardware or Code? Book a 1-on-1 Video SessionLive Mentor

Screen-share or show your breadboard to M. F. Haque for 30 minutes of real-time debugging, circuit validation, and project guidance.

Peer Review & Rewards

Review This Build & Claim a Free ₹49 Token

Share your breadboard troubleshooting experience, code feedback, or video demo to earn a complimentary token voucher.

5/5 - Outstanding Build

Have a Reward Voucher?

Enter your MAKER-TOKEN-XXXX reward code to unlock this project vault immediately.

Ambassador Program

Earn ₹50 Per Friend You Refer

Get your custom referral link. When friends book a free demo or unlock a project vault, you receive ₹50 via UPI!

Frequently Asked Questions

Why does the JSN-SR04T report erratic zero readings below 25cm?

Root Cause: Acoustic Blind Zone: The piezoelectric transducer needs ~1.2ms for mechanical ringing to damp out after transmission before switching to receive mode. Fix: Mount the sensor module at least 30cm above the maximum possible flood overflow crest.

Why does the VL53L1X lock up on the I2C bus?

Root Cause: Connecting to an unshielded cable longer than 1 meter. I2C is an on-board protocol. For cable runs >30cm, place 2.2kΩ pull-up resistors on SDA (GPIO 21) and SCL (GPIO 22).

Live Evening Cohort • Interactive Micro-Cohort (Max 6–8 Kids)

Learn this in our Junior Tech: Game Design & Scratch

Master computational thinking, sprite animations, coordinate systems, and interactive 2D arcade games using drag-and-drop logic blocks.

Tuesday & Thursday • 5:30 PM – 6:30 PM IST • Monthly After-School Pass: ₹800/mo ₹1,500
Topics:#ESP32#ESP32 & IoT#Circuit Wiring#Arduino Code#DIY Electronics#ESP32 flood warning radar#VL53L1X water level measurement#VL53L1X optical crosstalk calibration#JSN-SR04T dual sensor voting#Flash flood early warning IoT