What if you could measure N buttons but using a digital input, rather than ADC input ??
Well, it's theoretically possible, and so it is in practice. I just implemented it, and works fine.
But for you to use this approach, you must:
- Not mind waiting a few milliseconds for buttons to sample.
- Have either a counter/timer available (or a simple for-loop somewhere)
Theoretically you can even sample multiple buttons, but that is hard to do.
Let's explain first how this works: here's the schematic:
We have a capacitor there. What we will measure is "how long" the capacitor takes to charge until the input pin of arduino reads as 1. We also need to discharge the capacitor before we sample again.
Let's assume no button is pressed, and our capacitor has a value of "VC" at its terminals. If we configure the PIN as OUTPUT LOW, then we're actually feeding only a few microvolts, so we'll sink current from the capacitor using R1.
The basic formula for a RC charge/discharge cycle is "V= V0 * e^(–t/RC)". I'll not write full equations here, you can ask me later for them.
So, after we wait some time (a few milliseconds) we put the PIN back in input mode. If any button is pressed, the capacitor will start charging using the specific resistor attached to that button. After a while, the input PIN will read as '1'. If we count time from when we put PIN as INPUT and PIN reading as '1' we see we have different values depending on which button was pressed.
This requires calibration and some error tolerance. For best results, you should sample 3 times, and if those 3 samples are near a certain known value for a button, you can assume it is pressed.
Here's a sample code I wrote just to demonstrate:
void setup()
{
Serial.begin(115200);
PORTB&=~(1);
}
void loop()
{
unsigned int c;
char measure[80];
// Reset pin.
DDRB|=1;
// Let discharge
delay(1);
DDRB&=~(1); // Input now.
for (c=0; c<65535; c++) {
if (PINB&1) {
sprintf(measure,"C: %u\r\n", c);
Serial.write(measure);
break;
}
}
delay(1000);
}
And here's output for 3 buttons, each pressed at a time and sampled three times:
C: 1795
C: 1780
C: 1798
C: 7357
C: 7550
C: 7381
C: 2162
C: 2173
C: 2139
Cool, no ? ![]()
Best,
Álvaro