The smallest range for adc?

How small voltages can we read with Arduino adc?

I try to avoid using operational amplifiers.

I made some tests with voltage dividers from 5V supply to ground with 3 resistors :

(5 V of Arduino powerpin)
R1 : 10K ohm
(point E1, to Aref)
R2: 10 ohm
(point E2, to Analog input A0)
R3: 10 ohm
(ground of Arduino pin)

On prototyping breadboard with wires I connected point E1 to Aref (without any protecting resistor! (of at least 5K ohms )) and
point E2 to analog input A0 through a resistor of 5K ohm.
There was 0.1microFarad capacitor between Aref and ground, and also between A0 and ground.

In theory, point E1 in the divider should have a voltage

U1 = 5v * (10 + 10 )/ (10 + 10 +10000) = 9.98 millivolts

and point E2 exactly half of that, 4.99 millivolts.

I checked the voltages with a multimeter and they agreed reasonably well.

I then read the adc values with a program. The program calls either
analogReference(DEFAULT) or analogReference(EXTERNAL) in the
setup(), and then calls analogRead(A0) in the loop().

I was very happy to see values around 501 from the call to analogRead(A0).
(in theory the value ought to have been 1023/2 = 511 or 512, but the
resistors are not that accurate)

But then I disconnected the 5V wire from the protoboard voltage divider and
was expecting garbage readings in analogRead(A0).

Surprise! The values were still around 501 :astonished:

I changed the resistor between E1 and E2 to 33 ohms, put back the 5 Volt wire and run
the measurement again. Got values about 234. (theory: 1024*10/(10+33) = 238). At least
something was probably measured.

If adc really can get 1024 values from a range of 10 millivolts with some consistency , the
stepsize would be only 10 microvolts in this arrangement.

In the tests above I was very worried about the warnings concerning Aref connection and
using a series resistor of at least 5K to protect it. I do not understand these warnings well,
but would like to learn.

If I put a 5K resistor between Aref and E1 then the program starts giving value 1023 and
the multimeter indicates
the voltage in E1, which is 2 or 3 times as high as previously. (as if the Aref pin would send
a current from 5V power line thought the 5K resistor to E1). In the original layout (without
the protecting resistor) the Aref pin seems to have almost infinite resistance (good).

How would you recommend to make the test circuits to find out, how small ranges of the adc can
be measured with some consistency (repeatability)?

I would use these results to interface e.g. hot wire anemometers, heart beat monitors etc to Arduino,
as a hobby. It is not important whether the adc-readings are ‘correct’ voltages, but the repeatability
(with reasonable standard deviation) is.

The image made with LTspiceIV, downloadable from, free.


The resolution of the ADC is Vref/1024. Therefore, with the default Vref of 5v, the resolution is 4.88mV. To get better resolution for reading low voltages, use analogReference to select a lower Vref, for example the bandgap reference which is 1.1v nominal.

If you want to provide Vref from an external source as you are doing, 1.0v is the minimum supported - see the atmega328p datasheet.

Using an op amp isn’t that difficult if you are only interested in non-negative input voltages. You can get op amps that include 0v in both the input and output ranges even when you run the op amp from a single +5v supply.

Thanks dc42.

The 1V lower limit for Aref was in fact mentioned in the tables in the end of the datasheet. Adc seemed to "work" also between Aref = about 0.5 V and 1.0 V (probably not as accurately as on the supported range). Aref under about 0.5 V the readings seemed to be always 1023 for any voltage.

In the above experiments I had made errors, but luckily did not burn my Arduino. I had by mistake created a short between 5V and Aref and thus feeding 5V to the adc instead of the lower voltages of the voltage divider :~ . I hope nobody repeats my experiment (without knowing exactly what he/she is doing ...).