SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Mausberry Circuit Script Slowndown

Tue Dec 17, 2013 1:24 am

I have a Mausberry shutdown circuit and I have found the script is adding some resource overhead. My ROMs (NES/SNES) that are heavier hitters (the ones that need the overclock) run slower once it is enabled. If I remove the switch.sh script from /etc, then the performance returns to normal...

Anyone else seen this?

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Re: Mausberry Circuit Script Slowndown

Sat Jan 11, 2014 11:55 pm

I would still like to figure out how to resolve this.

If I killall the script, there is an immediate improvement is speed, So what I would like to know is if it is possible to stop the script when launching a rom, then start it back up when returning to emulation station.

FM81
Posts: 518
Joined: Wed Apr 17, 2013 4:33 pm

Re: Mausberry Circuit Script Slowndown

Sun Jan 12, 2014 8:04 am

SuperSirLink wrote:So what I would like to know is if it is possible to stop the script when launching a rom, then start it back up when returning to emulation station.
Yes, this is possible; but in this case you mausberry-device wouldn't work during emulation! And I think you would have to program this by yourself?
Is this the content of your '/etc/switch.sh'?

Code: Select all

'#!/bin/bash

#this is the GPIO pin connected to the lead on switch labeled OUT
GPIOpin1=23

#this is the GPIO pin connected to the lead on switch labeled IN
GPIOpin2=24

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
while [ 1 = 1 ]; do
power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
if [ $power = 0 ]; then
sleep 1
else
sudo poweroff
fi
done
You can test, if a longer "sleep" gives you better results, you can also play around with the linux-command 'nice' ,,,

But in general a bash-script isn't a good idea for such shutdown-projects:
1. better performance (less CPU-load) you can reach with python-stuff
2. better performance than 1. you can reach with binaries (compiled C-program) in polling mode
3. better performance than 2. you can reach with binaries (compiled C-program) by using interrupts

MfG, FM_81
A: What does the command 'cat /dev/urandom', can you tell me please?
B: Yeah, that's very simple: It feeds your cat with radioactive material!

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Re: Mausberry Circuit Script Slowndown

Mon Jan 13, 2014 1:31 am

I wouldn't mind if it didn't work during emulation. From Emulation Station would be fine...

I tried renice, but that didn't seem to make a difference. The odd thing it according to top, it is not using that much cpu maybe 1-3% on average... I didn't think to change that sleep level, might play around with that and see what happens...

I know enough to be able to tweak some scripts, but not sure I know how to write one completely myself... I am open to any suggestions and learn, as I would love to have the switch work without the performance loss...

Yeah, that's it, though I have mine set to different pins:

Code: Select all

#!/bin/bash

#this is the GPIO pin connected to the lead on switch labeled OUT
GPIOpin1=22

#this is the GPIO pin connected to the lead on switch labeled IN
GPIOpin2=14

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
while [ 1 = 1 ]; do
power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
if [ $power = 0 ]; then
sleep 1
else
sudo poweroff
fi
done

User avatar
Elliott B
Posts: 96
Joined: Thu Jan 09, 2014 11:58 pm

Re: Mausberry Circuit Script Slowndown

Mon Jan 13, 2014 2:17 am

Try using interrupts instead of a while loop, that should use less CPU. There are some threads discussing these two methods, and with some googling, you should be able to find an example script.

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Re: Mausberry Circuit Script Slowndown

Thu Jan 16, 2014 2:46 am

So I have been doing some research/learning on using rpi.gpio interupts and found an example script. I was able to write another small script to read the status of the GPIO ports I am using (22 & 14). I am not sure if it is the most efficient, but it seems to work.

here is what I came up with:

Code: Select all

#!/usr/bin/python

# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
 
# Define a function to keep script running
def loop():
    raw_input()
 
# Define a function to run when an interrupt is called
def shutdown(pin):
    call('poweroff', shell=False)
 
gpio.setmode(gpio.BCM) # Set pin numbering to GPIO numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input

gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200) # Set up an interrupt to look for button presses
 
