One thing that was still missing for me on the Raspberry Pi®, was the inclusion of some kind of power switch. Considering how many common Raspberry Pi® projects could make use of this functionality. Still, we’ve lived with this problem with the old version for a long time, and there are plenty of switch products out there to get around it. Today I’ve been Designing the Powerunit͘® to switch my the Raspberry Pi® On and Off.

Why Do I Need A Switch?

Well, you don’t. You also don’t need a Raspberry Pi® , a iPhone, or even that candy bar you’re eating as you read this. A switch for the Raspberry Pi® is a “nice thing to have”.

It means you don’t have to plug and unplug the micro USB power cable each time you use your Pi – hopefully increasing the life of that delicate connection. It also saves you having to bend down and unplug that Raspberry Pi® media center, making the experience that whole lot slicker.

There’s also a learning element here – this example requires full assembly, and there’s only a few parts to solder. I personally enjoy this side of projects, but less confident ‘makers’ may opt for a ready-made solution. So it’s up to you if you want to add a switch to your Raspberry Pi® – but I certainly want one!

Hardware

When the Raspberry Pi® is in the shutdown state, it still uses a considerable amount of power and leaves the power LED lit, so it is therefore not particularly suitable to certain applications. That’s why I’m looking for a way to create a fully functional On/Off power switch. This solution includes an On switch, a  Off switch, and a reset switch, as well as an LED as power indicator. The solution connects in-line with your 5V power supply.

Components

1 x ATTINY85
1 x 220Ω resistor
2 x 10KΩ resistor
2 x Momentary switch
1 x BC548 (NPN transistor)
1 x 1N4001 Diode
1 x Omron G5V-1-5DC Relay
1 x 3mm LED

The circuit is fairly simple

When the relay is in the off state, but 5V is supplied to the input, the voltage does not travels through the relay. But will only power the ATTiny85. The ATTiny85 is Programmed as a “simple” On/Of Switch. When you press the On/Off button It will set the relay to High. Once the output is high , it turns on the BC548 transistor, which connects one end of the relay coil to ground. The relay is instantly activated. This causes power to be supplied to the output.

When you press the On/Off button It will set the relay to High. But It also Sets Pin 7 of the Raspberry Pi® to High. As long as this pin stay’s High. noting will happen and the Raspberry Pi® stays on. When you press the On/Off button It will not set the relay to Low. Only Pin 7 of the raspberry will be set to Low. Once the Pin 7 is Low on the Raspberry Pi® , a Python script starts running, shutting down your Raspberry Pi® Safely. There’s a delay from 30 Seconds build in to give the Raspberry Pi® time to shutdown safely. When these 30 seconds have run out, it turns off the BC548 transistor, which disconnects one end of the relay coil to ground. The relay is instantly deactivated. This causes power to be cutoff to the output.

Then there’s a LED connected to Pin 11 from your Raspberry Pi® (Optional). This indicates weather the power is on or off. The Reset button is already integrated on your Raspberry Pi® as P6, you only need to connect a switch, to be able to reset your Raspberry Pi® , when necessary.

Code Examples

To turn on and of the power there’s some code needed for the safe shutdown functionality to work correctly. The switch causes the script to initiate the shutdown.

Attiny85 Code

Open Arduino IDE and paste in the code from beneath. A later section describes how to program the Attiny85.

/* Project name: Powerunit®
   Project URI:  https://www.studiopieters.nl/raspberry-pi-power-unit
   Description: Powerunit® - Atmel® ATTiny85 Software package
   Version: 3.9.2
   License: MIT - Copyright 2018 StudioPieters. (https://opensource.org/licenses/MIT)
*/

int RelaisPin = 0;                // ATTINY85/13A (PB0 / Physical Pin 5)
int PinSeven = 1;                 // ATTINY85/13A (PB1 / Physical Pin 6)
int ButtonPin = 2;                // ATTINY85/13A (PB2 / Physical Pin 7)


boolean OldRelaisState = LOW;     // variable to hold the OLD Relais state
boolean NewRelaisState = LOW;     // variable to hold the NEW Relais state
boolean Relaisstatus = LOW;       // variable to hold the Relais state

