Measuring the Mains
When my grandmother was still a child her family had electrical infrastructure run to their home for the first time. Her dad was so unsure of the new technology that he made it his job to stay up all night under the artificial light of the kitchen lamp to make sure they weren’t turning it off when nobody was looking. It’s been nearly 90 years since Great Grandpa put together his manually implemented check on grid stability, and here I am to take it a level or so deeper.
in case you’re just interested in the code and not my storytelling, that’s here
What he was doing is not too much unlike what I’m doing, implementing something of a brute-force algorithm to determine whether or not the service was reliable. His focus was on continuity, maybe indirectly grid fragility, but mine is on frequency and phase.
Recently, I learned of these nifty things called synchroscopes and how they allow you to bring generators online to an inextricably frequency-dependent AC grid. Here’s a video of a guy very excited to bring a hydroelectric dam online. The principal behind these, measuring the difference between your generator’s phase and the grid to know when to lock in, extends to something called a synchrophasor which is now part of phasor measurement units (PMUs) which plot precise measurements of the voltage and current usage against GPS-synchronized timestamps and systems watch for anomalies and ramp sample rates when the behavior is out of bounds so it can be analyzed more closely upstream in real time or after a grid failure. I cannot afford a PMU. The prices are a “call and ask” type of thing so I know I don’t need to.
AC is complex, and even as an amateur radio enthusiast and EE dropout I don’t feel I have the slightest grasp on the stuff, but I do know one thing: real load is not the measured load. In AC circuits, you can have something called “Reactive Power” which just means you’re moving more current than you actually have to for a load because it’s coming back to you. One problem: you’re still paying for the losses of that reactive power.
Inductive loads force the current usage to lag the voltage. If you think about it, this makes some sense. And inductor charges with the voltage but releases it’s induced field after losing voltage. If you have a capacitive load, the current can actually creep ahead of the voltage, but my mental model doesn’t have an explanation for that. A perfect match between the two is a Power Factor of 1, or “unity”.
Managing this power factor problem leads to very interesting solutions, like in a city I used to live in the power company would give you a small credit if you would allow them to remotely cut out your HVAC circuitry on hot summer days, because of the effect of cold-starting lots of large motors all at once on hot days, the remote cut-outs would given them a more forgiving load ramp to match with generation. This is exemplary of a gigantic problem in grid engineering: you can’t really control anything, including where current flows, only where connections are made or not and how much power you push in, and it needs to match the load or you’ll find yourself drifting ahead or behind the rest of the grid.
Grid oscillations and reverse current flows caused by being out-of-phase can cause catastrophic chains of failure, as all the parts of the grid work in tandem to attempt to assure enough power is available but no single resource ever takes all the load.
I wanted to see what the frequency drift looks like on my local grid, as I suspect it’s one of the more mis-managed lines in the region, with many outages over the year before last before they put in a new feed from the nearest big city (an area with the nation’s largest coal-fired power plant). I also wanted to know if I could measure the “phase angle” or power factor of an inductive load: a simple fan that I keep running all the time.
I bought a voltage transformer that isolates me from the AC current, allowing me instead to measure a generated DC analog of the waveform with +-1% linearity. The current sensor is just a transformer at 90 degree to a wire clasped through a split ferrite core, 100 Amps == 1 volt potential. I can’t even use more than 20 amps on this circuit, so it was well beyond safe enough to just plug this into the ADC.
I was unlucky enough to have chosen a voltage sensor and ADCs that both wanted a steady 5 volts, while my Pi was going to operate the I2C bus at 3.3v. I had to get a 5v voltage regulator (LC7805) and wire it up because the last time I needed different voltages I used a second buck converter and managed to create reverse current and blew up my rpi 3 (r.i.p. it was a good slice of rpi). This time I knew I couldn’t have separate ground potentials (which I suspect was an issue) but I decided to add logic level converters to isolate the circuits anyway. I was so happy when I got everything plugged in and nothing released the magic smoke that makes it work that I forgot to be skeptical about the signals I would find.
I was very fortunate to find the Go package I use for GPIO on the Raspberry Pi, periph.io, has a package already built for the ADCs I chose, the ADS1115. I ended up finding that the switching time from one channel to another and back limited my sampling rate to around the ~130 Hz required to do Fourier transformations for finding frequency. I enabled a second I2C channel and started using separate ADCs read from different go routines for voltage and current.
At first I found that the voltage circuit had huge spikes, something like a sine wave but with the lower voltages suppressed and the peaks jutting out from an otherwise quiet signal. After too much remote troubleshooting with a gifted friend, I was able to get a clean signal by giving it a reference from a voltage divider that also served to pull down the floating signal. It also gained fidelity when I turned the gain down to about half it’s original setting. My circuit. A 12v lifepo4, buck converter with barrel plugs and USB output, voltage regulator LC7805, pi4 b+, logic level shifter, 2 ADS1115s, one current sensor (connected by 3.5mm tip-ring-sleeve jack), one voltage sensor (with the blue square)
I started accumulating the points on each wave a few thousand at a time, then I would wrap them as a protocol buffers and send them across the network to my newer rpi5 which has 1 TB NVME SSD to store silly data like this. I have had the system running for 5 or so days now and I’ve accumulated about 35 GB of data.
the sub-par sampling rate of 860 samples/second max from the ADCs + the indeterminacy of a garbage collected language like go means that on a medium range scale the signals look terrible. If you look closely at each point, it falls along the sinusoidal curve you expect, for both voltage and current.
What did I learn from all this?
Well, first I learned you have to have a periodic (evenly-spaced) set of samples to do Fourier transformations. That was my mistake. If I had known going in that this would be a problem I certainly would have considered something like a micro controller tuned to avoid any interrupts. I’m still considering putting in the work to do interpolation to move the points to periodic placement.
Second, I learned that you can measure frequency by dead reckoning over long sequences of samples, and the grid here stays pretty reliably between 60.05 and 59.95 Hz.
Third, I learned my sub-sampling creep means that I can’t get a reliable distance between the peak of voltage and current measurements, but it’s still somewhere between 7–15 degrees on average, for a very respectable power factor on my single phase fan.
Finally, I’m learning to be cautious and thoughtful about circuit design but moreso I’m learning how to lean on networks of people with special interests who want to talk about them so I can’t make idiotic mistakes in the first place. It’s incredible how much my friend was able to help me without ever having to research a word. My problems are not new, and I do not have to solve them alone.