When Clean Water Access Meets Reliable Hardware Design

Clean drinking water is a daily challenge in many rural and semi-urban areas across India. Public water dispensing stations exist, but they suffer from two recurring problems—unmetered usage that leads to rapid depletion, and maintenance costs that nobody wants to pay. We wanted to build something that solved both problems at once.
The result is a solar-powered RFID water vending machine. Users tap an RFID card, get a pre-paid amount of clean water, and the system tracks every drop. It runs entirely on solar energy, so it works even where grid power is unreliable or absent. This case study walks through the hardware decisions, firmware logic, and PCB design that made it possible.
The Problem We Started With
Municipal water points in many regions operate on trust. There is no way to limit how much water one person takes, no data on usage patterns, and no revenue stream to fund maintenance. Tanks run dry by noon, pumps break and stay broken, and the community loses access.
We wanted a system that could:
- Dispense a fixed quantity of water per user
- Work without grid power
- Record usage data for administrators
- Survive dust, heat, and rough handling
The RFID vending machine concept ticked all the boxes. A prepaid card system is familiar, solar power removes the grid dependency, and an ESP32 gives us connectivity for data logging.
Hardware Architecture

The Brains: ESP32-WROOM-32
We chose the ESP32-WROOM-32 module for the controller. It gives us dual-core processing at 240 MHz, built-in Wi-Fi and Bluetooth, and enough GPIOs to handle all our peripherals without an I/O expander. The deep sleep mode draws only ~10 µA, which matters when you are running on battery backup through the night.
The Payment System: MFRC522 RFID Module
For card reading, we went with the MFRC522. It operates at 13.56 MHz and communicates over SPI. The module costs almost nothing, has solid library support, and reads passive RFID cards from a distance of about 3-4 cm. Users tap their card, and the reader picks up the UID within 50 ms.
The Dispensing Mechanism: 12V Solenoid Valve
Water flow is controlled by a 12V solenoid valve. When the valve opens, water flows through a 0.5-inch pipe. We calibrated the flow rate at 6 liters per minute, so a 10-liter dispense takes roughly 100 seconds. The valve draws 500 mA when energized, which is well within our power budget.
The Power System: Solar + Battery
The entire system runs on a 20W solar panel and a 12V 12Ah sealed lead-acid battery. A solar charge controller handles the charging, and we use buck converters to step down to 5V for the ESP32 and 3.3V for the RFID module.
Here is the power flow:
Solar Panel (20W, 18V) → Charge Controller → 12V Battery
├── 12V → Solenoid Valve
├── 5V → ESP32 (via buck converter)
└── 3.3V → RFID Module (via LDO)
The battery gives us about 8 hours of continuous operation without sun. Since the machine only runs during daylight hours, this is more than enough margin.
The Enclosure: 3D Printed and Sealed
We designed a compact enclosure in Fusion 360 that holds the PCB, RFID reader, battery, and valve. The water path is completely isolated from the electronics. The RFID reader sits behind a 2mm acrylic window, and the ESP32 is mounted on the PCB with headers for easy replacement.
Custom PCB Design in KiCad
We went with a custom PCB instead of breadboard prototyping because this machine sits outside in harsh conditions. A custom board is more reliable, easier to service, and smaller.
Board Layout
The PCB is a 2-layer board, 100mm x 80mm. Here is what it carries:
- ESP32-WROOM-32 module with all decoupling capacitors
- MFRC522 footprint with matching antenna tuning circuit
- 12V to 5V buck converter (MP1584-based) with input/output capacitors
- 5V to 3.3V LDO (AMS1117) for the RFID module
- MOSFET switch (IRLZ44N) to drive the solenoid valve
- Voltage divider for battery monitoring through the ESP32 ADC
- I2C header for an optional OLED display
- Programming header for flashing firmware
Grounding Considerations

