Path: Home => AVR_EN => Applications => Key matrix => DIP switches   Diese Seite in Deutsch:   Applications of AVR Single chip controllers AT90S, ATtiny, ATmega and ATxmega DIP switches and resistors on an ADC input

## 1 DIP switches Rather often your AVR has to read in DIP switches to react on user input. If you want to read in a DIP switch with four single switches you need four I/O pins, with pull-up resistors on, and the DIP switches pull the pin low if they are closed. With the scheme to the left, the number of necessary pins can be reduced from 4 down to 1 if an AD converter input channel measures the voltage produced by the resistors.

A warning at the early beginning: do not try this with more than four switches, it does not work! Rather use two AD channels for 6 or 8 bit switches.

It is clear that the resistors have to be different: each switch has to produce roughly the double voltage increase than its previous one. Unfortunately the math of parallel resistors is a little bit strange:
Rhigh = 1 / (1 / R1 + 1 / R2 + ... + 1 / RN)

And the resulting voltage of
UADC = Uop * R0 / (R0 + Rhigh)

is anything else than straight-forward and linear math.

So selecting the otimal resistors is a task for a large table calculation or, better, a dynamic iteration task.

## 2 Optimizing resistors

Optimization has to consider that
1. resistor values are organized in rows. The E12 row provides 12 different values er decade (1.0, 1.2, 1.5, ..., 8.2) while E24 has 24 values (1.0, 1.1, 1.2, 1.3, 1.5, ..., 9.1) per decade. Theoretically also E48 and E96 are defined but are not held in stock by electronic shops.
2. resistor values are not exact due to production tolerances. Available tolerances are +/-5%, +/-2% and +/-1%. If you measure the resistor value manually you can achieve less tolerance but this is unsuitable for more than only a few devices.
3. the ADC can measure in two modes: 8 bit or 10 bit. Higher accurancies require extra chips and are more subject to noise, so better forget this. This software, written in Lazarus Pascal and executable under Windows and Linux (Wine) operating systems, performs the lengthy iteration processes.

You can select
1. the number of DIP switches (2, 3 or 4),
2. the resistor row to be selected from (E12, E24 or E48 - if you find a trader offering that),
3. the resistor tolerance (5%, 2%, 1% or 0.5% and 0.1% if you want to hand-select them),
4. the ADC's resolution (8 or 10 bit).
The button "Restart" resets the resistor values to their default. Note that each iteration sequence might end up with different results as the resistor to be checked next is randomly selected.

By pushing the button "Iterate1" a resistor between 1 and N is randomly selected. For the next resistor in the row, for the previous resistor in the row and for its current value the averaged squared sum of differences between the voltage required and the resulting voltage is calculated. If the previous or the next resistor value produce less differences those are selected. A window appears that displays the resistors and the resulting differences, so you can follow the iteration process.

The button "Iterate100" repeats this 100 times without displaying interim results.

The resistors are displayed in the upper right corner. If you click onto a resistor line, you can change its value manually by clicking the "Change Rn" button. Resistor values are selected from the currently selected E row only.

The result window on the bottom displays
1. the target value of the voltage (in mV/V),
2. the nominal value of the voltage (resistors = nominal resistance),
3. the lowest and the highest voltage value taking resistor tolerances into account),
4. the nominal and the lowest and highest ADC readings for the selected resolution.
Note that the lower and upper voltages are calculated with all resistors at their highest tolerance (low: R0 the smallest, all other R the highest) so that you can risk to switch tolerance one level higher than the resistors are, because all four are probably not at their upper value.

The button "Source code" writes an AVR assembler table like this (include source code is here):
``````
;
; Table for recognizing mouse piano state
;   4 switches, ADC resolution = 1024
;   Resistors E24, tolerance = 0.5%
;     R0 = 4k7
;     R1 = 68k
;     R2 = 27k
;     R3 = 10k
;     R4 = 2k4
;
PianoTab:
.dw 66,68 ; N=1
.dw 150,154 ; N=2
.dw 199,203 ; N=3
.dw 325,330 ; N=4
.dw 356,362 ; N=5
.dw 398,404 ; N=6
.dw 423,429 ; N=7
.dw 675,680 ; N=8
.dw 683,688 ; N=9
.dw 694,700 ; N=10
.dw 701,707 ; N=11
.dw 722,728 ; N=12
.dw 728,734 ; N=13
.dw 737,742 ; N=14
.dw 742,747 ; N=15
.dw 0,0 ; No more stages
;
; (+)
;  |   __    / S4
;  o--|R4|--O O--
;  |   --        |
;  |   __    / S3|
;  o--|R3|--O O--o
;      --        |
;  |   __    / S2|
;  o--|R2|--O O--o
;      --        |
;  |   __    / S1|
;      --        |
;                -
;               | |R0
;               |_|
;                |
;               ---
;
```
``` The button "Schematic" draws a graphic of the current results. By clicking on it it can be saved as a PNG or BMP file.