I first posted this in the general forum, but it ended up more like a project log than anything else, so I moved it to the build logs.
It’s time for me to build yet another irrigation valve controller and I want to try something new, which is to not use 24VAC, i.e., the standard drive for garden variety solenoid valves. My requirements are pretty simple: esp32 driving up to 8 or so solenoid valves and measuring water flow using one of the cheap hall-effect flow meters. It needs to support two simultaneously active valves so I can have a master valve and a branch valve on at the same time.
One of the uses is to upgrade my old veggie garden controller from 8 valves to 18 for individual planting bed control. It uses 24VAC, a bunch of relays, and good 'ol 1-wire driven by a really ancient NAS thingie. Hey, it has been working for >15 years…
The downside of the 24VAC drive is that turning it into 3.3V for the esp32 isn’t small or cheap (at least when I did my back-of-the-envelope calculations) and I’m not a big fan of relays or small SSRs for inductive loads (I’ve used the AQH2223 type of SSRs with good reliability, so not saying it can’t be done). Maybe what I should really say is that I wanted to try something different.
So I read up a bit on solenoid drive and the closely related driving of relays and contactors. When driving solenoids via A/C the current is less than with the same nominal DC voltage because of the solenoid coil reactance and once the piston moves it further increases reactance thereby reducing current and thus power. The net result is that driving these valves using DC instead of AC uses a lot more power, which turns into hot solenoids, which turns into a short lifetime.
Opensprinkler.com does something interesting. They want to run off a USB power wart at 5V. To accomplish that they use a boost DC-DC regulator to get about 20V DC, charge up a big fat capacitor, and then use that to initially activate the solenoid and then hold it using just 5V. Neat, but I don’t really care about using USB power and the boost converter plus big cap just uses more space and $$$.
I decided to try powering the whole thing with 12V DC and looking at two alternatives for reducing the power and heat while holding the solenoids. The first is to use a programmable buck converter to reduce the voltage after the initial actuation. The second is to PWM the 12V drive.
To power the esp32 itself I ended up with an AP63203 buck 2A 3.3V converter. I ended up with that part by going through Digikey looking for the cheapest buck with enough amps and >24 Vin for flexibility. So I thought why not rig up a second unit as “programmable voltage regulator” with which I could initially drive the solenoid with 12V and then switch down to a lower voltage for holding.
The trick to make the Vreg programmable is to tweak the input into the feedback (FB) pin using a DAC output from the esp32. How to do that is described in https://www.microchip.com/forums/m688260.aspx
and power supply - DAC controlled buck regulator - Electrical Engineering Stack Exchange. The upshot is that if you look at the typical buck converter application diagram below, there’s a voltage divider from the output to drive the feedback pin that sets the desired output voltage and one can “just” add another branch into the feedback pin using a third resistor connecting the feedback pin to the DAC. This allows the MCU to bias the feedback up or down using the DAC.
I didn’t have any of the adjustable AP63200 or AP63201 in my parts bins, so I used a 3.3V fixed reg and added a voltage divider to give me something to control. After releasing the proverbial smoke from a couple of Vregs I ended up with a 22K/47K divider and 10K between DAC and FB. Since this is a 3.3V Vreg it tries to make the FB sit at 3.3V and thus with this divider and no DAC input I had a minimum of about 4.8V. By outputting a voltage lower than 3.3V from the DAC I can increase the output, in theory up to a tad over 12V. In practice, the Vreg can’t go above around Vin - 1.5V, so 10.5V for my set-up. (The reason for the 1.5V difference has to do with having to switch off the output periodically in order to charge the boost cap which provides a voltage higher than Vin to drive the high-side FET.) There are buck Vregs that can switch to an LDO mode resulting in a lower dropout voltage, they just cost more.
I started my experiments with a cheap “DC 12V” valve manifold direct off the china truck (I want to use these in the greenhouse where the flows are relatively small). Something like:
I first connected it to a bench power supply and dialed the voltage up & down while blowing through the manifold to be sure I could detect when it opens and closes. My notes say:
- 12V, 460mA, 5.5W
- 6V, 220mA, 1.34W (24% of 5.5)
- 5V, 190mA, 0.93W (17% of 5.5)
Releases below 5V, prob need 6V to hold reliably
Notice how briefly driving the solenoid with 12V and then holding it with 6V results in a significant power and thus heat reduction. Instead of burning my fingers the solenoid becomes just mildly warm.
I then attached the valve to the Vreg output and repeated the same experiment using the DAC control. That worked great once I was done burning up two chips! In a real circuit I would use the adjustable version of the Vreg or even a cheaper 18V max Vin part. The worst part of the circuit is actually the inductor: big and more expensive than the Vreg itself, and the smoothing cap is also either big or not cheap. I’m sure I could skimp on both given that I don’t really need ripple-free regulation.
With that in place I turned to the second alternative, which is to drive the solenoid with 12V PWM. There are chips that do exactly that, like the Ti DRV104
, but I’m too cheap and I prefer a programmable PWM over casting the timing in solder and resistors.
To turn the valves on/off from the esp32 I picked ZXMS6004DN8
dual protected 1.3A N-MOSFET drivers. At this point I think I could use a plain MOSFET but when I ordered some parts I thought the “protection” would eliminate some external components. (The Vreg also has lots of “protection” built in, so the value of those insurances clearly varies!)
The typical frequencies used to drive solenoids and relays are in the 15kHz-20kHz range, or higher. As I started my experiments I quickly found out that the ZXMS driver isn’t exactly fast! (Even though it is the fastest of a number of alternate source parts.) Above about 15kHz it just doesn’t do it so I ended up trying 10kHz and 8kHz. If you go down this route you may want to choose your part more wisely or accept the lower frequencies (which don’t bother me and if they scare some critters away then the better).
I coded up a couple of lines of Python to cycle the solenoid through 12V solid, then 12V PWM, then off and I tried a few different PWM frequencies and duty cycles:
- 10Khz, 56% duty, 220mA when ON, 125mA avg, 1.5W avg
- 10Khz, 63% duty, 230mA when ON, 145mA avg, 1.7W avg
- 8kHz, 54% duty, 210mA when ON, 110mA avg, 1.4W avg
- 8kHz, 61% duty, 230mA when ON, 140mA avg, 1.7W avg
I used a 1 Ohm resistor in series with the driver & solenoid and a scope to look at the current. From that I derived actual duty cycle and approx power consumption, which I cross-checked with the bench power supply status LCD. The lines above show the lowest PWM duty cycle before the valve closes and a value “a bit higher” for a more reliable set-point. The “when ON” values refer to the current while the solenoid is driven (it’s lower than when using 12V DC!) and the avg values take the duty cycle into account. I should add that these tests include the esp32’s power consumption, which is around 180mW, so that should really be deducted.
I also tried powering everything with 9V instead of 12V to attempt to reduce power consumption further:
- 8Khz, 72% duty, 210mA when ON, 150mA avg, 1.3W (PWM setting 491)
- 8Khz, 77% duty, 230mA when ON, 180mA avg, 2.1W (PWM setting 540)
This indeed reduced power a bit more, but from the sound I wondered how solid the actuation is at 9V.
Compared to the buck converter approach I couldn’t get the power quite as low, but in practice the remaining difference doesn’t matter. In terms of circuit complexity the PWM adds only one extra shottky diode per valve instead of the whole buck converter stuff. That is a significant simplification! (When I started I saw significantly higher power consumption during the PWM because the ZXM driver clamps the reverse voltage spike when the solenoid current is turned off with a 65V zener. Adding a shottky diode as clamp solved that issue.)
My next experiment changed the “DC 12V” valve out for a more standard irrigation valve as one would find in a big-box store. The solenoid on mine reads DIG S390 S/N 9100
and is a conventional 24V A/C solenoid. To my surprise, this valve uses far less power:
- 8kHz, 49% duty, 130mA when ON, 60mA avg, 760mW avg (PWM setting 286)
- 8kHz, 28% duty, 80mA when ON, 24mA avg, 290mW avg (PWM setting 188)
I stopped with these two tests feeling “good enough”: when driven at 12V w/out PWM the solenoid draws 450mA (5.5W).
At this point I think the programmable buck converter was a nice excursion and I’m going to stick with PWM because it’s simpler with a lower parts count. The one thing that bothers me a bit is that I didn’t see a way to detect when the solenoid actuator drops out during the PWM phase by monitoring the current drawn. I had hoped I could detect that and auto-calibrate each valve. I’ll have to rely on the flow meter instead, which is not a bad choice either.
I don’t have any schematics to show at this point, just a messy prototyping board (it was supposed to just quickly verify the circuit, not support all these experiments and failures):
The esp32 “SIM” module at the top is my own design, the two square green adapter boards hold the Vregs together with inductor and caps jammed in there (not fun when I blew up one of them 2 times and had to hot-air swap just that part under the rest of the mess). The little 8-pin chip in the middle is the ZXMS driver (I’m only using half of it, hence the 4 dangling pins.
Now I’m off to designing a real circuit and PCB. I can share the results if there’s any interest.