Go Down

Topic: Modified R-2R ladder for input buttons (Read 5295 times) previous topic - next topic


Dec 06, 2016, 09:25 am Last Edit: Dec 06, 2016, 09:40 am by arduino_314
I have a need to connect 8 buttons to the ATmega328p (aka Arduino Uno bare clone), however only 1 pin is available.

Using of some dedicated I/O extender is out of question, as it is expensive and as well require more than 1 available pin to connect.

Thinking about simpler solution, I know exists some Arduino LCD shield with about the same buttons which use some resistance ladder, however with that is really difficult to detect multiple button connection...

Then I started to think about R-2R ladder. It seems to me ideal solution, except floating bits must be solved as button must be between VCC and input pin. In that case, when all except one button is pressed there will be voltage level which is not expected...

The only obvious way to solve that is to have additional pull-down resistor, but then again voltage level slightly drifts from expected values...

Long story short, I have a feeling that I'm "reinventing wheel". Is there already some mathematical model have in consideration additional pull-down resistors or I would have to make my own? I have not found any relevant study about on internet.


I don't think that you'll find a mathematical solution, that can be implemented with simple electronic circuits.

If you want to monitor all inputs at the same time, you may use SPDT switches with a R-2R ladder, which allow to toggle between Vcc and Gnd. Alternatively each SPST switch can toggle a logic gate (inverter...), to provide the right signal levels to the ladder.

For a single input you can use a simple R ladder, with the switches connecting to Vcc. Then the output voltage of that voltage divider depends solely on the closed switch closest to the bottom resistor (to Gnd).

Another approach were multiple (switchable) current sources, with the currents summed up on a resistor to form a voltage. The current sources can be approximated by resistors of values 2^x, e.g. 1k, 2k, 4k...256k. An opamp may be required for the conversion from current into a voltage, with a zero input impedance.


The R-2R ladder should work. Put a buffer between the switches (pulled to Vcc) and ladder inputs, then analogRead the ladder output. The 74hc244 logic IC has exactly 8 buffers and costs around $0.50.


Dec 06, 2016, 11:43 pm Last Edit: Dec 06, 2016, 11:57 pm by Ballscrewbob Reason: add extra
By careful selection of the resistors its should be more than possible using your own suggestion to use a section of an LCD shield code.

Included a link to such a sketch so you can see how its done.
This already reads 5 buttons so another 3 would be quite simple.


It also includes a schematic from which to deduce your own resistance ladder.

I have used a similar approach in an industrial application and the only thing I changed slightly was to add a better debounce function with no loss of responsiveness.

If you strip out the unwanted LCD sections you are left with a quite nice sketch to add in your own uses.

A simple search of the forum itself also turns up a plethora of similar sketches and answers one such HERE

Or a slightly better method HERE with room to spare for additional buttons.

It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.


There are 256 possible combinations with 8 buttons if you want multiple button detection.
A practical problem with Arduino's 10-bit A/D, because you likely would need perfect switches that are always near zero ohms when closed, and 0.1% resistors for the ladder.
What else is using up all the pins of the 328. Maybe you could change something there.


If you only need to operate one button at a time ...

Button Volts
B1     1.0
B2     1.5
B3     2.0
B4     2.5
B5     3.0
B6     3.5
B7     4.0
B8     4.5


Thanks to all.

The R-2R ladder should work. Put a buffer between the switches (pulled to Vcc) and ladder inputs, then analogRead the ladder output. The 74hc244 logic IC has exactly 8 buffers and costs around $0.50.
The idea with non inverting buffer/line driver sounds perfect. This should handle floating input pins and plain R-2R ladder can be used allowing predictable voltage level as output with multiple push buttons support.

Thank you very much, Daniel.


Dec 07, 2016, 08:42 am Last Edit: Dec 08, 2016, 12:49 am by dlloyd
Using of some dedicated I/O extender is out of question, as it is expensive and as well require more than 1 available pin to connect.
$1.20, need 2 available pins, gain 14 I/O.  datasheet

Check the forum here for examples and library or check adafruit.

Haven't seen any success using 8 buttons with R2R ladder approach (4 or 5 seem to be the max).


