← All Projects
Embedded / IoT ★ Featured

IoT-Based Water
ATM System

Automated water dispensing with IoT-based metering, payment integration, remote monitoring over MQTT, and fault detection — bringing smart infrastructure to community water access.

💧
Add project photo or schematic here

01 Overview

Access to clean, metered water in underserved communities is a logistical and financial challenge. Traditional ATM-style dispensing units are either cost-prohibitive or lack remote monitoring capabilities, making maintenance reactive and inefficient.

This system replaces manual operation with a fully automated, IoT-connected water ATM — users dispense a measured volume of water after payment, the unit logs every transaction in real time, and operators get a live dashboard for remote oversight, fault alerts, and consumption analytics.

02 System Architecture

The system is split into three layers: edge hardware, communication middleware, and cloud dashboard.

# System Architecture — IoT Water ATM [EDGE LAYER — ESP32] ├── Flow meter (YF-S201) — pulse counting ├── Solenoid valve — 12V NC, relay-controlled ├── Payment module — coin acceptor / RFID reader ├── LCD display — 20×4 I2C, user feedback └── Watchdog timer — autonomous recovery [COMMUNICATION — MQTT / Wi-Fi] ├── Broker: Mosquitto on VPS ├── Topics: atm/dispense, atm/fault, atm/telemetry └── QoS 1 for transaction events, QoS 0 for telemetry [CLOUD / DASHBOARD — Node-RED + InfluxDB] ├── Node-RED: flow processing, alert logic ├── InfluxDB: time-series transaction storage └── Grafana: operator dashboard — live + historical
🔌
ESP32
Main MCU — controls all peripherals, runs MQTT client
💧
Flow Meter
YF-S201 — pulse counting for volume measurement
Solenoid Valve
12V NC valve — relay-controlled water release
💳
Payment Module
RFID reader + coin acceptor for dual-mode payment
📡
MQTT Broker
Mosquitto on VPS — real-time message relay
📊
Grafana Dashboard
Live volume, revenue, fault, and uptime monitoring

03 Key Engineering Challenges

Accurate flow metering: The YF-S201 has non-linearity at low flow rates. Implemented a calibration curve per unit with interrupt-driven pulse counting at 1ms resolution — achieving ±2% accuracy across the operating range.

Payment atomicity: Preventing dispensing without confirmed payment — and refunding on valve failure — required careful state machine design with hardware watchdog recovery. Every transaction is logged to non-volatile flash before the valve opens.

Connectivity resilience: Deployed in areas with unstable Wi-Fi. Implemented local offline queuing with SD card buffering — transactions complete offline and sync when connectivity is restored. Never a lost record.

Power management: Running on a shared 12V supply shared between the valve relay, ESP32, and LCD. Designed proper decoupling and brownout detection to prevent corrupted flash writes during voltage dips.

04 Firmware State Machine

// Simplified dispensing state machine (C++) enum class State { IDLE, AWAITING_PAYMENT, PAYMENT_CONFIRMED, DISPENSING, COMPLETE, FAULT }; void loop() { switch (currentState) { case State::IDLE: display.show("Insert coin / Tap card"); if (paymentDetected()) setState(AWAITING_PAYMENT); break; case State::PAYMENT_CONFIRMED: flash.write(txRecord); // persist before valve opens mqtt.publish("atm/dispense", txJSON); valve.open(); setState(DISPENSING); break; case State::DISPENSING: volume += flowMeter.pulseToLitres(); if (volume >= targetVolume) { valve.close(); setState(COMPLETE); } break; } }

05 Results & Outcomes

±2% Flow Accuracy
100% Tx Integrity
Live Remote Monitor

The system achieved ±2% volume accuracy, zero lost transactions across all test deployments (including simulated connectivity failures), and sub-5-second fault detection via the MQTT monitoring pipeline.

06 Tech Stack

ESP32 C / C++ (Arduino) MQTT (Mosquitto) Node-RED InfluxDB Grafana FreeRTOS KiCad (PCB) YF-S201 Flow Sensor MFRC522 RFID