Go Down

Topic: Skewed voltage divider readings (Read 869 times) previous topic - next topic

danielcdev

Hi all,

I'm attempting to build a voltmeter with an Arduino and getting horribly skewed readings through voltage divider.  My layout is as follows:

Analog reference set to 1.1v
R1 = 1M ohms (1% tolerance)
R2 = 8.2k ohms (1% tolerance)

Junction of voltage divider going to A2.  I feed 5.0v (DMM reads 4.98v) from board to R1, and get a reading of 2.11322 volts in Arduino (calculated with voltage divider.)

Using circuit simulators and my DMM, I can confirm the correct reading of ~0.040 volts at the junction I'm pulling into the Arduino.  If I manually change vout in the code to 0.040 volts my voltage divider calculation works perfectly fine.

To test the ADC accuracy of my board, I've removed all resistors, changed AREF to 5.0 and read directly from a AA battery.  DMM gives me 1.25 volts and Arduino reads 1.2453.  Pretty dead on.

Any help would be greatly appreciated.  I'm a software engineer by trade, and trying to expand my knowledge into hardware... but it's really kicking my butt.

I've included a picture of my voltage divider, and here is my code

Code: [Select]

#define ANALOG_INPUT A2
#define ANALOG_RESOLUTION 1024.0
#define VREF 1.1
#define R1 1000000.0
#define R2 8200.0

const float voltageDividerRatio = (R2 / (R1 + R2));

void setup() {
  Serial.begin(9600);
 
  if (VREF == 1.1)
    analogReference(INTERNAL);

  pinMode(ANALOG_INPUT, INPUT);
}

void loop() {
  float vout = (analogRead(ANALOG_INPUT) * VREF) / ANALOG_RESOLUTION;
  float vin = vout / voltageDividerRatio;
 
  Serial.print(vout, 5);
  Serial.print(" ");
  Serial.print(vin, 5);
 
  Serial.println();

  delay (1000);
}

6v6gt

#1
Nov 12, 2019, 10:47 pm Last Edit: Nov 12, 2019, 11:02 pm by 6v6gt
The circuit connected to an (AVR at least) analogue pin should have a maximum of 10k impedance.

From the ATmega328p data sheet:
"The ADC is optimized for analog signals with an output impedance of approximately 10 k or less"

Edit:
Maybe try to change the voltage divider to 10k / 82 ohms. If you don't like the power wastage, switch the top of the divider with a digital pin and only on when you want to make a measurement.

DVDdoug

#2
Nov 12, 2019, 11:11 pm Last Edit: Nov 12, 2019, 11:14 pm by DVDdoug
Try "printing out" the raw ADC reading.  It should be about 38 (at 40mV with a 1.1V reference).

...If the meter reads 40mV the source impedance isn't the issue.    The meter and Arduino are both reading the same physical voltage, but the meter is probably filtered/smoothed to minimize noise and the meter is probably more accurate.

If the raw ADC value is wrong, what Arduino are you using?  (The internal references and reference commands are different on some Arduinos.)   You can also check the AREF pin with your multimeter.

---------------------------------------------
Once you get this sorted out, note that the 1.1V reference is stable but it's not necessarily super-accurate.  So you may need to do some calibration (in software) depending on how much accuracy you need.

And, if you are really  going to read 5V you're loosing a lot of resolution by reducing the voltage that much with a voltage divider.  I assume you are planning on reading higher voltages?


Idahowalker

#3
Nov 12, 2019, 11:21 pm Last Edit: Nov 12, 2019, 11:22 pm by Idahowalker
Here is a good place to do the divider thing http://www.ohmslawcalculator.com/voltage-divider-calculator.

When I used an Uno, the item that made the largest difference in settling down the A:D readings was to put a cap into the aRef and gnd connectors on the board and soldering the divider components vs using a breadboard.
Receiving partial information does not help me help you and wastes my time.

danielcdev

Hey all,

Thanks for taking the time to respond!

My apologies for not stating that I intend to use this as a multi-purpose voltmeter.  I'm just using the 5v as a known good, stable reference to calibrate my readings.  Having decent range would be desirable.

DVDdoug,
I printed out the raw ADC values.  Varying slightly at 30-31.  As I mentioned before, I took the resistors out of the circuit and my arduino read a AA battery accurately at 1.25 volts.  The inaccuracies start with the addition of resistors.

I've measured the 5v and AREF on the Arduino, they're ~4.80 and 1.1 +/- .02 volts.  Started out using an Uno, which it's ADC values did -not- reflect the accurate voltage of a AA battery, but the Leonardo I'm using did.

6v6gt,
I was under the assumption that the "10k or less" was measured from R2 to analog input?  I suppose this is where my elementary understanding of basic circuits is failing me.  I'll give that a shot, but is there any other way to get more range out of this?  I was hoping to measure up to at least 50vdc if that's feasible.