loop() # Run the loop function to keep script running
If I start the script manually then press the power button, the system halts and powers off. So it appears to work! BUT, if I put an & at the end of the command when starting it, it doesn't seem to be working at all.

Now I am using a non momentary switch wired to the mausberry circuit and port 22 is connected to the "out" on the mausberry board and 14 on the "in". Note sure if that matters or not...

Anyone have any pointers as to what I am missing?

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Re: Mausberry Circuit Script Slowndown

Fri Jan 17, 2014 2:11 am

I think my issue might the the

Code: Select all

raw_input()
used to keep the script running in a loop... Can that not be used to run it in the background?

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Shut down script using RPi.GPIO interrupts

Sat Jan 18, 2014 1:44 am

I think I have a working solution, performance is great and it runs in the background now...

I removed the raw input and assocated function definition...
Using while and time.sleep, I came up with this:

Code: Select all

#!/usr/bin/env python

# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
import time
 
# Define a function to run when an interrupt is called
def shutdown(pin):
    call('poweroff', shell=False)

gpio.setmode(gpio.BCM) # Set pin numbering to GPIO numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input

gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200) # Set up an interrupt to look for button presses
 
# Allows the script to run in a loop
while 1:
        time.sleep(1)
I thought it could still be improved instead of using the time.sleep, which I then came up with this:

Code: Select all

#!/usr/bin/env python

# Import the RPi.GPIO and OS
import RPi.GPIO as GPIO
import os

# GPIO port setup 
GPIO.setmode(GPIO.BCM) # Set pin numbering to GPIO numbering
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Set up pin 22 as an input, pulled down

# Power button event
GPIO.wait_for_edge(22, GPIO.RISING) # Stop script till button released

# Power button action
os.system('poweroff') # action performed on button press
I am still VERY new to python and programing on the RPI, but to me the second seems better... Both give me the same results seemingly...

Are there any errors or bad calls, better way to do this?

User avatar
Elliott B
Posts: 96
Joined: Thu Jan 09, 2014 11:58 pm

Re: Mausberry Circuit Script Slowndown

Tue Feb 18, 2014 2:33 am

I appreciate all your effort developing this script. I'm brand new to Python, but I was able to get it working with one change. I had to set pin 18 (24) high or else the system would never respond to a button press. (I am using board numbering for better cross-system compatibility.)

Code: Select all

# Import the RPi.GPIO and OS
import RPi.GPIO as GPIO
import os

# GPIO port setup
GPIO.setmode(GPIO.BOARD) # Set pin numbering to BOARD numbering
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Set up pin 16 (23) as an input, pulled down
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, 1) # Set pin 18 (24) value to 1

# Power button event
GPIO.wait_for_edge(16, GPIO.RISING) # Stop script till button released

# Power button action
os.system('poweroff') # action performed on button press
Also, I have to hold the button for 1-2 seconds for this to detect it. I wonder why that is. I'm using a momentary switch, if that makes any difference.

ruadrim
Posts: 2
Joined: Wed Apr 17, 2013 2:48 pm

Re: Mausberry Circuit Script Slowndown

Wed Feb 19, 2014 6:28 pm

Hi, I have the momentary script from Mausberry and your python script works perfectly.

Thanks for this!

User avatar
Elliott B
Posts: 96
Joined: Thu Jan 09, 2014 11:58 pm

Re: Mausberry Circuit Script Slowndown

Wed Feb 19, 2014 6:57 pm

How long do you have to press the button for it to register?

dover19
Posts: 3
Joined: Sun Dec 18, 2016 3:07 am

Re: Mausberry Circuit Script Slowndown

Sun Dec 18, 2016 3:09 am

I'm really interested in what you've done here but I'm a little bit confused. You're using python instead of the switch.sh script? How do I go from using the switch.sh script to what you've written?

fdr4prez
Posts: 17
Joined: Fri May 13, 2016 8:06 pm

Re: Mausberry Circuit Script Slowndown

Wed Dec 21, 2016 8:18 pm

