# Computing stuff tied to the physical world

## AC current detection works!

In AVR, Software on Oct 10, 2011 at 00:01

As promised, the results for the ATtiny85 as AC current detector, i.e. measuring current over a 0.1 Ω shunt.

Yesterday’s setup showed the following values in the display:

``````    30 71-101 68.
``````

From right to left, that translates to:

• it took 68 ms to capture 500 samples, i.e. about 7 KHz
• the measured values were in the range 71 .. 101
• the spread was therefore 30

With a 75 W lamp connected, drawing about 100 mA, I get this:

With the 25 W lamp, the readout becomes:

And finally, with a 1 kΩ resistor drawing 20 mA, this is the result:

As soon as the load is removed, readings drop back to the first values listed above.

Now it seems to me that these readings will be fine for detection. Even a low 20 mA (i.e. 4.4 W @ 220V) load produces a reading with is 30 times higher than zero-load (with about 10% variation over time).

I’m measuring with 2.56V as reference voltage to remain independent of VCC (which is 3.8V on batteries). So each step is 2.5 mV with the built-in 10-bit ADC. With the 20x amplification, that becomes 0.125 mV per ADC step. Now let’s see… a 20 mA DC current across a 0.1 Ω shunt would generate a 2 mV differential. I’m using an order 31 moving average, but I didn’t divide the final result by 31, so that 1099 result is actually 35 on the ADC. Given that one ADC step is 0.125 mV, that’s about 4.4 mV peak-to-peak. Hey, that looks more or less right!

There is still a problem, though. Because half of the time I get this:

Total breakdown, completely ridiculous values. The other thing that doesn’t look right, is that none of the readings are negative. With a differential amplifier fed with AC, one expects the values and signs to constantly alternate. Maybe I damaged the ATtiny – I’ll get another one for comparison. And maybe I didn’t get the sign-extensions right for the ADC’s “bipolar differential” mode. There’s a lot of bit-fiddling to set all the right register bits.

But still… this looks promising!

Update – Problem solved: it was a signed / unsigned issue. The values are now completely stable with under 1 % variation between measurements. I’m not even filtering out high frequencies, although I know I should.

1. Congratulations! Great result!

2. Could the ATtiny85 be mounted on a plug to be attached to a JeenNode? Or could it be attached to a RF12B module and behave on the air as a JeeNode? And finally, could it be made into an independent device that gets its power from the mains (yes I know it’s dangerous if not done properly) and broadcasts a radio signal indicating whether the lamp is on or off?

Second batch of questions: what about using this system to detect whether a switching power supply is on or off? The switching process, to my knowledge, produces plenty of harmonics on the power line, does it affect the signal, the filtering and in the end, the measurements the ATtimny85 can make?

• Splendid questions! Exactly what I’d like to find out as well. I haven’t tied this to AC mains yet, but I will. With a bit of luck, the currents might be sufficiently distinct to detect whether a cell-phone charger is charging or not, for example. As for how to turn this into a self-contained unit – stay tuned, I might have some options there…

• To follow up: on (transformer-isolated) AC mains, things work great. Unloaded -> readout 30, 25 W -> 1000, 75 W -> 3000. And best of all, for my cellphone charger: nothing connected -> 40, charging -> 280. An old USB charger which draws 0.3 W unloaded registers a jump from 30 to 50, which is barely enough. The efficient AA charger I found a while back alternates between readouts of 30 and 270 while charging, and doesn’t register at all while not charging. Neither does a good low-power USB charger when unloaded. Excellent.

So all in all, I think this setup should be good enough to detect power consumption changes down to perhaps 2 W.

3. Do I understand correctly that you’re now connected (indirectly) to the mains, and not to the 20V AC transformer?

Have you tested the maximum load you can handle? Ie no problems with overflow calculations etc.??

If you would power this through the same mains connection, I guess you can ‘calculate’ the mains voltage also and create a very, very simple Watt meter with some calibration. Donno what kind of watts you’re measuring in that case though (RMS, real power etc..)

• Yes, my last comment was w.r.t. 220V. Max load is 1000 W, that’ll generate ≈ 2W in the 0.1 Ω shunt (ignoring RMS). I’ll test with direct AC mains and 700 W one of these days. There are no issues with integer overflow for these values, but the ATtiny 20 x gain will need to be switched off for high power levels. I’m not concerned about that at this stage, because all I want is current detection, so signal clipping is not important.

4. 1000W is more than enough for most systems! And does it matter how the neutral and live lines are connected? Or is that problem solved by the differential ADC of the Attiny?

I see nice things coming! I know you just wanna detect if something is ON or OFF, but by adding a treshold and a relay and you’ve got a standby-killer in your hands…

Add a bit more (code + hw) and you can have simple energy monitoring and on/off switching combined in one little unit.

Then, make it real tiny, put it inside a 4/6/8/10 socket extension unit and you can measure each outlet and switch each outlet independently!

;-)

5. This is really interesting to follow. I’ve built a JeeNode wired to a Kill-A-Watt and spent a lot of time trying to figure out how to count the data I was getting out of it. I eventually put it aside and haven’t gone back to it.

What are you using for your moving average now? Is it a 31 element array that you keep a running sum of then divide to get the value? I noticed in your “Power Measurement (ACS) – code” article that your optimized moving average is actually an exponential moving average. That puts more weight on the newest elements over the older ones and would produce a different result than would be obtained simply calculating the average of the measurements, and I don’t think that’s what you want considering the dataset is a wave.