Contents — 26 sections
Project Overview
Watches sewer level and toxic gas inside a manhole — warning of flooding before it hits the street and of the lethal atmosphere before a worker climbs in.
A manhole is two hazards in one hole. As a sewer or drainage access, its level rising toward the surface is an early sign of a blockage or a flood about to back up into streets and homes — caught early, it can be cleared before it overflows. And as a confined space, its atmosphere can be lethal: sewers generate hydrogen sulphide (toxic and, at higher levels, deadly), methane (explosive), carbon monoxide, and oxygen-deficient pockets — and workers die every year entering manholes with a bad atmosphere they could not see. This project monitors both continuously: the level, for flood/blockage early warning, and the toxic gases, for worker and public safety.
The monitor sits in the manhole and senses level (an ultrasonic or pressure sensor tracking how high the water/sewage has risen) and the gases that matter in a sewer — hydrogen sulphide, methane/combustible gas, carbon monoxide, and oxygen level. A rising level trending toward overflow triggers a flood/blockage alert with enough lead time to respond; a dangerous gas concentration triggers a safety alert. Because a manhole is a classic confined space, the gas data does double duty: it feeds a live picture for public/flood safety, and — critically — it can tell a worker (and their supervisor) the atmosphere before anyone descends, complementing the personal gas detector that confined-space entry legally requires.
Manholes are buried, wet, corrosive and without power, so the monitor is battery-powered and reports over LoRa, ruggedised and sealed, with cover-open detection as a bonus (an opened cover may mean unauthorised entry or theft). It is emphatic about scope and safety: this is a monitoring and early-warning aid, not a substitute for the certified, calibrated, personal gas detectors and the confined-space entry procedures that law and life-safety demand — no one should ever enter a manhole relying on a fixed monitor instead of proper detection and procedure. But as a manhole safety monitor, it delivers two genuinely valuable things a city otherwise lacks: early warning of sewer flooding before it reaches the street, and continuous awareness of the toxic atmosphere in a space that kills workers who cannot see the danger.
What this project does
- Monitors manhole/sewer level for flood/blockage early warning
- Senses toxic/explosive gases (H₂S, methane, CO) and oxygen level
- Alerts on rising level trending toward overflow
- Alerts on dangerous gas concentrations
- Provides atmosphere awareness before confined-space entry
- Detects cover-open (unauthorised entry/theft)
- Runs on battery + LoRa from buried, powerless infrastructure
Real-World Applications
| Setting | How it is used |
|---|---|
| Sewer flood/blockage early warning | Catching rising levels before they back up into streets/homes. |
| Confined-space / worker safety awareness | Atmosphere awareness before/around manhole entry (with certified detectors and procedures). |
| Utility asset monitoring | Level, gas and cover status across a network of manholes. |
| Public safety / smart city | City-wide sewer and drainage safety monitoring. |
Deployment contexts where a build of this kind earns its keep.
Features & Capabilities
- Dual hazard: flood level + toxic atmosphere
- Sewer gas sensing (H₂S/CH₄/CO/O₂)
- Flood/blockage early warning with lead time
- Pre-entry atmosphere awareness (complements personal detectors)
- Cover-open detection
- Battery + LoRa, rugged/sealed
- Explicit: aid, NOT a substitute for certified detectors/procedures
Difficulty, Time & Required Skills
| Attribute | Value |
|---|---|
| Difficulty level | Advanced |
| Estimated completion time | 12–18 hours |
| Indicative build cost | ₹4,500 – ₹7,000 |
| Primary discipline | Smart City |
| Reference platform | ESP32 DevKit V1 (ESP-WROOM-32) |
Skills you should have (or will pick up)
- Level sensing (ultrasonic/pressure) in a manhole
- Sewer gas sensing (H₂S/CH₄/CO/O₂)
- Flood early warning and gas alarming
- LoRa + battery for buried infrastructure
- Confined-space safety awareness (scope/limits)
Bill of Materials
Every part below is commonly available from Indian and international hobby-electronics suppliers. Prices are indicative 2026 retail figures in Indian rupees and will drift — treat them as a budgeting guide, not a quotation.
| Component | Key specification | Qty | Approx. cost |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) Wi-Fi transmit bursts peak near 500 mA — size the regulator accordingly. | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18× 12-bit ADC, 2× 8-bit DAC | 1 | ₹450 |
| JSN-SR04T waterproof ultrasonic sensor The 25 cm blind zone matters — mount it above the maximum expected water level. | 25–450 cm, ±1 cm, IP67 sealed transducer, 45° beam | 1 | ₹450 |
| mq4 | — | 1 | — |
| MQ-7 carbon monoxide sensor Requires an alternating 60 s / 90 s heater cycle to read correctly — a constant 5 V gives wrong numbers. | 20–2000 ppm CO, dual-heater cycle (1.4 V / 5 V), analogue output | 1 | ₹260 |
| Dissolved-oxygen probe (galvanic) The membrane and electrolyte are consumables — budget a replacement every 6–12 months. | 0–20 mg/L, ±0.3 mg/L, galvanic, no warm-up, membrane cap consumable | 1 | ₹5,800 |
| Reed switch + magnet pair (door contact) Wire it normally-closed so a cut cable reads the same as an open door — fail-safe by construction. | NO contact, 10–15 mm operating gap, 100 V / 0.5 A, > 10⁷ operations | 1 | ₹55 |
| SX1278 LoRa 433 MHz module (Ra-02) Never power the radio without an antenna — the PA will destroy itself. | −148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7–SF12 | 1 | ₹480 |
| 18650 Li-ion cell 3400 mAh + holder Never charge below 0 °C; always use a protected cell or a BMS. | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 1 | ₹450 |
| Sewer gas sensors Educational-grade; certified personal detectors required for entry | H₂S, methane/combustible, CO and O₂ sensors (rated for the environment) | 1 | ₹1,500 |
| Level sensor | Non-contact ultrasonic or hydrostatic level (rated, sealed) | 1 | ₹800 |
| Cover-open sensor | Reed/tilt to detect an opened cover | 1 | ₹150 |
| Sealed rugged enclosure + LoRa | Corrosion/water-proof housing and LoRa; long-life battery | 1 | ₹900 |
Estimated total: ₹11,295, excluding tools, shipping and consumables.
Tools and consumables
- Soldering iron (temperature controlled, 350 °C) with 0.8 mm 60/40 or lead-free solder
- Digital multimeter — continuity, DC volts and current ranges
- Wire strippers, flush cutters and a small set of precision screwdrivers
- Heat-shrink tubing and a heat gun (or a lighter, carefully)
- A laptop with a USB port and the toolchain listed above
Hardware Specifications
| Part | Specification | Supply | Interface | Reference |
|---|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | Dual-core Xtensa LX6 @ 240 MHz, 520 KB SRAM, 4 MB flash, Wi-Fi 802.11 b/g/n + BLE 4.2, 34 GPIO, 18× 12-bit ADC, 2× 8-bit DAC | 3.3 V logic / 5 V USB | UART, SPI, I²C, I²S, CAN, PWM | Datasheet |
| JSN-SR04T waterproof ultrasonic sensor | 25–450 cm, ±1 cm, IP67 sealed transducer, 45° beam | 5 V | Trigger/Echo or UART | Datasheet |
| MQ-7 carbon monoxide sensor | 20–2000 ppm CO, dual-heater cycle (1.4 V / 5 V), analogue output | 5 V | Analogue (PWM heater) | Datasheet |
| Dissolved-oxygen probe (galvanic) | 0–20 mg/L, ±0.3 mg/L, galvanic, no warm-up, membrane cap consumable | 3.3–5 V | Analogue | Datasheet |
| Reed switch + magnet pair (door contact) | NO contact, 10–15 mm operating gap, 100 V / 0.5 A, > 10⁷ operations | passive | Digital with pull-up | Datasheet |
| SX1278 LoRa 433 MHz module (Ra-02) | −148 dBm sensitivity, +20 dBm output, up to 10 km line of sight, SF7–SF12 | 3.3 V | SPI | Datasheet |
| 18650 Li-ion cell 3400 mAh + holder | 3.7 V nominal, 4.2 V full, 3400 mAh, ~12.6 Wh, 2 C discharge | 3.0–4.2 V | Holder / spot-welded tabs | Datasheet |
Consolidated electrical and interface specifications for every active part in the build.
Power Budget & Supply Sizing
Add up the typical active current of every part, then size the supply with at least 50 % headroom so transmit bursts and motor inrush never brown out the controller.
| Load | Supply rail | Typical current (mA) | Notes |
|---|---|---|---|
| ESP32 DevKit V1 (ESP-WROOM-32) | 3.3 V logic / 5 V USB | 160 | Wi-Fi transmit bursts peak near 500 mA — size the regulator accordingly. |
| JSN-SR04T waterproof ultrasonic sensor | 5 V | 30 | The 25 cm blind zone matters — mount it above the maximum expected water level. |
| MQ-7 carbon monoxide sensor | 5 V | 150 | Requires an alternating 60 s / 90 s heater cycle to read correctly — a constant 5 V gives wrong numbers. |
| Dissolved-oxygen probe (galvanic) | 3.3–5 V | 5 | The membrane and electrolyte are consumables — budget a replacement every 6–12 months. |
| SX1278 LoRa 433 MHz module (Ra-02) | 3.3 V | 120 | Never power the radio without an antenna — the PA will destroy itself. |
Summed typical draw is 465 mA. With a 1.5× design margin the supply should deliver at least 700 mA continuously at the stated rail voltage.
Software Requirements & Development Environment
Reference toolchain: Arduino IDE 2.3.x with the ESP32 board package 3.x (or PlatformIO on VS Code). Anything newer normally works; anything older may lack the board definitions used here.
- Install the Arduino IDE 2.3.x (or PlatformIO if you prefer a real editor and dependency locking).
- Add
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonunder File → Preferences → Additional Board Manager URLs, then install esp32 from the Boards Manager. - Set the correct port under Tools → Port. On Linux add yourself to the
dialoutgroup:sudo usermod -aG dialout $USERand log out and back in. - Open the Serial Monitor at 115200 baud — every sketch here logs its state there.
- Keep File → Preferences → Show verbose output during: compilation switched on while you are debugging build errors.
Required libraries
| Library | Why it is needed | Install |
|---|---|---|
| WiFi (ESP32 core) bundled | Station/AP connection management for the ESP32. | Bundled with the ESP32 Arduino core |
| LoRa (sandeepmistry) 0.8.0 | SX127x radio configuration, packet TX/RX and callbacks. | Library Manager → "LoRa" by Sandeep Mistry |
| ArduinoJson 7.x | Zero-allocation JSON serialisation and parsing. | Library Manager → "ArduinoJson" by Benoit Blanchon |
| Preferences (NVS) bundled | Wear-levelled key/value storage in ESP32 flash for settings. | Bundled with the ESP32 core |
| NTPClient / configTime bundled | Wall-clock time from an NTP server for timestamping. | Bundled (`configTime()` on ESP32) |
Block Diagram
The block diagram shows the functional decomposition of the system — what senses, what decides, what acts, and where the data ends up.
Circuit Diagram & Wiring
Every signal line in the build is shown below, followed by a pin-by-pin connection table you can work through with a multimeter in hand.
| Peripheral | Peripheral pin | Controller pin | Signal |
|---|---|---|---|
| Level sensor | TRIG/ECHO/AOUT | GPIO 26/25/34 | Sewer level |
| Gas sensors | AOUT | GPIO 35/32/33 | H₂S/CH₄/CO/O₂ |
| Cover reed | NC | GPIO 27 | Cover open |
| LoRa | SPI | GPIO 18/19/23/5 | Alerts/status |
| Battery | sense | ADC | Supervision |
| Local beacon (opt) | IN | GPIO 13 | On-site alarm |
| Supply | +/– | 3V3 reg | Power |
Wire one row at a time and tick it off — most "it does not work" reports trace back to a single swapped pair.
Wiring explanation
- Monitor level (non-contact ultrasonic or hydrostatic) for flood/blockage warning and the sewer gases (H₂S, methane, CO, O₂) for safety.
- Seal and ruggedise everything against the wet, corrosive sewer environment; use appropriately-rated sensors.
- Battery + LoRa — manholes have no power/network; deep-sleep and report on change/schedule for long life.
- Add cover-open detection (reed/tilt) to flag an opened cover.
- THIS IS AN AID — certified, calibrated personal gas detectors and confined-space procedures are required for any entry, never this fixed monitor alone.
System Architecture
Read the stack from the bottom up: physical hardware, the firmware that drives it, the transport that moves data off the device, and the software a human actually looks at.
Working Principle
A manhole concentrates two very different hazards into one small space, and the monitor addresses both because both are otherwise invisible until it is too late. The first is flooding/blockage: a sewer or drain backing up shows first as a rising level inside the manhole, well before it overflows onto the street or into homes, so watching the level gives early warning with time to clear a blockage or mobilise a response. The second is the lethal atmosphere of a confined space: sewers generate hydrogen sulphide, methane, carbon monoxide and oxygen-deficient pockets, and these gases are odour-fooling and deadly — H₂S in particular deadens the sense of smell at dangerous concentrations, so a worker can climb in unaware. Monitoring both level and gas turns two invisible, high-consequence hazards into observable, alertable conditions.
Flood early warning comes from the level and its trend. A non-contact ultrasonic or hydrostatic sensor tracks how high the water/sewage has risen; a level rising steadily toward the overflow point, especially faster than normal, signals a developing blockage or flood. Alerting on that trend — not just a high mark — gives lead time to act before it reaches the surface, which is the difference between a cleared blockage and a flooded street.
The atmosphere side senses the gases that matter in a sewer — H₂S (toxic), methane/combustible (explosive), CO, and oxygen level — and alarms on dangerous concentrations. This data serves public/flood safety, but its most important role is around confined-space entry: it can tell a worker and their supervisor what the atmosphere is before anyone descends, and monitor it while work happens. Here the design draws an emphatic line: continuous atmosphere awareness is a valuable complement to, but never a substitute for, the certified, calibrated personal gas detector each worker must carry and the confined-space entry procedures (ventilation, permit, standby, rescue plan) that law and life-safety require. No one should ever enter relying on a fixed monitor instead of proper detection and procedure — the monitor informs and warns; it does not certify a space safe to enter.
The deployment realities and honest scope complete it. Manholes are buried, wet, corrosive and powerless, so the monitor is battery-powered, reports over LoRa, and is sealed and ruggedised for the environment, deep-sleeping and reporting on change/schedule for long life; cover-open detection adds a flag for unauthorised entry or cover theft. And the scope is stated plainly and repeatedly: this is a monitoring and early-warning aid — for flooding, and for atmosphere awareness — not a certified safety instrument and not a replacement for the personal detectors and procedures that confined-space work legally and morally demands. Within that frame, it delivers two things a city otherwise lacks and that genuinely save property and lives: warning of sewer flooding before it hits the street, and continuous awareness of a toxic atmosphere in a space that kills the workers who cannot see the danger.
The maths behind it
Flood/blockage early warning
Level L rising toward the overflow point L_of:
alert if L > L_warn OR dL/dt > R_warn (rising fast)
time_to_overflow ≈ (L_of − L) / (dL/dt)
Early warning with lead time to clear a blockage/respond.
Gas / atmosphere safety
Alarm on dangerous concentrations:
H2S > exposure limit (toxic; deadly higher)
CH4 > %LEL alarm (explosive)
CO > exposure limit
O2 < 19.5% (deficient) or > 23.5%
Atmosphere AWARENESS — NOT a substitute for personal
detectors + confined-space procedures for entry.
Cover-open + battery life
cover_open from reed/tilt → flag (unauthorised entry/theft)
Buried + powerless → battery + LoRa:
deep-sleep; report on change/schedule; faster if alarmed.
Program Flowchart
The firmware is a single cooperative loop. Nothing blocks for long, so networking, sensing and the user interface all stay responsive.
Assembly Instructions
Build on a breadboard first and only commit to solder once the whole system has run for an hour without a fault.
Deploy sealed, rugged sensing
Fit a level sensor (non-contact/hydrostatic) and sewer gas sensors (H₂S/CH₄/CO/O₂), sealed and ruggedised against the wet, corrosive environment, plus a cover-open sensor.
Battery-power with deep sleep and LoRa reporting; supervise the battery.
Set up alerts
Alert on rising level trending toward overflow (with lead time) and on dangerous gas/low-oxygen concentrations; flag cover-open.
Report and map
Report level/gas/cover status and alerts over LoRa to a city map, with pre-entry atmosphere awareness for authorised workers/supervisors.
Step-by-Step Implementation Guide
Work through these in order. Each step ends in something you can observe, so a failure is always localised to the step you just finished.
Assess flood and atmosphere
Compute the level trend and time-to-overflow for flood warning, and evaluate gas concentrations for safety, sampling faster when alarmed.
cppmanhole-assess.ino#define L_OVERFLOW 20.0f // cm below cover = overflow risk #define R_WARN 5.0f // cm/min rising fast const char* floodCheck(float level, float rate){ if (level > (100.0f - L_OVERFLOW)) return "level near overflow"; if (rate > R_WARN) return "level rising fast (blockage?)"; return nullptr; } // Atmosphere AWARENESS (not entry certification). const char* gasCheck(float h2s, float ch4_lel, float co, float o2){ if (o2 < 19.5f || o2 > 23.5f) return "oxygen out of range"; if (h2s > H2S_LIMIT) return "H2S toxic"; if (ch4_lel > LEL_ALARM) return "methane explosive"; if (co > CO_LIMIT) return "CO high"; return nullptr; }if (rate > R_WARN) return "level rising fast (blockage?)"A fast-rising level warns of a developing blockage/flood with lead time, before it overflows onto the street.if (o2 < 19.5f || o2 > 23.5f) return "oxygen out of range"Oxygen deficiency (or enrichment) is a primary confined-space killer and is checked first.if (h2s > H2S_LIMIT) return "H2S toxic"Hydrogen sulphide — the classic lethal sewer gas that fools the sense of smell — is alarmed at its toxic limit.Atmosphere AWARENESS (not entry certification)The comment states the scope in the code: this informs and warns about the atmosphere; it does not certify a space safe to enter, which requires personal detectors and procedures.Alert, report and supervise
Raise flood and gas/safety alerts, flag cover-open, report status/alerts over LoRa to a city map, and supervise battery — sampling faster while alarmed.
Complete Source Code
The listing below is complete and compiles as written — there are no elided sections. Read the annotations under each block before you upload it.
/* ═══════════════════════════════════════════════════════════════
Manhole Safety Monitor — ESP32, LoRa, battery (sealed/rugged)
Monitors sewer LEVEL (flood/blockage early warning) and toxic/
explosive GASES + oxygen (worker/public safety awareness), plus
cover-open. AN AID — NOT a substitute for certified personal gas
detectors and confined-space entry procedures.
══════════════════════════════════════════════════════════════════ */
#include <LoRa.h>
#include <SPI.h>
#include <Preferences.h>
#include <math.h>
#define PIN_TRIG 26
#define PIN_ECHO 25
#define PIN_H2S 35
#define PIN_CH4 32
#define PIN_CO 33
#define PIN_O2 34
#define PIN_COVER 27
#define DEPTH_CM 100.0f
#define NODE_ID 23
Preferences prefs;
RTC_DATA_ATTR float prevLevel = NAN; RTC_DATA_ATTR uint32_t prevMs = 0;
float levelCm(){
digitalWrite(PIN_TRIG,LOW); delayMicroseconds(2);
digitalWrite(PIN_TRIG,HIGH); delayMicroseconds(10); digitalWrite(PIN_TRIG,LOW);
long us=pulseIn(PIN_ECHO,HIGH,30000);
if(!us) return NAN;
return DEPTH_CM - us/58.0f; // water height
}
float gas(int pin, float fs){ long s=0; for(int i=0;i<32;i++) s+=analogRead(pin);
return (s/32.0f)/4095.0f*fs; }
void report(float lvl,float h2s,float ch4,float co,float o2,bool cover,
const char* flood,const char* gasAlert){
LoRa.beginPacket();
LoRa.printf("{\"mh\":%d,\"level\":%.0f,\"h2s\":%.1f,\"ch4_lel\":%.0f,"
"\"co\":%.0f,\"o2\":%.1f,\"cover_open\":%d,"
"\"flood\":\"%s\",\"gas\":\"%s\"}",
NODE_ID, lvl, h2s, ch4, co, o2, cover?1:0,
flood?flood:"none", gasAlert?gasAlert:"none");
LoRa.endPacket();
}
void setup(){
Serial.begin(115200);
pinMode(PIN_TRIG,OUTPUT); pinMode(PIN_ECHO,INPUT); pinMode(PIN_COVER,INPUT_PULLUP);
SPI.begin(); LoRa.setPins(5,14,2); LoRa.begin(433E6); LoRa.setSpreadingFactor(10);
float lvl = levelCm();
uint32_t now = millis();
float rate = (!isnan(prevLevel)&&prevMs)? (lvl-prevLevel)/((now-prevMs)/60000.0f):0;
prevLevel=lvl; prevMs=now;
float h2s=gas(PIN_H2S,H2S_FS), ch4=gas(PIN_CH4,100), co=gas(PIN_CO,CO_FS),
o2=gas(PIN_O2,25);
bool cover = digitalRead(PIN_COVER)==HIGH;
const char* flood = (lvl > 80.0f) ? "near overflow" :
(rate > 5.0f) ? "rising fast" : nullptr;
const char* gasAlert = (o2<19.5f||o2>23.5f)?"oxygen out of range":
(h2s>H2S_LIMIT)?"H2S toxic":
(ch4>LEL_ALARM)?"methane explosive":
(co>CO_LIMIT)?"CO high":nullptr;
report(lvl,h2s,ch4,co,o2,cover,flood,gasAlert);
bool alarmed = flood || gasAlert || cover;
esp_sleep_enable_timer_wakeup((uint64_t)(alarmed?120:900)*1000000ULL);
esp_deep_sleep_start();
}
void loop(){}
Configuration & Calibration
Configuration steps
- Configure level sensing and the overflow/rate thresholds, and the gas sensors and safety limits (H₂S/CH₄/CO/O₂).
- Configure cover-open detection, LoRa reporting and battery supervision.
- Set faster sampling when alarmed and the city-map integration.
- State the scope clearly: aid, not a substitute for certified detectors/procedures.
Calibration procedure
An uncalibrated sensor produces confident, precise, wrong numbers. Do this once per physical unit and record the constants.
Level
Calibrate the level scale and overflow point; verify the rate-of-rise warning.
Gas
Understand these are educational-grade sensors; set conservative safety limits and test response. Certified personal detectors are required for entry.
Battery/report
Verify long battery life with deep sleep and faster-when-alarmed reporting.
Network Architecture & Connectivity
Communication protocol
Nodes report level/gas/cover on change/schedule (faster when alarmed); flood and gas/safety alerts publish immediately. Framed as an aid, not entry certification.
| Topic / endpoint | Direction | Payload |
|---|---|---|
manhole/<id>/status | node → dashboard | level, gases, O₂, cover |
manhole/<id>/alert | node → ops | flood/blockage / gas / cover-open |
manhole/<id>/health | node → ops | battery/supervision |
Message contract between the device and the broker.
Cloud platform configuration
A dashboard maps manhole level, atmosphere and cover status across the city, raises flood and gas alerts, and provides atmosphere awareness — clearly as an aid, not a substitute for certified detectors/procedures.
Dashboard setup
A city map of manhole level/gas/cover, flood/gas alerts, and sensor/battery health.
Mobile app integration
Flood/blockage and gas/safety alerts; cover-open notifications.
Security considerations
- Authenticate node data; supervise battery/health.
- Frame gas data as awareness, never entry certification.
- Alert on silent nodes.
Testing Procedure & Expected Output
Test from the bottom up. Confirm power, then each sensor in isolation, then the integrated loop — the first failing step tells you exactly where to look.
| Test | What you should see |
|---|---|
| Raise the level toward overflow | Flood/blockage early warning with lead time |
| Introduce test gas / low oxygen (safely) | Gas/safety alert |
| Open the cover | Cover-open flag |
| Alarmed vs quiet | Faster sampling when alarmed; long life when quiet |
| Confirm scope in output/UI | Clear "aid, not a substitute for personal detectors/procedures" messaging |
| Solar/battery cycle | Node reports over a season; supervision works |
Bench-test checklist. If a row fails, stop and fix it before moving on.
Expected output
The city map shows each manhole's level, gas readings, cover status and alerts (flood, gas, cover), with pre-entry atmosphere awareness clearly framed as an aid.
{
"mh": 23,
"level": 84,
"h2s": 12.0,
"ch4_lel": 8,
"co": 5,
"o2": 20.6,
"cover_open": 0,
"flood": "near overflow",
"gas": "none"
}
Manhole 23 near overflow (flood early warning) with a currently-safe atmosphere; a dangerous gas reading would raise a safety alert — but entry always requires certified personal detectors and confined-space procedures, never this monitor alone.
Troubleshooting: Common Errors & Fixes
Performance Optimisation
- Deep-sleep between reads; sample faster when a flood or gas hazard is present.
- Persist level state for rate-of-rise across sleep.
- Report on change/schedule and alerts immediately.
- Supervise battery/health across the network.
- Replace every
delay()with amillis()comparison — blocking delays are the single most common cause of dropped readings. - Sample sensors on a fixed cadence and publish on a slower one; you almost never need to transmit at the sampling rate.
- Move networking into its own FreeRTOS task so a slow DNS lookup cannot stall the control loop.
- Use
uint8_t/uint16_twhere the range allows; on an 8-bit AVR a 32-bit add costs four times as much. - Batch several samples into one MQTT publish. Radio time, not CPU time, dominates the energy budget.
- Set the MQTT keep-alive to a value that matches your reporting interval so the broker does not churn reconnections.
- For battery builds use deep sleep between samples: an ESP32 drops from ~160 mA awake to about 10 µA asleep, which is the difference between days and months of runtime.
Safety Precautions
- THIS IS A MONITORING/EARLY-WARNING AID — NOT a substitute for certified, calibrated PERSONAL gas detectors and confined-space entry procedures (ventilation, permit, standby, rescue). Never enter relying on a fixed monitor.
- Confined spaces and toxic/explosive atmospheres are lethal — H₂S deadens smell; follow the law and life-safety procedures.
- Seal/ruggedise for the wet, corrosive environment; use rated sensors.
- Provide flood early warning and atmosphere awareness; escalate real hazards to proper procedures.
- Lithium cells vent and burn when abused. Only use protected cells or a proper BMS, never charge below 0 °C, and never leave a charging pack unattended on a wooden desk.
- Never power an RF module without its antenna fitted — the reflected power destroys the output stage. Check your local licence-free band and duty-cycle limits before transmitting.
- Wear eye protection when soldering or cutting, and solder in a ventilated space — rosin flux fumes are a respiratory irritant.
- Power the circuit through a bench supply with a current limit while you are testing. A 300 mA limit turns a wiring mistake into a beep instead of a dead board.
- Disconnect power before changing any wiring. Hot-plugging a sensor onto a live bus is the fastest way to lose a controller.
Maintenance
- Recalibrate/replace gas sensors regularly; verify level sensing.
- Inspect seals/enclosure for corrosion; supervise battery.
- Test alerts and cover-open detection.
- Reinforce scope: aid, not a substitute for personal detectors/procedures.
- Re-check every screw terminal and header after the first week — thermal cycling loosens connections that felt tight on day one.
- Log pack voltage. When resting voltage after a full charge drops below about 4.0 V, the cell is near end of life — replace it.
- Keep the broker and dashboard containers patched, and rotate device credentials at least once a year.
- Recalibrate at the interval given in the calibration section, and keep the constants in a text file next to the firmware — not only in flash.
- Keep a short logbook of firmware versions and what changed. Six months later you will not remember why that constant is 1.083.
Future Improvements & Upgrades
A working v1 is a platform, not a finish line. These are the upgrades that add the most capability for the least rework.
- Add flow/rainfall data for better flood prediction.
- Add H₂S corrosion monitoring for asset management.
- Integrate with confined-space entry management (still requiring personal detectors).
- City-wide sewer analytics and predictive maintenance.
- Design a proper PCB. Once the breadboard version has run for a month, moving to a two-layer board removes the intermittent-contact failures that dominate prototype faults.
- Add over-the-air firmware updates so you never have to physically reach a deployed node again.
- Add persistent local storage (microSD or the on-chip flash) so a network outage does not create a hole in your data.
- Move configuration out of the source: a captive-portal setup page or a JSON config file makes the build reusable without a recompile.
- Add a battery and solar option so the unit survives a power cut and can be sited away from a socket.
- Write a small test harness that feeds synthetic sensor values through the decision logic, so you can validate thresholds without physically triggering the event.
Frequently Asked Questions
References & Learning Resources
These are the primary sources worth reading in full. Manufacturer datasheets always outrank forum posts when the two disagree.
- Confined space and sewer gas hazards (OSHA)OSHA
- Hydrogen sulphide (H₂S) safetyReference
- Sewer gasReference
- Manhole / sewer monitoringReference
- Gas detection and exposure limitsReference