RPi Timed UPS - No more corrupt cards from power failure!

This is just in design stage so far. Here’s how it works…

A 17 volt supply is used to power the entire system and keep a 9.6 volt 2200mAh battery monitored via a MAX712 smart charging IC with power pass through. A PTN78020WAH 5 volt 6 amp regulator module powers the board and up to two Raspberry Pi’s. An ATTINY26 AVR Microcontroller runs the show. A 20X2 LCD displays battery percentage and the minutes set for the timer.

When the power goes out a selectable timer starts (from 5 minutes to an hour). The LCD displays battery life and shows a count down of the timer. If power is returned before the timer expires, the LCD resets and the Pi happily runs along as if nothing happened. Otherwise the AVR triggers an opto-coupled (isolated) switch between GPIO 3 and Ground (pins 5 & 6) to initiate a bit of code on the Pi that shuts down the Pi safely. In another 20 seconds, power is cut to the Pi and the batteries preserving them until power is restored.

When power is returned, the Pi powers up and the batteries begin the charging process and everybody is happy that no micro SD cards were harmed that day.

TINY26 operations flowchart:

Cut-off above text is:
System Standby
Waiting for Power

How to do a safe shutdown via GPIO:

Create a folder called GPIO3 in the /home/pi directory.
Copy shutdown5.sh to GPIO3
In the GPIO3 folder, create a folder called shutdown5
Copy shutdown5.py to the shutdown5 folder
In terminal, type the following and enter:

cd /home
cd pi
cd GPIO3
cd shutdown5
chmod 755 shutdown5.py
cd …
chmod 755 shutdown5.sh
sudo cp shutdown5.sh /etc/init.d
sudo /etc/init.d/shutdown5.sh start

Your service should now be running.
You can check the status with this:

/etc/init.d/shutdown5.sh status

You can also stop the service with:

sudo /etc/init.d/shutdown5.sh stop

To autorun on start-up type:

sudo update-rc.d shutdown5.sh defaults

Ground pin 5 (GPIO 3) with pin 6 (GND) and the Pi will safely shutdown. This is especially great for headless units running a NAS, web server or anything that you want corruption free.


shutdown5.sh contents


[code]#!/bin/sh

BEGIN INIT INFO

Provides: shutdown5

Required-Start: $remote_fs $syslog

Required-Stop: $remote_fs $syslog

Default-Start: 2 3 4 5

Default-Stop: 0 1 6

Short-Description: Safe Shutdown operation

Description: By shorting GPIO 3 (pin 5) to GND, the Pi will perform a safe shutdown.

END INIT INFO

Change the next 3 lines to suit where you install your script and what you want to call it

DIR=/home/pi/GPIO3/shutdown5
DAEMON=$DIR/shutdown5.py
DAEMON_NAME=shutdown5

This next line determines what user the script runs as.

Root is generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.

DAEMON_USER=root

The process ID of the script when it runs is stored here:

PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
log_daemon_msg “Starting system $DAEMON_NAME daemon”
start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER $
log_end_msg $?
}
do_stop () {
log_daemon_msg “Stopping system $DAEMON_NAME daemon”
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}

case “$1” in

start|stop)
    do_${1}
    ;;

restart|reload|force-reload)
    do_stop
    do_start
    ;;

status)
    status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
    ;;
*)
    echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
    exit 1
    ;;

esac
exit 0[/code]


shutdown5.py contents


[code]#!/usr/bin/env python2.7

script by Alex Eames h t t p ://RasPi.tv/

h t t p ://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio

import subprocess
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

GPIO 3 (pin 5) set up as input. It is pulled up to stop false signals

GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)

now the program will do nothing until the signal on port 3

starts to fall towards zero. This is why we used the pullup

to keep the signal high and prevent a false interrupt

try:
GPIO.wait_for_edge(3, GPIO.FALLING)

subprocess.call(['shutdown -h now "System halted by GPIO action"'], shell=True)

except KeyboardInterrupt:
GPIO.cleanup() # clean up GPIO on CTRL+C exit
GPIO.cleanup() # clean up GPIO on normal exit[/code]

Looks like a decent solution to the corruption issues from power failures!

Yes, and if I can get enough interest, I’ll try to mass produce.

This is especially great for headless units running a NAS, web server or anything that you want corruption free.