How to perform a software shutdown with the Mausberry and the diode/transistor hack?
NOTE: This does only work on momentary switches!
1. Prerequisites
You need to solder a diode (1N400x type 1N4001 or 1N4002) or a transistor (NPN-Type, 2N3904, BC547 or BC337) to the Mausberry on/off switch.
For the diode: Connect it between a GPIO and the mausberry button ground.
The transistors needs to soldered between ground and positive to the switch and the base line is connected to the GPIO (maybe you need a resistor to control current flow)
Therefore I strongly recommand the DIODE hack!
Don't be afraid the Raspberry is in both ways protected against current backdraws! Use the diode or the right direction as shown in the box above....
GPIO MAUSBERRY
from Pie DIODE switch ground
O---------------->|----------------O
1N4002
More to read here
2. Software part
Create gpio-shutoff with sudo nano /lib/systemd/system-shutdown/gpio-shutoff
Enter code from box below
Make the script executable with sudo chmod +x /lib/systemd/system-shutdown/gpio-shutoff
GPIO16 (or PIN 36 ) is just an example here and is my real setup
#!/bin/sh
# Perform Software Shutdown with Mausberry switch
# cyperghost for retropie.org.uk
# This is the GPIO pinconnected to the diode or transistor
GPIOpinDIODE=16
if [ "$1" = "poweroff" ]; then
echo $GPIOpinDIODE > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$GPIOpinDIODE/direction
echo 1 > /sys/class/gpio/gpio$GPIOpinDIODE/value
sleep 0.5
echo 0 > /sys/class/gpio/gpio$GPIOpinDIODE/value
sleep 0.5
fi
3. Software script with proper Reset and Shutdown
This is the full working bash script
Installation:
add it to /etc/rc.local/
add it to /opt/retropie/configs/all/autostart.sh`
whatever case you select make the script executable with chmod +x scriptname.shand add sudo yourscript.sh & to choosen autostart
This script adds:
Working Reset button
1.1 if an emulator is running it will end this
1.2 if ES is running (without emulator) a restart of ES will be made
Working shutdown button
#!/bin/bash
# Mausberry shutdown script v3
#
# extended by cyperghost for
# Yet annother NESPi case
# Tested version 15/01/18
es_action()
{
case $1 in
check)
[[ -f "/dev/shm/runcommand.info" ]] && \
emu="$(sed '4!d; s/\([\\"]\|[[:alnum:]_]\+=[^ ]* \)//g; s/[][(){}^$*.|+? ]/\\&/g' /dev/shm/runcommand.info)" && \
[[ -n "$emu" ]] && emupid="$(pgrep -f "$emu")" && \
rcpid="$(pgrep -f -o runcommand.sh)"
espid="$(pgrep -f "/opt/retropie/supplementary/.*/emulationstation([^.]|$)")"
;;#"
restart_es)
touch /tmp/es-restart && chown pi:pi /tmp/es-restart
[[ -n $emupid ]] && kill $emupid && es_wait $emupid && es_wait $rcpid
[[ -z $emupid ]] && kill $espid && sleep 5
;;
shutdown_es)
touch /tmp/es-shutdown && chown pi:pi /tmp/es-shutdown
;;
esac
}
es_wait() #Wait function for finishing running emulators
{
while [ -e /proc/$1 ]
do
sleep 0.15
done
}
#this is the GPIO pin connected to the duoLed RED
GPIOpinLED=21
#this is the GPIO pin connected to NESPi RESET siwtch
GPIOpinRESET=20
#this is the GPIO pin connected to the lead on switch labeled OUT
GPIOpin1=19
#this is the GPIO pin connected to the lead on switch labeled IN
GPIOpin2=26
#SWITCH LED ON
echo "$GPIOpinLED" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio$GPIOpinLED/direction
echo "1" > /sys/class/gpio/gpio$GPIOpinLED/value
#Initiate RESET
echo "$GPIOpinRESET" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio$GPIOpinRESET/direction
#Initiate MAUSBERRY SWITCH
echo "$GPIOpin1" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio$GPIOpin1/direction
echo "$GPIOpin2" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio$GPIOpin2/direction
echo "1" > /sys/class/gpio/gpio$GPIOpin2/value
power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
reset=$(cat /sys/class/gpio/gpio$GPIOpinRESET/value)
until [ $power = 1 ]; do
power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
reset=$(cat /sys/class/gpio/gpio$GPIOpinRESET/value)
[ $reset = 0 ] && es_action check && es_action restart_es
sleep 1
done
# Power button pressed?
if [ $power = 1 ]; then
es_action check
[[ -n $emupid ]] && kill $emupid && es_wait $emupid && es_wait $rcpid
es_action shutdown_es
kill $espid && es_wait $espid
exit #Give back maincontrol to emulationstation.sh
fi
poweroff
4. Why are you doing this?
The Mausberry gots a little design issue. If you performing a software shutdown (maybe via ES > Shutdown system or via SSH sudo poweroff) the PI will shut down but the Mausberry will stay active (LED is on). Furthermore it won't respond to a power button press anymore - it's stuck! So you have to switch it off completly by removing your wall plug or by resetting the Mausberry.
The diode or transistor just simulates a button press and the Mausberry will properly shutdown ;)
5. Closing words
It would be better to use @meleu's nice shutdown service in addition with the gpio-shutdown in section 1 and 2. The great benefit of this is you don't need to modify any scripts that are part of ES or to edit any script in meleus package.
The button-script is intended to give an example how to perform faster shutdowns (by bypassing sleep timers) and to show the difference between a while-loop with enclousured if-clause in it and a better choosen until-loop with external if-clause ;) - I recommand a script that is python powered ;)
Link to meleus shutdown service is here