Instructables
Picture of DIY Amp / Watt Hour Volt Meter - Arduino
acs715 output.PNG
P1010472.JPG
P1010487.JPG
P1010520.JPG

Major corrections and additions made 9/9/2014

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.

 
Remove these adsRemove these ads by Signing Up

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

UPDATE:

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 67Next »
Un4Seen6 days 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)  Un4Seen6 days 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.

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

sspence (author)  Un4Seen6 days ago

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

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

Tvixen13 days 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 Tvixen13 days 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)  Tvixen12 days ago
The sample counter resets to 0 after every 10 samples, or every 100 ms.
Tvixen sspence12 days ago

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

Only that " sample = sample +1; "

sspence (author)  Tvixen12 days 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 sspence12 days 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)  Tvixen12 days 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 sspence12 days 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 :)

MattsterT1 month 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)  MattsterT1 month ago
It makes no difference. What you are measuring is the voltage dropped across the shunt resistor.
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?

Thanks.
sspence (author)  MattsterT1 month 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.

I suspect that the use of the negative side in boats is because it is mechanically easier to combine the negative sides of multiple batteries into a single connection point.

How would I apply a 2.5V bias to the input pin of the Arduino?

sspence (author)  MattsterT1 month ago

by using a voltage divider as shown at http://openenergymonitor.org/emon/buildingblocks/measuring-voltage-with-an-acac-power-adapter

Thanks for the prompt responses. I think I'm OK with the design details now, but a question: you use DallasTemperature.h in your program - where do I find this header file? T hanks

sspence (author)  MattsterT1 month ago

This sketch does not use DallasTemperature.h
Where did you see that?

vipzsflinchsz2 months ago

I really find it hard to find the components used. like the arduino.
can i use gizduino mini atmega 168 for this set up? we dont really have
acs715 in our country right now. can i get somehow the coding if i use
IC LMP8480? very much appreciated it! thankksss

sspence (author)  vipzsflinchsz1 month ago

Yes, the 168 could be used, you just have less memory, but there should be enough for this project. I posted the lmp8480 data sheet in your other question.

anushk3202 months ago
vipzsflinchsz2 months ago

Thanks for sharing! Hi. can i get the list of all equipment you used for this project? and If i use IC LMP8480 what will i change in the coding for it to work? thanks I appreciated your help!

sspence (author)  vipzsflinchsz2 months ago
I listed the components. An ACS715 (current sensor) and two resistors (voltage sensor). The 8480 outputs a voltage when it senses current, so it should not be too hard to use, see the info at http://www.ti.com/product/lmp8480

ayasbek1 year ago
Thanks for sharing!

I have an idea about why you have that 0.00610 multiplier instead of the ideal 0.0048... your code is only taking the simple ratio of the resistors - it should maybe be
ratio = (float(R1) +float(R2))/ float(R2)? Please let me know if this correct?

I love the instructable. I am using it to create an amp-hour battery gauge for my new-to-me electric car. The car already has a shunt (400A - 50 mV) so I will be using that. I may use an op-amp to boost the mV signal. Then again the 4.8 mV resolution on the arduino might be fine.
sspence (author)  ayasbek3 months ago

I've corrected and simplified the readings. for a voltage input that will never exceed 20vdc, make R1 15k ohm, R2 5kohm. For a 12v system, 0-20v input will output 0-5v to the adc. 5v / 1024 = .00488 / step. so adc reading * .00488 = voltage on A0. Voltage on A0 * 4 = voltage input, becasue 20v / 5v = 4.

myfaithnka5 months ago

sorry for my ignorance, Can i use this IC instead of Hall effect sensors ? LMP8480
thank you,

nithin

sspence (author)  myfaithnka5 months ago

Yes you can. Code will look a bit different, but not drastically.

:) Thank you sir,This saves my day.
kobniala6 months ago

hello everyone!..

someone here tried to add up the wattage...

for example, if given 24 hours how much wattage did the system consumed.

it will be a great help from us if anybody can teach us how..thnx

sspence (author)  kobniala6 months ago
100w * 24h = 2400 watt hours (2.4 kWh)
musu7 months ago

I`m using this project for my off grid setup, battery 90ah, solar pannel 50W.. the problem is when connecting the current sensor with the system, no values are given on the LCD screen ( indication of incoming power) i would like some help what can be done thanks.

sspence (author)  musu7 months ago
did you put the current sensor in series with the positive lead of the solar panel?
musu sspence7 months ago

yes, i did as shown in the diagram given : http://cdn.instructables.com/F31/TBJZ/H3QFJ5ER/F31...

mainly the LCD screen is giving just 0.53v and the other vaules are 0w and 0A

Johnnysenex11 months ago
Hi, I would like to get some help.
I have a 5kw inverter (24v) on 720 ah of batteries, with 1000 w solar panels.
I want to measure the what hours in, and the watt hours out, to be able to make sure I don't drain my batteries.
Therefor, I would like to build two watt hour meters to do so.
Obviously, the design must be such that it does not hamper my amps when I'm pulling a big load. ( my fuse is a 400amp fuse' and my cables are 70mm^2)
Thanks, and looking forward to your answer!
Johnny.
sspence (author)  Johnnysenex11 months ago
You would only have to have one unit between the battery and the rest of the system. Will need to customize the code to read amps in (+) and amps out (-) to get a amp hours left in the battery. These units are non obtrusive (hall affect), unlike a shunt. The sensor I used is not rated for 200 amps, so a different sensor will need to be used. I'll have to do more research for you.
Thanks for the reply.
I understand that the grounds must be common, but isnt there a risk for different circuits to share a DC ground?

I read the part about the ADC optimization and did not really understand as I do not see any S/H capacitors anywhere. As my load will be a DC-DC converter it wil have a high impedence and thus the lower impedence of the voltage divider will trickle discharge the battery.
sspence (author)  svendickman1 year ago
the capacitors are inside the atmel 328p. No, there is no risk with shared ground.
1-40 of 67Next »