ADC reading changes when digital pins are HIGH

Hi guys, I've finally joined the crowd, got a pair of arduino unos for my house automation project.

Here's what I'm currently trying to get working smooth, I'm using my uno to read a voltage from a TMP36GZ sensor, I restricted my aref to the internal reading because my temp will never go above 1.1v so this should give me better resolution. At this point I've got it all working well, however I noticed a strange thing and would like some help.

Whenever set a digital pin to high the adc reading goes down a few notches (3-4), I know this isn't much but it translates into about 1/2F and very repeatable, so it's not just jitter. It does this with or without a load (with load little more). Is this due to an internal pull-up? If so, is there a way to get around this so that I'm not getting a 1F lower reading that I'm supposed to simply because I have a pin pulled up?

PS: I'm using an external 12v psu, and with a scope my 5v peak to peak is 5.059v, with zero drop with the pin switched on.

I think it's just the nature of the beast. Where there is digital and and analog signals sharing the same IC die, board ground plane, and power traces your going to see a certain amount of noise, jitter, variation, whatever one chooses to call a differnce between theoretical conversion vs actual conversion. The 10 bit +/- 2 LSB of total accuracy is a very loose spec that AVR allows themselves. That says you can't rely on better then +/- 3 counts overall accuracy worst case.

If you desire or need instrumentation quality A/D performance then you should look at purpose build dedicated analog front end and A/D converter chips placed on well designed PCB with proper support components. The AVR built in A/D pins are a really cool feature and very very useful, but expectations need to match reality. There are things one can do to smooth out conversion performance, like external RC filtering or software averaging over multiple sampling.


Well, that's the thing, I'm averaging the temperature already, but error is not something that can be averaged, the reading just drops by about 3-4. If that's the norm then I guess I can deal, I'm going to experiment with doing digitalWrite in a wrapper function which will also set a flag, which if set will offset my ADC reading by +3. Sort of compensate for the discrepancy.

Thanks for the confirmation of the issue though, I had a feeling that the AVR adc just isn't accurate enough

I don't know...I think there might be something else going on, specifically with the internal reference shifting a little bit. My guess is the internal reference is a current shunt and if you're driving current out of the chip by setting a digital pin high, you can subtly change the reference voltage (which is NOT a precise reference). So it's not the analog value that's changing, it's your reference (at least that's my theory). On the other hand, by my theory the voltage reference would be going DOWN as you drive current out, which would make your analog reading go UP, not down.

Can you try going to an external reference (AREF pin) with a more precise reference voltage applied?

The Aussie Shield: breakout all 28 pins to quick-connect terminals

Well, while doing some more testing I came across something really odd.

I'm now taking 300 temp samples every 1 second, and it's way more stable this way, but yeah I still get the shift of a few bits when a load is applied. what's really weird is that now, randomly my adc will read crazy low values, like it'll be reading like 679+-2 then will read 575+-30, then go back up. Nothing changes externally.

I'm powering the arduino from USB, and have a dvm showing voltage on the 5v bus the whole time and there's no change at all, steady 5.059v.

I actually have a 2nd arduino I bought for a little I2C experiment, so I'll try this same code in that one and see what happens.

Ok, seems I've found my cuprit, looks like my sensor is broken. I just put my dvm across the sensor's output pin and ground, it'll read .706v at room temp, but randomly i see the number jump around. down to like .62 and below, then recovers to .706 again. It does this while supply voltage is stable at 5.052+-.003

I guess I'll just leave it at this, a purely academic test, though a very effective one since I learned a lot.

I have a DHT22 temp/humidity sensor on order from sparkfun.

The Arduino board connects the digital and analog supplies together - this compromises analog accuracy considerably, you need a custom board with separate analog and digital supplies, regulator and ground planes to improve things. The most likely reason for the disturbance is the regulator output voltage changing as the pin switches due to the increased current demand, or an IR voltage developed in the supply traces. We are talking 15mV or so to trigger a few LSBs.

I think there might be something else going on, specifically with the internal reference shifting a little bit. My guess is the internal reference is a current shunt and if you're driving current out of the chip by setting a digital pin high, you can subtly change the reference voltage

What a coincidence! I just finished a several week test using an ATtiny85 processor with varying supply voltages, ambient temperatures, and output pins. The internal voltage reference varied from 1.087 to 1.092; a range of about 0.45%. The supply voltage and ambient temperature seemed to effect the reference. The output pins did not.

(which is NOT a precise reference)

It is certainly not always "1.1 volts" but, in my experience, it is very stable.

Have you tried to measure how much AC is on your sensor output? 0.01 or 0.1uf cap to ground may help

I found that a .1ufd cap from the aref pin to ground helped quite down a +/- 2 count variation measuring a fixed DC input. Funny it helped one board, a RS-232 serial arduino, but wasn't needed on my Seeeduino mega board, go figure. Hey it's analog, if it was pure digital any code monkey could handle it. 8)