I've built a general-purpose power control circuit using a D1 Mini, an optoisolator, and a transistor for the main power management components. It's a simple yet effective design that's perfect for projects where minimal hardware is valued and Auto-OFF will help save battery life.
Its cost-effective, simple and has ZERO current draw when turned off. I've specifically chosen components that are both inexpensive and readily available, making this design more accessible. Almost every existing design I found had current leakage, draining the batteries in just a few days. I've had battery connected to this design for months without any decrease in capacity.
This circuit features three buttons (more can be added), each capable of turning the device on with a simple press, functioning as a normal button input, and can turn the circuit off with a long press.
Here's the link to the short video:
I'd love to hear your thoughts, suggestions, or any similar experiences you've had. This video is more of an overview rather than a detailed tutorial. If you'd like to see a more detailed video, let me know.
Its cost-effective, simple and has ZERO current draw when turned off. I've specifically chosen components that are both inexpensive and readily available, making this design more accessible. Almost every existing design I found had current leakage, draining the batteries in just a few days. I've had battery connected to this design for months without any decrease in capacity.
This circuit features three buttons (more can be added), each capable of turning the device on with a simple press, functioning as a normal button input, and can turn the circuit off with a long press.
Here's the link to the short video:
I'd love to hear your thoughts, suggestions, or any similar experiences you've had. This video is more of an overview rather than a detailed tutorial. If you'd like to see a more detailed video, let me know.
Arduino Code:
// HackMakeMod Autoshuttoff with 3 Buttons
// Press any button to power ON
// Press any button to act as an input
// Press any button for more than 1 second then let go to turn OFF
// TIMEOUT = 10000 shuts down the power 10 seconds the last button press
#include <FastLED.h>
#define NUM_LEDS 3
#define DATA_PIN D0
CRGB leds[NUM_LEDS] = {CRGB::Black, CRGB::Black, CRGB::Black};
const int buttonPins[3] = {D5, D6, D7};
unsigned long btnPressTimes[3] = {0, 0, 0};
bool lastButtonStates[3] = {HIGH, HIGH, HIGH};
int colorStates[3] = {0, 0, 0}; // 0 = Off, 1 = Red, 2 = Green, 3 = Blue
unsigned long lastButtonPressTime = 0; // New variable to keep track of the last button press time
const unsigned long TIMEOUT = 10000; // 10 seconds in milliseconds
const int outputPin = D3;
void setup() {
Serial.begin(9600); // Initialize serial communication at 9600 baud rate
FastLED.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
for (int i = 0; i < 3; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(outputPin, OUTPUT);
digitalWrite(outputPin, HIGH);
Serial.println("Setup complete!");
}
void loop() {
for (int i = 0; i < 3; i++) {
handleButton(i);
}
checkForTimeout();
FastLED.show();
}
void handleButton(int index) {
bool currentState = digitalRead(buttonPins[index]);
if (currentState == LOW && lastButtonStates[index] == HIGH) { // Button just pressed
btnPressTimes[index] = millis();
lastButtonPressTime = millis(); // Update the last button press time
changeColor(index);
Serial.print("Button at index ");
Serial.print(index);
Serial.println(" pressed.");
}
if (currentState == HIGH && lastButtonStates[index] == LOW) { // Button just released
unsigned long pressDuration = millis() - btnPressTimes[index];
if (pressDuration > 1000) {
digitalWrite(outputPin, LOW);
Serial.println("Long press detected. PIN D3 set to LOW.");
}
}
lastButtonStates[index] = currentState;
}
void checkForTimeout() {
if (millis() - lastButtonPressTime > TIMEOUT) {
digitalWrite(outputPin, LOW);
Serial.println("10 seconds elapsed since last button press. PIN D3 set to LOW.");
lastButtonPressTime = millis(); // Reset the timer to avoid continuous triggering
}
}
void changeColor(int index) {
colorStates[index]++;
if (colorStates[index] > 3) colorStates[index] = 1;
switch (colorStates[index]) {
case 1:
leds[index] = CRGB::Red;
break;
case 2:
leds[index] = CRGB::Green;
break;
case 3:
leds[index] = CRGB::Blue;
break;
default:
leds[index] = CRGB::Black;
break;
}
Serial.print("LED at index ");
Serial.print(index);
Serial.print(" set to color state: ");
Serial.println(colorStates[index]);
}