DC volt value not accurate using A0.

I believe this is more of an electronics question rather than an Arduino question, but I thought I would post it here to see if anyone has experienced this issue.

Problem: DC volts into A0 are not measured accurately by Arduino.

More detail:
I'm measuring AC volts from an audio power amp. There is a voltage divider across the non-inductive load. After the voltage divider, I'm using a precision AC RMS to DC converter with an op amp buffer on the output with a bit of gain to give a range of 0-5 DC Volts (to represent a scaled version of 0-50V AC rms). This hardware side is linear all day long. Meaning the scaled output through the RMS converter and buffer are spot on from less than one volt to 50 volts.

Post op amp buffer, the [DC] signal is fed directly into A0. With A0 connected as my input, the 5 digit bench top meter reads XXX, the calculated Arduino output is always just a bit less than XXX from about 0-10V. The Arduino is spot on from about 10-30V and then reads a bit high after 30V. So not linear measurement. Real examples: 2.00 Vdc from bench meter reads 1.86 via Arduino. 15.00 Vdc from bench meter is 15.00 via Arduino. 37.50 Vdc from bench meter reads 37.85 via Arduino.

I have this on a breadboard, which I know are sources for ground problems and noise. I've worked through this. All my grounds are at one point and my wires are short. I looked for noise and oscillation with my scope.

I'm using a regulated 12V supply for the Arduino via the external power connector.
Vref is external with a regulated 5V supply.
I have bypass caps across all important areas. Extra bypass caps didn't help when placed across A0 and other places.

As an experiment, I created a variable test voltage divider using my 5V regulated supply that is used for Vref and fed that directly to A0 to check the ADC and Arduino code. INTERESTING, the direct DC value is spot on with the Arduino ADC and calculation through out the whole range. So does this mean the Arduino and LM358 buffer IC are not compatible?

I see no meter loading when A0 is connected and no oscillations with an oscilloscope.

When I have a moment, I'm going to setup my voltage variable test divider and send it directly to A0 and then setup A1 to receive the same voltage but from the LM358 buffer (gain of zero) and see my results. I know the LM358 is not a precision part, but it is what I had on hand.

Again, more of an electronics question, but hoping someone with some prior experience can support this.

Thank you!

Have a look at the "map" instruction. This can be used to calibrate your analog input by mapping the measured voltage to a number - high and low range.

If it's non linear you could make a look up array .

I'm suprised its non linear tho , I've not seen that problem , are you sure you don't have a problem elsewhere - is your reference voltage steady ? Has the processor a true 5v supply ( if it's 4.8 volts , then the analog input won't read correct with 5v on it).

You could try running with a lower v ref in case the A/D is running out of head room. Bear in mind too that if you put 5v on Vin the processor will be running at a voltage less than this due to the drop across the regulator .

Post a diagram. Some things are questionable, like using an LM358.
This is not a rail2rail opamp, and can only output ~0-3.5volt on a 5volt supply.
Using an external 5volt reference can also be dangerous for the Arduino.

Why didn't you use the internal 1.1volt Aref.
Leo..

The LM358 is a shocking performer above a few kHz - it basically cannot handle large signals above
about about 3kHz at all and goes completely distorted. Use it for DC perhaps, not audio...

Thanks for the replies. I'm not going to quote all the replies, but help answer some questions below. Also, diagram attached.

The LM358 was used because it was a single supply opamp. It only sees DC, not AC.
Vref external / internal is 5.0 / 4.999. Internal or external, the issue is the same.
I found using the 1.1v internal off too and even more difficult to measure the low DC level input.

After some testing last night, it appears it is not the LM358. I do have some Linear Tech devices on their way. I created some test jigs using some precision potentiometers to create a direct DC 0-5V variable supply. This was input to A0 and split into the zero gain setup on the LM358 into A1. Both A0 and A1 measured the same value ADC wise. So LM358 not the issue.

