/* * ATtiny85 Raspberry Pi Power Controller * * Arduino pin 0 / PB0 = PSU enable * Arduino pin 1 / PB1 = Status LED * Arduino pin 2 / PB2 = Power button to GND * Arduino pin 3 / PB3 = Shutdown request to Pi GPIO16 * Arduino pin 4 / PB4 = Pi alive input from Pi GPIO26 * * ATtiny runs at 5 V. * PB3 is open-drain style: * idle = INPUT / Hi-Z * shutdown request = OUTPUT LOW */ #define PSU_ENABLE_PIN 0 #define LED_PIN 1 #define BUTTON_PIN 2 #define SHUTDOWN_PIN 3 #define PI_ALIVE_PIN 4 #define BOOT_GRACE_MS 60000UL #define SHUTDOWN_HOLD_MS 1000UL #define POWEROFF_DELAY_MS 70000UL // 10000UL is enough for normal shutdowns, 70000UL accomadate pi restarts #define DEBOUNCE_MS 50UL bool systemOn = false; bool shutdownRequested = false; bool buttonLast = HIGH; unsigned long powerOnTime = 0; void setup() { pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(LED_PIN, OUTPUT); digitalWrite(LED_PIN, LOW); pinMode(PSU_ENABLE_PIN, OUTPUT); digitalWrite(PSU_ENABLE_PIN, LOW); pinMode(SHUTDOWN_PIN, OUTPUT); digitalWrite(SHUTDOWN_PIN, LOW); pinMode(PI_ALIVE_PIN, INPUT); } void loop() { updateLed(); handleButton(); monitorPiAliveOrTimeout(); delay(20); } void updateLed() { if (systemOn) { digitalWrite(LED_PIN, HIGH); // solid ON when Pi power is on return; } // Slow heartbeat when PSU is off: // ON 80 ms, OFF 120 ms, ON 80 ms, OFF 720 ms unsigned long t = millis() % 1000UL; if ((t < 80UL) || (t >= 200UL && t < 280UL)) { digitalWrite(LED_PIN, HIGH); } else { digitalWrite(LED_PIN, LOW); } } void handleButton() { bool button = digitalRead(BUTTON_PIN); if (button == LOW && buttonLast == HIGH) { delay(DEBOUNCE_MS); if (digitalRead(BUTTON_PIN) == LOW) { if (!systemOn) { turnSystemOn(); } else if (!shutdownRequested) { requestPiShutdown(); } } } buttonLast = button; } void turnSystemOn() { digitalWrite(PSU_ENABLE_PIN, HIGH); systemOn = true; shutdownRequested = false; powerOnTime = millis(); } void requestPiShutdown() { // Pull Pi GPIO16 LOW. // Turn on the SS8050 transistor digitalWrite(SHUTDOWN_PIN, HIGH); delay(SHUTDOWN_HOLD_MS); digitalWrite(SHUTDOWN_PIN, LOW); shutdownRequested = true; } void monitorPiAliveOrTimeout() { if (!systemOn) return; // Ignore alive pin while Pi is booting if (millis() - powerOnTime < BOOT_GRACE_MS) return; // Pi GPIO26 via gpio-poweroff: // HIGH = Pi running // LOW = Pi halted / safe to power off if (digitalRead(PI_ALIVE_PIN) == LOW) { delay(POWEROFF_DELAY_MS); if (digitalRead(PI_ALIVE_PIN) == LOW) { turnSystemOff(); return; } } } void turnSystemOff() { digitalWrite(PSU_ENABLE_PIN, LOW); systemOn = false; shutdownRequested = false; digitalWrite(LED_PIN, LOW); }