Is there a way to reduce resistor count in this circuit?

I have 8 configuration DIP switches connected to 4 analog pins of an ATTiny, so 2 switches per pin. I need to be able to read any combination and this is the only way I've been able to get it working (I tried the internal pullups but they don't seem to be reliable in this circuit).

Is there a trick to using fewer resistors that I'm missing?

Thanks as always.

Well, for 1, why aren't R9 and R10 just 1 20K resistor? Same goes for the others around the switch that are essentially in series.

So, if I get it, when you read A0 you get:

READING SW7 SW8
0.0V open open
1.7V open closed
2.5V closed open
3.0V closed closed

with Vcc being 5V

as suggested, replace the two series 10k resistors (R3 and R14) with one 20k.

I think there's a mixup with the component numbers. To clarify, R9 and R10 aren't in series. They're different resistance taps on a voltage divider. Pairs such as R3 and R14 however are effectively in series to +5v when the switch conducts between them.

That's four down. I don't see a good way to minimize more than that. Maybe source a resistor pack instead of individual parts, if that helps any.

It might be possible to reverse the ground and V+ sides, allowing you to remove the four pull-downs you currently use. That's assuming the AVR lets you enable the internal pull-up resistors while in analog input mode, and I don't remember if that's even a valid port mode combination. You would have to calculate the ratios based on the internal pull-ups, and I have no idea what kind of tolerance to expect. I would not assume them to be 1%, since any old value will typically do. Still, you may be able to calibrate accordingly.

magagna:
Is there a trick to using fewer resistors that I'm missing?

A SIL resistor array instead of R3 - R10 won't reduce the number of resistors, but will reduce the footprint of those resistors, if that's your problem.

Here's a thought...

Use three digital output pins to drive a 74ls156 (open collector 3to8 decoder) and one digital input pin (with an internal pull-up resistor) tied to all eight outputs of the '156 and you can read all 8 switches individually without any external resistors!

What are the other pins of the ATtiny used for? I normally use diode multiplexing to read large numbers of switches with a smaller number of Arduino pins. Depending on what the other pins are used for (for example, if some of them are used to multiplex an LED display or to drive an LCD display), that may be an option here. You would need 8 small signal diodes but no resistors.

Thanks all for the input.

I apologize for the unclear schematic, yes R9 and R10 are not in series -- one connects to DIP switch 1 and the other to DIP switch 2. They're both required otherwise I'm not able to distinguish between switches 1 and 2 being off-on vs on-on.

SirNickity - I did try replacing R3 / R14 with a single 20K resistor and that works so that's definitely one option, thanks. That's a little embarrassing I missed something so obvious....

Henry_Best - I didn't know resistor arrays like that existed. Thanks!

MajiG - The 74ls156 looks interesting, I will check it out.

dc42 - All 11 ATtiny pins are in use - 4 go to a TLC5916 (latch, clock, data, enable), 2 go to an i2c device, 1 goes to an on/off pushbutton, and the remaining 4 go to this DIP switch array. I'd never seen diode multiplexing before either; thanks for introducing that to me as well. I'll keep that in mind for future projects.

magagna:
dc42 - All 11 ATtiny pins are in use - 4 go to a TLC5916 (latch, clock, data, enable), 2 go to an i2c device, 1 goes to an on/off pushbutton, and the remaining 4 go to this DIP switch array. I'd never seen diode multiplexing before either; thanks for introducing that to me as well. I'll keep that in mind for future projects.

With that setup, you could indeed use diode multiplexing, like this:

  • Connect your 8 dip switches plus the pushbutton in a 3x3 matrix, with a diode in series with each switch or pushbutton.
  • The three rows connect to 3 input pins (3 of the 4 pins you are currently using for reading the dip switches). Enable the internal pullups on those pins.
  • For the three columns use the 4th of those pins, the pin you were using for the pushbutton, and the pin providing the data connection to the TLC5916.

To read the switches, drive one column low at a time, then read the 3 inputs to see which of them read low.

However, it's not much of a component saving - 9 diodes rather than 12 resistors. One advantage is that reading the DIP switches will be faster because you don't have to make analogRead calls, however, that may not matter unless you are reading them frequently.

Thanks for the idea. I originally had the pushbutton on its own pin (PB2) so I could use the hardware interrupt on it, but since I have to poll the pins for the DIP switches anyway I think I can make it work.

Why polling dipswitches ?
Aren't they always the same unless changed during power off ?
Typically dipswitches are set before you power up.
If that's indeed the case, you do not need to poll those during your program.
Just read them once during power up /setup.
You can even use a single pin to select the dipswitches and use the other pins for whatever need you have after reading those switches.

magagna:
Thanks for the idea. I originally had the pushbutton on its own pin (PB2) so I could use the hardware interrupt on it, but since I have to poll the pins for the DIP switches anyway I think I can make it work.

It's quite possible to use multiplexed input pins like this and still to have an interrupt generated when the system is idle and a particular button is pressed. I've recently done that in one of my designs, where I wanted to wake the system from sleep mode when a particular button is pressed (because that button doubles as the power button).

dc42:

magagna:
Thanks for the idea. I originally had the pushbutton on its own pin (PB2) so I could use the hardware interrupt on it, but since I have to poll the pins for the DIP switches anyway I think I can make it work.

It's quite possible to use multiplexed input pins like this and still to have an interrupt generated when the system is idle and a particular button is pressed. I've recently done that in one of my designs, where I wanted to wake the system from sleep mode when a particular button is pressed (because that button doubles as the power button).

Doing 4 switches at a time like this rather than all 8 will reduce the noise problem greatly. A common 1k8 pull down, then
4 switched pull-ups (1k, 1k8, 3k9, 8k2) for a pin would give 16 distinct voltage levels with reasonable spread, and you'd need
2 pins, 10 resistors in total.

magagna:
Henry_Best - I didn't know resistor arrays like that existed. Thanks!

You're welcome.
See:
http://www.rapidonline.com/electronic-components/sil-resistor-networks-29581/