GPIO button to exit emulator
-
Hello coders out there. I just got a nespi case and and want to use the reset button to act just like the reset button on the real nes classic. Just exit the emulator or program running and go back to ES. First thing connecting the button. Do just run it from a GPIO pin to ground? so when i press it, it shorts the pin to ground. Will that work?
second @meleu and @cyperghost. I like how the script you guys built to exit the emulators and then shut down, I would like some help to write a script that reads this gpio and then just does the first part of the other script without the exit emulation station and shut down. Or if you guys, or anyone else, have any another other suggestions? -
@lostless
I think the GPIO part is yours or annother user will help - but you can copy and paste the coding parts out of the shutdown scripts. The part posted above will just terminate the emulator. Maybe you can remove sleep part to get quicker response to ES.AFAIK you can direclty connect 3,3V to set high level to GPIO but it's better to use resistors to get a clean signal... (therefore the name PullUP/PullDOWN - resistor) and to check the change from HIGH-level to LOW-level by action. Because a change from LOW to HIGH can also be triggered by touching GPIO or via radiation caused by your mobile (afaik!)
#!/bin/bash # Terminate any emulatorcall! # This works just for RetroPie! emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.')" if [[ -n "$emucall" ]]; then emupid="$(pgrep -f "$emucall")" pkill -P "$emupid" kill "$emupid" sleep 4 fi
-
Just to follow up on the GPIO question.
There are a few things you'll want to do to get the button working properly/safely.-
In software, configure your GPIO pin as an input.
-
Either physically connect a resistor from your GPIO pin to 3.3V
OR
Configure (in software) your GPIO pin to use it's internal pull-up resistor. -
Connect your button from the GPIO pin to ground.
Notes:
- You definitely don't want to connect directly from the GPIO pin to 3.3V. If you do this, then pressing the button will create a short-circuit path from 3.3V to ground. That might damage your pi or cause the power to cycle or some other nastiness... or the 3.3V output might get current limited to the point of being harmless, but it's best not to tempt fate ;)
- In case you're wondering about that connection to 3.3V, it's there to make sure the GPIO has a well defined value when the button isn't being pressed. It needs to be 3.3V (i.e. 'high') so that when the button is pressed (GPIO connected to ground), there's a clear transition from high to low on the pin
- If you decide to hook up your own external resistor, the resistance value isn't too important. The bare minimum would be around 100 ohms, but it'd be much better to use 1000, 10000 or even 100000 to cut down on the current draw (just don't go too much higher or it starts looking like an open circuit and you can get some finicky behaviour)
- If you happen to be using pin 5 (a.k.a BCM pin 3, see here) it seems to enable it's pull-up resistor by default so you can skip that part. I'm not sure if any other pins do that though (if you try it on an already enabled pin, you get a little print out message, so it's mostly harmless)
As far as configuring the pins (set to input and pull-up enable) in software, I'm not sure how to do it with bash scripting, though I think it's possible. It's very easy to do with python (using RPi.GPIO library) but then I don't know bash well enough to understand the parsing done in cyperghost's script to find running emulators, so I can't really convert that part to python for you. However, here's the basic structure of a python script which configures a GPIO pin and sets it up to run a function ('interrupt_resetBtn') when the button is pressed (though missing the code to detect/end running emulators):
import RPi.GPIO as GPIO import time # Define which pin you're using for the reset button (change this to whatever pin you use) resetBtn = 7 # Use 'board' pin numbering (i.e. the zig-zaging numbering scheme) GPIO.setmode(GPIO.BOARD) # See: https://pinout.xyz/ for the pin layout # Set the resetBtn pin to an input and enable the pull-up resistor GPIO.setup(resetBtn, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Define a function which will be called when your reset button is pressed def interrupt_resetBtn(channel): # Print indication to console print "You pressed the reset button!" # Code for detecting/ending an # emulator would go here # Enable reset button interrupt to trigger on a falling edge (i.e. high-to-low transition) GPIO.add_event_detect(resetBtn, GPIO.FALLING, callback = interrupt_resetBtn, bouncetime = 1000) # -------------------------------------------------------------------- # Now just wait forever for the user to press a button # The sleep time doesn't really matter, make it long enough so it isn't wasting cpu cycles while 1: time.sleep(5)
You'd want to save that as a python file (i.e.
resetbutton.py
) somewhere on your pi and then add an entry to your /etc/rc.local file to have it run on startup in the background:python /path/to/the/python/file/resetbutton.py &
Edit:
If you get really stuck trying to setup the GPIO pins with bash, you could have the python script call cyperghost's bash script to check/end running emulators. -
-
@heyoeyo @cyperghost Thank you you 2. I have a fully working reset switch. And at the same time learned something. (Dang you Raspberry PI foundation and wanting to teach about computers. All i wanted to do is play games LOL)
so I ended up using this python script with @cyperghost bash shell file and it works. Ended up using this python command.# Code for detecting/ending an # emulator would go here import os os.system('/home/pi/exit.sh')
The only issue I have is if i press the button in the terminal on the pi, it just sticks and never gives me control back of the terminal. Is there and "exit" command or something i'm missing or is is that just how python takes controll?Edit: Never mind. just had to press enter and "BOOM" exit. LOL
-
-
@cyperghost well I will thank @meleu as well. I know he did that snipit. So thanks to all 3 of you 👍🏻
-
Just to summarise to see if I do this correctly:
#!/bin/bash # Terminate any emulatorcall! # This works just for RetroPie! emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.')" if [[ -n "$emucall" ]]; then emupid="$(pgrep -f "$emucall")" pkill -P "$emupid" kill "$emupid" sleep 4 fi
- create directory home/pi/scripts
- Create 'resetbutton.py'
- Paste or type into resetbutton.py:
import RPi.GPIO as GPIO import time # Define which pin you're using for the reset button (change this to whatever pin you use) resetBtn = 29 # Use 'board' pin numbering (i.e. the zig-zaging numbering scheme) GPIO.setmode(GPIO.BOARD) # See: https://pinout.xyz/ for the pin layout # Set the resetBtn pin to an input and enable the pull-up resistor GPIO.setup(resetBtn, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Define a function which will be called when your reset button is pressed def interrupt_resetBtn(channel): # Print indication to console print "You pressed the reset button!" # Code for detecting/ending an # emulator would go here import os os.system('/home/pi/exit.sh') # Enable reset button interrupt to trigger on a falling edge (i.e. high-to-low transition) GPIO.add_event_detect(resetBtn, GPIO.FALLING, callback = interrupt_resetBtn, bouncetime = 1000) # -------------------------------------------------------------------- # Now just wait forever for the user to press a button # The sleep time doesn't really matter, make it long enough so it isn't wasting cpu cycles while 1: time.sleep(5)
-
add an entry to your /etc/rc.local
-
test with:
python /home/pi/scripts/resetbutton.py &
and it should run right?
I seem to get this error:
-
@kalidor
Well ... read your text on your first point again!I think you have problems with user rights because this will end in a permission denied messagePlease update the
emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.')"
withemucall="$(sed '4!d; s/\([\\"]\|[[:alnum:]_]\+=[^ ]* \)//g; s/[][(){}^$*.|+? ]/\\&/g' /dev/shm/runcommand.info
EDIT: LOL
please make exit.sh executablechmod +x exit.sh
what does happen you run
./exit.sh
if a emulator is running? Does it exit? -
-
-
I know this topic is old. Has there been any updates to this procedure? I'm looking to do this exact same thing on my own build but I have one minor (major?) difference. I'm using an Odroid XU4. From their wiki I have determined the pin I want to use. I have a wire which I will connect to the pin when ready. The part I'm not sure about is the script for the exit. It says it only works with RetroPie. Is this 100% true or will it work on the THERA build (simply put, it's an "almost" 1:1 copy with some paths changed (pigaming vs pi and RetroArena vs RetroPie). I know how to make these changes in the scripts. I'd just like to know if anybody has done this with the XU4 yet and if the method presented here works.
-
@hansolo77 you can take a look to my github there I've an exit script for Xu4 and its OTG case
-
@cyperghost said in GPIO button to exit emulator:
@hansolo77 you can take a look to my github there I've an exit script for Xu4 and its OTG case
You always pull through! :) I'll take a look at it soon. Thanks!
-
@cyperghost thanks for this, think this is exactly what I need to get my reset button working.
Total noob question - where/how do I add the code from the reset button script?
I have a custom n64 case for my odroid xu4 (running theRA) and think I have the power button figured out...but still trying to figure out the reset button (which would be wired to a gpio pin) that when pressed, would exit whatever rom I'm in.
-
@3drinksahead I add the button code always to
/opt/configs/retropie/autostart.sh
just before theemulationstation #auto
line.For the ODROID you can use this script here. The script supports command line inputs for gpio button as default (for the OGST case pin 24 is assigned as reset button)
So a possible autostart would look like this (please don't forget the &-sign!)
# Start Resetbutton code /home/pigaming/scripts/button.sh & # Emulationstation emulationstation #auto
-
@cyperghost so just to play back the entire process (again very new to all this so assume I know nothing)
-
create directory home/pigaming/scripts
(How do I do this?) -
Create 'button.py'
(Again, how do I do this?) -
Paste or type your script into button.py
4 . Edit /opt/configs/retropie/autostart.sh by adding your "Start Resetbutton code...." above the emulationststion autostart line
Is that right?
-
-
@3drinksahead Step by step
mkdir $HOME/scripts
cd $HOME/scripts
wget https://raw.githubusercontent.com/crcerror/XU4-ORA-scripts/master/reset_button.sh
chmod +x reset_button.sh
nano /opt/configs/retropie/all/autostart.sh
- add the line
sudo $HOME/scripts/reset_button.sh &
above the line of emulationstation
I'm not sure if the pathes in pt. 5 are correct. I sold my XU4 a few weeks ago.... So I can't recheck. The XU4 and the OGST case was fine but the Raspberry is the better supported platform.
-
@cyperghost thanks. Followed the above steps (the path for step 5 where the autostart.sh file is was "...configs/all...")
But now when I start up, when emulationststion boots, I get the repeating message "cat: /sys/class/gpio/gpio24/value : No such file or directory"
Thoughts?
-
@3drinksahead Sorry my bad the line should be
sudo $HOME/scripts/reset_button.sh &
you need sudo command for exporting the GPIOs. I corrected the "guide" from posting above.
-
@cyperghost thanks for the quick replies, but now emulationstation continuously reboots with the message "terminated" popping up, without me pressing my reset switch.
To confirm, I have the reset switch hooked up to gpio #24 (using the zig-zagging naming convention,so 4th from the end) and one of the ground pins.
FWIW I tried removing the switch and am still getting the same effect where emulationstation is auto terminating
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.