Reading an analogue voltage accurately

I have a sensor that is connected to input 0 on my board and measured with my meter it’s delivering 4.08v to the pin.

I wrote a simple sketch to start experimenting with reading the voltage accurately:

int aReading;
float Vin1;
float Vin2;

void setup()

void loop()
  aReading = analogRead(0);

  //Using a "default" 5v value
  Vin1 = (5.00/1024) * aReading;
  //Using the measured supply voltage
  Vin2 = (5.06/1024) * aReading;

  Serial.print("Reading = ");
  Serial.print("\t5.00 = ");
  Serial.print("\t5.06 = ");


From everything I’ve read (reference voltage/resolution)*reading should give me the voltage input.

If I use 5v I’m “missing” 0.05v off the reading (which is a big difference with what I’m doing), but if I measure the 5v supply on the board it’s 5.06v. If I use this I get an accurate voltage reading.

So my question is, do I really have to measure the supply voltage and use that or have I missed something along the way?

If I do have to measure the supply, would dipping the supply (perhaps turning on a lot of LEDs etc) affect the calcs?

Thanks in advance, Easty.

The Arduino’s analog voltage inputs use the 5V power supply as a avoltage reference. If that’s not accurate enough, you’ll need to use an external voltage reference, from a more accurate source. You’ll need to enable the external Aref pin, and also you’ll need careful circuit design and layout to maintain accuracy.

I doubt your meter is anywhere near 1% accurate. And does it really matter if your reading is off by a few percent anyway?

But if you do want the result as accurate as possible, in addition to the above mentioned reference voltage, note that the max reading will be 1023 (not 1024) when the voltage is 5 volts (or whatever the exact value is). Also, Serial.print of floats only displays two decimal places so you may want to make the calculation:
Vin1 = (5000.0/1023) * aReading; // vin is in millivolts

I noticed a discrepancy on an analog input project recently. It turns out my USB voltage was a bit low (4.90 range, IIRC, well within tolerances) and accounted for the error in my measurement.


Thanks guys, great replies (as always) and a lot to think about!

As it’s Friday night I’m going to put it down for now and take a look over it again at the weekend.