Battery Monitor

i would like to build a battery monitoring system for 12 12v batteries. i was thinking a could use a system like this:
along with an analog multiplexer and an lcd for voltage reading output
can someone please help explain the code for a project like this?

thanks in advance

All you need for a 12 volt battery monitor is two resitors setting up a voltage divider.

I used a 47k and 100k and used the adc ( 0 to 15v )

when i do an analogRead, the output changes very quickly as if nothing was connected to it but 4v is being outputted according to my multimeter
any help???

i dont need an rc timer of any kind?

No , I just did a analog test every 100ms or so by adding delay().

My values was constant with a fixed voltage.

i got it working now thanks
i didnt have the ground connected of course

can anyone help me with displaying the voltage to the hundredths place in the serial monitor?
so far i have this but it outputs 12.60 volts when the true voltage is 12.85

827-829 on the analogRead = 12.85v

int vPin = 5;
int val = 0;

void setup(){
  pinMode(vPin, INPUT);

void loop(){
  val = analogRead(vPin);
  Serial.print(val / (645/10), DEC);
  Serial.println(val % (645/10) ,DEC); 

any help?

Between the (normal) noise in the least significant bit of the ADC, variations in actual values of the resistors, tolerances in the resistors, etc, it may not be reasonable to expect .01V accuracy…

Use a meter to check the actual values of the resistors in your divider and see if some modification to your formula is in order.


i realize that it wont be accurate to .01 volts but is it possible to preserve a decimal when sending over serial?

it said this was true for the float variable, is it true for all decimals?
Serial.println() truncates floats (throws away the fractions) into integers when sending serial. Multiply by power of ten to preserve resolution.

Dont forget that ver13 of the idea has the support for printing to 2 decimal places.
Liquidcrystal and serial print both support it.
With some changes to print.h and print.cpp you can specify the precision.
I believe ver14 will have variable precision available as well.


can you explain how to edit the print settings?

You need to modify the print function in print.h and print.cpp in /hardware/cores/arduino/ to accept an extra parameter for the precision and pass it to printFloat.
As a hack I just modified these functions.
It means that wherever you have serial.print you also have to pass the precision.
When I get round to it ill do it properly. But I believe something like this will be added to ver14 of the ide.

in print.cpp

void Print::print(double n)
  printFloat(n, 2);


void Print::print(double n,uint8_t digits)
  printFloat(n, digits);

and print.h

void print(double);


void print(double,uint8_t);


thanks for your help
i ended up using code from this post about printing a float or double variable
works great

One thing I like to do when making a voltage divider is put a trimpot between the two resistors and adjust for the best reading possible. Connect the wiper pin on the trimpot to the arduino and adjust the trimpot until the Arduino reads correctly.

The trimpot should be the lowest value possible that covers the range you need, to allow easy adjustment. In the example peter247 gave with 100K and 47K, I would suggest either a 1K or 2.5K trimpot. You may need a larger trimpot if the resistors are off by much.