considerable discrepancy of ADC values in Leonardo at low V

Hello, i'm having an issue with ADC readings that are way off in the milivolt range, i'll post the measured input of the ADC with a DMM in mV range and the resulting code and discrepancies:

  • 46.6mV-6(29.29mV)
  • 95.35mV-16(16 equals to 78.125mV)
  • 144.4mV-26(126.9mV)
  • 241.6mV-45(219.72mV)
  • 484.2mV-95(463.86mV)
  • 970.4mV-194(947.26mV)

As a baseline i measured the 5V rail, results in 1023, 0V results in 0

The results are horrid!, absolutely off!, we're talking about a 50% error below 50mV, ~30% error at 100mV~, 10% error at 240mV~ and that lowers to 3% above ~480mV.

¿Is this correct?.

i'm running a sketch that needs to read these super low values but there's no way i can convert them back to voltage when they're so wrong.

quick edit1: i did a simple circuit with a pot connected to the ADC input to validate my results: Vin is 133.3mV, code is 25=122mV

Also tried other analog inputs, same result

If you want to read low analogue voltages, then switch to the build-in 1.1volt Aref in setup().

analogReference(INTERNAL);

That will result in 0-1023 with an input voltage of 0-1.1volt. Note: Must calibrate, because that stable reference could be 1-1.2volt.

"947.26mV" is about 100,000 values. Wishful thinking with a 10-bit A/D (1000 values).

Don't compare voltage measurements (must be compared to a stable reference) with potentiometer measurements (ratiometric sensor, compared to it's own supply).

An ADS1115 breakout board can measure voltages with 15-bit precision. Leo..

Wawa,
the issue is that 1.1V is not useful to me because the input needs to be the full 5V range and maintain the 10 bit accuracy throughout(i could be measuring 100mV and next read 4.5V).
Also, on the 32U4 the internal reference is 2.56V(1.1V is on the 328P), which is still useless to me.

The ADC is 10bit, which means ~5mV per code(5/1024) (barring accuracy of the ADC).
According to the 32U4 datasheet, the absolute accuracy is 2 LSB, which should result in no more than ONE code of difference, gain error and NL errors are about 2.5LSB(but with a 4Vref) that means 0.244% error, i’m two orders of magnitude off that number.

i can compare the potentiometer output because i used it to simply drive the ADC input to the voltage my circuit provided, as sort of a sanity test (due to the output impedance of my circuit), but since the results are the same i can rule it out. It would be same if i used a programmable power supply to output the 133mV to test

What do you mean by ““947.26mV” is about 100,000 values. Wishful thinking with a 10-bit A/D (1000 values).”, 947,26mV is almost 1/5th the input range of the ADC(with 5Vref as default), it’s not “wishful thinking”.

I don’t have a ADS1115 or another ADC to use for this project

Errors in the low range could mean ground currents (shared ground on a breadboard?). Since you didn't post a diagram, or a picture of the setup, or code, we have to guess most of it.

1/5 of a 10-bit A/D range is about 200 A/D values. Do you think you could upscale that to 94726 values without creating jumps/gaps. Loose the two decimal places, and you still have jumping problems in the readout.

Not wise to compare input voltage to the potentially unstable MCU supply (what you do). Better to use a voltage divider to dial down to 2.56volt, and use the more stable internal reference to compare to. Leo..

i made sure to use star grounding for the setup(and the measures i do with the DMM are in the exact same position as the ADC input), code is simply a staight analogread once per second, nothing more that's why i didn't post any code. I don't have a schematic at hand, it's essentially a current shunt amplifier (with a 66 gain).

yes, it's 200 A/D values, that's my point, 947mV should not be measuring 30mV off, that's completely out of spec. I still don't understand why you're upscaling the 947,26mV to 94726, i stated the exact value as my DMM has that accuracy, even if it's rounded off to 0.947V due to A/D accuracy.

I mean, taking for example the simple "analogreadserial" example that uses a potentiometer, i'm already off by 30mV on that simple sketch.

"Not wise to compare input voltage to the potentially unstable MCU supply (what you do)." --> i don't quite follow, shouldn't the MCU input be regulated?, and AVCC is taken off that.

