Monday, December 28, 2015

Arduino: Micro Processing Renewable Energy - Part 2 - Measuring Current

Measuring Current

A microprocessor can't really measure current directly. It can only read voltage. There are many ways to create a voltage that can relate to a current. The most basic being a shunt. A shunt is just a known resistor that is used in the circuit to be measured. When the voltage drop across the resistor is measured, Ohm's Law can be used to solve for current.

V = I x R
I = V/R
V = Voltage
I = Current
R = Resistance

For instance, if you have a 1 ohm resistor in a circuit, and you measure a voltage across the resistor of 3.7 volts, then the current flowing through that resistor is 3.7 amps (3.7 volts / 1 ohm). That resistor would be pretty hot, though. Since power is equal to the current squared times the resistance, that resistor would be emitting 13.69 watts. A typical resistor that you would see on a small circuit board can only hand a quarter watt, so nearly 14 watts would blow a hole through it and shoot flames out its sides. Not a pretty picture.

Burning resistor as seen on
A more appropriate resistor would be like this 25 watt one.

But, that seems like a lot of wasted heat just to check the current. And the resistor actually limits the current slightly. What if we used a resistor with much less resistance? How about a 0.001 ohm? Then, every milivolt we detect across the resistor would equal one amp of current. For wasted heat, that would be great, only 14 mW instead of 14 watts. Wow, 1/1,000th of the original wasted heat.

There would be a problem though. The Arduino only reads 0 to 5 volts and it does it in 1,023 discreet steps. The lowest value it can detect after zero would be 4.9 milivolts or 0.0049 volts. You could only detect 0 amps, 4.9 amps, 9.8 amps, etc. Not a great solution. There are a few ways to compensate for this though; oversampling, op amp, hall effect, or use a different resistor at 0.01 ohm.


There are many scholarly articles written on oversampling, so I won't go into excessive detail here. I'll just cover the basics. In the above example using a 0.001 ohm resistor, we can only detect a change of 4.9 amp increments. This is because we are reading the voltage at a 10-bit resolution. But what if we somehow (magically?) used 14-bit resolution? That would be 16, 383 steps, each step to 5 volts would be equal to 0.0003 volts or 0.3 mV per step.

We can do that through oversampling. We just take multiple samples and average them to come up with a new, more accurate value. For instance, take a light in your house, that either turns on or off. That is 1-bit resolution. If you flick the light off and on and record those readings, you can then average 4 readings to get 2-bit resolution. Values would include 0, 0.33, 0.66, and 1.0. Another way to express that is OFF, 33%, 66%, and ON.

The rule of thumb is to accumulate 4^n 10-bit samples, where n is the desired extra number of bits in the resolution. For example, to get 14-bit resolution, that is 4 more than 10, so 4 to the 4th power would be 256 samples taken, then divide the result by 256. To get 16-bit resolution, take 4 to the 6th power (4,096) samples and divide by 4,096.

This approach works only because there is almost always some RF or electrical noise in the system to make minor variations occur while taking the samples. More info can be found at

Op Amp

Op Amp, or operational amplifier, is an electronic chip that takes an input and amplifies the output a number of times. In the above example of using a 0.001 ohm shunt resistor to measure current, we could just amplify the voltage reading to get something more appropriate to the Arduino. If, for example, 30 amps is the max current we expected, we could make that equal 5 volts to the Arduino input pin. The voltage drop across the resistor would be 30mV. So, we would have to set the Op Amp to amplify the output by 167 times.

Hall Effect

Many times you can buy a hall effect current measuring device that will measure AC and DC current in either direction. This one will measure 30 amps. There is a trick to make this 30 amp version measure much more. For instance, to double its capacity, just place a jumper wire across the terminals to shunt half of the current. You may have to experiment with the thickness and length of wire to use as the bypass, and you would also have to adjust a variable in your Arduino program to get the accuracy where it should be.


The simple solution to the initial problem is to use a 0.01 ohm resistor instead of a 0.001 ohm resistor. Instead of 1 mV being equal to 1 amp, 10 mV equals 1 amp. Since the Arduino can normally read in 5 mV increments, this would be good enough to measure current in half amp increments. At 3.7 amps, that would be 37 mV. The Arduino could only see 35 mV or 40 mV, so the resolution wouldn't quite be there. Your program would just have to report it as 3.5 amps.

Which solution to use?

Well, they all have their place depending on the scenario. I've used all of the above. One of my favorites is to mix the hall effect with oversampling. Then I add a shunt around the hall effect to up my current capacity. This gives me the best of all worlds, 14-bit accuracy with over 100 amps of measurement on a 30 amp hall sensor budget.

Then Take A Look At This!