Picture of DIY Amp / Watt Hour Volt Meter - Arduino
acs715 output.PNG

Major corrections and additions made 9/9/2014

See the new and improved 2015 version at http://www.green-trust.org/jmc

For my off-grid Ham Radio and Solar projects, I needed a way to measure volts, amps, watts, amp hours and watt hours. There's a couple of commercial products that can do this, but not with the flexibility I wanted. I designed a Arduino micro-controller based solution that is very extensible. Right now it monitors the above values of attached gear, and I'm thinking about adding web monitoring and a sd card for data collection. Well, let's get started.

Step 1: Voltage Divider

Picture of Voltage Divider

UPDATE 9/9/2014 !

The Arduino can accept up to 5v on a analog input. Our voltage can range as high as 20vdc in certain situations (open circuit pv voltage), so we designed a voltage divider that would provide 5v at 20v battery voltage, and less at various lower voltages. See http://en.wikipedia.org/wiki/Voltage_divider for more information on Voltage Dividers.

First we visit our friendly Voltage Divider Calculator. I input 20v as the input, 5v as the output, and 3k for R2 (experiment with <10k resistors till you get a likely pair). This calculates a R1 of 9K. Try to keep the values as close to, but under 10k Ohms as possible.

R1 = 9k Ohms

R2 = 3k Ohms

Vout = (R1 / (R1 + R2)) * Vin

Vout = (9000 / (9000 + 3000)) * 20v

Vout = (9000 / 12000) * 20v

Vout = .75 * 20v

Vout = 5v

Ratio = Vin / Vout

Ratio = 4

Because the Arduino has a 10-bit ADC, it outputs 0-1023 (1024 steps) for a 0-5v input. That's 0.00488v / step.

With a Voltage Divider with R1 = 9k Ohm and R2 = 3k Ohm, A 12v battery would calculate as follows:

12v / Ratio = 3v on the A4 pin.

3v / .00488 = 615 (ADC Reading - round up)

so A4 pin Voltage = .00488 * ADC reading (615 in this case), or 3.00 volts.

Then battery voltage = A4 pin voltage * Ratio (3 * 4 = 12)

The code to read that value is as follows:

ADCVal = analogRead(batMonPin); // read the voltage on the divider on pin A4
pinVoltage = ADCVal * 0.00488; // Calculate the voltage on the A/D pin
// A reading of 1 for the A/D = 0.00488mV
// if we multiply the A/D reading by 0.00488 then
// we get the voltage on the pin.

batteryVoltage = pinVoltage * Ratio; // Use the Ratio calculated for the voltage divider
// to calculate the battery voltage, Ratio = Vin / Vout

More details at http://arduinotronics.blogspot.com/2012/04/voltage-monitor.html


Improved voltage reading circuit and sketch at AC Volt Meter (works with DC as well). Rock solid voltage measurement, and very accurate.

1-40 of 85Next »
Where should i put the test probes?
sspence (author)  Suliyen AnneS17 days ago
for measuring current, typically in series with the negative cable. some industries like the boating industry prefer the positive lead.Does not really matter.
Rahul Mitra3 months ago

Can i use this with my battery from a truck... ??? i thinking there would be a high current on the resistors................

sspence (author)  Rahul Mitra3 months ago
There's no high current going through any resistors. Yes, it will work with your truck battery.
Eric Brouwer3 months ago

Thanks for sharing your code. I immediately build one for a battery test I am buzy with.

wolfe.rose.54 months ago
I have a strange problem...i duplicated your protoboard circuit (ammeter and voltage divider), and it served to work as expected. I then thought it should be easy to add an lm7805 voltage regulator to power the arduino from the measured voltage, and connected 7805's Vin to the voltage divider's input voltage, 7805's GND and Vout to the 4pin header's GND and VCC. Powered up, everything looks great so far... then i reconnected a small load to the hall sensor, and the arduino blacked out. Remove the load, it comes on and works again. Why is this happening and how might i correct it?
MattsterT5 months ago

I'm curious about using the Pololu current sensors. If I understand, they carry the full current of whatever they're measuring. I have a couple of them but I've avoided using them because I don't understand the max current limits and it is going in my RV. In theory I should not ever see more than maybe 10-15 amps max but when I looked at those little circuit boards that seemed like a lot for such a wee little thing. Thanks.

kapusiaron5 months ago


If I want to use this Amp Hour meter for high current (10-15 A) and 10V, what must I change?

Thanks for the answer!

sspence (author)  kapusiaron5 months ago
It will work fine as is. It's designed to read up to 20v and 20-30 amps.
tgvoss5 months ago

I am thinking of using these 10k potentiometers instead of the thin film resistors as referenced in your blog post link. Does this seem correct?

I am using a 100w solar panel that has an open circuit voltage of 22.4V.

sspence (author)  tgvoss5 months ago
Yes, you can use potentiometers, but you will have to measure their resistance and put that into the code. Don't ever adjust them once you have the finalized values. It's easier to use fixed value 1% resistors.

20V to 5V using voltage dividers? OUCH.

You are going to have to deal with serious heat issues! And not to mention high watt resistors. Why not go for a 7805 voltage regulator?

How would a schematic look if I were to use the voltage regulator instead.