If i change the gain of my shunt amp to 2.56V full scale, i kill off any low-end precision as the extremely low output voltages i already have would get divided essentially by 2. (for example, for 100mA i get 46.6mV as is, if i change the gain i'd get less than 33mV i'm entering into problems at those values, and 100mA is not the lower end for what i'm measuring i need to go 10 times lower which would not even register as an LSB at 2.56V)

eliminateur:
it’s essentially a current shunt amplifier (with a 66 gain).

I already guessed that from one of your previous posts.

A shunt for DC in the ground path could be dangerous though.
Must have a well though-over star ground.
Maybe easier to sense high-side, with an INA226 or similar.

eliminateur:
“Not wise to compare input voltage to the potentially unstable MCU supply (what you do).” → i don’t quite follow, shouldn’t the MCU input be regulated?, and AVCC is taken off that.

If you input 2.5volt to the Arduino with a 5.0volt supply and default Aref, then you get an A/D value of 512.
If that supply drops to 4.8volt or increases to 5.2volt, quite possible on USB supply, or with a varying load of displays/LEDs, then the A/D value changes to 2.5/4.81024= 533 or 2.5/5.21024= 492.
The displayed voltage changes with the same ratio as the supply of the MCU.

A ratiometric A/D (default) is good for ratiometric sensors (pots), but bad for absolute/voltage sensors (shunt voltages).

If you supply a pot with 5volt, then the wiper voltage will be 2.5volt.
If you lower supply to 4volt, the wiper will be 2volt.
But it you read it with an A/D with 4volt reference, it will still output 512.
Read up about absolute vs. ratiometric A/Ds.

If you lower/halve shunt amp gain, and double A/D gain by lowering Aref, then the result is the same.
Leo…

i see what you mean by the ratiometric/absolute.

Yes the INA226, or even using a AD620 amp would be ideal, sadly i don't have neither at hand. I could also do with a precision 5V reference(can't recall the most used parts for this, could be a MAX675, a LT1027, etc) and using that for AREF and/or an external 16bit ADC like the ADS1115 or ADS1113 you mention(the most i have is a 8bit external ADC, i also have a 12bit one but it's super ancient in PLCC package and only uses a parallel bus, which no one has ever interfaced to arduino).

As a side note, the ADS1115 is weird, it has a 4V or 6.125V input range which would need 7V supply. Side note 2: Sadly the INA226 breakouts all have a shunt included, can't find a board without one.

¿why is a low side shunt dangerous?

The issue of lowering he gain is like i've said, it will give me issues with very low currents(as-is the circuit already gives me problems showing far less gain at lower currents -less than 100mA- than at high, for example, for ~40mV output it's showing 40~ gain instead of the 66 it should have), crushing the output range to 2.56V full scale would put me in the noise figures of the op amp where i suspect i'm getting nonlinearity problems(i was in fact considering upping the gain to at least double what i have now to ~120 range and kill my absolute current range in half to gain accuracy for lower currents)

Been experimenting a little with the ADS115 and it works well both single ended and differential. Even just using a 5.0 volt VDD you are good to an analog in of 5.3 volts. Inexpensive too. Henry's bench has a decent write up on it:

http://henrysbench.capnfatz.com/henrys-bench/arduino-voltage-measurements/arduino-ads1115-module-getting-started-tutorial/

Then of course the actual data sheet:

http://www.ti.com/lit/ds/symlink/ads1114.pdf

Ron

eliminateur:
Hello,
i’m having an issue with ADC readings that are way off in the milivolt range, i’ll post the measured input of the ADC with a DMM in mV range and the resulting code and discrepancies:

  • 46.6mV-6(29.29mV)
  • 95.35mV-16(16 equals to 78.125mV)
  • 144.4mV-26(126.9mV)
  • 241.6mV-45(219.72mV)
  • 484.2mV-95(463.86mV)
  • 970.4mV-194(947.26mV)

The line is straight, this is probably an offset voltage between the chip’s analog ground and where you placed your multimeter probe, the offset is about 0.15V. If any non-soldered connections are involved its not unusual to see such voltage offsets due to oxidized contacts or IR voltages in wires carrying current.

Star grounding is vital in this kind of situation.

eliminateur: As a side note, the ADS1115 is weird, it has a 4V or 6.125V input range which would need 7V supply.

Read the datasheet again. Default PGA2/3 has an input of 0-VCC, but with limited A/D range (would reach full scale if 6.125volt). The first thing to do is to set the right PGA scale for your application.

eliminateur: ¿why is a low side shunt dangerous?

As with most A/Ds and op-amps, you can't input any voltage below ground without clipping (common mode). The wrong star ground can easily result in problems like that. Therefore most solutions are not suited for shunts in the ground line. The AD620 can't measure close to ground it's negative supply (must be >1.9volt above). Use a chip that is designed for current sensing.

eliminateur: Sadly the INA226 breakouts all have a shunt included, can't find a board without one.

For higher currents, use an external shunt in parallel to the internal shunt (leave it on the board). It just adds ~3Amp to the current capability of the external one. Calculate the combined resistance, or calibrate final current printout. Leo..

An update on results and changes:

  1. revised the ground topology as best as i can in a protoboard at least.
  2. changed to internal ref and changed gain to slightly higher than before ~70.81 (in reality it gives 63 real gain at low signal levels and ~68~69 at high levels)

Due to the changes, the digital read is ~5mV below the DMM measure so i can add that and i’ll get a somewhat consistent reading.

Still the circuit cannot read below ~13mA (maybe if i up the gain above 100, but that would kill my high end).

Wawa, what i’ll do is desolder the board shunt as i’ll be passing near 10A on that when i get the modules in 3 months+

What current you pass through the onboard shunt is a result of voltage across that shunt. If you use an external 10A/75mV shunt, then the current through the onboard shunt will be 0.075/0.1= 0.75A. Well within the limits of that onboard shunt.

What are you measuring. Resistive loads?, motors?, PWM? Smoothing code might be needed too.

Still want to see a diagram of that instrumentation amp. Leo..

i'm measuring a purely digital load but it can drive lots of stuff.

the circuit is this essentially: https://www.planetanalog.com/wp-content/uploads/images-common-planetanalog-2015-11-564091-Image-1.jpg

Insufficient information in that block diagram. Only certain op-amps can work in that diagram (not an AD620). Leo..

the difference with my circuit is that i’m not referencing the op amp to ground and i have a split supply, i’m using a OPA4277 that i had laying around. RF andRG are ~107k and 1531ohm for ~70.81 gain

OPA*4*277, so you should make an instrumentation amp with that, with Kelvin connections to the shunt. Leo..

Wawa: OPA*4*277, so you should make an instrumentation amp with that, with Kelvin connections to the shunt. Leo..

i am using kelvin connections, the shunt has separate terminals for that and those are the ones i'm connecting it