I spent about an hour moving grounds around and grounding all the grounds together on my Uno board. This improved the measured with voltmeter to Arduino ADC and calculation results. But it is not perfect. From about 2 volts down to zero, there still is about a 100mV discrepancy. Example: 1.90Vdc on bench meter reads 1.80Vdc via Arduino. The ADC value for 1.80 when looking at the serial monitor is correct.

I think I am going to move this setup to some perf board and solder everything into place. I'm starting to lean towards ground issues with small signals. Although, 2V is not considered small signal and I would think it would be accurate.

Most of the time the Uno is powered by 12V DC regulated power. The only time the USB is connected is when I look at the ADC value.

@ hammy, I'll look at the map instruction too.

Thanks.

That's a block diagram.
I already understood all of that from the text.

The sensible thing to do is to remove that buffer and the 5volt reference, and use 1.1volt Aref.
And connect the RMS converter output directly to the Arduino input.
Depending on RMS output impedance and voltage levels, you might need a voltage divider or buffer with divider.
Not possible to give you proper advice without seeing a real circuit diagram.
Leo..

OK, just a quick follow-up on this subject. I moved everything over to a perf board and soldered everything with a good ground scheme. I also grounded all the Arduino inputs that were not being used. Just soldering everything solved all the problems with the small signals I was having. I have regulated power supplies for the Arduino and Vref and all grounds are tied together at one point.

I did scope the floating analog inputs before I grounded them and I could see a bunch of noise; switching or clocking.m

The ATmega 10 bit ADC is pretty good performer, though to I've never explicitly measured its linearity.
I think I might do that and report back, I've just got a 2-channel DDS signal generator I could use
to generate a two-tone IM test signal.

It sounds like all you needed was perhaps attention to decoupling, and a 10nF to 100nF capacitor on A0 -
sounds very like noise issues, plus lack of groundplane/star-ground maybe? Were you powering the
Arduino via USB? That's the noisiest possible way to power anything usually!

I tried decoupling caps at the input (A0), but it did not make a difference. I have power supply decoupling caps right by the IC pins.

I am using a regulated 12V supply for the Arduino board and then a regulated 5V supply for Vref.

Grounding was the main issue. The poor contacts in / on the bread board was also a problem.

I have laid out a PCB that I will have fabricated. Hopefully, no noise issues with the board layout. It is audio frequencies only, but you never know. I placed plenty of ground connection points in case I need move the primary ground point around.

Let me know your results of the linearity test.

nautifan:
...and then a regulated 5V supply for Vref.

Told you in post#2 that that is a bad/dangerous idea.
Why didn't you use the internal 1.1volt reference.

"Buffer with gain"
What buffer, and how much gain is needed after the RMS converter.
You might not need it at all if you use 1.1volt Aref.

Again, post a circuit diagram if you want proper help.
Leo..

Told you in post#2 that that is a bad/dangerous idea.
Why didn't you use the internal 1.1volt reference.

I did not like the way the 1.1V reference responded and even adding averaging, I still was not happy. Plus, the 1.1V reference was a bit low 1.0xx (which I know you can compensate for in the software).

As for the regulated Vref, why not. Even with a 12V supply to the Uno or 3 Nano boards I own, the 5 Volts was 4.9xx or even one board was 4.8xx. I wanted something stable and independent of the hardware on the Arduino boards.

I'm happy with my results thus far. I'm moving from perf board to a PCB soon. I'm sure I'll encounter some issues based on my board layout...but fingers crossed!

nautifan:
I did not like the way the 1.1V reference responded and even adding averaging, I still was not happy.

Plus, the 1.1V reference was a bit low 1.0xx (which I know you can compensate for in the software).

Shouldn't be any different from default Aref, so what was the problem.
A lower Aref could mean that you don't need a buffer with gain. What's wrong with that.

nautifan:
As for the regulated Vref, why not.

Default Aref and VCC should never be more than 0.3volt different.
Even if you set Aref to external in setup(), Aref should never be 0.3volt higher than VCC.
Not easy with two 5volt supplies during startup/shutdown.
A better option could be to use the onboard 3.3volt supply as Aref.

But I could be wrong. Still haven't seen your diagram.
Leo..