Analog input affected by it's neighbor

I'm getting some strange behavior on my analog inputs that I don't understand. I'm using Arduino Duemolanove. I have two 1M ohm pull-up resistors connected from the analog inputs 0 and 1 to +5v. The purpose of this is to keep the analog input high, close to 1023. Now when I connect a 100k resistor between the input and ground, I expect the input to go pretty low, which it does. The problem is the neighboring input also goes low also, but not as much. For example, when I have two 1M resistors connected to the inputs and +5v, the ADC value is varies between 997 to 1006 on A0 and 1020 to 1021 on A1. Now when add a 100k resistor between A0 and ground, the value on A0 goes down to about 93, which is what I expect, but the value of A1 goes down to about 750. Similarly if I put the 100k resistor on A1 instead of A0, then the value of A1 goes to 91 and the value of A0 goes down to about 750. A2 also goes down affected when I have the 100k resistor on A1.

(Analog 1) ---/\/\/\/----- +5v

GND ---\/\/\/--- (Analog 0) ---/\/\/\/----- +5v 100K 1M

What's going on? I don't understand when changing an input the neighboring inputs change also.

The purpose of this experiment is to mimic the resistance of a wet sponge used as a water leak detector. Instead of the 100k resistor, I'd have a sponge with copper wires inserted into it. When the sponge is dry, it's like an open circuit and the 1M resistor keeps the input high. When the sponge is wet, the resistance is about 100k, and this would pull the input low.

This is only a shot in the dark, but sometimes the ADC conversion can take a sample to settle when you switch between inputs - apparently the MUX needs a finite time to charge up/down to the new signal level. Have you tried taking two readings for each input and throwing the first one away?

Another guess, it might be the resistance being too big. Capacitance grows with resistance so if you try 10K an 1K, do you see the same result? What happens if you add delay between reading A0 and A1?

Well those two guesses are right. The resistance is too high giving the capacitor on the sample and hold not enough time.

What happens if you add delay between reading A0 and A1?

I will tell you - nothing. However if you take a reading on A0 then delay then take another reading on A0 the second reading will be closer to the required voltage.

I print the values of the input to the serial monitor every second. The behavior I mentioned persists, it's not just exhibited initially. I tried a 100mS delay between reads, that didn't help. Even a 2 second delay between reads doesn't help.

I tried it with a pair 100k and 10k instead of 1M and 100k and I don't have the problem. The neighboring input isn't affected with the 100k/10k combo.

Even a 2 second delay between reads doesn't help.

That is not what I said please read my reply again.

ScottG: I print the values of the input to the serial monitor every second. The behavior I mentioned persists, it's not just exhibited initially. I tried a 100mS delay between reads, that didn't help. Even a 2 second delay between reads doesn't help.

Without seeing the code I can't tell whether you have got the point. Anyway, if you have made the problem go away I guess that's all that matters.

This is from section 26.6.1 of the ATmega datasheet:

...The ADC is optimized for analog signals with an output impedance of approximately 10k? or less....

So with the 100k sponge, you probably need an op-amp as a buffer. (An op-amp has an effective output impedance of approximately zero ohms... But, don't try to drive a very-low impedance load with it because if you exceed it's current limit you can fry it. :D )

Here's what I'm doing now for a test. 1M between input and +5v for A0 and A1. 100k between gnd and A0.

Read A0 1 second delay Print A0 Read A0 1 second delay Print A0

Read A1 1 second delay Print A1 Read A1 1 second delay Print A1

When I do this the first two A0 values are fine, like always. The first time I read A1, it's around 750, but the 2nd time I read it, it's back up to 1023, where it should be. So the delay fixes the problem. Can you explain what's going on.

All the answers in this thread have explained the problem. If you read and understand any of them they will explain why this fix works.

You don't need any delays, you just need to read each input twice. The first read switches the MUX to this input and takes a sample (which we expect to be inaccurate because the MUX hasn't had time to settle). The second reading [u]of the same input[/u] gives you the accurate answer because now the MUX has had much longer to settle.

The settling time could be reduced by reducing the resistances, but without changing them just reading each input twice would work just as well.

DVDdoug:
This is from section 26.6.1 of the ATmega datasheet:

…The ADC is optimized for analog signals with an output impedance of approximately 10k? or less…

So with the 100k sponge, you probably need an op-amp as a buffer. (An op-amp has an effective output impedance of approximately zero ohms… But, don’t try to drive a very-low impedance load with it because if you exceed it’s current limit you can fry it. :smiley: )

Can you tell me how I would properly wire the op amp? Originally I wanted to just do this on the digital I/O, but I didn’t have enough available. Is the digital I/O also optimized for 10k? or less?

PeterH: All the answers in this thread have explained the problem. If you read and understand any of them they will explain why this fix works.

You don't need any delays, you just need to read each input twice. The first read switches the MUX to this input and takes a sample (which we expect to be inaccurate because the MUX hasn't had time to settle). The second reading [u]of the same input[/u] gives you the accurate answer because now the MUX has had much longer to settle.

The settling time could be reduced by reducing the resistances, but without changing them just reading each input twice would work just as well.

Great. Thanks for your help!

Can you tell me how I would properly wire the op amp?

You make a [u]buffer[/u] by simply connecting the op-amp's output to it's -input. Then you connect your resistor & sponge to the + input. To be safe, run your op-amp off of +/-5V. (You can't put more than 5V into the Arduino.)

Is the digital I/O also optimized for 10k? or less?

I haven't looked that up, but generally you'd want to drive the digital input with a low impedance source also.

An op-amp can also be used to make a [u]comparator[/u] which has two analog inputs and a digital output. You put your analog input on one input-pin, and a reference voltage on the other pin. When your voltage exceeds the reference, the output stage switches. (You can use a couple of resistors to make a voltage divider to supply the reference.)

Thanks for the info.

Originally I wanted to just do this on the digital I/O, but I didn't have enough available

Analogue pins can be used just like digital pins if you use the pin numbers 14 to 19 for the pins A0 to A6.

Do I need to use pinmode() to configure them like you do with digital pins?

Yes use pinMode(14,WHATEVER) to use analogue pin 0 just like a digital pin.

PeterH:
…You don’t need any delays, you just need to read each input twice. The first read switches the MUX to this input and takes a sample (which we expect to be inaccurate because the MUX hasn’t had time to settle). The second reading of the same input gives you the accurate answer because now the MUX has had much longer to settle.

The settling time could be reduced by reducing the resistances, but without changing them just reading each input twice would work just as well.

Does this need to read the input twice apply to the digital inputs, or just analog inputs?

Just analogue signals, it is caused by the high impedance signal having to charge the sample and hold capacitor. You would not run digital signals with such high resistances because they would not work.

Grumpy_Mike: Just analogue signals, it is caused by the high impedance signal having to charge the sample and hold capacitor. You would not run digital signals with such high resistances because they would not work.

The setup I described for the analog pins also applies to a few digital pins:

GND -----\/\/\/----- (Digital Input) ---/\/\/\/----- +5v 100K? (sponge) 1M?

Will this setup not work because of the 1M? resistance? I didn't mention it before because it seems to be working okay - but I've only done a little desktop testing.

Also, if I configure the analog inputs as a digital inputs, will the input behave as the other digital inputs or will it behave like the analog inputs - with respect to this issue of charging the sample and hold capacitor.

Thanks again for your feedback. It's a big help in my understanding of how these inputs work.