void setup()
{
  pinMode(RelaisPin, OUTPUT);     // Set Relaispin as Output
  digitalWrite(RelaisPin, LOW);   // Set Relaispin to LOW

  pinMode(PinSeven, OUTPUT);      // Set PinSeven as Output
  digitalWrite(PinSeven, LOW);    // Set PinSeven to LOW

  pinMode(ButtonPin, INPUT);      // Set Buttonpin as Input
}

void loop()
{
  NewRelaisState = digitalRead(ButtonPin);

  if ( NewRelaisState != OldRelaisState )
  {
    if ( NewRelaisState == HIGH )
    {
      if ( Relaisstatus == LOW ) {
        digitalWrite(RelaisPin, HIGH);    // Set Relaispin to HIGH
        digitalWrite(PinSeven, HIGH);     // Set PinSeven to HIGH
        Relaisstatus = HIGH;
      }
      else                    {
        digitalWrite(PinSeven, LOW);      // Set PinSeven to LOW
        delay(30000);                    // wait for 30 Seconds to shutdown all services on your Pi
        digitalWrite(RelaisPin, LOW);     // Set Relaispin to LOW
        Relaisstatus = LOW;
      }
    }
    OldRelaisState = NewRelaisState;
  }
}
programming the Attiny85

Let’s connect the necessary pins together on both boards.

1 x Arduino Nano (or any Arduino board will do)
1 x ATtiny85
6 x Jumper Wires
1 x Electrolytic Capacitor – 10µF ~ 25V

We need to connect the MOSI, MISO and SCK pins of both boards together (refer to the IC pin out), and Digital Pin 10 of the Arduino Nano to P5 of the ATTiny85.

Connect the following (I am using an Arduino Nano, so you have to take note the necessary pins of the board you are using when using it as an ISP).

Add a 10uF capacitor between RESET and GND in arduino. This is to avoid Arduino Nano from being auto reset when we upload the program to attiny85. If you are using a electrolytic capacitor make sure the anode goes in GND of  Arduino Nano.

 

Arduino Nano ATTINY85
MOSI Digital Pin 11 PB0 (Chip Pin 5)
MISO Digital Pin 12 PB1 (Chip Pin 6)
SCL Digital Pin 13 PB2 (Chip Pin 7)
RESET Digital Pin 10 PB5 (Chip Pin 1)
VCC VCC (5V) VCC (Chip Pin 8)
GND GND GND (Any GND pin)

 

There are two things we need to set up to successfully program the ATTiny85.

INSTALLING THE ATTINY BOARDS

Open the  Arduino IDE Software then go to Arduino > Preferences. You will see Additional Boards Manager URLs. Add this link there, by pressing the rightmost icon. and ad this link:


https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json


Press OK (then another OK to exit from Preferences).

Now, go to Tools > Board > Boards Manager. Type attiny in the search field, and you should see attiny by David A. Mellis. Click it (attiny by David A. Mellis) and install the board. Now, you should see attiny boards from the list when you go to Tool > Boards. Scroll down to verify that the board is indeed installed.

ARDUINO AS ISP

Attach the Arduino Nano to your computer. Go to File > Examples > ArduinoISP, and click on Arduino ISP. Then go to Tools > Boards and select Arduino Nano (or your preferred board). Go to Tools > Port and select the port where your board is connected to. Upload the ArduinoISP sketch to your Arduino Nano (or your preferred board) by going to Sketch > Upload. At this stage, your Arduino Nano is ready to be used as a programmer.


Note: In some cases you need to select Processor : “ATMega328P (Old Bootloader)”

 

UPLOADING SKETCH TO ATTINY85 DEVELOPMENT BOARD

Make sure that the connections are as stated as described here above. Open the program / sketch you want upload to your ATtiny85. Go to Tool and setup the following.

Board: “ATtiny25/45/85”
Processor:  “ATtiny85”
Clock: “Internal 8 MHz”
Port: Select the port where your board is connected to.

Then make sure Arduino as ISP is selected under Tools -> Programmer. By default the ATtiny85 runs at 1MHz. To make it to run at 8MHz select Tools -> Burn Bootloader. Now open the Attiny85 Code from my github here and upload. Your Attiny85 is now ready for use.

 

Python Code

In Python you have two ways to implement this solution – with a while loop or using interrupts. Open Atom text editor and paste in the code from beneath. A later section describes how to load a Python file during the boot process.

