RetroPie forum home
    • Recent
    • Tags
    • Popular
    • Home
    • Docs
    • Register
    • Login

    Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches

    Scheduled Pinned Locked Moved Projects and Themes
    nespinespi casemausberrycyperghost
    57 Posts 6 Posters 18.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cyperghostC
      cyperghost @lostless
      last edited by

      @lostless But I think you have to stick to Python. Can you post code please?

      lostlessL 2 Replies Last reply Reply Quote 0
      • lostlessL
        lostless @cyperghost
        last edited by

        @cyperghost i will when i figure out whats wrong with my code and why it stopped working. could be something simple as permission issues.

        1 Reply Last reply Reply Quote 0
        • lostlessL
          lostless @cyperghost
          last edited by lostless

          @cyperghost @day
          ok, come to find out, you don't need to feed the gpio 3V. setting it as a pullup automatically sets it to 3.3V, I guess? its working! so new image of final. 0_1507845132488_IMG_0115.jpg
          now for the scripting. i want to thank @Heyoeyo for this and helping me understand a tad bit of python. Im using pin 32 so thats been made. change the pin to whatever one you're using. The file is in the home folder called reset.py

          import RPi.GPIO as GPIO
          import time
          import os 
          
          # Define which pin u're using for the reset button (change this to whatever pin you use)
          resetBtn = 32
          
          
          # 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
                  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)
          

          so this just calls for a shell script called exit.sh i made in the home folder. thanks to @meleu for this. (What would do without him?)

          # Terminate any emulatorcall!
          # This works just for RetroPie!
          emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.' | sed 's/[^ ]*=[^ ]* //g')"
          # If there's an emulator running, we need to kill it and go back to ES
          if [[ -n "$emucall" ]]; then
              emupid="$(pgrep -f "$emucall" | tr '\n' ' ')"
              pkill -P "$(echo $emupid | tr ' ' ',')"
              kill "$emupid"
              wait "$emupid"
              sleep 5 # maybe it can be lesser
          fi
          

          this needs to be made executable, if you called the file exit.sh

          sudo chmod +x /home/pi/exit.sh
          

          now add to /etc/rc.local

          python /home/pi/reset.py &
          

          right before
          exit 0
          reboot andnow the reset can be used to exit back to es. if you want to make reset do something else, remove the

                  import os
                  os.system('/home/pi/exit.sh')
          

          and put in the code you want it to do.

          J 1 Reply Last reply Reply Quote 1
          • lostlessL
            lostless
            last edited by

            This is my mauseberry custom script that seems to be working. Im starting to actually understand this scripting stuff. Thanks to @meleu and @cyperghost and tad bit of me piecing this together form their scripts.
            so edit the /etc/switch.sh file after installing the mauseberry driver.

            #!/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
            
            # End Emulationstation if condition of running binary is true 
            # Thanks @meleu and @cyperghost for 99.9999999999999% of this
            # Edited by @lostless
             
            
            espid="$(pgrep -f "/opt/retropie/supplementary/.*/emulationstation([^.]|$)")"
            # Terminate any emulatorcall!
            # This works just for RetroPie!
            emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.' | sed 's/[^ ]*=[^ ]* //g')"
            # If there's an emulator running, we need to kill it and go back to ES
            if [[ -n "$emucall" ]]; then
                emupid="$(pgrep -f "$emucall" | tr '\n' ' ')"
                pkill -P "$(echo $emupid | tr ' ' ',')"
                kill "$emupid"
                wait "$emupid"
                sleep 5 # maybe it can be lesser
            fi
            
            if [ "$espid" ]; then
               touch /tmp/es-shutdown && chown pi:pi /tmp/es-shutdown
               kill $espid
               exit
            fi
            # End Emulationstation if condition of running binary is true (v1.56)
            
            sudo poweroff
            fi
            done
            

            If anyone has ideas on how to improve this. Im all ears.

            meleuM caver01C 2 Replies Last reply Reply Quote 0
            • meleuM
              meleu @lostless
              last edited by

              @lostless said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

              If anyone has ideas on how to improve this.

              yes. Use a proper indentation! ;-)

              • Useful topics
              • joystick-selection tool
              • rpie-art tool
              • achievements I made
              1 Reply Last reply Reply Quote 0
              • lostlessL
                lostless
                last edited by

                @meleu oh forgive for my archaic organizational skill. Be kind I’m new to this. At least I got this far. Lol 😂

                meleuM 1 Reply Last reply Reply Quote 0
                • caver01C
                  caver01 @lostless
                  last edited by caver01

                  @lostless said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                  If anyone has ideas on how to improve this. Im all ears.

                  I highly recommend shifting this more complicated script over to a simplified python script (which uses efficient GPIO edge detection instead of a BASH sleep/wait loop) in conjunction with @meleu's shutdown service (with updated kill process code as needed).

                  This solution @meleu's service idea takes everything that has been learned about killing emus and closing ES to save metadata and makes it into a generic script that runs no matter what is doing the shutdown. In other words, it is no longer tied to a "mausberry" script. Anything can call a shutdown and the service will trigger the proper kill commands. Then, with the complex stuff out of the way, your mausberry script can either revert to the original BASH script, or can be switched to python for more efficiency/less burden on the CPU. Performance gains are probably minimal.

                  This has a certain elegance, as it is switch-agnostic.

                  My 4-player cocktail style cabinet built as a custom "roadcase"

                  1 Reply Last reply Reply Quote 1
                  • meleuM
                    meleu @lostless
                    last edited by

                    @lostless said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                    @meleu oh forgive for my archaic organizational skill. Be kind I’m new to this. At least I got this far. Lol 😂

                    Hey bro, no need to apologize. I'm glad if I can inspire people to code. That was just an idea for improvement, as you requested. ;-)

                    • Useful topics
                    • joystick-selection tool
                    • rpie-art tool
                    • achievements I made
                    lostlessL 1 Reply Last reply Reply Quote 0
                    • lostlessL
                      lostless @meleu
                      last edited by lostless

                      @meleu I was hoping the sarcasm came though. I guess with English as your second language, it gets lost in translation. I’m not apologizing and I very much appreciate you and your desire to teach peoel. You have probably taught me more than any one else here. So keep it up.

                      meleuM 1 Reply Last reply Reply Quote 1
                      • meleuM
                        meleu @lostless
                        last edited by

                        @lostless
                        By the way, that emulator kill script is still not as strong as I want to make it to be. If more changes come to how runcommand invoke the emulators the script can fail to kill the emu... I'll try to make it stronger and then post the solution on that thread @caver01 linked.

                        Cheers!

                        • Useful topics
                        • joystick-selection tool
                        • rpie-art tool
                        • achievements I made
                        1 Reply Last reply Reply Quote 1
                        • J
                          jmcfsu13 @lostless
                          last edited by

                          @lostless I had said before that you didnt need to add the 3v and you disagreed lol. but after you did I did research and although it is not required it is recomended. The pullup in the pie software isnt reliable according to the interwebs and to be safe you should keep your circuit how it was

                          lostlessL 1 Reply Last reply Reply Quote 0
                          • lostlessL
                            lostless @jmcfsu13
                            last edited by lostless

                            @jmcfsu13
                            I’m learning here. Most my knowledge is trial and error with research when I get stuck. But what do you mean by unreliable? What issues have others had? All that I can think of is possibly giving the gpio a more solid 3.3 v to work with?

                            cyperghostC 1 Reply Last reply Reply Quote 0
                            • cyperghostC
                              cyperghost @lostless
                              last edited by

                              @lostless said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                              @jmcfsu13
                              I’m learning here. Most my knowledge is trial and error with research when I get stuck. But what do you mean by unreliable? What issues have others had? All that I can think of is possibly giving the gpio a more solid 3.3 v to work with?

                              unreliable means that the GPIO - if it is unpowered is in a floating state.
                              If you wait for signal on this GPIO to get high than this can be caused by radiation by your mobile, electrostatic stroke if you touch one of the Pie components....

                              The most relieable method (afaik) is to power the GPIO with 2.5-3.3V to get a high signal and wait for it's state changing to 0 by pressing the button ;)

                              lostlessL 1 Reply Last reply Reply Quote 0
                              • lostlessL
                                lostless @cyperghost
                                last edited by

                                @cyperghost from what I’ve experiened, GPIO is actually powered with 3.3v From inside the pi’s GPIO pin if pull up is turned on and it turns on an internal software resistor. It still needs to be pulled down to trigger the low. All that adding the other 3.3v is to lower the current though the GPIO pin as far as I can tell.

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Heyoeyo
                                  last edited by Heyoeyo

                                  Very cool! Makes me want to get a proper case for mine.

                                  Just to chime in on some of the questions/comments:

                                  Pull-up resistors:

                                  • If you configure a GPIO pin as an input and only connect a button, (no internal/external pull-up resistor) then the pin will be 'floating' until the button is pressed (i.e. it doesn't have a definite value). This means you'll get erratic signals on the pin, which will probably be misinterpreted by the pi as high-to-low and low-to-high transitions. So you might end up rebooting/shutting down your pi just by waving your hand near it.
                                  • The internal pull-up should connect a resistor (internally) from the specified GPIO to 3.3v as @lostless says. It's the same as wiring your own external resistor, it's just there to save you the hassle because it's such a common thing to do. I believe the pi also has internal pull-down resistors if you feel like flipping the circuit upside down :p
                                  • I don't know anything about the reliability of the internal pull-ups, but the situation @cyperghost is describing is exactly what you'd expect from a pin without pull-ups, so if they were enabled and it stills does that, I'd agree that they're unreliable! The main benefit of an external resistor is that it's something you can see and test, so it's definitely an option worth considering.
                                  • Enabling the internal resistor and having an external resistor increases the current draw of the circuit (you're drawing current through 2 resistors in parallel instead of 1). This isn't much of an issue if you use a big enough external resistor and the benefit is that you get an added bit of redundancy in case one resistor fails.
                                  • @lostless in the reset button wiring diagram you posted (with a 10k and 1k resistor), having that 1k resistor means the pin will only drop to 0.09V instead of fully grounding (0V) when the button is pushed. That's still well within the low-voltage threshold for the pi, so it's fine to keep it, but you can safely replace it with a direct connection if you want to simplify the circuit wiring (the 10k is providing protection from shorting the 3.3v supply. Meanwhile, connecting a GPIO-input pin directly to anything between 0-3.3V is harmless)

                                  Reset python file:

                                  • Just a minor thing, but I'd recommend moving the line:
                                    import os
                                    To the top of the file (with the other import commands). As is, the script is trying to import a library every time the reset button is pressed. Python might be smart enough to ignore it after the first call (I'm not familiar enough with python to know...) but it's overall just safer/cleaner to have it do this only once at the top of the script.

                                  Mausberry custom script:
                                  I'm not familiar with the Mausberry, so forgive me if I'm missing/misinterpreting something here!
                                  The script you posted looks like it could be combined into the reset python script fairly easily. I'm not super familiar with bash, but the lines:

                                  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
                                  

                                  Seem to be configuring the pins, which I would interpret (in python) as:

                                  GPIO.setup(GPIOpin1, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
                                  GPIO.setup(GPIOpin2, GPIO.OUT, initial=GPIO.HIGH)
                                  

                                  It doesn't look like the bash script uses the internal resistors (though maybe it does by default?). I've included the pull-down resistor, because of what happens in the while loop afterwards. You can remove the pull_up_down = GPIO.PUD_DOWN bit if you don't need it.

                                  Then the while loop that follows (in the bash script) appears to be checking GPIOpin1 for a low-to-high transition to trigger a safe shutdown (I guess that has to do with the Mausberry?). You can do this in python with code similar to the reset button script:

                                  # Define a function which will be called when the shutdown button is triggered
                                  def interrupt_shutdownBtn(channel):
                                          os.system('/home/pi/maus_shutdown.sh')
                                  
                                  # Enable shutdown button (GPIOpin1) interrupt to trigger on a rising edge (i.e. low-to-high transition)
                                  GPIO.add_event_detect(GPIOpin1, GPIO.RISING, callback = interrupt_shutdownBtn, bouncetime = 1000)
                                  

                                  And then you'd have to make a maus_shutdown.sh script like you did with the exit.sh script, by copying the rest of that bash script into a file:

                                  espid="$(pgrep -f "/opt/retropie/supplementary/.*/emulationstation([^.]|$)")"
                                  # Terminate any emulatorcall!
                                  # This works just for RetroPie!
                                  emucall="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.' | sed 's/[^ ]*=[^ ]* //g')"
                                  # If there's an emulator running, we need to kill it and go back to ES
                                  if [[ -n "$emucall" ]]; then
                                      emupid="$(pgrep -f "$emucall" | tr '\n' ' ')"
                                      pkill -P "$(echo $emupid | tr ' ' ',')"
                                      kill "$emupid"
                                      wait "$emupid"
                                      sleep 5 # maybe it can be lesser
                                  fi
                                  
                                  if [ "$espid" ]; then
                                     touch /tmp/es-shutdown && chown pi:pi /tmp/es-shutdown
                                     kill $espid
                                     exit
                                  fi
                                  # End Emulationstation if condition of running binary is true (v1.56)
                                  
                                  sudo poweroff
                                  

                                  In fact, the first part of this is the exit.sh followed by some extra code to close emulationstation at the end (so you could split it up and re-use the exit script if you wanted, just be careful to move the espid=... part if you do).
                                  Anyways, you should be able to combine the python bits into the existing reset script (though I haven't tested this!). Just make sure to copy each part into the appropriate section. So for example, the pin definitions go near the top (with resetBtn = 32), GPIO.setup lines go one after another, the interrupt functions should be written one after the other and the GPIO.add_event_detect lines should be together as well.

                                  EDIT:
                                  Changed one of the lines to use the pull-down resistor.

                                  lostlessL 1 Reply Last reply Reply Quote 1
                                  • lostlessL
                                    lostless @Heyoeyo
                                    last edited by

                                    @heyoeyo well that was a read. LOL. So any way, I understand the electronics of whats going on and I figured out the pin does have its own 3.3V accidentally when i unplugged the 3.3V and the reset was still working. Pulled out my meter and, there you go 3.3V. As far as false positives, The wire run i'm running is very short to pin 32. I don't think it's going to pick up much noise plus it's running it to trigger on low. Noise would have a greater change to trigger a low to high. As far as the 10k to 3.3V being gone now, I'm willing to take the very minor risk of a possible failure of the software resistor.

                                    Now as far as moving the import os to the top. done and It works still. Thank you for starting my understanding of python. After looking at yours I was looking at other scripts on how to program the button as a dual purpose to make the reset do 2 things based on how many times pressed. Ended up using yours, but it makes sense what i'm doing now.

                                    1 Reply Last reply Reply Quote 0
                                    • lostlessL
                                      lostless
                                      last edited by lostless

                                      0_1507987607571_9BA0CE2D-0924-4710-B776-38D29AEA4DAF.jpeg
                                      Oh and all, final build. My own mini NES

                                      1 Reply Last reply Reply Quote 4
                                      • H
                                        Heyoeyo
                                        last edited by

                                        @lostless said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                                        @heyoeyo well that was a read. LOL

                                        Haha, ya sorry about that! I kinda got carried away by the Mausberry thing :/

                                        There's probably a few ways to have it respond to double pressing the reset button. One of the simplest (but not exactly prettiest) is by placing some extra code in the interrupt to watch for another button press (by polling it). You'd probably have to play around with the bouncetime setting on the interrupt as well as playing with delays while polling to get it to feel right, but it could definitely work.

                                        Otherwise, glad to hear everything's working!

                                        1 Reply Last reply Reply Quote 0
                                        • cyperghostC
                                          cyperghost
                                          last edited by cyperghost

                                          @heyoeyo said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                                          I don't know anything about the reliability of the internal pull-ups, but the situation @cyperghost is describing is exactly what you'd expect from a pin without pull-ups, so if they were enabled and it stills does that, I'd agree that they're unreliable! The main benefit of an external resistor is that it's something you can see and test, so it's definitely an option worth considering.

                                          I never used python for coding. But I never saw a tutorial yet, that says that there is no external or no external power feed needed.

                                          Thank you for talking about the two resistors. AFAIK there is an internal resistors available (round about 50k) that splits voltage. So truely you need only one resistor outside ... it's value isn't really a great deal ... 500R up to 50kR.
                                          But please correct me if I'm wrong....

                                          Great explaination btw... thanks

                                          H 1 Reply Last reply Reply Quote 0
                                          • H
                                            Heyoeyo @cyperghost
                                            last edited by

                                            @cyperghost said in Yet annother Retroflag NESPi case with Mausberry, Softshutdown, DUO-LED, Momentary switches:

                                            So truely you need only one resistor outside ... it's value isn't really a great deal ... 500R up to 50kR.

                                            If the internal pull-up resistor is enabled, you don't need any external resistors (just the switch connected from the GPIO to ground). However, if you're going to be sharing this with others (especially someone who might modify or try to copy the connections) then having the external resistor might be a nice courtesy since it makes the wiring much clearer.
                                            Here's a set of possible connections from your button to the Raspberry Pi GPIO input:

                                            0_1507998439600_goodExamples.png

                                            If you use an external resistor, then anything around 10k is a good value to aim for (though as you say, going as low as 500 ohms will work, it will just draw more current when the button is pressed).

                                            And just to be sure, here are some bad connections, maybe useful for anyone who wants to double check they haven't accidentally wired up this way:

                                            0_1507998698585_badExamples.png

                                            cyperghostC lostlessL 2 Replies Last reply Reply Quote 1
                                            • First post
                                              Last post

                                            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.