Connecting push button to a controller pin

This problem is decades old but I do not see a direct answer to it on this site. I want the following:

This circuit just allows to check the state of the button from inside the micro-controller. Nothing fancy. My questions:

1. Is there anything better than this simple design?
2. Is the value of 100 kilo ohms resistor adequate for our days CMOS devices, like dsPIC30FXXXX and not a high power application?
• 1) Not really, unless you're looking for hardware debouncing. 2) Yes. – NickHalden Mar 14 '13 at 23:10

First, a lot of microcontrollers and digital signal controllers will have internal pull up resistors. Here's an example, an Atmel ATMega164.

There will typically be a register that allows the internal pull ups to be turned on and off. Due to variations in the fabrication process, these internal pullups come in a very wide range, and are not a good choice if you need very close control over current draw in ultra low power applications. If keeping component count low is important, this is an easy way to do it. Using internal pull ups for hardware debounce would not be a good idea, since it's not possible to predict their exact value.

Whether the 100$k\Omega$ value is adequate depends. If it's just a switch that will be periodically flipped by a user, then 100$k\Omega$ would be a good choice for minimizing power consumption. For things that are going to switch more rapidly, such as rotary encoders, the process I would go through is

1. Find maximum sink current in data sheet
2. Calculate a pull up value using Ohm's Law
3. Choose a standard sized resistor a few sizes bigger, depending on the speed actually needed
4. Test and see if the resistor size chosen gives the required rise and fall times

So if the maximum sink current per GPIO pin were 10 mA and operating at 5V: $R=\dfrac{V}{I}=\dfrac{5V}{10mA}=500\Omega$. Keeping this R value small as possible will allow for the sharpest edges and highest switching frequencies.

• Are you saying that because of wire/trace capacitance you'll have an RC circuit that will cause signal propagation delays to the uC, and that with a larger R these propagation delays can actually cause misreading of a rotary encoder? – angelatlarge Mar 15 '13 at 0:11
• Yes, parasitic reactances are just a fact of life that need to be dealt with more and more as frequency increases. – Matt Young Mar 15 '13 at 0:14
• Interesting! I am confused though: assuming that paracitic capacitance is less than 1 uF, given a resistor of 100k Ohms and assuming 0.1uF parasitic C, we get a time constant of around 23mS (input = 5V, output =4.5V). In other words in a 5V circuit, the uC will see 4.5V on the input in an up-going pulse in less than 25ms. For the uC to miss that (under the assumption that it isn't polling), the encoder would be generating pulses at 40Hz or so. Is that something we should worry about? – angelatlarge Mar 15 '13 at 0:28
• Parasitic capacitance is typically in the nano or pico Farad range. This becomes a problem with rotary encoders at higher speeds. Consider an optical encoder that puts out 24 pulses per revolution, and is spinning at 1500 RPM. The output square waves are going to be 600Hz with a period of about 1.2ms. This is still slow enough that the minimum sized pull up would be unnecessary, but 100$k\Omega$ would make for rise and fall times that are unlikely to be acceptable. This is worth a question on its own. – Matt Young Mar 15 '13 at 1:01
• True and true. I was thinking of manual rotary encoders. – angelatlarge Mar 15 '13 at 1:05

You can get simplier than that.

Just use an internal pull-up/pull-down resistor in your microcontroller.

100k is adequate, but internal pullups could to be a bit lower in some MCUs, for example in AVR atmega8 it's 30-80kOhm for reset pull-up and 20-50kOhm for all the other I/O pins.

• You cant't say that 100k is adequate. There is no universal receipt, you have to compute the value according the the MCU and the device driving the pin at the other side. – Blup1980 Mar 15 '13 at 8:46
• The person asking the question specified a push button. I don't see a problem with this answer. – mjh2007 Mar 15 '13 at 14:34
1. Is there anything better than this simple design?

Better can't be answered without specific criteria to measure against, which you haven't provided. In most cases, the topology you show is fine. Two variations might be "better" depending on the situation:

Many microcontrollers have internal pullups on some of their pins. These are meant for exactly this kind of situation. The resistor is then internal to the micro and you set a bit someplace to enable it. The only external part required is the just the pushbutton itself.

Another useful variant to keep in mind is for low power designs where the button might be a switch that can be closed for long periods of time. In that case you want to minimize the long term average current thru the pullup resistor. You make it as big as possible, but there are limits to that and drawbacks for making it too big. Instead, you switch the pullup on for just a few µs at a time to take a button reading. If you check the button every 1 ms and the pullup is on for 10 µs, then the average pullup current is reduced by 100x. With a external resistor you use another pin to drive the top side of the pullup. With a internal pullup, you enable/disable it in firmware as needed.

2. Is the value of 100 kilo ohms resistor adequate for our days CMOS devices, like dsPIC30FXXXX and not a high power application?