Gas station without pumps

2016 January 19

Reading switches with ADC

Filed under: Uncategorized — gasstationwithoutpumps @ 22:49
Tags: , ,
Circuit for reading 4 switches.

Circuit for reading 4 switches.

It is often necessary to read the pattern of a large number of switches using few pins on a microcontroller—this problem came up for my son and me in planning to read 9 switches of a DIP switch for setting a DMX-512 address on theater lighting.  There are many ways to do this, but I’ll only talk about one today—using an analog input to read a voltage provided by a voltage divider.

In the circuit to the right, each switch can be open (1) or closed (0). The resistance of the pulldown is the sum of the resistances associated with each switch, and the voltage is Rsum/(Rup+Rsum) Vdd.

To make this work, all the pulldown resistors must be different, so that each combination of switches makes a different voltage. We want to make sure that the values are all easily distinguished by the analog-to-digital converter of the microcontroller, even with worst-case tolerances of the resistors and noise on the ADC input.

I wrote a little python program to optimize the values for different number of switches, selecting optimal thresholds and measuring how close the worst-case resistance values come to the thresholds. I used only standard resistor values from either the E48 series or the E24 series, all with 1% tolerance, and assumed that the ADC had either a 10-bit resolution (like Arduinos) or a 16-bit resolution (like Teensys).  The resolution matters, because the thresholds are integers, and so rounding may reduce the tolerance for noise when the ideal threshold is halfway between integers.

E48 resistor series, 1% tolerance. 10-bit DAC

pulldowns pullup minimum distance to threshold
 1,1.62  1.62 58.322
 1,1.87, 3.48  6.49 19.772
1,1.96, 3.83, 7.5  14.7 7.187
 1, 2.05, 4.02, 7.87, 16.2  30.1 2.016

E48 resistor series, 1% tolerance. 16-bit DAC

pulldowns pullup minimum distance to threshold
 1,1.62  1.62 3704.975
 1,1.87, 3.48  5.9 1239.316
 1,1.96, 3.83, 7.5  14 430.585
 1, 2.05, 4.02, 7.87, 16.2  31.6 103.930

E24 resistor series, 1% 10-bit ADC

pulldowns pullup minimum distance to threshold
 1, 1.6  1.5  56.952
 1, 2, 3.6  4.7 18.586
 1, 2, 3.9, 7.5  12 6.993
 1, 2, 3.9, 8.2, 16  33 1.804

E24 resistor series, 1% 16-bit ADC

pulldowns pullup minimum distance to threshold
 1, 1.6  1.5   3644.94
 1, 2, 3.6  6.2  1181.525
 1, 2, 3.9, 7.5  13  425.540
 1, 2, 3.9, 8.2, 16  27 103.065

Note that a 10-bit DAC with ±2LSB of noise can decode 5 switches only with the E48 series—the E24 series does not allow values to be tweaked sufficiently (and ±2LSB on a 10-bit ADC is unusually low noise—it probably isn’t safe to put more than 4 switches on a 10-bit ADC). A 16-bit ADC with <±100LSB of noise should be able to decode 5 switches with no trouble.

I was not able to find a 6-switch solution with 1% tolerance resistors, even assuming a high-precision ADC.



  1. I was thumbing through a copy of Python Playground by Mahesh Venkitachalam, and there is a reference to your work in Chapter 4: Generating Musical Overtones with the Karplus Strong Algorithm. I suppose I am surprised to see it in a book for lay people, and I’m eager to see if I can understand it. I plan to read the chapter this weekend.

    Comment by V John — 2016 January 29 @ 22:26 | Reply

    • The Karplus-Strong algorithm (or, as we called it, the Digitar algorithm) is very simple to implement. I think that the Python Playground added unnecessary computational complexity (with an extraneous multiply), but the copy I had borrowed from the library was recalled, so I can’t check it. The original algorithm had only a few machine-language instructions: memory read, address increment and compare for the pointer, memory read, add, right shift, and store. It could run up to 4 strings on an old 8080 microprocessor in real time. There should be no difficulty doing several strings on an ARM processor like the Teensy boards, though I’ve not implemented it for the Teensy yet.

      Comment by gasstationwithoutpumps — 2016 January 29 @ 23:15 | Reply

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: