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 17.7k 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.
    • lostlessL
      lostless @Heyoeyo
      last edited by

      @heyoeyo those diagrams confirm what I was suspecting. Thanks.

      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:

        But can the internal resistor only enabled via python via PULLUP _ PULLDOWN-command as additional value to the GPIO setting? That's the only language that stays clear to enable/disable the commands.

        It can definitely be done with languages other than python. I only know of the wiringPi C library, which provides the same kind of functionality, but there are probably other options as well.

        It might also be possible to do it with bash, though I'm not familiar enough with it to know for sure. The actual (low-level) required steps are listed in the datasheet for the BCM chip the pi uses, which I've copied here for reference (from page 101):

        The GPIO Pull-up/down Clock Registers control the actuation of internal pull-downs on
        the respective GPIO pins. These registers must be used in conjunction with the GPPUD
        register to effect GPIO Pull-up/down changes. The following sequence of events is
        required:

        1. Write to GPPUD to set the required control signal (i.e. Pull-up or Pull-Down or neither
          to remove the current Pull-up/down)
        2. Wait 150 cycles – this provides the required set-up time for the control signal
        3. Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads you wish to
          modify – NOTE only the pads which receive a clock will be modified, all others will
          retain their previous state.
        4. Wait 150 cycles – this provides the required hold time for the control signal
        5. Write to GPPUD to remove the control signal
        6. Write to GPPUDCLK0/1 to remove the clock

        That's as technical a description as you'll find, but that's what python/wiringPi are doing 'under the hood'. As far as I can tell, it basically boils down to:

        • Write a value to a register (special memory location): 0 Disables pullup/down, 1 enables pull-down, 2 enables pull-up
        • Wait a short period of time
        • Write another value to another register, which specifies the pin you are using (the value you set in the first register is mapped onto the pin selected by this register)
        • Wait a short period of time (this is where the resistor is physically connected)
        • Write something (say a value of 0) to both of the previous registers to reset them so they can be used for another pin

        I'm not 100% sure of that last step though!
        Anyways, this is only a little more complicated than setting the pins as regular inputs/outputs, which bash seems capable of doing based on what I've seen from the code that was posted. So it seems entirely possible that it's just a matter of writing an appropriate value into the correct file/folder to enable the internal resistors with bash.

        1 Reply Last reply Reply Quote 1
        • J
          jmcfsu13
          last edited by

          so i finally had time to get mine wired. you guys have come a long way with the script. @cyperghost @lostless what are you now using for your completed shutdown and reset scripts?

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

            @jmcfsu13 look further up. I’ve done a whole explanation of my power and reset button programming. I have my reset exit back to Es. And power exits retroarch and properly shuts down Es.

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

              @lostless so you are still using the bash one? not the python?

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

                @jmcfsu13 i am. If you want to try a python one and report back, give us the details of what you did

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

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

                  If you want to try a python one and report back, give us the details of what you did

                  I use a python script as shown in the first post on THIS THREAD. I simply replaced the call at startup in /etc/rc.local with a python /path-to-python-script &

                  This creates a more efficient shutdown, and @meleu's killes.sh script does all of the heavy lifting with respect to finding the emulator and ES processes and exiting.

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

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

                    @caver01 I was reading that thread, is there any rewireing of the mauseberry, as far as what pins to use or adding a transistor? And also does it solve the mauseberry not turning off if you shutdown via software?

                    caver01C 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:

                      @caver01 I was reading that thread, is there any rewireing of the mauseberry, as far as what pins to use

                      Of course, you would need to update the script to cover whatever pins you are using for IN/OUT, but the version I posted in that thread uses the recommended/example values from Mausberry (although it is using Broadcom pin numbering instead of GPIO numbers). Think of it as a direct replacement of the script from the Mausberry site.

                      or adding a transistor?

                      We can get into the transistor details, which comes to fruition in this post. That's the point at which I actually installed the transistor on another PIN and triggered it inside the more complex version of the BASH version (getting convoluted I know) of the mausberry script. Of course, I am now using python. The transistor trick (which could also be an opto-coupler MOSFET--Solid State Relay, or even just a diode as described above) does work, but it is not handled by this simplified python script. See below.

                      And also does it solve the mauseberry not turning off if you shutdown via software?

                      The key with the python solution is to replace the BASH "sleep loop" with a more efficient edge-detection method for watching GPIO. The python script achieves this quite easily, but of course, none of the extra stuff is included. It merely duplicates original mausberry shutdown.

                      For the ES and emulator exit, I have all of those commands conveniently separated from the trigger loop. The graceful exiting of emulators now resides in the killes.sh script coupled with the service. Another method could be to simply call the killes.sh script from the python script. That way, you still are letting the python edge detection handle the GPIO trigger, but keeping enhancements to the shutdown routine separate. I prefer the service, personally, as it is shutdown-agnostic (works with any shutdown request).

                      Finally, to finish the answer with respect to the transistor, my transistor trigger is now part of my killes.sh. So, when ever a shutdown is initiated, whether UI/software initiated or via the mausberry switch, the killes.sh gets called, closing down ES, emulators, and for me, tripping the transistor. That way, if the shutdown was triggered by the UI/software, the mausberry circuit still thinks the button was pressed.

                      There is one downside to this--no soft reboots. A reboot would still close the service, and trigger killes.sh which would tap the transistor and the mausberry circuit will cut power while the PI goes down. For me, no soft reboot (becomes shutdown instead) is a small price to pay for coverage of all other shutdown scenarios. My mausberry circuit no longer locks into a powered state, and I get the benefit of safe shutdown no matter how it was requested--all while doing python-based GPIO edge-detection for the switch.

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

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

                        @caver01 ok so the transistor just allows the mauseberry to shut down properly in any situation. But then python script is literally just a functionally identical script to the original, other then it being python?

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

                          @lostless

                          ok so the transistor just allows the mauseberry to shut down properly in any situation

                          Yes... the any situation is exacatly one situation. If you use sudo poweroff or sudo shutdown -h now and do a software poweroff, then the mausberry does not respond on any keypress (you can't power on your Raspberry) and you have to reset the MB circuit :(

                          But then python script is literally just a functionally identical script to the original, other then it being python?

                          It's the same. Only the detection of the GPIO event is different as @caver01 wrote.
                          It's better to use the shutdown service that @meleu introduced. It's a more solid solution except of the shutdown/reboot failure if you use the MB-circuit and the transistor/diode trick.

                          But you can easily solve it if you use this sniplet. I don't know any better solution so far :(

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

                            @cyperghost I may experiment with the python to get rid of that loop, but I rarely if ever use a software shutdown.

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

                              OUTDATED: Take a look at this code piece

                              This is the full working bash script

                              1. 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
                              2. Working shutdown button
                                2.1 We need to make a small addition to annother script
                                2.2 Software shutdown works with this

                              sudo nano /opt/retropie/supplementary/emulationstation/emulationstation.sh
                              add a sleep timer before the rm-command

                              ....
                                  if [ -f /tmp/es-shutdown ]; then
                                      sleep 5
                                      rm -f /tmp/es-shutdown
                                      sudo poweroff
                                      break
                              ...
                              
                              #!/bin/bash
                              
                              # Mausberry shutdown script
                              # extended by cyperghost for
                              # Yet annother NESPi case
                              # Tested version 12/07/17
                              
                              # Function to initiate Restarts and Shutdown
                              # and to achive PID numbers via "es_action check" command
                              # PID number fuction by cyperghost and meleu
                              es_action()
                              {
                                  case $1 in
                                      check)
                                              [[ -f "/dev/shm/runcommand.info" ]] && \
                                              #emu="$(sed -n 4p /dev/shm/runcommand.info | tr -d '\\"' | tr '^$[]*.()|+?{}' '.')" && \
                                              emu="$(sed '4!d; s/\([\\"]\|[[:alnum:]_]\+=[^ ]* \)//g; s/[][(){}^$*.|+? ]/\\&/g' /dev/shm/runcommand.info)" && \
                                              [[ -n "$emu" ]] && emupid="$(pgrep -f "$emu")"
                                              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 && sleep 2
                                              [[ -z $emupid ]] && kill $espid && sleep 5
                                          ;;
                              
                                      shutdown_es)
                                              touch /tmp/es-shutdown && chown pi:pi /tmp/es-shutdown
                                          ;;
                                  esac
                              }
                              
                              # Smart wait function
                              # use es_wait PID number
                              es_wait() #Wait function for finishing running emulators
                              {
                                  while [[ -e /proc/$1 ]]
                                  do
                                      sleep 0.25
                                  done
                              }
                              
                              # ----------------------------------------------------------------------
                              # Initiate Mausberry GPIOs
                              # ----------------------------------------------------------------------
                              
                              
                              #this is the GPIO pinconnected to the diode/transistor
                              GPIOpinTRANS=16
                              
                              #this is the GPIO pin connected to the duoLed RED 
                              GPIOpinLED=21
                              
                              #this is the GPIO pin connected to NESPi RESET switch
                              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
                              
                              #This is the Transistor/Diode hack for software shutdowns
                              echo "$GPIOpinTRANS" > /sys/class/gpio/export
                              echo out > /sys/class/gpio/gpio$GPIOpinTRANS/direction
                              
                              
                              #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
                              
                              # ----------------------------------------------------------------------
                              # Initiate Mausberry Loop funtion
                              # This is a bit modified with an until loop and no if statement!
                              # ----------------------------------------------------------------------
                              
                              
                              
                              power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
                              reset=$(cat /sys/class/gpio/gpio$GPIOpinRESET/value)
                              
                              until [ $power = 1 ] || [ -f /tmp/es-shutdown ]; 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 && sleep 2
                                  es_action shutdown_es
                                  kill $espid && es_wait $espid
                                  exit #Give back maincontrol to emulationstation.sh
                              fi
                              
                              # Perform Software Shutdown
                              # 1. Check for es-shutdown existance ;)
                              # 2. Send logical 1 to GPIO connected to software switch
                              # 3. Wait 1 second
                              # 4. Send logical 0 to GPIO (to hinder reset by MausBerry)
                              # 5. Give control back to ES via exit command
                              # EDIT /opt/.../emulationstation.sh 
                              # and wait for switch.sh close before rm es-shutdown!
                              [ -f /tmp/es-shutdown ] && echo 1 > /sys/class/gpio/gpio$GPIOpinTRANS/value && sleep 1 && echo 0 > /sys/class/gpio/gpio$GPIOpinTRANS/value && exit
                              
                              poweroff
                              

                              You may ask... Why do you not use @meleu's shutdown service?
                              The simple answer is... I need a loop to detect the keypress of the reset button so why not just make full use of the old version?

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

                                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

                                1. Create gpio-shutoff with sudo nano /lib/systemd/system-shutdown/gpio-shutoff
                                2. Enter code from box below
                                3. 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:

                                1. 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
                                2. 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

                                1 Reply 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.