Analog Input Reads Incorrect Voltages

A project I am working on requires me to read voltages from an array of inputs using 16 voltage divider circuits. There is one circuit per input on the Arduino Mega that I am using.

This issue I am having is the Arduino's readings across all the pins are 0.1-0.3 volts above my multimeter's. This is consistent regardless as to whether the multimeter is attached to any of the voltage divider circuits.

My circuit is very similar to the wiring diagram seen in this post: [Solved] Arduino not reading the expected voltage on a voltage divider - Using Arduino / Sensors - Arduino Forum, however, I have an "unknown" resistor and am only using the yellow wire that is in parallel to both resistors. My known resistors are 10ohm mil-specs with a tolerance of +/-1% and the unknown resistor values are always between 7 and 10 ohms.

Also, in that post, the solution appeared to be reading the analog pins twice, but tossing the first reading so the MUX can be set for that pin. I am mimicking this solution and even putting in a 100ms delay between the first and second reading for each pin seen in this code below:

float getVoltage(int pin) {
  analogRead(pin);  // Dummy reading - to set the MUX to `pin` and allow input to settle.
  delay(100);
  return analogRead(pin) / 1024.0 * 5.0;
}

I also took a look at the analogReference method and messed around with using an EXTERNAL reference and leaving it at the DEFAULT--both of which resulted in no change.

Thanks for your time.

Welcome to the forum.

Can you show your wiring with a photo, or draw on a piece of paper how it is wired, or make a schematic.
Can you tell more about your project ? What are those voltage divider circuits ?

Can you measure the 5V pin ? Wat is the voltage ?
If it is lower than 5V, then the Arduino thinks that the measured voltage at the analog input is higher.
It is better to use an internal voltage reference if you want to measure a voltage.
However, if you want to measure resistors, then it is worse (unless the resistors are powered with an external power).
You see, everything has consequences. The more you can tell about your project, the better we can answer.

Is there enough power for those resistor values ?
Do you use a breadboard ? they have often bad contacts. I think you can not use that current with a breadboard.
To measure such resistors with a lot of current, you need a 4-terminal sensing. I doubt if that is possible with your circuit.

I'd guess your reference voltage is a little low. That would make your readings high, and the higher voltages would have proportionally more error. I think the ADC is supposed to be accurate to 2-counts so that would be a 10mV error with a "perfect" 5V reference.

Your meter will also have some inaccuracy. Your meter also probably has some smoothing/averaging so if there is any electrical noise the Arduino readings could be less stable.

Those are low values... That either means relatively-high current, or low voltage across the unknown resistor.

If you are measuring low voltages you can get better accuracy/precision with the optional 1.1V reference. The internal 1.1V reference is super stable but not super-accurate so you'll have to calibrate it (make a correction factor).

BTW - You can also make a linear calibration with the 5V reference - With straight-line calibration there is an offset (which is added or subtracted from the raw reading) and a slope (a multiplier value). Usually the offset is measured/calculated at zero (or near zero*) and the multiplier is measured/calculated at the maximum, but you can also calibrate the multiplier where you expect most of your readings to be, especially if you never expect to read the maximum.

  • The zero can be trick if there is negative error because the Arduino's ADC can't read negative.

P.S.
Analog measurements are NEVER perfect.

Hi Koepel,

Thank you for your response. Here is the information you've requested:

  1. Wiring Diagram: Imgur
  2. As I stated above, the voltage divider circuits are very similar to the one from the post I link, just replicated 16 times and measuring only the yellow wire that is across both resistors.
  3. The 5V pin from the Arduino is unused in this circuit as all divider circuits are externally powered with a 5V, 10A power supply. However, it is used to run an LED strip, but I wouldn't think that'd be relevant?
  4. I am using PCBs with hard-soldered connections, so I wouldn't think it'd be a loose connection.
  5. Are your 4 terminals referencing a whetstone bridge? I'm not familiar with these circuits if this is the case.

Jules

Your picture:

The Wikipedia page is not very clear: https://en.wikipedia.org/wiki/Four-terminal_sensing.

