There are several questions close to this topic already, but they are either for another µC family, or target reading analog voltages or other special cases.

So here goes: I would like to read a button and drive a LED from the same I/O pin on the ATmega32U4. Is there anything wrong with:

  • Pin => 22K resistor => button => GND
  • Pin => LED resistor => LED => GND

Then of course the pin would be put into input mode (with internal pullup) ever so often, and be in output mode most of the time.

As far as I can tell, the internal pullup is 50-100K on that µC, so the 22K with the button should be able to sufficiently sink that.

In output mode, when the button is not pressed, all is as normal; if the button is pressed, this will add a path through 22K to GND, which might or might not make the LED slightly darker; anyhow, in my application it would not matter at all how the LED looks while that button is pressed.

Any chance to damage anything? Any pitfall that is not obvious?

  • \$\begingroup\$ You can easily calculate the voltage on the pin in all situations, and then see if these voltages will fit into definition of logical 1 and logical 0 for MCU. I do not think you will damage anything, it may just not work. \$\endgroup\$ – Anonymous Oct 18 '16 at 12:15

Don't do this the way you describe. As I uderstand, your cicruit would look like:


simulate this circuit – Schematic created using CircuitLab

Now, assume the GPIO is in input mode (high impedance), and the button is not pressed. The voltage on the GPIO will be at about the LED forward voltage. Indeed, even though there will be very little current, there is a path through Rpullup-R2-D1, and there will be about 1.8V~2.5V (depending on the type of led you're using) at the MCU pin, which means logic level will be outside specs (it depends on the supply voltage you're using, but most likely, you'll be between high and low voltage limits). So the MCU won't behave consistently, and you won't really be able to tell if the button is pressed or not. The MCU may also consume excessive power in this case.

Here is what I came up with:


simulate this circuit

You must either drive the GPIO at low level to turn the led on, or set it to high impedance to turn the led off and eventually read the button state. The GPIO must never be actively driven high from the software, because if the button is pressed at the same time, the pin will be short-circuited.

The obvious drawback of the above circuit is that, when the button is pressed, the led will be fully on. But it seems not to be a problem in your case, and apart from this, this circuit is simple, safe for the MCU (if you follow the above rule) and guarantees correct input levels.

| improve this answer | |
  • \$\begingroup\$ Sounds good, thank you. I guess there is no easy way to avoid that potential shortcut (in case of programming errors), or you would have mentioned it... \$\endgroup\$ – AnoE Oct 18 '16 at 16:21
  • \$\begingroup\$ Actually, there is a way, but it requires additional external components. Look in the previous revisions of this post, the circuit suggested with a transistor is safe in all aspects, but more complex. I changed because I thought it added no value. \$\endgroup\$ – dim Oct 18 '16 at 17:28
  • \$\begingroup\$ Thank you; answer accepted. Looks like textbook worthy information to me. I would find it useful if you would bring your transistor variant back from the older revision in case someone needs that protection. \$\endgroup\$ – AnoE Oct 19 '16 at 8:15
  • \$\begingroup\$ @AnoE You're right, with some rewording, it may be worth it. I'll do that in a little while. \$\endgroup\$ – dim Oct 19 '16 at 8:51
  • 1
    \$\begingroup\$ @tedder42 in input pullup mode, the LED is OFF, except when the button is pressed. In output low, the led is ON. So when you sense, the state of the LED actually depends on the button. If this doesn't fit your requirements, I suggest you post another question stating exactly what you want to achieve. It will be much more appropriate. \$\endgroup\$ – dim Sep 20 '18 at 9:17

The simple solution is to put the LED resistor, the LED and the button in a row, and connect the I/O between LED and button.

The I/O is set to open drain output, meaning only the pull transistor is ever activated. Now you can read the pin to sample the button while the output circuit is floating, and turn on the LED on by putting the output circuit to low.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.