0
\$\begingroup\$

I am measuring voltage output from a device with 10 kohm output impedance with an arduino analog input pin. I see what I would expect with a multimeter, but with the arduino I get either garbage, or at best, oscillating measurements that average out to about what I would expect.

I know the impedance of the analog pins to be 100 Mohms, while on the DMM, it would be around 10 Mohms, so I wasn't expecting the Arduino to be useless while the DMM works fine.

I finally found that shorting the outputs with a capacitor gives me what I'm expecting, but don't really understand why. Resistors helped but I still saw oscillation, and I assumed, being an issue seemingly with impedance, that resistance mismatch was the culprit.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ "the impedance of the analog pins to be 100 Mohms" is more than a little unlikely, particularly when a conversion takes place. Where did you get that idea? \$\endgroup\$
    – brhans
    Commented Aug 3, 2020 at 23:27
  • \$\begingroup\$ It's just what I remember from a precursory googling: here \$\endgroup\$
    – stupidGaN
    Commented Aug 4, 2020 at 19:06

3 Answers 3

2
\$\begingroup\$

The MCU in Arduino has a successive approximation ADC.

It works by briefly taking a voltage sample via a multiplexer into a small storage capacitor to handle multiple input channels with one ADC.

With a high source impedance, the sample/hold capacitor may not have time to fully charge, and thus the sample of the voltage does not resemble the actual voltage.

So the impedance of an analog input pin is not 100 Mohms, as it is momenrarily charging a 14pF capacitor with 1kohm series resistance, and there can be current in or out of the pin.

Therefore the source impedance must be low enough to charge the sample/hold capacitor to within 0.5 ADC counts during the sample time.

Assuming the MCU on your Arduino is an AVR, the ADC specifications say it works best when the source impedance is 10k or less. It seems that your sensor is having a high output impedance.

Also if the sensor output cannot handle the gulps of periodic sampling capacitor charging, it might become unstable and exhibit ringing when the empty capacitor is suddenly connected for charging.

The same is basically when you do have a filter capacitor at the AVR input to have low enough short-term AC impedance, so you can take one measurement without much affecting the value. But if the filter cap is charged by a 1 Mohm resistor, it will still have a high long-term DC impedance, so it takes long to charge the capacitor back to original value, so taking measurements too often will slowly discharge the filter capacitor.

So there are many reasons why analog measurements made with Arduino won't work when compared to a multimeter. The Arduino does not have a built in signal conditioning and buffering like a multimeter has. The required analog input stage should be built between sensor and MCU.

\$\endgroup\$
2
  • \$\begingroup\$ > With a high source impedance, the sample/hold capacitor may not have time to fully charge, and thus the sample of the voltage does not resemble the actual voltage. This sounds like it explains everything. And the oscillation I am seeing is a result of this cap being slowly charged/discharged? \$\endgroup\$
    – stupidGaN
    Commented Aug 4, 2020 at 17:47
  • \$\begingroup\$ It could be. Pretty hard to say without seeing oscilloscope measurements along with the ADC results, or knowing the sampling rate, or actual sensor output impedance, among other stuff. \$\endgroup\$
    – Justme
    Commented Aug 4, 2020 at 17:56
0
\$\begingroup\$

The meter will have either a real capacitor or a software-simulation of one internally.

If it didn't, you'd never get a stable number to be displayed and it'd be impossible to read.

You can be sure this has nothing to do with any 'resistance mismatch'.

A little story....

When I was in college, I was taking a CMOS class - We laid out integrated circuits and had them fabricated. My team decided to do a 'voltmeter on a chip' --- It had the analog inputs, and would output directly to a typical 7-segment LED digital display. When we powered it up, it read "888". Of course, we were super bummed, until somebody suggested adding a small cap to the input. Suddenly it worked. So what was happening is, the numbers were bouncing so rapidly, all the LED segments were lighting up so fast they appeared to be steady-lit.

If you could somehow operate your Arduino in an environment with zero electromagnetic noise, you'd get perfectly stable readings without the cap. But such an environment doesn't exist. There will ALWAYS be something perturbing the wires to a degree. So the Arduino isn't lying to you. It's reporting what it sees at the pins. Just so happens the value at the pins is moving around. Placing the cap there introduces a smoothing action to the voltage, so it becomes stable enough to make a reading.

That said you do need to give the Arduino a hand by making the voltage stable as possible. For example, using tightly twisted wire instead of two separate leads nearly always will yield improvement. Noise-reduction and proper grounding techniques aren't something I could describe in a short post, you could fill textbooks with the stuff. But if you simply can't get the stability you want, posting some pics of your setup may get you useful feedback here.

\$\endgroup\$
0
\$\begingroup\$

Following up on Kyle B answer, if you're not using a GROUND PLANE, then do so.

I assist a guy in sensing/digitizing musical instrument transients.

Over the last year, he/we have learned how to reduce the error floor from 90 milliVolts to about 0.3 milliVolts.

  • Have a 0.01uF cap on input to the ADC

  • Have a unity_gain buffer before that 0.1uF cap.

  • Don't use switching_regulator power supplies.

  • If you must use SwitchRegs, then pay for the better grade.

  • Use a Ground Plane.

  • You may need common_mode chokes, on VDD/GROUND wiring to the SwitchRegs.

  • In the VDD to any opamp buffer, have 10 Ohms in series, and 100uF shunting.

\$\endgroup\$
2
  • \$\begingroup\$ The cap I used had to to be a higher value. Although I'm not sure what it is, I had it lying around, but I think it's in the 10s-100s of uF. A 10nF cap was doing nothing. If I had known how much frustration would have resulted from not being an EE, I would have just been an EE >:( Using a ground plane is an issue because I don't exactly know how the arduino is laid out. \$\endgroup\$
    – stupidGaN
    Commented Aug 4, 2020 at 19:09
  • \$\begingroup\$ I think I once made some calculations that the filter capacitor value should be around 33nF on the AVR ADC input to provide one stable reading under worst case conditions. And then the time between readings depends on what the actual source impedance is. Continuous readings would still drain the capacitor if the sensor source impedance is extremely high. So the 10nF should have helped if the source impedance can charge it between readings. \$\endgroup\$
    – Justme
    Commented Aug 4, 2020 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.