The more we know, the better we can answer. Is the GND of the Arduino connected to the GND of the 10A power supply, and if it is, how and where ?
How is the Arduino board powered ?

This is your picture with the GND at the bottom:

There is a common ground between the GND pin of the Arduino and the GND of the power supply. They are connected through the PCB I mentioned earlier via a male-male dupont wire. All of the "To Arduino Pin" wires above are through these dupont wires.

However, the entire project is powered through a common power strip, with the Arduino powered through the USB port connected to a common phone charger brick (one of those from Samsung I believe). But again, the only thing the board is driving is an LED strip, so I wouldn't think that would be an issue?

Jules

It might be possible to power the Arduino board with the same 5V 10A power supply, but that is dangerous, since a current could flow into the computer if a USB cable is connected. For now, keep the 5V charger.

The issue is the analog voltage reference and the ground currents.

If you connect the Arduino GND at the begin of the ground rail, then you have different measurement than when the Arduino GND is connected to the end of the ground rail.

You need protection resistors of 1k to 4k7 in the signal line before each analog input.
When the Arduino is powered off, then too much current will flow into a analog pin via the internal ESD protection diodes. The protection diodes will prevent that.

Can you make a new schematic or drawing and make photos. How is the ledstrip connected and how many leds does it have. Do you have a protection resistor of 470Ω to the ledstrip and a capacitor at the begin of the ledstrip ?

Note: this might all seem trivial, but as soon as you mentioned resistors between 7 and 10 ohms, then there are currents that can and will disturb the measurements.

Back powering isn't an issue. The Arduino is never powered off with the 5V, 10A rail powered as, again, they are connected to the same power strip, switched together.

The Arduino GND pin is soldered at the end of the ground rail.

Wouldn't any protection resistor change the input values being read on the Arduino as they would introduce more impedance on the line? What would be your recommendation for accounting for this?

Also, before I make a new schematic, could you elaborate why you think the LED strip would be an issue? The divider circuits are powered externally, so what role would the LED strip play? But there are 16 Adafruit NeoPixels being driven in series.

Jules

That means there should be 1A for the ledstrip. I hope you don't use the 5V pin of the Arduino for that.

The analog measurement is guaranteed to be accurate with a circuit impedance up to 10kΩ. So I was on the safe side with 1k to 4k7, I don't even mind if you use 100k.

Suppose you have 0V and 5V from the power supply with wires to the power rail.
It could be 0.6V and 4.4V at the begin of the rail and 1.1V and 3.9V at the end of the rail.
The Arduino sees the 1.1V as its own GND. That will mess up everything. It might even be possible that a analog input gets a negative voltage.

I wrote: "The issue is the analog voltage reference and the ground currents". Do you have clear view on that ? The Arduino needs something as a reference and ground currents are the worst.

Thanks for your patience with me on this, I'm not the most well-versed in electronics (hopefully that is obvious lol).

Anyways, I am driving the strip through the 5V pin on the Mega. I haven't had any issues with that in terms of dimming or flickering--basically any indication of overdraw from the 5V pin.

I checked the ground rail using that multimeter while the circuit was under load and saw no voltage on it, which means no current. I also checked the inputs on each analog pin and saw no negative voltage, so I wouldn't think it'd be that.

While I work with Koepel on his suggestions, I can work on this in parallel. Thanks for the suggestion, DVDdoug. I'll let you know if this changes anything.

Jules

Another observation that may help; I ran to a friends house and grabbed his fluke. I am noticing that the voltage its reporting is jumping around wildly between 2.0-2.5 volts, but seems to level out at around 2.3 volts.

The Arduino is reporting around 2.5. Do you think it would be more beneficial to take an average of like 3-5 readings instead of just using the one?

Jules

Can you power the ledstrip with the 5V 10A as well ?
The 5V pin can be used for up to 200 mA or so.
When powered via the USB connector, it can deliver up to 500mA, but that will lower the 5V. At the moment, you use that as reference to measure the voltages.