One thing we learned the hard way—the solenoid valve creates a voltage spike when it de-energizes. The flyback diode across the valve coil is mandatory, and we also added a 100µF capacitor on the 12V rail to absorb transients. Without these, the ESP32 would randomly reset when the valve closed.
Board Review Checklist
We did a proper design review before sending the board to fabrication. Key checks included:
- Trace widths for the 12V and 5V rails (we used 1mm minimum)
- Proper clearance between the high-current and low-current sections
- Antenna matching network for the MFRC522 (we followed the datasheet reference design exactly)
- Mounting holes aligned with the 3D printed enclosure
Firmware Development
RTOS vs Bare Metal
We wrote the firmware using ESP-IDF with FreeRTOS. The system has three tasks:
1. RFID read task — polls the MFRC522 for card presence
2. Valve control task — opens the valve for the required duration
3. Battery monitor task — samples the battery voltage every 30 seconds
Dispensing Logic
The core dispensing routine is straightforward:
void dispense_water(uint16_t uid, float liters) {
float flow_rate = 6.0; // liters per minute
float dispense_time = (liters / flow_rate) * 60.0; // seconds
uint16_t seconds = (uint16_t)dispense_time;
// Open valve
gpio_set_level(VALVE_PIN, 1);
// Dispense for calculated duration
vTaskDelay(pdMS_TO_TICKS(seconds * 1000));
// Close valve
gpio_set_level(VALVE_PIN, 0);
}
Card Authentication
We store a list of authorized UIDs in flash memory. When a card is tapped, the firmware checks the UID against the list. If it matches, the system checks the card's remaining balance in a simple EEPROM-backed data structure. Each dispense decrements the balance by the amount of water taken.
Data Logging
The ESP32 logs every transaction to an SD card via SPI. Each entry includes:
- Timestamp (from an RTC module)
- Card UID
- Water dispensed
- Battery voltage at time of dispense
If the machine has Wi-Fi coverage, the ESP32 also pushes the data to an MQTT broker. This lets administrators monitor usage remotely.
Assembly and Testing
Step 1: PCB Assembly
We assembled the first board by hand using a reflow hotplate. The ESP32 module is the trickiest part—it has a 0.8mm pitch QFN footprint, and getting it aligned takes patience. We used a stencil for solder paste application, which made the process much cleaner.
Step 2: Firmware Bring-Up
The first boot test is always nerve-wracking. We flashed a simple LED blink program to verify the ESP32 was alive. Then we tested each peripheral one at a time—RFID read, valve switching, battery monitoring.
Step 3: Water Flow Calibration
We filled a 20-liter bucket and timed how long it took to empty through the valve. The measured flow rate was 5.8 liters per minute, close enough to our 6.0 L/min estimate. We adjusted the dispense time calculation to account for the 3% difference.
Step 4: Solar Power Integration
We connected the solar panel and battery, then ran the machine for 48 hours straight. The battery voltage stayed above 12.2V throughout, even with 20 dispenses per hour during peak usage.
Final Outcome
The machine works. It dispenses exactly 10 liters per card tap, runs entirely on solar power, and logs every transaction to the SD card. The custom PCB handles the harsh environment well—we have had it running for three months in a semi-outdoor location with no failures.
The total cost of components was around ₹4,500 ($55). That is a fraction of the cost of commercial vending machines, and it does exactly what we need.
What We Would Do Differently
If we were to build this again, we would:
- Use an ESP32-S3 for more flash storage and native USB programming
- Add a 4G LTE module for connectivity in areas without Wi-Fi
- Design a more rugged connector for the solenoid valve (we initially used a JST connector and it corroded within a month)
- Add a water flow sensor to verify the actual dispensed amount instead of relying on timing
Source Files
All design files are available on GitHub:
https://github.com/ChanchalKumari1/solar-powered-rfid-water-vending-machine/blob/main/README.md
Final Thoughts
This project is a good example of what a small embedded systems team can build with off-the-shelf parts and a custom PCB. The ESP32 handles the logic, the MFRC522 handles the payment, and the solar panel handles the power. No grid connection, no complex infrastructure, just a practical solution to a real problem.
If you are working on a similar project—water dispensing, prepaid metering, or solar-powered IoT—feel free to reach out. We are happy to share more details about the design decisions we made along the way.