Can Arduino measure its own Vin?

I have noticed that when I power my Arduino from the computer via the USB port, then Vin is 5.02 volts, according to my multimeter. But when I power the Arduino from a wall-wart through the onboard regulator, then Vin is only 4.96 volts. I expect there would be greater variation if I used batteries. That's not much difference, but does introduce a small inaccuracy if I just assume that Vin is always 5.0, especially in using floating point calculations. So is there any way for the Arduino to measure its own Vin? If so, how would I do that? Thanks in advance for any suggestions.

The analogue measuring system uses a reference voltage that is the supply voltage. Therefore when you connect the 5V line to the analogue input you will always get that top number of 1023.
So to stop this from happening you have to use another source for the reference voltage Vref.
You can switch to an internal 1.1V voltage that is independent of the supply voltage but then the system will only measure up to 1.1V. So the 5V line has to be cut down with a potential divider to get it in range, A 5 to 1 ratio would be good.

Alternatively you could supply an externally stableness reference voltage to the Vref pin, switch to that in software and have another potential divider, but not so big this time.
What ever you do you can't put a voltage bigger than the supply voltage into an analogue input or you will damage the chip.

There is a little trick using that internal 1.1v reference Grumpy Mike talks about. I'm not sure exactly how they measure the Vcc (or probably AVcc) without any external voltage divider. http://code.google.com/p/tinkerit/wiki/SecretVoltmeter
This only works for the atmega 168 or 328.

There's also a similar method of measuring the temperature: Google Code Archive - Long-term storage for Google Code Project Hosting.
This only works for the atmega 328.

Both links found here: Google Code Archive - Long-term storage for Google Code Project Hosting.

Not only the 168 and 328 have the internal reference voltage feature (VRef). I have used the technique with an ATTiny26L, it's internal VRef is ~2.56V. The 1.1V of the 168/328 is also not EXACTLY 1.1V but about that. I've measured on couple of different ATTiny26s VRef of 2.66, 2.58 etc. Calibrating the value this can be done by runing once a sketch that saves in EEPROM the measured value and by suppling an exact voltage to ARef of say 5.0V.

So is there any way for the Arduino to measure its own Vin?

Keep in mind that the on board +5vdc powering the processor is not the same voltage as the Vin pin. Be sure you are attempting to measure what you intend to measure. :wink:

You can measure the Vin pin with a properly sized external voltage divider only. One might want to measure the Vin pin because it's from a battery, to determine it's charge state.

Lefty

When doing the divider you want to keep the source impedance less than 10K.
For a two resistor divider from Vin to ground the impedance is the parallel
combination of the two resistors.

(* jcl *)


www: http://www.wiblocks.com
twitter: http://twitter.com/wiblocks
blog: http://luciani.org

Thanks to everybody who responded, although now I'm confused again. My goal is to use Vin to supply power for an external circuit but I want to know as precisely as I can what the Vin voltage is. I tried the “Secret Voltmeter” mentioned by Raron at http://code.google.com/p/tinkerit/wiki/SecretVoltmeter, and it worked like a charm, giving a voltage (under USB power) that alternated between 5.073 and 5.051 every few seconds. That's probably good enough although it seemed odd that it would change between those two values, but maybe that was my computer doing that. However, both of these values are different from what my multimeter reads for Vin, which remains 5.02.
But then Lefty said that the “Secret Voltmeter” internal voltage is NOT the same as Vin. That would explain the difference above, but still leaves me a little uncertain about the best way to measure Vin.
If a voltage divider is the only way to measure Vin, then I assume that the reason that voltage divider is necessary is to reduce the voltage being measured to less than 5 volts so that the Analog pins can detect it properly. But then I would have to know the positive rail voltage to know what voltage value was being divided (as well as the resistor values, of course). But that seems to be a circular problem, since I would then have to measure the positive rail voltage somehow. Am I missing something here? I confess I did not understand JLuciani's comment about impedance.

Thanks again for any further comments.

The divider is to reduce the voltage to be measured below the reference voltage of the
analog to digital converter (ADC). The reference voltage can be the VCC of the
microntroller (which can vary) or as Grumpy_Mike suggested the 1.1V internal
reference which will not vary.

