I've been wracking my brain all night with a problem, and I think I've found a solution, but I thought I'd run it by you.
I have two resistive touch switches in my circuit. The two analog pins they're connected to are pulled down via 1M resistors, and one of the contacts is connected to +5v. When you bridge the two contacts with your finger, you pull the analog pins up because your finger has less resistance than the pulldown resistor.
Sounds good on paper, but when first tried doing this, I was getting all kinds of crazy readings. GrumpyMike explained that the analog pins are multiplexed... that there's only one ADC to read voltages on the microcontroller, and it just switches it between the pins. And because my pulldown resistor was so large, it couldn't pull the ADC down quickly enough to get a proper reading. The solution he explained, was to read the pin twice, with a delay between. The first read would switch the multiplexer to the appropriate pin and allow it time to pull it down. The second would read the actual value.
The problem is, I can't have my program sitting there doing nothing for 40 milliseconds. I have other pins I need to update. I tried using the millisecond timer to perform the same task while still being able to do other stuff, but it worked terribly, and I had no idea why, since I wasn't accessing any of the other analog pins while I was waiting for the pins to discharge.
So I started looking for a hardware solution. And the solution I came up with after many false starts is deceptively simple:
I connected one analog pin to ground via a 10K pulldown.
Now why would I do this?
Well, when I ws having problems reading these switches in the first place, GrumpyMike explained to me that the analog pins are all connected to a multiplexer which switches them to a single ADC in the microcontroller. And the reason I was getting readings that were all over the place was because my 1M pulldowns weren't pulling the ADC's input down fast enough.
The solution he offered to this problem was to add those delays. Read the pin once, wait for it to settle down, then read it again.
But I didn't have time for that. And my attempts to borrow time by switching to the pin, doing stuff, then going back to read it had failed.
So I wondered if there wasn't some way I could pull that input down faster, as if I had 10K resistors on my touch switches?
That's when it occured to me that I could attach the 10K pulldown to a spare analog pin I had. Then, because internally it was connected to the same thing as the pins my high impedance switches were conneced to, I could simply read it to switch the multiplexer to it briefly, pull the ADC input down to near 0v, and then switch to the pins I wanted to read which could be pulled up faster than they could be pulled down because skin has a lower resistance than the pulldown I'd stuck on the pin.
The results I got from this change were immediate. Rather than values that were all over the place, I now got very clean readings, even when reading the pins with no delay at all.
As far as I know, what I've done shouldn't harm the Ardunino at all. It's just a pulldown resistor. I will need to do more tests to see if I get any better results if I add a small delay or read the ports twice, but the raw numbes I'm getting are so good I don't think I'll need to do much more than a running average to smooth them out a little more.
So what do you think? Good technique?