Introduction
This project will describe how to create a power switch for your Raspberry Pi (any version) that safely shuts your R-Pi down with the press of a button and then cut power to the R-Pi. Then, to start the R-Pi back up again, press another button right next to it. Pretty cool, right?
It should be stated that this is not my original idea or design, and I would like to attribute the original creator of the circuit but sadly I can not find their blog anymore. However, I do have a picture that I saved from the blog, which I'll display below. Whoever you are, thank you for creating the original design! You are awesome!
The original circuit diagram. |
The purpose of recreating the circuit and blog post is that I've made some improvements to the project overall. In light of the fact that this idea was not my own, I will be open sourcing everything, including all circuit diagrams and PCB designs. Feel free to download them, edit them, and make them your own!
A quick warning about this project is that I have tested this circuit with my own R-Pi with a prototype board I threw together myself and it works perfectly fine, but I have not actually tested the finalized PCB produced by EasyEDA yet, so I have no idea whether it works for sure or not (I'm fairly certain it will work, but I can't guarantee that it will work, so use at your own risk!). Once I order the PCB and test it myself, I will come back and update this post.
The Circuit
Another reason for recreating the circuit diagram was that the original image was very small and a little pixelated, so I have provided a much larger image for download that is easier to see.
The new circuit diagram. |
As you can see, I have used the software called EasyEDA to design this diagram (and the PCB as well). The files will be available in EasyEDA source code, as a PNG image, and a PDF file. The Gerber file and other files will be available as well, but I'll get into that later.
Now, I am certainly no expert at laying out a circuit diagram (or PCB layout, as you'll see later), so I apologize if it's a little strange looking. It's a fairly simple circuit; one tactile switch, when pressed, turns on the relay that supplies the 5 volts for the R-Pi and simultaneously starts charging up the capacitor that keeps the relay engaged. When the second tactile switch is pressed, it begins discharging the capacitor as well as sending a 3.3 volt logic level signal to the R-Pi that lets the Pi know it should begin shutting down. The capacitor stays charged for long enough that the R-Pi is able to shut down safely before the cap runs out of charge and switches the relay off. This is an oversimplification of exactly how the circuit works (I really didn't mention the role the transistors play), but it's enough to get a basic understanding.
From here, you can certainly solder everything together on a prototype board and begin using it with your R-Pi, however if you are interested in the PCB, continue reading to the next section. If not, skip ahead to "The Code" section.
Downloads
- EasyEDA Source Code, JSON, 35.1KB
- Circuit Diagram, PNG, 119KB
- Circuit Diagram, PDF, 42.2KB
The Board
The PCB design was not really planned out in any specific way, and I kind of just laid it out how I thought it looked good to me. You can see a 3D preview of it below.
The old 3D preview of the unpopulated PCB with no screw holes. |
The new 3D preview, with the screw holes. |
The board is designed to take 5 volt power in from a micro-B USB socket, which both powers the circuit and the R-Pi. The output is a standard female USB connector that the R-Pi plugs into. To interface with the R-Pi, there is a 1x2 header pin that can be used to connect to the Pi with jumper wires or something similar. When you build this yourself, you can choose to leave out the header altogether and solder wires directly to the board.
The PCB layout in EasyEDA showing the front traces (red), the rear traces (blue), the pads (gray), and the silk screen (yellow). |
Above is an image of the PCB being laid out in EasyEDA, which I'm not sure if you'll find useful, but I decided to include it anyways. One reason I included this image is to mention that I did not route these traces myself, I used the autorouter. I know, I know!! Blasphemy! However, it appears to have done the job well enough for this PCB. If something looks incorrect or janky to you, don't blame me, blame EasyEDA's autorouter! (I would like to hear about how the traces could be better routed in the comments, this is my first PCB ever!)
Anyways, everything you might need for this board is below, including the Gerber file.
Downloads
- Fabrication (Gerber) File (NO screws), ZIP, 16.7KB
- Fabrication (Gerber) File (With screws), ZIP, 17.1KB
- Bill of Materials, CSV, 1.49KB
- PCB Layout (NO screws), PDF, 58KB
- PCB Layout (NO screws), PNG, 180KB
- PCB Layout (With screws), PDF, 59.4KB
- PCB Layout (With screws), PNG, 197KB
The Code
The code has also been adapted and rewritten from the original, but I don't have the original code unfortunately. This code was written in Node.js (of course, what else would I write it in?), but if you have the skills you can adapt this code to any language that can interface with the R-Pi's GPIO pins. Without further ado, here's the code below.
var Gpio = require('pigpio').Gpio; var exec = require("child_process").exec; var input = new Gpio(4, { mode: Gpio.INPUT, pullUpDown: Gpio.PUD_DOWN, edge: Gpio.FALLING_EDGE }); var output = new Gpio(2, {mode: Gpio.OUTPUT}); output.digitalWrite(1); input.on('interrupt', (level) => { exec('sudo shutdown -h now', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log('Shutting down now!'); }); });
You may need to edit the code if you decide to use different pins than I chose to use, which are
Once you have downloaded the code and its dependencies (Wiring-Pi) to your R-Pi, all you need to do is make the script run at startup, by adding the following line to a new line in your rc.local file:
sudo node /path/to/softshut.js &
Next up, it's time to put it all together.
Downloads
- softshut.js, JS, 479B
Putting it All Together
Once you have your board soldered and put together, it is time to hook it up to your Raspberry Pi. Plug in the micro-B USB cable from your power adapter to the input on the board, then plug in another USB cable from the output to your R-Pi power input. Next, connect the pin on the board labeled "Input" to the R-Pi GPIO pin that will be acting as the output in the script, and then connect the pin labeled "Output" to the R-Pi's pin that will be accepting an input.
Now, press the "On" button and see if it boots up! You will hear the relay click the instant you press the on button. Wait for the R-Pi to fully boot, then try pressing the "Off" button. If the Pi does not immediately start its shutdown sequence, then you've got a problem! If this is the case, enter the shutdown command to your R-Pi as quickly as you can, as the capacitor will have started draining and the relay will switch off the power to your R-Pi soon. Something is wrong with either your script not starting up correctly, or maybe the pins are assigned incorrectly, or something along those lines. You'll need to do some troubleshooting to figure out exactly what went wrong!
Conclusion
All in all this is a very useful addition to just about any Raspberry Pi project, especially with projects that are battery powered! I really wish something like this was built into the R-Pi already, but it makes sense why it wasn't included when you consider the fact that the Raspberry Pi was engineered to be as cheap as possible.
Like I said, I will be coming back and updating/refining this post as I go, but I wanted to publish it as soon as possible, just to get it out into people's hands.
This project will also be available on GitHub once it is finalized, so stayed tuned!