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)
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.
(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.)
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.
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.
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)
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.
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.
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.