sspence (author)  woodsphysics5 months ago
It wouldn't work. You are trying to measure change. There's no change with a voltage regulator.
sspence (author)  OhYeahThatGuy815 months ago
Very little heat, as there's not much current flow. Arduino inputs are high impedance. A voltage regulator would not allow a voltage change, so how would you know when the source changes?
AlfredY6 months ago

I'm trying to understand before I go buy this for my wind turbine project. Also, is the Uno good for this project?

In the calculation of current, I am a little confused. I need to put this in my paper so I need to fully understand it.

Does the sensor rest at 100 sensor value at 0V=0A? And where does the 1A = 133mV come from? Is it from the datasheet?

Can you please see what I'm wrong in the below?

5000mv = 30000mA, ratio is 1:6

ACS715OutputVoltage = (SensorValue - 100)* 5000/1024

Current = ACS715Voltage * 6

TimSwift6 months ago

Hi i made a similar meter to monitor a battery but its not giving a liner output. The resisters on my devider are much larger then yours could that be the problem!

Hi sspence.

Great project and it helps me a lot. Thank you. I just wanna ask about LCD display. are u using LCD serial or Parallel.

sspence (author)  Noor ShahirahS7 months ago
This one was parallel, I use I2C LCD's now to save pin counts.

Thank you!

BelialD7 months ago

Do you think this may work accurately (+-1%) in the range of 0-20mA and from 1-35V? I want to count the total mA used in an electrolysis process.

sspence (author)  BelialD7 months ago
with a different sensor, and a smaller aref, sure.
Nithin Prabhu8 months ago

The whole thing is quite genius i must say , but in the calculation 0.75*20 =5 ?! , you arrived at that because its not "Vout = (R1 / (R1 + R2)) * Vin " that's completely wrong! Its quit the opposite. "Vout = (R2 / (R1 + R2)) * Vin". so its 0.25*20=5. The links you provided are awesome ! Your blog is too good! Kudos !

Un4Seen8 months ago

Very nicely done tutorial! I'm happy I have found it.

I do have one question, though. You recommend not to use resistors with values over 10K in the voltage divider. What is the reason for this? Theoretically it would be good to use higher values for the resistors, so that the internal power consumption of the voltage divider is as low as possible. With photovoltaic panels it's a shame to waste even a milliwatt. Thank you!

sspence (author)  Un4Seen8 months ago
It has to do with the impedance of the ADC on the Arduino. The lower the resistor value, the more accurate the tracking. Have to find a happy medium.
Un4Seen sspence8 months ago

Thank you! Any idea what kind of accuracy loss we are talking about with 10K, what about with 100K? Thanks!

sspence (author)  Un4Seen8 months ago

I don't know, I'm just going with atmel recommendations.

Un4Seen sspence8 months ago

Allright, thank you again very much for the excelent tutotrial and for your quick answers!

Tvixen9 months ago

Hi Spence

What use is the sample counter for (in the loop), and what happens after 9,10 hurs ? .. As the sample is only made as an Integer. Will it calculate negative ?

Tvixen Tvixen9 months ago

ohh i can see theres only 10ms between every measurement, so the time is even lower. Correct me if im wrong, but after aprox 5,43 minutes the sample counter should be 0.

sspence (author)  Tvixen9 months ago
The sample counter resets to 0 after every 10 samples, or every 100 ms.
Tvixen sspence9 months ago

Is that a suggestion ? because i can't see this in your code.

Only that " sample = sample +1; "

sspence (author)  Tvixen9 months ago

hmmm... older code.

do the voltage sampling the same as the current sampling, with a

for (int x = 0; x < 10; x++){ // run through loop 10x


Time to redo this code with the newer IDE version and other updates since this was first produced.

Tvixen sspence9 months ago

I think you misunderstand. It's in the loop you have a variable called "int sample=0;" you use it as a counter. NOT as sample for input :)

This counter will overflow after 5,43 minutes. As it's made as a integer.

sspence (author)  Tvixen9 months ago

right, and if you only take voltage 10 samples and reset the counter (not shown in the posted code) it can never overflow. I'm suggesting rewriting that section of code to work like the current section.

Tvixen sspence9 months ago

Ahh oki, I thought we could use your code as it was.

Its oki, i'll make my own code. Thanks for ur time :)

MattsterT10 months ago

You hook the current sensor into the positive side of the system, I'm accustomed to using a shunt in the common negative bus in marine systems. Can you please comment why the difference? Thank you

sspence (author)  MattsterT10 months ago
It makes no difference. What you are measuring is the voltage dropped across the shunt resistor.
MattsterT sspence10 months ago
I understand that - that's why I'm curious why you chose to use the positive side when the industry practice for boats, RVs, etc is to use the negative side.

A separate question if I may, when using a shunt how does a microcontroller measure negative current during charging?

sspence (author)  MattsterT10 months ago

the industry practice is arbitrary, and varies with industry. in the solar industry, you are just as apt to find it in the positive lead. It doesn't matter, it's personal preference. by applying a 2.5v bias, you can move "0 amps" to 2.5v, so full Forward current is at 5v, and full reverse is at zero volts, or ground.

1-40 of 85Next »