River-Level Monitoring with ESP32 and GSM: A Monsoon Design Sketch
A low-cost river-level node for Assam's monsoon can be an ESP32, a waterproof ultrasonic sensor mounted on a bridge or post above the water, a GSM module and a small solar panel. It measures the distance down to the water every few minutes, works out the level and how fast it's rising, and sends an SMS when either crosses a threshold. It won't replace official flood forecasts, but it can watch a stream or channel that nobody else is watching.
Where this comes from: I haven't deployed a flood sensor. I've built a live weather station on an ESP32 and NodeMCU that cross-checked BME280 readings against OpenWeatherMap data to catch sensor drift, and a garden automation system that sent readings and alerts over a GSM/GPRS link. This sketch combines those two ideas for a river bank, and I've marked the parts I'd want to test in the field.
What already exists, and where a DIY node fits
Assam isn't short of official flood monitoring on its big rivers. A 2024 Rajya Sabha reply lists 30 Central Water Commission level-forecasting stations in Assam, and NESAC's FLEWS model lets ASDMA send district alerts with a lead time of about 24 to 36 hours.
Those stations sit on the main rivers. The gaps are smaller: a tributary behind a village, a drainage channel next to a school, a stream that cuts the road to a tea estate's far sections. That's where one or two cheap nodes make sense, owned by the people who live next to the water. They should always point people to official warnings first.
The parts
| Part | What I'd use | Why |
|---|---|---|
| Controller | ESP32 | Deep sleep, enough pins, cheap and easy to find |
| Level sensor | Waterproof ultrasonic module, such as the JSN-SR04T | Non-contact, nothing in the water |
| Air temperature | Any sealed sensor in a shade | Corrects the speed of sound |
| Network | 4G module with 2G fallback | Sends data and SMS where coverage exists |
| Power | Small solar panel, Li-ion cell, charge controller | Runs through cloudy weeks |
| Enclosure | Sealed box, cable glands, vent | Monsoon humidity gets into everything |
Why ultrasonic, mounted above the water
You have three realistic choices for measuring level on a budget:
- Ultrasonic, looking down. Easy to mount on a bridge railing or a post, and nothing touches the water, so silt and floating debris don't damage it. The JSN-SR04T has a sealed transducer head on a cable, but the control board isn't waterproof, so it goes inside the box. Published specs vary between vendors; the 2.0 datasheet and most listings give a blind zone of roughly 20 to 25 cm and a maximum of a few metres. Check the version you buy.
- Pressure sensor, submerged. Gives steady readings, but in a muddy monsoon river it gets buried, clogged or dragged away. It's also hard to retrieve for maintenance when the water is high, which is exactly when it matters.
- Radar level sensor. Handles rain, foam and fog better than ultrasonic. It costs more, so I'd treat it as the upgrade once a pilot has shown the site is worth it.
I'd start with ultrasonic. Mount it high enough that even at the highest flood you expect, the water stays further from the sensor than its blind zone, and over a spot where the water surface is calm rather than churning around a pillar.
Correcting for temperature
Ultrasonic sensors measure time, not distance. The speed of sound in air rises by about 0.6 m/s per degree Celsius, so a reading taken on a cool monsoon night and one taken on a hot afternoon will disagree slightly if you use a fixed speed. A cheap air temperature sensor next to the transducer fixes that: calculate the speed from the temperature, then the distance from the echo time.
Readings that ignore ripples and rain
A single ultrasonic reading over moving water is noisy: waves, raindrops, an insect, a floating branch. On each wake-up I'd take 10 to 15 readings a few hundred milliseconds apart, drop anything outside the sensor's range, and keep the median. Then:
- Level = mounting height minus measured distance.
- Rate of rise = change in level over the last 30 to 60 minutes, in centimetres per hour.
- Sanity check = if the level jumps by more than the river could physically manage in one interval, flag it as a bad reading rather than an emergency.
In my weather station, comparing local readings against an outside source was how I spotted drift. Here, if the node sits upstream or downstream of a CWC station on the same river, its published level is a useful cross-check over a season.
Alerts on how fast it rises, not just how high
A fixed "danger level" is the obvious alert, but on a small stream the useful warning is usually the speed. A channel that rises 30 cm in an hour after heavy rain upstream is a reason to move things to higher ground, even if it's still well below the bank.
I'd set three alerts, agreed with the people who'll receive them:
- Watch: rate of rise above a set threshold for two readings in a row.
- Warning: level above a marked point on the bank or bridge pillar.
- Node problem: no reading for an hour, battery low, or repeated bad readings.
When the rate crosses the watch threshold, the node should switch from reading every 15 minutes to every 2 to 5 minutes. My garden build used a similar idea: it only ran the pump when several conditions agreed, which avoided acting on one odd reading.
Getting data out over GSM
Mobile coverage near rivers in Assam can be patchy, and it can get worse when power cuts hit towers during a flood. Three rules:
- Buffer locally. Store every reading in flash and upload the backlog when the network returns. A gap in the graph is fine; losing data isn't.
- Use SMS for alerts. SMS often gets through when mobile data won't. Send readings as data, and alerts as both data and SMS to a short list of numbers.
- Pick the module carefully. The popular SIM800L is 2G-only. Airtel and Vi still run 2G, while Jio has no 2G network and has pushed for a 2G shutdown policy. For a node meant to last several seasons, I'd use a 4G module with 2G fallback and test which operator actually has signal at the site.
For the data link itself, small MQTT messages are lighter than HTTP over a weak connection. I covered that in best practices for MQTT telemetry.
Power for weeks of cloud
The monsoon means many days with little sun, so size for the worst week, not the average. The ESP32 spends almost all its time in deep sleep, waking to read and send; I wrote about the sleep modes in ESP32 deep sleep and wake sources. The GSM module is the hungry part, so power it through a switch and only turn it on to send. A pilot through one monsoon will tell you more about real consumption than any calculation.
What I'd do
If a village, school or estate in Assam asked me about this, I'd suggest:
- One node first, on a stream that floods often and has a safe mounting point.
- A painted gauge on the bridge pillar next to it, so people can check the sensor by eye.
- A full monsoon of data before anyone relies on the alerts, with thresholds tuned to what actually happened.
- A simple dashboard showing level, rate of rise and node health, plus SMS to a few named people.
I'd also reuse the approach from my tea garden IoT note: start small, test through a real season, then decide whether more nodes are worth it.
If you're planning something like this, my IoT development work in Assam covers sensor nodes, GSM telemetry and dashboards.
Frequently Asked Questions
Q:Can an ESP32 river-level sensor replace official flood warnings?
No. In Assam, the Central Water Commission issues flood forecasts from its gauge stations, and ASDMA issues district alerts. A low-cost node is useful as a local supplement: it watches one stream or channel that no official station covers and tells the people nearby how fast it is rising.
Q:Which sensor is best for measuring river level on a budget?
A non-contact sensor mounted above the water, such as a waterproof ultrasonic module, is the easiest to start with because nothing sits in the silt and debris. Submerged pressure sensors give steady readings but clog and get buried. Radar level sensors handle rain and foam better but cost more.
Q:Will a SIM800L GSM module still work in India?
The SIM800L is 2G-only, so it works only on operators that still run 2G and only where their 2G coverage reaches. Jio has no 2G network. For a node you want to last several seasons, a 4G module that can fall back to 2G is the safer choice.
Q:How often should a river-level node take readings?
Every 15 minutes is a reasonable default for a slow river. When the level starts rising faster than your set threshold, switch to every 2 to 5 minutes, and send an alert. Taking several readings per wake-up and using the median filters out ripples and splashes.
Related Engineering Notes
Related Project Cases
Matching Services Tracks
Working on something similar?
Let's collaborate to design custom PCB schematics, write deterministic FreeRTOS threads, or configure secure Next.js databases.