A/C Current Monitor
For starters, you should know that I hate plumbing. Really a lot. Every plumbing job requires a billion trips to the hardware store to buy one more adapter to make something fit into something else. And all plumbing repairs seem to involve laying on your back with water running into your eyes, or your belly in the mud with water running up your pant legs. Don't get me started on plumbing.
One day it occurred to me that it might be interesting to check my home's water well system for leaks. At this point, I can't even remember why. All I knew is that one good thing about computer projects is that they can get reused for other projects. In this case, I decided that the computer I used in my IoT property management project would get me about 80% of the way to a machine that would watch my water system and send me notifications via AWS.
The existing IoT property management system would need some extra hardware mods though. In case you are not familiar with well pump systems, a well pump does not drive the water system directly. Instead, it pumps the water into a pressure tank. A pressure tank is literally a tank with a rubber bladder in it. When you pump water in, water takes up space inside the tank and compresses the air inside the bladder. When the pressure in the tank reaches its high pressure setpoint, a pressure switch pump shuts the well pump off. As water gets used, the trapped air in the bladder provides the pressure to supply the water to the water system. Of course, the air pressure drops as more water is used. When the pressure reaches its low pressure setpoint, the pressure switch restarts the well pump. This kind of setup allows the well pump to work in bursts, saving wear and tear. It also allows the water level at the bottom of the well to recover in between pumping events.
So how to detect a leak? Well, it's simple. A household should never use water overnight, so the well pump should never cycle overnight. If there is a leak, you would expect to see the well pump periodically cycle, even overnight. If it's a big leak, the time between cycles would be short. The key to everything is detecting if and when the motor runs. Calculating the time interval between motor-on events would give you an idea of the size of the leak. All in all, not too difficult. So of course, this is where the project got a lot more complicated.
On the plus side, the project got way more interesting, too. It would have been possible to make some extremely simple mechanism to detect if the motor had power or not. But that seemed lame. It seemed far more interesting to measure the current going into the motor. Who knows, maybe knowing the current would allow me to detect an impending pump failure.
As it happens, the world is full of cheap non-contact AC (Alternating Current) current sensors. The problem is that those sensors do not easily connect to a processor. Processors don't like to deal with AC signals. I looked around at some hacks I found on the web, but I found them wanting. I did find a company called C.R. Magnetics, a purveyor of non-contact current sensors. Their documentation described a precision rectifier circuit for converting the AC signal into a DC signal. That was a good start. Then I read some bits in the "Art of Electronics" again, and they explained how I could use some op amps to do the rest. But op amps are analog, and therefore, black magic to a software guy like me.
Finally, it occurred to me that there are analog simulators out there. Maybe I could just input my design and see if it worked? So I downloaded Spice, and had at it. I remember my coworkers back in the old days telling me about their travails using Spice. Not only was analog black magic, but Spice analog was looking like black magic plus voodoo.
And indeed it was.
But I persisted, and ended up with a circuit design that Spice claimed would do what I wanted. So I made a board.
At the time, the smallest board I had ever made.
Yes, I know it's really not that small. There is really no point in making the first version of anything as small as possible because there will always be problems to be fixed or potential enhancements that don't become visible until you actually use the device.
This design converts the AC current into a DC voltage that the processor is capable of dealing with. A processor would connect the output voltage to one of its ADC pins, periodically read the ADC, do a bit of math, and then it would know the AC current going through the current sensor.
Version 1 arrived with a fatal flaw, but fortunately there was a work-around with a single trace cut and a jumper wire.
Version 1.1 fixed the flaw and did the first board shrink. It worked great. Sadly, "working great" served to point out that the ESP32 ADC converter is bad. Very, very bad. Bad, as in "totally unusable for my purposes" bad.
Live and learn. I'm not a big fan of the ESP32 anymore. And it's not just the ADC, so I'm not being vindictive about it.
Version 1.1 also added test pads at the top to break out the various parts of the analog signal chain for test purposes. I'm not sure why, because I don't own an oscilloscope. It seemed like the thing to do at the time.
Rather than change the processor and all the software in the main rental minder box to get a decent ADC, the Version 2 current sensor solved the problem by adding an external ADC converter to the current sensor board. The board got a tiny bit larger, but on the plus side, the new MCP3425 ADC was a killer sigma-delta converter that could generate 16-bit current readings over 10 times a second. The ADC converter is the 6-pin package labeled U1 on the silkscreen. It's a tiny little thing!
The new ADC was awesome, but because it is manufactured using a single I2C address, there could only be one current sensor board on an I2C bus at a time. Because I was having fun at this point, and because fabricating boards is so cheap, Version 3 was created to allow multiple current sensor boards. To do that, I verified that the ADC would tolerate having its I2C CLK signal gated by a new Slave Select (SS) signal, causing it to ignore I2C messages on the bus. Fortunately that worked, so I added a new SS signal to the connector and used the signal to gate CLK to the ADC. Now I can use three boards at once if I want to monitor 3-phase equipment. Our rental building has 3-phase power, so maybe it will!
Version 4 was a pretty significant board shrink. It got rid of the analog test points because I still don't own a scope, and the circuitry seemed to work fine. The project seemed near done, so it was worth going to the effort to shrink the layout.
While I was at it, V4.0 also added SS gating to the data acquisition sampling control signal. That was an attempt to minimize the amount of GPIO that would be required for a system with multiple current sensor boards in it. It worked, but there were some unintended impacts on the software driver which were irritating enough that if a V5.0 was going to happen, I planned to undo the change back to V3.0 style.
The V4.0 is shown below during initial testing. I was using an Arduino Pro Mini because I have a pile of them laying around. One cool feature of the design is that it can run anywhere from 2.7V to 5V with no changes. Attaching the current sensor board to a 5V Arduino Pro Mini or a 3.3V ESP32 is no problem - just hook it up and go.
One thing that turned out well for me was to create a C++ graphical Gauge class. That class was designed to allow me to create a wide variety of graphical gauges without a lot of work rewriting the Gauge for each new variant. You can see an example gauge on the OLED in the picture above. To create a Gauge object, you specify things like a size and location, start and end pointer angles, full scale readings, partial circle arcs, pointer lengths, tick lengths, etc. Gauges are hugely configurable. You can even specify the number of pointers. Why? Because with 2 pointers, you can do things like an aircraft's altitude gauge: small inner pointer reads in 10,000 feet increments and larger outer pointer for 1000 ft increments. With 3 pointers you can define a gauge that can be used to tell time, AKA an analog clock display. I love clocks, especially if they are unnecessarily accurate.
I like the gauge style shown above where the gauge layout leaves enough room at the bottom for a digital reading display. The analog pointer is really useful to visualize things like the startup current surge when an electric motor kicks on. A digital display is really good at displaying very precise information in a steady-state system. Between the two of them, things are covered.
The well pump house finally got a V4.0 current monitor installed. The funny part was that when the project was reaching a serious phase, I walked out to the pumphouse to see how I was going to mount everything out there. About 6 feet from the pumphouse door, I noticed that the ground had a pool of water on it. Being the middle of summer, this was unusual. It also explained why the rhododendrons over there were doing so well. So not only did I know I had a leak, but I already knew pretty much exactly where it was. But I was committed to this project, so I forged ahead anyway.
The new system got set up to send me an email every morning telling me about the last 16 pump events: what time the pump began its cycle and how long it ran. From that, I could determine the time between cycles. And with the very first report, it proved what my soggy ground already told me: there was a leak. The well pump was cycling about every 30 minutes all night long.
Since I hate plumbing (see above), I had a plumber come out to fix that leak. He asked me where it was located, and I pointed at the wet dirt. He dug a hole and quickly found the problem, and repaired the pipe. I was happy right up until next morning's report showed that instead of cycling every 30 minutes, the interval was now every 50 minutes. Obviously, another leak.
I told the plumber about that and he said, "If you don't know where it is, you're on you own." To make a long and irritating leak-finding story short, I did find it. Well, sort of. All I know is that the leak is located somewhere in a portion of the lawn irrigation system that we never use. I made a command decision to put in a valve to just shut off that portion of the water system. After closing the new valve, the pump quit cycling overnight. Victory, proved.
Looking back, it was a ton of work to find and fix those leaks. On the plus side, I discovered that our water system piping ran inside a 4 inch conduit buried for the 80ft from the house to the pumphouse. By hand digging a new 20 foot trench from the pumphouse to the garage, I was able to run 3 gigabit ethernet cables from the house to the garage. I added a nice PoE access point out in the garage and finally have good internet out there after only 4 years of putting that project off. The best part is that the new access point got set up so that I could stream baseball games while tending the burn pile. Luxury!
It's nice when boards are so cheap that you can make another version just because you feel like it. V5.0 removed the extra gating that got added in V4, and the software driver got simpler again. I also felt like this might truly be the last version, so I did another board shrink. Trust me, this photo doesn't show it well, but it is smaller than V4.0.
The real reason for V5.0 was to add another connector pin so that VOUT (the basic analog representation of the AC current signal) could go off-board. This feature was added to support a new project featuring a processor capable of sleeping until it sees an analog signal exceeded a preset voltage level. In that system, the current sensor constantly monitors the AC load, but the processor only wakes when the AC current exceeds about 3/4 of an Amp.
I had this V5 board made at OSHPark for the first time. All of their circuit boards are purple with ENIG (gold plated) pads. OSHPark is very cost effective if you have tiny boards, and the V5 is less than 1 sq inch. For larger boards, JLCPCB is more cost effective, even accounting for the DHL express fees.
I also swapped out opamps to support the low power requirements of the new project. The original TLV9064 would draw about 2.5 milliamps total for all 4 opamps in the package. I didn't care when the box was powered from AC lines. But the new project was going to be battery powered, and 2.5 mA would be way, way too much. I first tried a TLV9004 that dropped the power down to 240 uA. That was 10 times better, but still too much for a battery-powered system. I finally settled on an MCP6424 that uses only 14 uA to power all 4 opamps inside it. The MCP6424 seems to produce current readings that are a tiny bit noisier than the the other two, but that's probably the trade-off for such low power consumption. It's still perfectly usable for the goal.
There you are. Another successful project that's already been recycled for use in other projects. Who knows, maybe there will be a reason to make V6.0.
One thing I am proud of is that the analog design that I simulated in Spice worked in the real world, just as advertised. I made lots of changes to the board over the various versions, but the analog circuitry remained essentially unchanged throughout because it just plain worked. Yay simulation!