1-wire connection for hexadecimal switches to AVR microcontrollers

This page deals with connecting 4 dip-switches or 1 hexadecimal coding switch to an AVR microcontroller (e.g. ATmega8) using only 1 wire. The basic idea is to create an analog voltage level using resistors, which can be digitalized again, using the internal A/D converter of the microcontroller. Even if this might sound quite easy, chosing the resistors is rather tricky, if you want to fulfill the following goals:

1. There should be one pull-up resistor against VCC and 4 pull-down resistors against GND. The pull-down resistors are put in a parallel connection according to the switch position.
2. Both the resistors being used as pull-up and the resistors behind switches should be contained in the E24 series and allowed to have 1% tolerance.
3. It should be possible to replace the 4 switchable pull-down resistors by a single resistor also contained in E24 with ±1% tolerance.
4. The switch(es) and pull-down resistors should be able to be connected with a cable, having 10 Ohms resistance forth and back.
5. The resulting analog voltage should be unambiguously usable to detect the position of the hex-/dip-switches or the used single resistor with a 10-bit A/D converter where value 0 refers to 0V and value 1023 refers to (1023 / 1024) × VCC having a maximum absolute error of ±2 units. Between each valid range there should be at least one invalid value as buffer.

Using a computer simulation the following values turned out to be best (within reasonable orders of magnitude):

• pull-up resistor: 6.8k
• resistors for the switches:
• 0x01: 68k
• 0x02: 39k
• 0x04: 20k
• 0x08: 12k

The absolute maximum tolerance for these values is ±1.135%. The circuit looks as follows:

The 4 dip-switches can be replaced by a single hexadecimal coding switch. Note that the "0-10 Ohm" resistor is optional. It represents the resistance of a longer cable and/or plug connections. If the switches are connected with a longer cable, it might be advisable to add additional components to compensate radio interference, e.g. a second capacitor with 10 µF parallel to the 100 nF capacitor.

Many AVR controllers contain a 10 bit A/D converter with an absolute error of max. ±2/1024. As there is no additional tolerance margin in the calculations, you should use the ADC Noise Reduction Mode of the AVR microcontrollers, while measuring the voltage level. Given the tolerance of the used resistors, the nearest E24 resistors for the values of parallel connections of the resistors used for the switches, and also given the absolute error of the A/D converter you get the following mapping table for the output of the A/D converter:

hex value 12k 20k 39k 68k single resistor output of A/D converter
0x0 open open open open 1022-1023
0x1 open open open closed68k 927-935
0x2 open open closed open 39k 867-877
0x3 open open closedclosed24k 792-810
0x4 open closed open open 20k 758-771
0x5 open closed open closed15k 698-718
0x6 open closedclosed open 13k 665-684
! 0x8 !closed open open open 12k 646-661
! 0x7 ! open closedclosedclosed11k 625-642
0x9 closed open open closed10k 602-622
0xA closed open closed open 9.1k 578-596
0xB closed open closedclosed 8.2k 548-568
0xC closedclosed open open 7.5k 529-545
0xD closedclosed open closed 6.8k 502-520
0xE closedclosedclosed open 6.2k 481-500
0xF closedclosedclosedclosed 5.6k 455-478

Note that the parallel circuit of 20k, 39k and 68k (hex-value 0x07) results in approx. 11k, which is smaller than the single 12k resistor. Therefore the hex-values 0x7 and 0x8 have a swapped position in the table. Using the unused spaces in the output values of the A/D converter, you can detect more values using single resistors, which have no representation in the hex-/dip-switches:

hex value 12k 20k 39k 68k single resistor output of A/D converter
0x0 open open open open 1022-1023
0x1 open open open closed68k 927-935
56k 909-917
47k 890-899
0x2 open open closed open 39k 867-877
33k 844-854
30k 829-840
27k 812-824
0x3 open open closedclosed24k 792-810
22k 776-788
0x4 open closed open open 20k 758-771
18k 737-750
0x5 open closed open closed15k 698-718
0x6 open closedclosed open 13k 665-684
! 0x8 !closed open open open 12k 646-661
! 0x7 ! open closedclosedclosed11k 625-642
0x9 closed open open closed10k 602-622
0xA closed open closed open 9.1k 578-596
0xB closed open closedclosed 8.2k 548-568
0xC closedclosed open open 7.5k 529-545
0xD closedclosed open closed 6.8k 502-520
0xE closedclosedclosed open 6.2k 481-500
0xF closedclosedclosedclosed 5.6k 455-478
5.1k 431-447
4.7k 411-427
3.9k 389-405
3.6k 347-362
3.3k 327-342
3.0k 307-321
2.7k 284-299
2.4k 261-274
2.2k 244-258
2.0k 227-240
1.8k 208-221
1.5k 180-192
1.2k 149-160
1k 127-137
820 106-116
680 89-98
560 74-83
470 63-71
390 52-60
300 40-48
220 29-36
150 20-26
91 11-17

If you can't use the ADC Noise Reduction Mode or if you need additional margin, you should consider using a pull-up resistor with 0.1% tolerance instead of 1% tolerance.

You may freely copy, modify, merge or use this data collection. I do not assure that the data is correct. Use at your own risk.

My test circuit worked as expected and looks as follows: