I'd like to use a single 5V digital pin to control both colors of a 2 color common cathode LED. When the pin is high and on output I want the green LED lit. When it's on input the red should be lit.
No, this is an indicator for the push button power switch. Green means the unit is operating normally.
When you hold down the power switch it triggers the program saves then lowers the pin to switch to red.
Then the user knows to release the switch which turns everything off.
Yep, you can delete D1. Risk of red LED staying partially on due to emitter being at 7.4V while base being controlled by 5V D-PIN ... I guess that's why you have R3 at a high value (1MΩ). Might need to put the emitter at 5V (VCC) and lower R3 to 10K-100K.
Ok, got it working, but the green is much brighter than the red.
If I swap the LED anodes the balance is much better, so I swapped the resistors to keep the colors in their correct spots. Is it safe to operate with the resistors swapped?
The resistance can be set as desired according to the required brightness of the LED.
Furthermore, the one LED that lights up when digitalWrite is set to LOW always consumes current.
It only goes off when digitalWrite is set to HIGH, but the current is only changed to flow through the MOSFET instead of the LED.
In addition, the other lit LED draws current from the port, which increases consumption.
In other words, it is best to set the less frequently used LED (red in your case) to the side that lights up when digialWrite is HIGH.
After that, you can freely change the resistance value according to the brightness.
By the way, it is possible to provide the four states of both OFF , red ON / green OFF , green ON / red OFF and both ON(orange light?)
with a common cathode LED at single Arduino output pin.
But the Arduino output pin must be a PWM capable pin, and use one hardware timer...
The issue with that is that the signal pin is the same signal pin that holds the power supply high, so whatever color I want to show when the machine is running must be on the high side, which I'd prefer be green.
The red one should only ever be lit for a second or two as the machine shuts down.
How important is that?
If it is an indicator lamp, the current of the LED is enough at less than 1mA, so there is almost no need to worry about it.
People who use batteries (like coin cells) that are sensitive to the remaining amount may be important.
However, when the machine is turned off, the 5V power supply is lost at the same time, so the red LED doesn't light up?
Yes, for this project I only have a couple things to save but they are on the ESP32-Cam module so I have to trigger the save and wait for a response. Should be a blink for the user but better to be sure and it's nice to have that control.
The code is pretty simple too:
// Pin Assignments
byte pwr_btn = 10;
byte main_pwr = 11; // Must remain high to keep main power
// Power button variables
bool pwr_btn_pressed; // Power button state
uint32_t pwr_btn_prev_time = 0; // Last time power button was checked
uint16_t pwr_btn_timer = 100; // Delay between checking
uint16_t shutdown_count = 0; // Shutdown counter for power button hold
uint16_t shutdown_window = 1000; // Hold time necessary to shutdown
// Timed event variables
uint32_t time_now = 0; // Current time
bool new_state; // Current state reuse for each timed event
// Forward declarations
void power_off();
void setup() {
// Hold main power on
pinMode(main_pwr, OUTPUT);
digitalWrite(main_pwr, HIGH);
// Set up power button and check state
pinMode(pwr_btn, INPUT_PULLUP);
pwr_btn_pressed = digitalRead(pwr_btn) == LOW;
while (pwr_btn_pressed) {
// One time start up code if the button is held
pwr_btn_pressed = digitalRead(pwr_btn) == LOW;
}
}
void loop() {
// Check power button
time_now = millis();
if (time_now - pwr_btn_prev_time >= pwr_btn_timer) {
new_state = digitalRead(pwr_btn) == LOW;
shutdown_count = pwr_btn_pressed && new_state ? shutdown_count += pwr_btn_timer : 0;
if (shutdown_count >= shutdown_window) {
// Saves
power_off();
}
pwr_btn_pressed = new_state;
pwr_btn_prev_time = time_now; // Advance timer
}
// next timed event
}
void power_off() {
digitalWrite(main_pwr, LOW);
}
Sketch uses 1122 bytes (3%) of program storage space. Maximum is 32256 bytes.
Global variables use 21 bytes (1%) of dynamic memory, leaving 2027 bytes for local variables. Maximum is 2048 bytes.