Measuring power of IoT devices
As part of my research into IoT security, I wanted to understand if my security model requires more power (and hence energy) to run than the existing approaches. I figured I’d head over to the Engineering department and they would have a system for measuring power. They did. But in watt hours (Wh). My power consumption needs to be measured in mWh. I have somewhere between 70 and 300 mA of current, and a 3.3V supply. If you remember your physics lessons from school, power = voltage x current. And energy = power x time. So to capture the energy consumption, I needed to measure those three things: voltage, current and time.
Voltage is reasonably easy to measure. For example, out of the box, Arduino boards have several analog-to-digital converters (ADCs), that measure voltage. They are 10-bit converters, and they support an input reference voltage. They split that reference voltage from 0–1023, so if the input voltage is 5v, then the accuracy is roughly +/-5mV.
Current is harder to measure. I initially found some chips that use the Hall Effect to measure current (https://www.sparkfun.com/datasheets/BreakoutBoards/0712.pdf), but googling seemed to indicate these are not accurate enough. They produce at most 186mV/A, so if I am measuring a current of 100mA, I’d need to measure 18.6mV. Since my accuracy is +5mV, I’d be seriously inaccurate. One option would be to put an amplifier onto the output of the hall-effect sensor, and this is what the SparkFun breakout board does. Unfortunately the forum discussions seemed to say that even then, this chip is just not accurate enough to rely on for this level of current.
The easiest way of measuring current is simply to put it across a resistor of known resistance and measure the voltage across the resistor. This is how ammeters work. But the problem is that the addition of the resistor changes the circuit under test and then this “burden voltage” affects the measurements. The secret, it seems, is to use very low resistance, creating a tiny voltage to measure, and to then use amplifiers to increase that to a measurable result. Not being great at analogue electronics, I felt a bit out of my depth, but then I came across this device: the EVBlog uCurrent Gold multimeter adapter.
It effectively does what I want — converts low current to a measurable voltage, and with high accuracy.
The uCurrent Gold has three settings: 1mV/mA, 1mV/uA, and 1mV,nA. In fact, I need the least sensitive of these: 1mV/mA. The specs offer better than +/-0.1% accuracy on this range.
So now I will need to measure two different voltage levels: ~3.3V as the voltage used, and ~200mV as the current measurement. My first approach was to reduce the 3.3V by a factor of 4, and then use my Arduino’s 10-bit resolution to measure from 0–1V, giving me +/-1mV. This is a pretty good approach, but I then found an improved ADC chip for the Arduino on eBay for about £5. This ADS1115 chip and breakout board will measure from 0–5V with +/-0.125V accuracy, which means that I can measure my currents in the range of 50–200mA with better than +/-0.25% accuracy.
So the final solution is to use an Arduino (in my case a Leonardo) together with the ADS1115, and the uCurrent Gold. A small Arduino sketch captures the voltage and current measures, integrates them to create an elapsed power, and then prints the results out each second. Here is the overall system diagram:
A nice touch is that when the power goes to zero or negative for a few samples, I restart the energy calculation, meaning that every time I restart the device, the energy calculation restarts. I’m now just collecting the data from my device, so look out for some interesting results soon.