Arduino as voltage meter, protect inputs from reverse polarity and floating

First of all, yes, I googled, have used the search function et cetera, and my project is quite simple, for I want to use an Arduino to quickly measure up to 6 pieces of my AA-eneloops (the 1900mAh type, of which I have many), which go from 0 to 1.5V if fully charged, and in theory, this is easy: Connect each positive terminal to one of the analog inputs, the negative terminals to ground, and get the readings.

I want however to avoid troubles when there is a) no battery inserted and b) the battery has been dropped in wrong end first.

I had some ideas with diodes and resistors on how to do this properly, but would it not suffice to just to set up the battery holder in parallel with a resistor, and connect this to 3.3V with another resistor and ground and read the input from there?

  3V3──R1──┬──┤           ├──GND
           │  └────R2─────┘
           └analog input

I think this would work, and it would cover all cases (battery inserted correctly, reversed, or not at all). Am I right, or would it not, or are there better ways to do it?

I don't think it works if the battery is inserted backwards. Your analog input pin would see a low-impedance path to -1.5V, which would send large amounts of current through the protection diode.

I guess in theory it might work with a third resistor between the positive battery connector and the analog input. But this kind of thing will give you muted voltage readings because of all the dividing going on. Reverse battery protection usually involves a P-channel mosfet, but I'm not sure how well that works at these low voltages.

Sorry I don't have a solution for you.

Nothing bad happens with a floating/open input except you'll get unpredictable readings. A resistor between the analog input and ground will pull the input to ground when no battery is connected.

[u]Over-voltage and reverse-voltage protection circuits[/u]

D2 (along with the resistor) in the 2nd circuit protects against reverse voltage. (If it was me, I'd increase the resistor to 1K or mofre. The Arduino has super-high input impedance so any "reasonable" series resistor will have no effect on the readings.)

I don't need to protect the analog input from over-voltage, since the eneloops go up to 1.6V at the very maximum, however, I think I can get away with simply forgetting about the 3.3V-connection and putting a diode next to the battery holder. Since the voltage I want to read is between 0.9V and 1.5V, the forward voltage drop of 0.7V from the diode is acceptable.

    ┌──┤              ├──GND
    │  └──────R1──────┘
    └analog input

Since this is to be a battery tester, I really would like to have some kind of an indicator if a battery got dropped in head first, but this is not a must.

I am however not entirely sure if the Arduino can really take the current of all 6 fully charged batteries, I think it should, but I will just pop out my good old multimeter and test the circuit before connecting it to the Arduino.

Diodes will not help, they drop a voltage that will throw the reading completely off.

To prevent damage to the analog pin you need a resistor in series with the analog pin,
10k will do nicely.

To make it read 0V when no battery is present, just add a 10k resistor to ground at the point
the battery connects. That way when no battery the pin sees 20k to ground and reads 0.

Problem solved.

I agree with MarkT and DVDdoug. You have a load resistor for the battery. Forget the diode. Put a 10k resistor between the battery terminal and the analog input of the Arduino. Let the internal protection diodes on the Arduino pin absorb the minor current from a reversed battery. 1.5V/10k = 150uA.

This also helps protect the Arduino input from ESD (electrostatic discharge) into that pin.

Because of the load resistor, the input will read 0V without a battery.

Now... what have you done to protect against inaccuracies and noise caused by the fact that by default, analogRead() uses Vcc for the reference voltage, the Arduino has no isolation between Vcc and AVcc, and there is no bypassing on the Aref pin?

Besides that my little tester does not need to be perfectly accurate (±5% are absolutely fine, ±10% would also do) I intend to calibrate the device by comparing the readings with a “real” voltmeter, also, I just browsed over the tutorials I checked previously, many if not most of them make no mention of a protecting resistor for the input pin…

OK, don't bother, then, if you don't want to. You asked a question, we answered.

What I wanted to say with this is: Had I followed those tutorials, my first project would have ended in a fried microcontroller before I even started properly. So much for that :roll_eyes:

Yes, I find that many tutorials leave off any safety devices. It was smart of you to be thinking about protecting the input from a reversed battery.

I used 47k on a recent design, but I was facing a very likely 12volt level from an op-amp. I also added a diode to protect the input, but it probably is not necessary.

I'm not sure why some people respond to further questions so nastily. I guess they like putting people down, they usually have high post counts I noticed.

Hi all,
As stated before, the ADC input resistance is super high! It will not draw much current if the
polarity is correct. But, it is voltage sensitive. Do not apply an input greater than your Vdd!
When we measure battery voltage, we should apply a reasonable load to it. A 1 ma. load is
reasonable. We calculate 1000 ohms per volt so a 1.5V battery should have 1500 ohms and
a 12V battery should have 12000 ohms as a load resistor directly across its terminals. Next,
we should protect the ADC input circuit. An input resistor of 10K has been suggested and
is a good value. If you are worried about reversed polarity, then perhaps 100K would be better.
(There is no need for a diode because the ADC input has internally connected protection
diodes.) When using the ADC, it is a good idea, as suggested by Polymorph, to bypass
the Vref pin with a capacitor (to ground) to minimize the effects of noise and switching
transients which could cause unstable readings. For battery voltages greater than your
Vdd, more circuitry and cautions apply!

Who said anything nasty?

Okay, I finally tried a few things, got wildly inaccurate readings, so I followed the tutorial from, but I still have the same problem:

A battery I test with, let's say, 1.3 volts, gives me about 1.24 volts on the readout of the Arduino, which is perfectly within the expected margin of error, but the readings keeps bouncing around, from values from up to 1.4 volts to sometimes even only 0.6, a phenomenon that I do not see when I use a multimeter, and even if I just let it sit there and do nothing.

What is going on here?

I power the Arduino from a laptop computer via the USB-connection (since it is a Nano), it does not matter if I run the computer itself from a battery or directly from the power-plug, it does not matter if I pull down all analog inputs, or do I need to pull down all input pins?, or is this just normal behaviour and I just need to do, let's say, 10 measurements or something and just use the median value?

Can you post a picture of your setup, the schematic, and your code? I am currently working on a project that measures current (by measuring the voltage across a resistor and calculating the current), and it is very stable. I'm using multiple analog inputs and with some careful use of delays I am getting very stable and accurate results compared against a calibrated Fluke 289.

It sure sounds like there is some noise on the signal, or you have some bad connections. If you are using a breadboard that could be the problem. I build all of my circuits on perfboard, and use surface mount parts where possible. Not that you need many parts for your circuit... I suspect you have poor connections or some kind of ground wiring problem.

I was having problems with an analog input that was noisy. It turned out to be poor ground connections on a breadboard. I made a better ground, the noise disappeared.

I tossed that breadboard.