With 8 buttons (8-bit R2R ladder) you'll need to distinguish what button(s) are pressed to within 19.5mV steps or just 4 ADC code (good luck with that).

Consider the 5V regulator accuracy/stability/regulation for AREF, consider leakage through buttons, wiring, solder connections, crosstalk, noise pickup, resistor matching tolerance, temperature stability, accuracy drift, aging effects, etc.


Be welcome, and remember to use better precision resistors for the MSbits.


When AREF equals Vcc, no errors can result from varying supply voltage in the R-2R ladder.

Also the choice of the resistors is not critical. It's normally sufficient to pick resistors from the same charge, then also 10% resistors have almost the same parameters. Recently I built a R-2R ladder from 5% 270 Ohm SMD resistors, and it works perfectly in my DAC.

Really critical is the button connection. I'd suggest to place the drivers and ladder near the ADC, to keep the output voltage free of external noise.


For each more significant bit, the resistor needs to be proportionally more accurate. A DAC application could be more tolerant in reading jumps in the LSB, however for the OPs application, this would cause false readings of which button(s) were pressed. Many combinations could never be read correctly.

"Consider an 8-bit ladder specified so that there is solely a ±1.0% absolute tolerance on the resistors. The full resolution of the ladder may not be realized. Ratios within the network could be as poor as almost ±2.0% yielding a ladder, which, although manufactured with 8 bits, may only provide accurate outputs to the 6th or 7th bit."  - app note, pg5


Dec 08, 2016, 08:15 am Last Edit: Dec 08, 2016, 08:55 am by arduino_314
Well, I do not need the most of these additional info, but for other may be of interest.

When I practice SMD soldering by plain iron station, first board I have made is 16-bit DAC (overkill for this purpose, but anyway I have planned it for experiments with playing WAV). I have read all related info before soldering about R-2R ladder, bought more than needed 1% 0805 resistors and before soldering tested each resistor value and pickup the  closest ones - final results are in the specified range.

Thus, there is no question about precision of R-2R ladder. And there will be no need to cover all possible combinations (2^8), max 2 buttons push should be supported at the time.

I do not think it would be any problem with. Resolution of 10-bit ADC with 5V ref. is 5 / (2^10-1) = 4,887mV, which is 4 times more than need and certainly that is not 1%, but 400% total allowed error. With read voltage, it is trivial to determinate precisely which button combination was pressed.

Thanks to Daniel, this is now trivial.


Dec 08, 2016, 03:06 pm Last Edit: Dec 08, 2016, 03:11 pm by dlloyd
Need accuracy of 8-bit ladder to 1/2 LSB (9.75mV). 10-bit ADC precision will not help if the accuracy of the 8-bit ladder is beyond 0.5 LSB as there'll be missing 8-bit codes.

The MSB resistor effects the output voltage by 5/2 = 2.500V. For ±1% tolerance, the effect is ±25mV = 2.5 LSB

Need to pick MSB resistor to achieve ±0.25LSB (0.5 LSB range) which is ±4.88mV. Therefore, the MSB resistor tolerance needs to be better than ±0.2%

I suggest testing and recording all 8-bit readings. Then calculate step change (in LSB) and error (%) for each reading.


Dec 08, 2016, 06:24 pm Last Edit: Dec 08, 2016, 06:36 pm by arduino_314
If we have all 1% resistors and declared value of 1K (using 2 in series to make 2R) and measuring each one choose these are between 990 and 992 ohm, what is then total expected error of the 8-bit ladder? With my calculation and real test - very close to 0.

For a mostly "perfect" R-2R ladder, it is the most important to have equal value resistance, not in which sale category exists. Of course, material from which resistor is made should be quality, not to fail due soldering and durability.

Thus, for less money and a bit preparation before soldering, equally good DAC can be made comparing to extremely expensive 0% resistors.

That is my whole story when I built my own 16-bit DAC.


Yes, very close to 0 error (±0.1%) ... no missing 8-bit codes. Didn't realize you were picking values to within 0.2% spread. Just need to sort in batches 990Ω-992Ω, 993Ω-994Ω, etc for each DAC.

Go Up