Idahowalker,
I attempted a 44nF capacitor from R2 to ground.  Would that be enough?  It didn't really change the reading for me at all, except it slightly delayed returning to 0.00 volts when I removed the 5v lead.

I'll try soldering everything together later on tonight.

Idahowalker

Receiving partial information does not help me help you and wastes my time.

danielcdev


PerryBebbington


Quote
I was under the assumption that the "10k or less" was measured from R2 to analogue input?
Correct...almost.

Assuming that the output impedance of the supply providing the 5V to R1 is low enough to be ignored then from an impedance point of view the +ve and -ve of the 5V supply have a very low resistance between them, equivalent to the supply internal resistance. That means that you can consider the 5V connection to R1 and the 0V connection to R2 to be connected together through the power supply. That means you can consider R1 and R2 to be in parallel for the purposes of calculating the output impedance from these 2 resistors as seen by the A2D input at the junction of R1 and R2. The A2D therefore sees:
1/((1/1000000) + (1/8200)) = 8.133k Ohms.



6v6gt

Ok. But the sampling capacitor in the  adc has to be charged in a reasonable amount of time. The rate of charge will be affected by the high value resistor. In a static situation like this it is not so important, but for high sampling rates it begins to have an impact.

MarkT

#9
Nov 13, 2019, 03:44 pm Last Edit: Nov 13, 2019, 03:47 pm by MarkT
The circuit connected to an (AVR at least) analogue pin should have a maximum of 10k impedance.

From the ATmega328p data sheet:
"The ADC is optimized for analog signals with an output impedance of approximately 10 k or less"

Edit:
Maybe try to change the voltage divider to 10k / 82 ohms. If you don't like the power wastage, switch the top of the divider with a digital pin and only on when you want to make a measurement.
1M/8k2 divider has a source impedance of less than 10k, since its load is seeing 1M || 8k2.

Small voltage offsets will happen if you fail to use star-grounding for your divider.
[ I DO NOT respond to personal messages, I WILL delete them unread, use the forum please ]

PerryBebbington

Ok. But the sampling capacitor in the  adc has to be charged in a reasonable amount of time. The rate of charge will be affected by the high value resistor. In a static situation like this it is not so important, but for high sampling rates it begins to have an impact.
I suspect you are considering the situation of the 1M Ohm resistor alone and trying to apply it to the situation we are discussing, they are not the same.

If there were just the 1M Ohm resistor then the sampling capacitor would be charging through 1M Ohm to 5V.

This situation is the sampling capacitor charging to 0.04V from a source impedance of 8.133k Ohms. Different source impedance, different voltage.

JCA34F

#11
Nov 13, 2019, 06:44 pm Last Edit: Nov 13, 2019, 07:00 pm by JCA34F
What is the maximum voltage you want to read? With the divider you have (attenuation factor of 132) it would take 145V to reach full scale (ADC value of 1023). 5 volts would be way down in the mud, ADC value of 35, 142 mV per count.

gilshultz

I highly recommend using the voltage divider calculator at: http://www.ohmslawcalculator.com/voltage-divider-calculator.
Another thing check the accuracy you are trying to get, you show 6 digits in your calculation. To validate this you need a 7 digit meter (an order of magnitude better) to be sure of what you are getting.  How accurate is your DMM and how many digits.  Has it been calabrated recently? How accurate is your voltage source?  What is the tolerance of your parts, 1% will not support 6 digits straight up.
The following link gave me this table: https://www.avrfreaks.net/forum/what-relation-between-adc-resolution-and-dvm-digits   Just because the math can calculate 5 digets it in no way indicates your measurement is accurate to that. Don't get too hung-up on bit count, all they do is give you precision. They don't give you accuracy. Dig deeper into the datasheet.

Decimal digits   Bits required to represent:
5                       17
6                       20
7                       24
8                       27
9                       30
Another note, do not use the arduino 5V regulator to drive anything else, simply turning on a LED can cause a measurable difference in your reference voltage.


Good Luck & Have Fun!
Gil
This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

JCA34F

#13
Nov 13, 2019, 10:22 pm Last Edit: Nov 13, 2019, 10:22 pm by JCA34F
OOPS!  Math blunder:  >:(  Should have been:
With the divider you have (attenuation factor of 123) it would take 135V to reach full scale (ADC value of 1023).
5 volts would be way down in the mud, ADC value of 38, 132 mV per count.

6v6gt

OK. It looks like I still have to do some homework on impedance networks.

The OP's problem is, however, the assumption about the internal reference voltage on an 32U4 chip (Leonardo).
Unlike the 328P (Uno etc.) , this voltage is 2.56 volts, not 1.1 volts.

Go Up