Powerunit.py

# Project name: Powerunit®
# Project URI:  https://www.studiopieters.nl/raspberry-pi-power-unit
# Description: Powerunit® - Raspberry Pi® Software package
# Version: 1.0.1
# License: MIT - Copyright 2018 StudioPieters. (https://opensource.org/licenses/MIT)


#!/usr/bin/env python

# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as GPIO
from time import sleep

# Map pin seven and eight on the  Power.Unit͘  PCB to chosen pins on the Raspberry Pi header
# The PCB numbering is a legacy with the original design of the board
PinSeven = 7
           PinEleven = 11
                       GPIO.setmode(GPIO.BOARD) # Set pin numbering to board numbering
                       GPIO.setup(PinSeven, GPIO.IN) # Set up PinSeven as an input
                       GPIO.setup(PinEleven, GPIO.OUT, initial = 1) # Setup PinEleven as output

                       while (GPIO.input(PinSeven) == True): # While button not pressed
                           GPIO.wait_for_edge(PinSeven, GPIO.RISING) # Wait for a rising edge on PinSeven
                           sleep(0.1); # Sleep 100ms to avoid triggering a shutdown when a spike occured


  if (GPIO.input(PinSeven) == True):
    GPIO.output(PinEleven, 0) # Bring down PinEleven so that the LED turn off
    call('poweroff', shell = False) # Initiate OS Poweroff
else:
      call('reboot', shell = False) # Initiate OS Reboot

Obviously the file name Powerunit.py that we used above can be whatever you want it to be, and the folder names and locations are all up to you as wel. You just need to make sure that you maintain these throughout the above locations to make sure this code will function correctly on boot. In the above example we have used physical pin 7 on the GPIO header, which as you can see corresponds to the 4th pin from the right, on the top row (when looking down on the Pi from above, with the RCA video connector socket facing towards you).

Fuction Name Pin Pin Name Fuction
Power 3.3V 1 2 5V Power
SDA1 I2C GPIO2 3 4 5V Power
SCL1 I2C GPIO3 5 6 Ground
GPIO_GCLK GPIO4 7 8 GPIO14 UART0_TXD
Ground 9 10 GPIO15 UART0_RXD
GPIO17 11 12 GPIO18 PCM_CLK
GPIO27 13 14 Ground
GPIO22 15 16 GPIO23
Power 3.3V 17 18 GPIO24
SPI0_MOSI GPIO10 19 20 Ground
SPI0_MISO GPIO9 21 22 GPIO25
SPI0_SCLK GPIO11 23 24 GPIO8 SPI0_CE0_N
Ground 25 26 GPIO7 SPI0_CE1_N
I2C ID EEPROM ID_SD 27 28 ID_SC I2C ID EEPROM
GPIO5 29 30 Ground
GPIO6 31 32 GPIO12
GPIO13 33 34 Ground
GPIO19 35 36 GPIO16
GPIO26 37 38 GPIO20
Ground 39 40 GPIO21

You can change this to use any different GPIO pin, we just chose pin 7 as it is next to physical pin 11 which is the required pin to use for the automatic power supply switching without any additional code. It is additionally possible to add some code to the above to change to a pin other than physical pin 11 for the main automatic power off functionality.

Under-Voltage

If you use the Powerunit͘® with the Raspberry Pi® 3 you may experience under-voltage issues and unexpected power off. In order to solve the under voltage problem it is advisable to use shorter power cable. 15-30 cm with a thickness of 22 AWG should solve the issue. These types of cable are generally the ones used for phone charging and should be easily found in various shops.

Now that my Powerunit® Project – Prototyping phase is done I can go further with the Powerunit® Project – Software phase  of the project in the upcoming blog post.

REFERENCE

Raspberry Pi® (2019), The Raspberry Pi is a tiny and affordable computer that you can use to learn programming through fun, practical projects, https://www.raspberrypi.orgPython™  (2019 )Python is a programming language that lets you work quickly and integrate systems more effectively, https://www.python.org/ PiSupply (DEC 5 2017), Pi-Supply-Switch, Pi Supply Switch On/Off Switch for Raspberry Pi, https://github.com/PiSupply/Pi-Supply-Switch