If you use values of resistors that are too large you will introduce measurement errors.
If you keep at least one resistor in the divider below 10K you should not have a problem. Using a 40K and 10K will divide by 5 making your 5V input 1V.
This keeps your maximum voltage below the 1.1V reference.
Your impedance will be 8K (40K || 10K) which is below the 10K specification.

(* jcl *)

that alternated between 5.073 and 5.051 every few seconds...although it seemed odd that it would change between those two values

1126400 is the dividend from the source code. 222 and 223 are A/D converter readings...

1126400 / 222 = 5073
1126400 / 223 = 5051

It's a by-product of the converter's resolution.

You are grappling with too different issues.

  1. Vin pin is the power supplied from the Arduino external power connector and is in the range of 7.5 to 12vdc depending on what you are using. This Vin voltage has no effect on the analog reference accuracy of the analog input pins, however you may or may not have a desire to measure the Vin voltage, that is not clear to me.

  2. The Arduino processor uses a voltage source to set the measurement referenace for all analog reads from the analog input pins. This reference by default and can come from either the USB port or the on-board +5vdc regulator. You can with software commands change the reference to either an internal band-gap 1.1vdc reference or use a external voltage standard applied to the Aref pin. This external reference can be any voltage from around 1.1 to 5vdc.

So deal with issue number two first if you are concerned about having the best Analog calibration accuracy possible. And then deal with issue number one to determine the sizing of the voltage divider needed to be able to measure the Vin value, if that is what you are after.

Lefty

ISTM that the OP doesn't need the divider, that he can use the 'secret voltmeter', and he has to do the calibration mentioned by mircho.

retrolefty is explaining that the reference for the ADC by default comes from the power supplied to the AVR chip, whatever that is. There is an option to use an external voltage on the AREF pin, which is what the voltage divider does. Assuming that you don't need to have a lower reference voltage than 5V to get the accuracy and range needed for any other use of the ADC, just using VCC as the ADC reference works.

The "secret voltmeter" is using on on chip 'band gap' source, which as noted, isn't that accurate, but can be calibrated. Depending on how accurate you need the measurement, that calibration may need to take into account the temperature and (uh oh), the VCC voltage. But, it's actually all calibratable if you need to do that. You are measuring what is sort of a known value (1.1V) with an unknown voltage reference, and back calculating what the voltage reference (which is VCC) is.

The only thing the divider can do is lower the voltage of the reference. If you get it closer to the 1.1v of the band gap, you get more accuracy in the reading. I don't think you need that.

I'm doing the same thing, although I need to use the AREF because I really do need to get more accuracy at lower voltages from the ADC. My project involves measuring the resistance of a cable, to around 1/4 of an ohm. With a 100 ohm pullup resistor, the cable and the resistor make a voltage divider, and I'm measuring the voltage to calculate the resistance. I don't need more than 100 ohms max, so I'm using the divider to get a 2:1 reduction in the AREF, which gives me one bit more resolution in the measurement. With 2.5V full scale, 100 ohms in 10 bits is tenths of an ohm, but noise and other problems make that not realistic. Seems to work okay, but calculating the actual resistance only is possible if I know the VCC. The secret voltmeter is the way to find that out.

You might consider that powering the arduino from the dc jack uses the on board power regulator, which will give you tighter tolerance on the VCC than powering from USB will (usually). My project has to be battery powered, and I'm not going to be able to regulate the output of the battery, but you should be able to use the DC jack.

If a voltage divider is the only way to measure Vin, then I assume that the reason that voltage divider is necessary is to reduce the voltage being measured to less than 5 volts so that the Analog pins can detect it properly.

Have you forgot I said:-

What ever you do you can't put a voltage bigger than the supply voltage into an analogue input or you will damage the chip.

that alternated between 5.073 and 5.051 every few seconds.

Any analogue to digital converter can only produce a result that is + or - 1 least significant bit. It is the nature of quantisation and noise.

But then I would have to know the positive rail voltage to know what voltage value was being divided (as well as the resistor values, of course).

Yes, so what you do is guess at the maximum it will be and arrange the resistors so that the analogue input does not exceed 5V at this maximum. Measurements below this maximum are still possible and will yield the results you want.

This is a good place to put in protection in case you do exceed this value.
http://www.thebox.myzen.co.uk/Tutorial/Protection.html