John L Errington MSc

John Errington's Experiments with an Arduino

Precise voltage measurement with the Arduino board.

The Arduino range of microcontrollers provides analog inputs that can be used to measure voltage.  We can use this to build a voltmeter.  
The analogRead() function reads the voltage and converts it to a number between 0 and 1023 as shown below

// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the ADC reading (which goes from 0 - 1023) to a voltage reading (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
(1) 

This leads us to believe that a reading of 0 corresponds to an input of 0.000V; and 1023 corresponds to an input voltage of exactly 5.000 volts.  This is not entirely true. Lets look at the data sheet and see what it tells us.

The ATMEGA chip used on the Arduino has analog inputs that can be used to accurately measure voltage

The Arduino microcontroller is provided with a successive approximation type Analog to Digital converter (ADC) which has the following specification.  References shown in brackets thus  (2: 26.1) refer to sections of the AtMega 2560 data sheet.
(2: 26.1)
Resolution 10-bits  (i.e. 00 0000 00000 to  11 1111 1111 binary, or 0 - 1023 decimal)
Integral Non-linearity .. 1 LSB
Absolute Accuracy  ± 2 LSB
Conversion Time 13 - 260 µs
Input resistance R_in =100M  (2: 31.8)
Input resistance of Reference voltage R_ref = 32k  (2: 31.8)

These specifications tell us the Arduino is capable of measuring voltages to an accuracy
of  ± 2 LSB  - so the maximum error is 2 bits (4 decimal) in 10 bits (1024 decimal)
So the worst case accuracy of the converter is 4 / 1024 or 1 part in 256  i.e. 0.25%.

However the limit of the measurement accuracy depends on the voltage reference used.

The Arduino has its own voltage references - but they are not very precise

The chip - depending on type -  is provided with SOME of the following reference voltages
DEFAULT: the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)
INTERNAL: a built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328 and 2.56 volts on the ATmega8 (not available on the Arduino Mega)
INTERNAL1V1: Vint1 - a built-in 1.1V reference (Arduino Mega only)
INTERNAL2V56: Vint2 -  a built-in 2.56V reference (Arduino Mega only)
EXTERNAL: the voltage applied to the AREF pin (0 to 5V only).
(3)

However the accuracy of these "reference" voltages is very limited. For example
DEFAULT: depends on your computer power supply
(4: 7.3.2)  USB2  Vbus = 4.4V - 5.25V    
(2: 31.8)  Vint 1 = 1.10V  actually 1.00 -- 1.20V
(2: 31.8)  Vint 2 = 2.56V  actually 2.40 -- 2.80V

The accuracy of the reference against which the voltage is measured - using any of the above references -  is at best only 5.25 - 5.0/5.0 * 100 = 5%  - much worse than the 0.25%. the ADC provides.  Clearly if we wish to measure voltages to the accuracy provided by the Arduino the on-chip references are not good enough. The diagram below shows these errors as compared to a 4.096v reference described below.

 

error in voltage references

For precise measurements we need to provide a more accurate voltage reference

The LM4040DIZ-4.1/NOPB (5) is a voltage reference diode, and if we connect this to the "5V" supply through a resistor, so that a current of >100 uA and <15mA flows through the diode, it provides a voltage of 4.096V ± 0.2%.

circuit diagram

The input resistance of the reference terminal = 32k

Then Iref = 4.096V / 32k =  0.128mA

If the minimum diode current is 0.4mA then It = 0.4 + 0.128 = 0.528mA.

The minimum voltage from a USB port is 4.4V so R = 4.40 - 4.096 / 0.528 = 560 ohms.

The maximum current that will flow is 5.25V  - 4.096 / 0.560k = 2.16 mA

 

Using this voltage reference we can make voltage measurements to an accuracy of 0.25%

As an alternative the MCP1541 will provide the same 4.096V voltage reference, while the MCP1525 will give a 2.50V reference, and require a resistor of about 3k3.

N.B. In all cases the Vref terminal of the voltage reference should be decoupled to ground via a capacitor of 1uF across the regulator IC pins.

Now lets look at

 

REFERENCES:

1:  Arduino tutorial http://arduino.cc/en/Tutorial/ReadAnalogVoltage
2:  AtMega datasheet Complete http://www.atmel.com/devices/ATMEGA2560.aspx?tab=documents
3: Arduino reference http://arduino.cc/en/Reference/AnalogReference
4: USB standard http://www.usb.org/developers/docs/
5: Voltage reference datasheet www.ti.com/lit/ds/symlink/lm4040-n.pdf