dover19 wrote:I'm really interested in what you've done here but I'm a little bit confused. You're using python instead of the switch.sh script? How do I go from using the switch.sh script to what you've written?
You do not install the switch.sh, or remove it if you already have it installed.

You save the new Python script as a .py file, such as switch.py and save it into you home folder.

Then in etc/rc.local you add the following to the end of the rc.local, right above exit 0
python /home/switch.py &

If you don't have Python installed, and/or GPIO support installed, then you will need to do that, too, from the terminal:
sudo apt-get install python{,3}-pip
sudo pip install RPi.GPIO

dover19
Posts: 3
Joined: Sun Dec 18, 2016 3:07 am

Re: Mausberry Circuit Script Slowndown

Wed Dec 21, 2016 9:41 pm

Ok so this doesn't actually replace the script, it's simply a separate python script that stops the first one while an emulator runs?

fdr4prez
Posts: 17
Joined: Fri May 13, 2016 8:06 pm

Re: Mausberry Circuit Script Slowndown

Wed Dec 21, 2016 9:57 pm

No, it replaces the original switch.sh

The new script uses less CPU, so it must have 'fixed' the issue the OP was having.

This was a very old thread, and you can see that there hasn't been any follow up on it in years.

SuperSirLink
Posts: 12
Joined: Mon Nov 25, 2013 2:02 am

Re: Mausberry Circuit Script Slowndown

Sun Apr 02, 2017 12:49 pm

Sorry I have not post here in a while since I have not done much with this since I set it up. I went and updated to the latest version of RetroPie yesterday and found my Mausberry Circuit was shutting down the system shortly after booting with the in/out leads connected to the pins I always used. So something has been changed and reversed, will be playing with this to figure out what is happening...

I see that Elliot B added GPIO lines to set a GPIO output pin, not sure if something changed in the code to require that. They are using a momentary switch where as mine is a toggle (Switch from an NES deck)

But this behavior happens even before I install the script regardless of the position of the switch...

Edit: So I ended up having to add lines to set the other GPIO pin at an output (which is connected to the IN on the Mausberry)... Not sure why, since before I was able to sense a rise and fall using just one GPIO, maybe when updating something changed about this functionality?

Here is my script now:

Code: Select all

#!/usr/bin/env python

# Import the RPi.GPIO and OS
import RPi.GPIO as GPIO
import os

# GPIO port setup 
GPIO.setmode(GPIO.BCM) # Set pin numbering to GPIO numbering
GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Setup GPIO6 as an input, pulled downsude
GPIO.setup(5, GPIO.OUT) # Setup GPIO5 as an output 
GPIO.output(5, 1) # Setup initial value of GPIO to 1

# Power button event
GPIO.wait_for_edge(6, GPIO.RISING) # Stop script till button released

# Power button action
os.system('poweroff') # action performed on button press
I also changed my GPIO connections to 5 (Mausberry IN) and 6 (Mausberry OUT) since I am on a Pi 3 and no longer need to use the passthrough pins on my Petrock GPIO adapter...

Also for those who come across this and are interested, I am running this script via another script that runs as a service...

Code: Select all

#!/bin/sh

### BEGIN INIT INFO
# Provides:          powerbutton.py
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Power Button Listen Script
# Description:       Service that runs /usr/local/bin/powerbutton.py Python script to watch GPIO pins.
### END INIT INFO

# Change the next 3 lines to suit where you install your script and what you want to call it
DIR=/usr/local/bin/
DAEMON=$DIR/powerbutton.py
DAEMON_NAME=powerbutton

# This next line determines what user the script runs as.
# Root 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 --chuid $DAEMON_USER --startas $DAEMON
    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
service script goes in /etc/init.d
power button script goes in /usr/local/bin

make both executable using chmod
add symbolic links to /etc/rc?.d by running

Code: Select all

sudo update-rc.d /etc/init.d/nameofservicescript.sh defaults
Runs as expected now at startup and just as little overhead as before...

Return to “Python”