Raspberry Pi Smooth Shutdown
If a Raspberry Pi is frequently shut down by removing its power, it's possible for the SDHC card to become corrupted - the symptoms are that it initially refuses to permanently save changed and new data and then it fails altogether. This describes a way to add a simple Uninterruptible Power Supply (UPS) which gives a few seconds for a proper shutdown to be actioned.
Basic Raspberry Pi Uninterruptable Power Supply
The 5v supply for the Raspberry Pi is fed from a super capacitor, chosen to give several seconds running time after the power is lost - a minimum of about 3 Farads is likely to be required (the actual value depends on the Raspberry Pi version being used). The super capacitor is charged through a low-value resistor which limits the maximum current that the super capacitor can take when it's initially powered. This, in turn, is fed via a diode so that a loss of incoming power can be detected by a GPIO pin which then triggers the shutdown process. (A Schottky diode is used to minimise the voltage drop.)
The UPS components can be combined with a modified USB lead to power a 3G or Wi-Fi dongle (Pi Zero version shown below):
Of course, the USB socket isn't needed if only wi-fi is being used and the Raspberry Pi has a built-in wi-fi adaptor (as in the Pi Zero W or the Pi 3).
This design means that there is no point including power monitoring information in the camera image display because the link dongle will be disabled the instant that the power is lost as the shutdown begins. However, the system's camaction.py can send an email on startup once the power returns, which in some circumstances is broadly equivalent.
A dual opto-isolator can be carefully soldered directly to the Raspberry Pi GPIO header with the second channel being used for a remote trigger input. Pins 5, 6, 7 and 8 of the ILD74 type of opto-isolator (e.g. Maplin YY62) will connect directly to pins 14-16-18-20 of the Raspberry Pi, i.e. GND-GPIO23-GPIO24-GND. No other components are needed because built-in pull-up resistors can be switched on in the Raspberry Pi. The opto-isolator input pins are left pointing upwards ready to take thin wires from the UPS components.
GPIO 24 is used for the UPS. This means that GPIO 24 will be low when the system is operating normally and will rise high when power is lost. This just needs to be detected for the shutdown procedure to be initiated.
A small script is set to start running whenever the Raspberry Pi boots. If GPIO24 goes from low to high at any time then the command sudo shutdown now is issued which starts a smooth shutdown.
and press Enter. Copy and paste the following:
#!/usr/bin/python import RPi.GPIO as GPIO import os import time GPIO.setmode(GPIO.BCM) GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP) def softshut(channel): os.system('sudo shutdown now') GPIO.add_event_detect(24, GPIO.RISING, callback = softshut) while True: time.sleep(1)
Hold down the Ctrl key and press X, then Y, then Enter to save the changes. Make this runnable by typing
and press Enter. Then type
and press Enter. Copy and paste the following after the #fi at the end of the listing:
Hold down the Ctrl key and press X, then Y, then Enter to save the changes. The program will be run the next time that the Raspberry Pi starts up and every time thereafter.
Limitations of the basic approach
While the super capacitor circuit works well to prevent SDHC card corruption (and is all that is needed for a manually switched on/off installation), but where the RPi is permanently powered it can prevent power-on rebooting in some circumstances, as explained below.
When the power fails, there are three scenarios that can arise:
|1||Power returns immediately, within a second or so||The shutdown sequence and reboot is underway and needs to be allowed to complete to avoid data corruption, so the power return must be ignored.||The basic circuit deals with this ok.|
|2||Power returns within a minute or two||The shutdown is complete and the RPi appears ready to be restarted but sufficient voltage (above about 2.2v) may still be available from the super capacitor for some parts of the RPi to remain active which means that the returning power isn’t recognised by the RPi as a signal to reboot.||The RPi fails to reboot.|
|3||Power returns after several minutes||The super capacitor has discharged, the RPi is completely shut down and so a normal power-on reboot is possible.||The basic circuit deals with this ok.|
It might be thought that using the RPi's reset pin (P6) would be the way forward but this only works when the RPi is in particular states - if the power returns while the reset pin is inactive then the reboot fails. For a really universal solution, the power to the RPi needs to be cut momentarily by using a relay.
Automatic reboot version for a permanently-powered installation
This simple add-on circuit uses a 555 to pulse a relay only when the RPi is not running. The power to the RPi is taken through the relay's normally-closed (NC) contacts. To be absolutely certain that the RPi reboots, the reset signal repeats until the RPi is running again, so all eventualities are taken care of, which means that the 555 runs as an astable rather than a monostable.
Component types and values are not critical as long as the relay operates properly and the 555 period is long enough for the RPi to start up and take GPIO 14 high (about a second or so).
Because this version performs a full reset, a cron-driven script can be set up to do a clean restart every night if necessary by issuing a shutdown command at a particular time. Once shut down the 555 will start running and cause a reboot.
Note that when the RPi reboots the event log will be cleared.