One digital pin toggling to between reading a button or lighting an LED? Possible?

I have a pushbutton. I want the pushbutton to both light an LED and be read by the arduino on a digital pin.

But I also want the arduino to be able to light that same LED, using the same digital pin, and be safe if the pushbutton is pushed at the same time (it does not need to read the pushbutton in that scenario)

I think I can do that as follows?

Read mode: the pin is set to INPUT_PULLUP, which means the LED won't be lit while the pushbutton is not pressed, and will be read as HIGH. If the button is pressed, the pin is read as LOW and the LED lights.

Write mode: If the pin is outputting 1, the LED is not lit. If it is outputting 0, the LED is lit. If the button is pressed while the pin is outputting 1, the diode prevents the short circuit.

As far as the code is concerned, button pressed/LED Lit is LOW/0. Not pressed/lit is HIGH/1. So kind of inverted from what I would prefer. But to have pressed/lit as 1 I would need an external pulldown resistor (since there's no INPUT_PULLDOWN), it's simpler to take care of that in the code.

Am I correct?

Try again. With button pressed and output '1', diode is forward biased, and the output is definitely shorted to ground through it.

This will exceed the Arduino's per-pin-output-current limit. Admittedly, only for the duration of the button press, but it's still a bad design idea.

You're absolutely right, stupid me.

It can't work.

Thanks.

Do you want a solution that can work or are you giving up?

Can't it? You gave up very easily!

How about this:

(Don't think you need the diode, but it won't be a problem, but it might reduce the brightness of the LED).

When the Arduino pin is set to INPUT mode, the pin will read HIGH when the button is not pressed and LOW when it is pressed. (INPUT_PULLUP not required, the LED + resistor will pull the pin up).

When the Arduino pin is set to OUTPUT and LOW, the LED lights. If the button is pressed, this has no effect.

(Take care in your code not to set the pin to OUTPUT and HIGH, because if the button gets pressed this would damage the Arduino pin.)

To be clear,

So you're advocating simply never setting the output to high, just either "input", or "output low".

Works, presuming coding competence.

More clearly, results in a different brightness if the code sets the "output low", or the pin is "input" while the button is pressed; may or may not be an issue, depending on the currents involved.

This approach potentially solves a problem for a different issue a friend has requested, so thanks for pointing it out, @PaulRB.

Pins default to LOW when set as OUTPUT, so either set the pin mode to INPUT or OUTPUT. Don't use digitalWrite() on the pin.

Ah, so I only set the pin to OUTPUT (LOW) if I want to light the LED. If I don't want to light the LED, I leave the pin as INPUT, as opposed to OUTPUT HIGH. That did not occur to me, thanks all.

Which Arduino is this for?

How about a solution that won't fry your Arduino if you do accidently set it HIGH

@jim-p I am interested.

+5V --- LED - 500 Ohm --+
0V - button ------------+-- 500 Ohm - pin

If pin is INPUT, it reads HIGH or LOW depending on button. 5V / 500 Ohm = 10 mA for LED
(500 Ohm near the pin does not affect voltage, as pin tooks like 1 uA current ~ 0.5 mV)

  • If pin is OUTPUT, and HIGH and button open, the led is OFF, no current.

  • If pin is OUTPUT, and HIGH and button closed the LED will shine (~ 10 mA to the ground), the current from the pin is 10 mA (5V / 500 Ohm near the pin), so Arduino is happy and does not burn.

  • If pin is OUTPUT, and LOW and button open, the led is ON, 5 mA current to pin, Arduino happy (I normally use 1 kOhm resistors on LEDs, it shine nice).

  • If pin is OUTPUT, and LOW and button closed, the led is ON, 10 mA current to ground, Arduino happy (500 Ohm between pin and GND = 10mA).

So no problem for Arduino, reading pin works, output works, the button just make LED to shine little more (but 10 mA is OK for LED too)

@scottcalv

Or a real AND gate

No, it doesn't. But this would

Maybe that's what you were shooting for?

When the pin is "input", and the button is pressed, what pulls the pin down?

Nothing pulls it down, so it would not work as an input as @vectorspace000 intended. But it would prevent the short circuit they mentioned.

Not sure why I mentioned it, really, because it's not a solution. But I was curious what @vectorspace000 diode idea was getting at.

ahh. ok.

The following might, or might not, be a useful expansion of the solution for @vectorspace000 . I'm taking liberties here, as they haven't explained their specific context.

Our context: two buttons for setting a turnout(left/right) on a model RR, with a 3 pin CA bicolor LED for showing which route is selected(left/right); could also be used for single LED-per-route indications, where each exit of the turnout has a discrete LED.

For this, the ideal configuration would be:

0V - button ------------------------+-- 500 Ohm - pin (button selects the 'diverging' route)
. |
. |--- RLED--x
. |
+5V --- 500 Ohm - x
. |
. |--- GLED--x
. |
0V - button ------------------------+-- 500 Ohm - pin (button selects the 'normal' route)

Resultant Arduino "field" wiring would be 4 wires - 0V and 3 LED pins (field connections at x on the diagram; the LED is a 3 pin common anode red/green, but could also be two discrete LEDs). Bonus, if you short any field wiring combo, you can't blow a pin.

Apologies to @vectorspace000 for the semi-hijack.

Apologies, forgot how badly ASCII art comes across.

Apologies, I should have explained my context.

I am going to use 8 bits of input to instruct a stepper motor to rotate to one of 200 subdivisions of 360 degrees.

I would like it if I could use those same 8 bits of output to display the 8 bit value of the current subdivision, without the risk of shorting if someone sets inputs while the output is showing. I need many of the other pins so unless I use a Mega, I won't have enough pins for a dedicated 8 bit output for displaying.

My backup plan is to just flash 2 of my planned outputs in sequence to indicate 1/0 (either one is 1 and the other 0, or one is clock and the other 1/0)

Unless.... The Arduino happened to be a model that has internal pull-down resistors?

Then, the pin might be pulled up when the button was not pressed (internal pull-up/down resistors are weak) and pulled down by the internal pull-down resistor when the button is pressed.

When the button was not pressed, a tiny current would flow which might make the LED glow slightly.