There are several commercially available solutions on the market and there are quite a number of solutions created by Forum members. I have several designs published as well (just search for paulv). Unfortunately, many of these solutions can be expensive, or use parts most (beginner) forum members do not have, are hard to get, or cannot handle, like tiny, tiny SMD parts.
In the course of a lot of experimenting and trying many things out, I found a very simple and inexpensive solution to the challenge of providing a solid 5V to the Pi Module, and by adding a single button that will allow you to start the Pi, stop it (executing a powerdown command) and then making the Pi powerless.
All it takes are a momentary push button, a few resistors, one capacitor, a Zener diode and optionally an LED. Most of you will have these parts in your stash already, otherwise they are commonly available parts you can get for a few dollars or Euros. The only other components you need is a DC-DC Buck converter, and a little box to put things in. You also need one USB micro cable that has solid power wires. Lastly, you need a DC wall wart that supplies anything from 7V to 40V with a minimum of 1 Amp, better is 2 or more. If you are like me, you will have several of these supplies somewhere. They can come from old routers, USB hubs, modems, even from printers or laptops. These supplies were designed to provide a steady, reliable voltage and current and will most likely have all sorts of filters and safety measures, unlike many phone or pad chargers.
[EDIT: if you have a 5V supply or use batteries, read on down to a specific post for that situation]
We will use a DC-DC Buck converter to reduce the voltage from the supply you have to a steady and precise 5V for the Pi. The Buck converter will also be used to switch the power, and it is important that the converter is based on the LM2596-ADJ chip. Please check that when your ordering this little board. They can be purchased for as little as a few Dollars or Euros, depending on the delivery time you prefer. Here is a picture of such a Buck converter : If you are planning to use an old inkjet printer supply, chances are they supply 38V DC, so look for a Buck converter that can have an input voltage of 40V. The LM2598 can handle this voltage, but the input cap may not. Many input capacitors are rated for 35V, be aware!
You'll also need a really good USB cable to avoid power losses in the cable itself. I personally use several of these: Search for "micro USB power cable DC barrel"
Here is the schematic we're working from: [EDIT: To get more reliable result with various tolerances, R2 and C1 have been changed. This is reflected in the updated schematic and the text of this post]
For the sake of this how-to, we will assume you have a very common 12V DC wall wart or supply. To connect that to our little power board, you can either get yourself a matching DC power barrel connector, or just cut the cable and solder the leads (check for the proper polarity!) directly to the Buck converter.
Before you do anything else, connect your DC supply to the Buck converter and adjust the output level of the Buck converter to a precise 5.1V, or 5V1. Do not omit this step right here right now, or you may fry your Pi.
The Buck converter now needs to be modified so we can used it also as a power switch. This is a little tricky, but not difficult. You need to lift pin 5 of the LM2596 chip from the solder pad on the board. This pin turns the output on or off and we need to attach a small wire to it. This pin is normally connected to ground. Make sure you add some fresh solder and/or solder paste to this pin, so the solder is more fluid when you heat it. You can use a small pair of tweezers, a pen knife or even a little wire looped around the pin to lift the pin while you're heating it. Don't pull on it hard, because you will most likely lift the PCB pad and track with it. If all else fails, you can also cut the pin with a fine cutter, as long as there is enough pin left to solder a wire to it. You can test success by applying power to the board again and connect the pin to something with a voltage that is above 1.5V. This input pin has Logic TTL specifications. However, according to the specification, you can connect it to the input. If you were successful the output should have no voltage, if there is power, you may still have a solder bridge. The chip seems to have an internal pull-down resistor, but according to the TI spec, you should not let it float, but if you do, it does not do anything. If all is well, solder a thin piece of wire to the pin going directly to the chip. To test it once more, attach the other end of the wire to ground, and you should have an output voltage again. Connect the wire to the input and the output should be gone again. This was the hard part.
To supply power to the Pi, you can again use a DC barrel connector, or cut the DC barrel from the USB cable, strip it and solder the leads directly onto the output solder pads of the Buck converter. Make sure you connect the wires correctly to the Buck converter! The other end with the micro USB connector goes to the Pi to power it.
I highly recommend you to power your Pi through the micro USB connector and not through the P1 connector. By doing that you will disable the over-voltage protection of the Pi. When you're working with 5+ voltages anywhere near your Pi, you don't want to take that risk.
Now for the rest of the logic. The design is almost completely independent of whatever you have in your stash of wall warts. You can use just about any voltage between 7V and 40V, just make sure it has the proper wattage or amount of Amps (1 minimum, 2 or more is better).
The voltage coming from the supply goes through a little circuit to reduce the power to a 3V3 level that the Pi GPIO pins can handle safely. We use R8 to create a bias current of 5mA for the 3.3V zener diode, and this is the only component that needs to change based on your supply voltage. For anything from 10 to 15 V, you can use the 1K5 value. The formula for other voltages is in the diagram.
If you only use one particular wall-wart supply, and will not regularly change to other wall-warts (promise to yourself in writing!) that have other voltages, AND you don't have a 3V3 Zener diode, you can use a voltage divider instead. The Zener needs a bias current of about 5mA to produce 3V3. The circuit itself can use less (somewhere between 0.5 and 2mA), and at the same time, is even more safe for the GPIO pins. If you use a 12V DC wall-wart, the total resister value can be 12K to give a current of 1mA (12V / 1mA = 12K Ohm). You can use a 8K2 resistor in place of the 1K5 and use a 3K3 resistor in place of the Zener diode. This will produce a voltage that is about 3V4, which is close enough, and safe. However, BEFORE you connect your precious Pi, measure the voltage at the junction of the two resistors and verify it is indeed somewhere around 3V4, but not more than 4V. If you use another wall-wart voltage, or other resistors, you can use this calculator if you need it : http://www.raltron.com/cust/tools/voltage_divider.asp Using the calculator, plug in your supply voltage, the 3V4 as output voltage and the value of R2, which is 3K3. You'll get a value for R1, just round it to the closest resistor value. You don't need to be ultra precise, just make sure the voltage at the junction is above 3V2 and below 4V0.
The charge resistor R2 and the capacitor C1 need to provide at least about 2V at their junction when fully loaded. This limits the value range of R2, it can't be too high otherwise the voltage will not get high enough. This voltage level is important to pull the Enable pin of the LM2596 high, which will turn the output off.
When you press the button, the voltage across the capacitor and the Enable pin, through R3, a 10K resistor, will go to zero, and start to ramp up when you release the button again, because of R2. The ramp-up needs to be a little longer than it takes for the Pi to boot and to load the overlay, which will activate a low on GPIO-27, the KILL_PWR output. This active low will drive the voltage at the Enable pin close to ground through R6, another 10K resistor. So the KILL_PWR driven by the overlay will take over from the capacitor charge circuit and keep the power on from then onward. (the voltage at the Enable pin needs to be below 1.3V for the LM2596 to turn on). R3 and R6 need to be of the same value, allowing a tug of war for the action at the Enable pin, but not disturb the circuit on the other end so to speak.
This is what I mean with the tug of war at the Enable pin. During the boot process, when GPIO-27 is forced low through the overlay action, the Enable pin will be at about 200mV, because of the pull upwards through R5 and R3 towards 3V3. This is a pull up of about 160K, and will not be strong enough to lift the Enable pin towards a shut-off of the LM2596. It only causes the pin to go to about 200mV. Pressing the button during this period in the boot process will only make the level of the Enable pin to go more towards ground and as such will have no effect.
Towards the very end of the booting process however, our Python program gets loaded, and that will start to watch out for a button press to signal a powerdown request. To make the program recognize this button press, it sets the GPIO pull-up feature on the PI_SHUT_DOWN input. However, this will only add another 50K pull towards the 3V3 level at the button end, which lifts the Enable pin a little higher (to about 500mV) through R5, the 10K resistor. That will still have no effect on the LM2596 output because it is still nowhere near the 1V3 cut-off level.
At the button end however, the internal gpio 50K pull-up, through the protection resistor R9, will force about a 1V level at that junction, such that a push of the button will be recognized by the Python program correctly as a negative edge and a powerdown will start. At the end of that process, GPIO-27 will go high forcing the Enable pin way above the 1V3 level, and the power to the Pi will be cut.
A subsequent press of the button will restart the whole process and since the Pi is powerless, there is no effect on the Enable pin through Either the KILL_PWR signal or the PI_SHUT_DWN pin, so we really start the whole process from scratch again.
In normal situations, with a Pi Model B rev 2, it takes about 3.6 seconds from power-up until the overlay is loaded.
I found that after the latest firmware updates, the activation time went from 3.5 sec to about 5 sec. Depending on the tolerances of R2 and C1, you may want to increase either or both to create an 8 sec. window to be safer from further changes.
To be on the safe side for future changes (nope!) in the boot process, the R2 and C1 values will create a period of about 5 seconds before the power gets cut again. This time is highly dependent on the values of the components, and especially electrolytes (C1) can have tolerances of 20-30%. It is no problem to extend the period to more than 5 seconds, just don't go too close to 3.6 seconds because the Pi may end up without power during the boot process.
To connect the two GPIO pins to our little circuit, I used an old cable from a PC reset or power switch (proper reuse!). They have a nice two-pin connector with the proper spacing, so you can directly push it on the P1 connector of the Pi. I recommend you use GPIO-17 and GPIO-27 because they are next to each other on the P1 connector, and are general purpose pins with no surprises. You can use any GPIO pin you like, just make sure you change the following settings to reflect that. I do recommend you stay away from all the special GPIO pins, to avoid nasty surprises.
How you connect the other parts together depends on your skills and available perf. or prototype board. It should not be hard to connect this all together.
If you want to have an indication that your wall wart is plugged in, I suggest you add R1 and the LED.
When you have finished the hardware, don't connect it yet to the Pi. We need to prepare it first. Boot the Pi and get yourself to the prompt.
There are three things we need to install on the Pi in terms of software.
First open up an editor to modify the configuration file:
Code: Select all
sudo nano /boot/config.txt
Code: Select all
Now we need to add a program that will listen to the button press that signals a stop. We will use GPIO-17 to listen to the button press. In order to do that reliably, we will activate the GPIO pull-up that will allow the program to register a falling edge.
Here is that Python program:
Code: Select all
#!/usr/bin/env python2.7 #------------------------------------------------------------------------------- # Name: Shutdown Daemon # # Purpose: This program gets activated at the end of the boot process by # cron. (@ reboot sudo python /home/pi/shutdown_daemon.py) # It monitors a button press. If the user presses the button, we # Halt the Pi, by executing the poweroff command. # # The power to the Pi will then be cut when the Pi has reached the # poweroff state (Halt). # To activate a gpio pin with the poweroff state, the # /boot/config.txt file needs to have : # dtoverlay=gpio-poweroff,gpiopin=27 # # Author: Paul Versteeg # # Created: 15-06-2015, revised on 18-12-2015 # Copyright: (c) Paul 2015 # Licence: <your licence> #------------------------------------------------------------------------------- import RPi.GPIO as GPIO import subprocess GPIO.setmode(GPIO.BCM) # use GPIO numbering GPIO.setwarnings(False) # I use the following two GPIO pins because they are next to each other, # and I can use a two pin header to connect the switch logic to the Pi. INT = 17 # GPIO-17 button interrupt to shutdown procedure KILL = 27 # GPIO-27 /KILL : this pin is programmed in /boot/config.txt and # cannot be used by any other program # use a weak pull_up to create a high GPIO.setup(INT, GPIO.IN, pull_up_down=GPIO.PUD_UP) def main(): while True: # set an interrupt on a falling edge and wait for it to happen GPIO.wait_for_edge(INT, GPIO.FALLING) subprocess.call(['poweroff'], shell=True, \ stdout=subprocess.PIPE, stderr=subprocess.PIPE) if __name__ == '__main__': main()
Code: Select all
We will use the cron scheduler to start this Python program at boot time.
Start the crontab editor:
Code: Select all
Code: Select all
@reboot sudo python /home/pi/shutdown_daemon.py
Now it's time to test what you've done.
Code: Select all
Code: Select all
This will tell you that Cron has indeed installed the Python program, and it is running as root.2152 ? Ss 0:00 /usr/sbin/cron
2155 ? S 0:00 /USR/SBIN/CRON
2158 ? Ss 0:00 /bin/sh -c sudo python /home/pi/shutdown_daemon.py
2159 ? Ss 0:00 /usr/bin/dbus-daemon --system
2161 ? S 0:00 sudo python /home/pi/shutdown_daemon.py
2166 ? S 0:00 python /home/pi/shutdown_daemon.py
Shutdown the Pi to make it powerless :
Code: Select all
Now it is time to connect the Pi to your new supply and also connect the two GPIO pins on the Pi to your hardware. Check if everything is correct, and plug the wall-wart back into the mains.
The Pi should boot normally. If you only get a momentary power to the Pi, you either made a mistake with the hardware, so check the wiring, or you may have a capacitor that is too far out from the value that I specified. You should be aware that electrolytes can be off by as much as 50%. If in doubt, measure the capacity, or use another one. You can also add a capacitor in parallel to C1 to increase the total capacitance value.
[Look for a post below for some trouble shooting tips if you have a problem with the hardware at this point.]
If your Pi booted up correctly, it's time to test the stop functionality. If you have a monitor connected, you don't need to log in, just press the button and the screen will tell you that the shutdown happened. If you log in through SSH, you'll get a message that the Pi will be halted.
As soon as the Pi is halted, the power will be cut, and you can restart the Pi by pressing the button again.
If everything is working you can now tweak the power supplied to the Pi by measuring the voltage on the Pi PCB (between TP1 and TP2 for classic Pi's or between P1-1 and P1-3) with a DMM. You can adjust the voltage to a precise 5.0V by adjusting the Buck supply and compensate for any losses in connectors and cables.
There are two caveats you need to be aware off with this simple but effective solution. One is that the first time when the power is supplied to the Pi (the wall-wart is plugged into the mains), the Pi will boot automatically. After that first time, the button will function normally.
The second caveat is that you cannot execute a software reboot (sudo reboot), because the Pi will become powerless and you'll have to manually press the button to power it up again.
I hope that this description will be complete enough for you to build this missing functionality for your Pi. Believe me, if you try and test things often on your Pi, you'll be grateful to have this capability.
Enjoy and happy holidays!
PS Here is some more information if you're interested : viewtopic.php?f=37&t=128019