65.9K
CodeProject is changing. Read more.
Home

Build a Raspberry Pi powersupply with Digispark Attiny85

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (7 votes)

Dec 26, 2016

CPOL

3 min read

viewsIcon

41100

downloadIcon

432

Power on, safe shutdown and power cut-off for Raspberry Pi

Introduction

Raspberry Pi is an amazing device, packing so much power into a small form factor with such a cheap cost.

Unfortunately, it does not comes with its own power supply. Shutting down involves running the shutdown command and unplugging the USB power.

A video demonstration of the implementation can be found here.

Design

This power supply consists of:

  1. Push Button - To trigger on, off and forced power off function
  2. LED light - To show status of, ON (light up), Turning off (blinking), OFF (light off)
  3. Relay - Driving the power into the Pi using Attiny85 (5V USB power)
  4. Transistors x 2 (2N2222 or any similar NPN Transistor)
    • One for driving the Relay to feed power into Pi
    • One for trigging the shutdown command of Pi (using GPIO12 / Pin32 in this example)
  5. Attiny85 (I used Digispark USB development board for development) - Main controller

Here's how the switch is designed to work:

When power is connected, the attiny85 is powered up, relay is in OFF state and Pi is NOT powered. The attiny85 is waiting for button to be pressed.

  • When button is pressed, relay is switched on. Pi is powered and boots up.
  • When button is pressed again, the program sends a signal to Pi to shutdown. The Pi has a python script running and listening to signal on the GPIO port. When signal is received, Pi will run shutdown command.
  • The program waits until Pi is fully shutdown by monitoring GPIO14 (UART TX) (voltage <0.1).
  • Once confirmed Pi is fully shutdown, the program turns the relay to OFF and Pi's power will be cut.

Circuit Diagram

  • Circuit diagram also attached:
    • P0 of digispark drives the relay to power to Pi
    • P1 of digispark drives the status LED
    • P2 of digispark takes input from button for power on / off button
    • P3 of digispark trigger shutdown of Pi via GPIO12
    • P4 of digispark detects if Pi is shutdown via GPIO14 (UART TX)

Using the Code

  • Install the sketch into attiny85. I am using Digispark USB development board (sketch_pi_switch.ino)
  • Run the shutdown script in Raspberry Pi (ShutdownDetect.py)

Points of Interest

int SHUTDOWN_PIN = 3;
int RELAY_PIN = 0;
int BUTTON_PIN = 2;
int LED_PIN = 1;

The powerstatus variable is used to keep track of the power status of pi.

int powerstatus = 0; 
//Power Toggle Mode
// 0 Power off
// 1 Powering On (not used for now)
// 2 Powered on 
// 3 Powering off
// 4 Waiting for Safe Shutdown to finish
// 5 Hard Shutdown

Each loop is delayed by 50ms, making timing a bit easy (e.g., how long the button has been pressed).

If button is pressed for a long time (60 * 50ms) = 3s, force to power down.

    if(buttondowncount>=60 && buttonupcount >2)
        {//Long Pressed Button
          buttondowncount = 0;
          buttonupcount = 0;
          powerstatus = 5;
        }

If button is pressed for a short time (3 * 50ms) = 150ms. Either move from power off (powerstatus 0 to 1) or start power off sequence (powerstatus 2 to 3).

else if(buttondowncount>=3 && buttonupcount >2)
        {//Button Pressed
          buttondowncount = 0;
          buttonupcount = 0;
          if(powerstatus==0)
            powerstatus=2;
          else if(powerstatus==2)
            powerstatus=3;            
        }

The next section of the code is where the actions are for each powerstatus.

      //Switch on relay to power on
      if(powerstatus==2)
      {   
          digitalWrite(SHUTDOWN_PIN, LOW);
          digitalWrite(LED_PIN, HIGH);
          digitalWrite(RELAY_PIN, HIGH);                
      }
      else if(powerstatus==3)
      {
          //Start Shutdown Sequence
          //Trigger shutdown script in Pi 
          digitalWrite(SHUTDOWN_PIN, HIGH);
          delay(100);
          digitalWrite(SHUTDOWN_PIN, LOW);
          powerstatus=4;
          checkOffCount = 0;
      }
      else if(powerstatus==4)
      {
          //Waiting for fully power off signal in TX pin
          //Blink LED to signal powering off
          digitalWrite(LED_PIN, LOW);
          delay(300);
          digitalWrite(LED_PIN, HIGH);
          delay(200);

          //Check if it's off 5 times before shutting down                
          if(checkPiOff())
            checkOffCount = checkOffCount + 1;
          else
            checkOffCount=0;
          
          if(checkOffCount==10)
          {
              //It's really off
              digitalWrite(LED_PIN, LOW);
              digitalWrite(RELAY_PIN, LOW); 
              powerstatus = 0;
              checkOffCount = 0;
          }                   
      }
      else if(powerstatus==5) //Hard shutdown
      {
          digitalWrite(LED_PIN, LOW);
          digitalWrite(RELAY_PIN, LOW);
          powerstatus = 0;
          checkOffCount = 0;
      }

The most interesting section would be powerstatus==3 and 4. Below triggers the pi and runs the shutdown command and sets the powerstatus to 4 (waiting for Safe Shutdown to finish).

digitalWrite(SHUTDOWN_PIN, HIGH);
delay(100);
digitalWrite(SHUTDOWN_PIN, LOW);

powerstatus=4;

Then in powerstatus == 4, it blinks the LED light and monitors whether the pi is fully in shutdown state.

      else if(powerstatus==4)
      {
          digitalWrite(LED_PIN, LOW);
          delay(300);
          digitalWrite(LED_PIN, HIGH);
          delay(200);

          //Check if it's off 5 times before shutting down                
          if(checkPiOff())
            checkOffCount = checkOffCount + 1;
          else
            checkOffCount=0;
          
          if(checkOffCount==5)
          {
              //It's really off
              digitalWrite(LED_PIN, LOW);
              digitalWrite(RELAY_PIN, LOW); 
              powerstatus = 0;
              checkOffCount = 0;
          }                                          
      }

Points of Interest

  • Digispark does draw some power, even when the PI is shutdown. I am running it in 1Mhz mode so that it draws the minimum power.
  • This project can be easily improved to remotely control the Pi's power via Infrared. Let me know your thoughts!