Taking the average of a number of samples is often done.
Even with 5 samples, there is an improvement. Sometimes I used the average of up to 10000 samples. About 20 samples is a good start.

If every voltage below 2.56V ? then you can use the internal reference of 2.56V.
Or are you willing to add a voltage divider for each analog input ? They protect the input at the same time. That takes two resistor per analog input instead of one protection resistor per input.

I can hook them to the 5V 10A rail; however, I still don't think it is an issue. The LEDs are only drawing 60 mA according to the fluke. And when they are disconnected entirely, I don't see any change in the readings from the inputs.

As for setting the reference to 2.56V, I cannot do that. The unknown resistors may be faulty and therefore return 5V to the analog inputs. I tried the 1v1 suggestion above by DVDdoug; however, that just caused Arduino to report 1023 at all times.

Jules

Why would you have leds if they are not used :thinking: I assume that you want to turn them on some day ?

If you use a voltage divider for the analog input (R1 = 10k, R2 = 10k) and a analog reference of 2.56V, then you don't need the protection resistor anymore. The voltage divider is the protection.

I have the impression that I'm starting to repeat myself.

I think we are talking past each other right now due to miscommunication, so let me try to clarify what I am trying to explain.

The LED strip is connected to the Arduino when the unknown resistors are tested. However, for the purpose of testing their effect on this issue, I disconnected them. I ran the tests again and saw no change. I then reconnected them and measured the current draw they have which is 60 mA. So, to me, this appears to rule out the LED strip as a culprit.

If I read back into our earlier communications, I think you're still worried about ground currents and the analog reference and suggested the voltage protection (now divider) circuit to combat this. I also ran tests to identify if there were any currents on the ground rail while the circuits were idle or active--and I didn't see anything. The multimeter and fluke both reported 0.0V, which would imply no current. Like the LED strip, this to me would appear to rule out ground currents as the culprit. I have yet to rehash analogReference because I felt like we were talking past each other.

Also, maybe I am missing some key information about how analogReference works, but how would setting the reference to 2.56V help if the circuit can expect to see above that voltage? Wouldn't that mean that any voltage above 2.56V be snapped to 1023 and virtually unusable?

Hopefully this helps clear up where I am at?

Thanks again,
Jules

Voltage divider: https://en.wikipedia.org/wiki/Voltage_divider.
R1 to the voltage to be measures and A0.
R2 to A0 and GND.
Both 10k, then you can measure up to 5V.

If you don't want to use the ledstrip then put it away.
If you want to use it, then don't power it with the 5V pin. Or maybe if only few are turned on at a time.

If you turn everything on (all your resistors), and measure the difference between the 0V of the power supply and the GND at the end of the rail, then I would like how many (milli)Volts there are.
It is impossible that it is 0.0V. If it is 0.00001, then I would like to know that.

The 5V as reference is not steady. The charger can vary, and there is a usb cable. If your 5V pin is 5.000V all the time, then you have a good reference.
It is therefor better to use one of the internal reference voltages.

When the 5V is lower, for example 4.8V, then your calculation is wrong, because that assumes 5V. With a lower reference voltage, the Arduino thinks that the measured voltage is higher. You measure something that is higher, so obviously your reference is too low.
Have you measured the 5V pin ?
Suppose you measure 4.934 Volt and put that in the calculation in your sketch. That will even make it worse. Then the sketch will only work for 4.934 Volt, which it never is.

So lets look at what is happening:

The A/D converter divides the voltage reference into 1024 "steps" then compares the unknown to find the closest "step".

Looking at the possible errors:

  1. If you 5V is not 5.0V then your steps will be not what is expected.

  2. By spec the A/D conversion may be off a step or two from the "best" step

  3. Your Multimeter may not be exactly correct. Physically where are you making your multimeter reading? Are you directly across the 10 Ohm?

  4. You have 16 of such circuits. The mega can only be grounded in one location. If there are voltage drops in you "GND" wire they will show as errors.

That's only useful if resistor divider impedance is larger than about 10k ohms.

Yes, above the reference the reference voltage the ADC reads 1023.