An ESP32, a flow sensor, a temperature sensor, and a UVC LED driver sound like the ingredients for a fairly simple embedded project.
On paper, the logic is straightforward: detect water flow, check the temperature, and enable the UVC source when everything looks normal.
The interesting part starts when you ask what “normal” actually means.
A flow sensor can stop responding. A temperature sensor can disappear from the bus. The water can move too slowly or too quickly. A driver may expect a different enable voltage from the ESP32. And a system that powers up in the wrong state can create a problem before the firmware has even finished initializing.
That is why I think the control logic deserves as much attention as the UVC hardware itself.
Start with the interfaces, not the firmware
The first thing I would check is voltage compatibility.
Many inexpensive Hall-effect flow sensors are powered from 5 V, and some produce output signals that can also rise toward 5 V. An ESP32, however, uses 3.3 V logic.
Those two facts should never be connected by assumption.
Before wiring the flow signal to a GPIO pin, check the actual sensor datasheet or measure the output. If the signal can exceed the ESP32's allowed input level, use a suitable voltage divider, level shifter, transistor stage, or another appropriate interface.
This sounds obvious, but it is one of those details that is easy to miss when a prototype is assembled quickly on a workbench.
Espressif's own hardware documentation is worth checking whenever there is uncertainty about GPIO voltage limits.
Temperature sensing is useful, but location matters
A DS18B20 is a convenient choice for monitoring temperature because it is inexpensive, easy to integrate, and only requires one data line.
There are two details I would not skip.
First, the 1-Wire data line needs the appropriate pull-up resistor. The common arrangement uses roughly 4.7 kΩ between the data line and 3.3 V.
Second, the temperature reported by the sensor is only the temperature where the sensor is mounted.
If the DS18B20 is attached to a heat sink, it is measuring the heat sink. If it is mounted near the LED PCB, it is measuring that area. It is not directly measuring the LED junction temperature.
That matters when deciding on a shutdown threshold.
A value such as 60°C might be useful during prototype development, but it should not become a universal limit copied from one project to another. The real threshold depends on the LED module, PCB, drive current, heat sink, ambient temperature, and the position of the sensor.
“Water is flowing” is not enough
The simplest possible controller only asks one question:
Is there flow?
For a flow-through UVC system, I would ask two:
Is the flow high enough?
And is it still below the maximum operating range?
The first condition prevents the UVC source from operating when water is stationary or barely moving.
The second is just as important.
As flow through a fixed chamber increases, the water normally spends less time inside that chamber. That means a system should not automatically treat every non-zero flow rate as acceptable.
This does not mean the ESP32 can determine whether the water is microbiologically safe. It cannot.
The maximum acceptable flow has to come from the design and validation of the complete UV reactor.
What the controller can do is enforce the range that the system designer has already established.
Calibrate the sensor you actually have
Flow-sensor examples often contain one calibration value that gets copied from project to project.
I would avoid doing that.
Different sensors can produce very different numbers of pulses for the same volume of water. Even two units of the same inexpensive sensor may not behave exactly the same.
A better approach is surprisingly low-tech.
Run a known volume of water through the sensor, record the number of pulses, repeat the test several times, and calculate an average pulses-per-liter value.
That measured value becomes much more useful than a number taken from an unrelated tutorial.
If accurate flow measurement matters to the final product, calibration should also be checked at several flow rates rather than only at one point.
Make OFF the default state
One of the most useful design decisions is also one of the simplest:
The UVC output should start OFF.
When the ESP32 boots, resets, loses a sensor, or encounters an invalid condition, the controlled output should remain disabled until the system has enough information to justify enabling it.
I prefer thinking of this as permission rather than switching.
The controller is not asking, “Is there a reason to turn the UVC off?”
It is asking, “Do I currently have enough valid information to allow it to turn on?”
That small change in perspective produces better fault handling.
If the temperature sensor disappears, that is not an unknown temperature that can be ignored. It is a missing safety input.
If the flow signal disappears, the controller should not assume the water is still moving.
Unknown conditions should generally move the system toward the safer state.
Don’t switch on after a single good reading
Sensors are noisy. Pumps start. Valves open. Flow rates fluctuate.
For that reason, I would not enable the UVC driver after the first measurement that happens to fall inside the acceptable range.
A short stability period is more useful.
For example, the controller can require two or three consecutive valid measurement cycles before allowing the output to turn on.
Faults should work differently.
If flow suddenly stops or the temperature crosses the shutdown limit, there is little reason to wait for several more samples before responding.
This leads to a control behavior I like for protective systems:
Slow to enable, fast to disable.
It is a simple idea, but it makes the controller much less twitchy around thresholds.
The LED driver is part of the design
Another detail that deserves checking is the driver's enable input.
An ESP32 GPIO should only control the enable pin directly if that pin is documented as compatible with 3.3 V logic.
Some drivers may need a transistor, MOSFET, optocoupler, or level interface.
And the microcontroller should never be treated as the LED power source.
A high-power UVC LED needs a suitable constant-current driver matched to the LED module's electrical requirements.
The ESP32's job is to make decisions.
The driver's job is to regulate LED current.
Keeping those responsibilities separate makes the hardware much easier to reason about.
UVC control is not the same as water-disinfection validation
This distinction is probably the most important one in the whole project.
A controller can measure flow, watch temperature, detect faults, and manage the LED driver.
None of those things prove that a particular microbial reduction has been achieved.
UV water-treatment performance also depends on factors such as wavelength, optical radiant output, water UV transmittance, reactor geometry, flow distribution, exposure time, fouling, temperature, and the target microorganism.
That means an ESP32 prototype can demonstrate good control behavior while still saying nothing about whether the reactor delivers a validated UV dose.
Those are two separate engineering problems.
Keeping them separate also prevents a prototype from making claims that the hardware has not actually demonstrated.
What I would add next
Once the basic flow and temperature logic is working reliably, there are several useful directions to take the controller.
UV intensity monitoring would be near the top of my list. Driver-current feedback would also help detect electrical faults that a simple enable signal cannot see.
Other useful additions include leak detection, total treated-water volume, LED operating hours, data logging, a hardware watchdog, and an independent enclosure interlock.
At that point, the project becomes much more than an ESP32 turning a UVC LED on and off.
It becomes a small safety-oriented control system.
And that is the part I find most interesting: not how to switch the light source, but how to decide when the controller has enough trustworthy information to allow the system to operate.
Further reading
For the electrical side of the design, I recommend checking Espressif's official documentation on ESP32 GPIO voltage limits and the Analog Devices DS18B20 datasheet rather than relying only on hobby-project wiring diagrams.
Those two documents answer most of the basic questions about signal voltage and 1-Wire sensor wiring before the first prototype is powered.
Top comments (0)