I did not understand somehing in the volt meter Would appreciate help

I'm learning how a voltmeter works and I went through this page:

but I can not understand how it creates a value between 0-1023 for the Arduino ...
I realized that because the Arduino can not get 25 volts and only 0-5 volts how does the voltmeter actually pass a value between 1023?

The main reason is that the values returned are not voltages but fractions of a given reference voltage.

The reference voltage in this example is 5V (usual for an Arduino UNO, but may be also 3.3 V for other controllers!).

The voltage supplied to the analog input pin (one of the pins A0 to A5) is compared by the controller to those 5V.

What you get is the fraction of 5V that has been found:

  • 1023 means that the controller has found 1023/1024 x 5V = about 5 V at the pin
  • 512 means that the controller has found 512/1024 x 5 V at the pin (which is 1/2 x 5 V = 2.5 V)
  • 256 means 256/1024 x 5 V = 1/4 x 5 V = 1.25 V
  • etc.

If you look at the code on the page you linked you see this:

  value = analogRead(voltageSensor);
  vOUT = (value * 5.0) / 1024.0;
  vIN = vOUT / (R2/(R1+R2));

Now you must also know (or learn) something about Ohm's Law:

https://en.wikipedia.org/wiki/Ohm%27s_law

Actually it is nicely explained in the page the linked:

image

Assume you connect GND and Vcc to this circuit as marked and Vcc may be 10 V.

If you measure between

  • GND and Vcc your voltmeter will show 10 V
  • GND and S you will get 10 V x 7.5k/(7.5k+30k) = 10 V x 7.5k/37.5k = 10 V x 0.2 = 2 V
  • S and Vcc you will get 10 V x 30k/(7.5k+30k) = 10 V x 30k/37.5k = 10 V x 0.8 = 8 V

As you can see the voltage between GND<->S and S<->Vcc add to 10 V again, but they are divided into two parts.

Whatever voltage you use for Vcc it will always be divided into 0.8 x Vcc between S<->Vcc and 0.2 x Vcc between GND<->S. From the 0.2 x Vcc you see that Vcc is always 5 times the voltage at S.

If the maximum you can measure between GND and S is 5V you can easily calculate the maximum you may connect to Vcc, don't you? And vice versa from the voltage you measure at point S you can calculate the voltage at point Vcc.

Understandable or still confused? :wink:

P.S.: And be aware that

  • connecting higher voltages to Vcc may (or will!) destroy your Arduino
  • this method here only applies for low direct current voltages! Never play around with mains or power supplies if you are not sure about what you are doing!

Even voltages that are not hazardous to a human being may be dangerous, e.g. by blowing up capacitors or setting resistors on fire ...

2 Likes

A little more (or maybe a little more of the same things)...

The analog-to-digital converter is 10-bits so in binary you get this:
11 1111 1111 which is 1023 in decimal. (1) That's as high as you can count with 10-bits. (The Windows calculator in "programmer mode" will convert between decimal, hexadecimal, octal, and binary.)

The 0-1023 number is simply proportional to the reference voltage. The default reference is Vcc, so about 5V.(2) 2.5V would read 511 or if the reference is 1V then 1V would read 1023 and 1/2V would read 511 and 1/10th of a volt would read 102, etc. (It's an integer so nothing to the right of the decimal place.)

The Arduino Uno has an optional 1.1V reference or you can supply your own external reference if you wanted to use 1V or some other reference. (The reference can't be higher Vcc.)

In order to understand how a voltage divider works you need to know;
Ohm's Law (the relationship between voltage, resistance and current).
The same current flows through all series components.
Resistance in series sums-up.

So, you have 5V applied across the total resistance of 37.5K Ohms. Now you can calculate the current.

Knowing the current you can calculate the voltage across each resistor. With a regular multimeter you can measure the voltage across each resistor separately but the Arduino can only measure relative to ground so you can only measure the voltage across R2.

BTW - The voltages will sum to Vcc. (That's one of Kirchhoff's Laws.)

(1) The spaces are added for human readability, but you can't have spaces if you use binary in your code. Also, each group of 4-bits converts exactly to 1 hexadecimal number, making it easy to convert between binary and hex in your head. Converting between decimal and binary isn't so easy and that's why programmers often use hex instead of decimal when dealing with binary numbers or "bit patterns". Of course, inside the computer everything is binary.

(2) Since the reference is Vcc, the reference will very if you have a battery-operated Arduino without a voltage regulator.... That means you can get inaccurate readings and you have to use some "tricks" if you want to measure it's own batteries... If you just measure the battery voltage with the battery as the reference it will always read 1023. :wink:

Of course any 5V power supply will very, but regulated power supplies are usually "close".

1 Like

P.S.
The Arduino can only measure relative to its ground. A regular multimeter doesn't have an actual ground lead, it just has "minus" (or black) lead and a "plus" (or red) lead so a regular multimeter will read relative to wherever the "minus" lead is connected.

The Arduino can be damaged by voltages greater than Vcc or by negative voltages (relative to its ground), which means it can't directly measure AC (which swings positive & negative).

Also, things can get blown if you "short" the ground to the wrong place.

Regular multimeters are protected against over-voltage (typically up to 600V) and if you connect a negative voltage (or connect it backwards) it will simply read negative. It also won't be damaged if you connect AC while it's set to measure DC.

The one bad thing that can happen with a multimeter is if you connect it wrong when measuring current. In current-mode the meter is (essentially) a short circuit. That's why most multimeters have a separate connection for measuring current... So you don't fry things by accidently switching to current mode.

Thanks so much for the explanation!

If I understood correctly...
If I connect 10V to VCC, in S it will actually be 2V and the Arduino will see it as about ~ 410 out of 1024?

If I want to measure a 15V battery but high current (lipo battery) it may burn the Arduino?

Thank you very much.:heart_eyes:

the returned values are not voltages, but fractions of the specified voltage reference.

No, it won't burn it as long as the voltage between GND<->S is 5V or below.

Ohm's Law is R = U/I which means resistance = voltage / current.
With a little math you can write this also as I = U/R which means current = voltage/resistance

If you would measure the current that goes throught the two resistors you would get

current = voltage/resistance = 15 V / (30kOhm +7.5 kOhm) = 0.4 milliamps

which is a quite low current.

During the flow of current through resistors the electrical energy is converted to "heat", so if you have a small resistance the current might become higher (finally limited by the inner resistance of the source, but that is a separate issue ...).

If you multiply the current through a resistor with the voltage over the resistor you get a measure for the heat p = U x I. p is measured in Watt = V x A. The resistors used must be able to "withstand" (actually to get rid of) the heat without getting to hot. That is why resistor data ususally include not only a value in Ohm but also the power they can withstand in Watt or milliWatt.

What I wrote here is true?

What you wrote is correct:

  • 10 V at Vcc will provide 2 V at S
  • 5 V at S are equivalent to about 1023 and therefore the value of analogRead() will result in (1023 / 5) x 2 = about 409 or 410. So the data should be in that range.

Very good!

Thanks so much to everyone for the help

1 Like


I do not know but suddenly the sensor went crazy and shows inaccurate values ​​...
What can it be? (I connected 16 volts)

Why does the perceived value change?

It is quite likely that your input is floating. Did you

a) connect 5V DC from the Arduino to your input and get readings of (about) 5V stable?

b) connect to a different input pin?

The data you posted (618, 683) are measured with the voltage source applied or with open input?

Can you check the 16V with an oszilloscope? Usually multimeters will give you an averaged voltage...

A yes
B no
I'm not sure about your question but you have some background ...
image

The voltmeter is connected to the battery and transmits the informant to the Arduino (it is also connected to 5V of the Arduino)
And the adroino gets its power as in the picture

It looks as if your drawing is more a principal sketch than the original connection, isn't it?

A voltmeter has a high internal resistance and would be connected in parallel to the component between plus and minus.

If you use an ampere meter (to measure the current) it will have a low internal resistance and is placed in series between two components.

BTW, the battery is supplying power to several components. Depending on type and age/usage of the battery its internal resistance might be something between 0,003 to several Ohms. The more current you draw the more the voltage that you can measure outside the battery will drop.

See here https://en.m.wikipedia.org/wiki/Internal_resistance

P.S.: Sorry for some typos, I am writing this on a smartphone display and sometimes in addition auto correction successfully creates nonsens :wink:

First thing to do is work out your V divider for the input volts + margin for safety.

if R2 is 7500 and 16 V is the input volts and the desired output volts is 5 volts then R1 needs to be 16500.

If you are expecting to measure 16V use 20V for the input V's.

Better for impedance matching use 10K for R2 and R1 will need to be a 30K to work with 20V's.

Resistors only determine the ratio ... in my case, it's 0.2
7.5k / (7.5k + 30k)=0.2

This means that if I connect 16 volts in S it should be 3.2
X / 1024 x 5 = 3.2 V
X = 655

So the adc_value is very close ...
But why does it change while the ANALOG_IN_PIN is fixed ...

adc_value = analogRead (ANALOG_IN_PIN);

What @Idahowalker mentioned is that you can improve the resolution if you use a resistor combination that is close to the maximum voltage you want to measure.

However it does not explain the changes of the data when you have a fixed voltage (unless you would measure in a non linear area).

If all worked well in the past, you might identify changes in your circuitry. Or use a different input pin for testing. Just record the raw data.

What is the current drawn from the battery pack, could you measure this also?