Picade hat Change volume controls

Hello, just got my Picade hat and I don’t have additional button holes to hook up to 13 and 26. Is there a way I can change the volume controls to work on 23 and 24 (coin and start) with the hotkey

You absolutely can change them. You’ll need to git clone the repo and then edit the picadehatd file before installing it, linked below.

The lines that you’ll need to edit are:

VOLUME_DOWN = 13
VOLUME_UP = 26

And then drop back into the top folder in the repo and run sudo ./setup.sh.

Hope that helps!

Thank you, very helpful as I probably would have tried it after the install.
To get the volume control to work with the retropie default hotkey would this modification work or how would that be incorporated?

VOLUME_DOWN = 23, 22
VOLUME_UP = 24, 22

We might have some crossed wires here, what did you mean by “with the hotkey”?

Is it possible for coin and start to also function as volume control with a modifier key?

It’s not supported currently, but I see no reason why not- if you have a key you can spare as a modifier.

It would require some re-writing of the Python driver linked above, but nothing too complex.

The portion that handles what key binds to what function is:

KEYS = {
    ENTER: e.KEY_ENTER,
    ESCAPE: e.KEY_ESC,
    COIN: e.KEY_C,
    START: e.KEY_S,
    UP: e.KEY_UP,
    DOWN: e.KEY_DOWN,
    LEFT: e.KEY_LEFT,
    RIGHT: e.KEY_RIGHT,
    BUTTON1: e.KEY_LEFTCTRL,
    BUTTON2: e.KEY_LEFTALT,
    BUTTON3: e.KEY_SPACE,
    BUTTON4: e.KEY_LEFTSHIFT,
    BUTTON5: e.KEY_Z,
    BUTTON6: e.KEY_X
}

Which you would want to re-write to have an alternate function for each key:

KEYS = {
    ENTER: (e.KEY_ENTER, e.KEY_ESC),
    ESCAPE: ("shift", None),
    COIN: (e.KEY_C, "picade-mixvolume +"),
    START: (e.KEY_S, "picade-mixvolume +"),
    UP: (e.KEY_UP, None),
    DOWN: (e.KEY_DOWN, None),
    LEFT: (e.KEY_LEFT, None),
    RIGHT: (e.KEY_RIGHT, None),
    BUTTON1: (e.KEY_LEFTCTRL, None),
    BUTTON2: (e.KEY_LEFTALT, None),
    BUTTON3: (e.KEY_SPACE, None),
    BUTTON4: (e.KEY_LEFTSHIFT, None),
    BUTTON5: (e.KEY_Z, None),
    BUTTON6: (e.KEY_X, None)
}

The above assumes you want ESCAPE to be your shift key, and for shift+ENTER to be ESCAPE.

Then you would need a place to keep track of the current shift state:

shift_key = False

And you would use that shift_key value to figure out which function to run on each button (True/False map handily to 1/0):

def handle_button(pin):
    global shift_key
    key = KEYS[pin][shift_key]
    if key is None:
        return

    time.sleep(BOUNCE_TIME)
    state = 0 if gpio.input(pin) else 1

    # The key is an integer representing a keypress
    if type(key) is int:
        ui.write(e.EV_KEY, key, state)
        ui.syn()
        if DEBUG:
            log("Pin: {}, KeyCode: {}, Event: {}".format(pin, key, 'press' if state else 'release'))

    # The key is a string, representing a system command
    if type(key) is str:
        if key == "shift": # If the string is "shift" this is our shift key
            shift_key = state
        elif state: # Otherwise run it like a system command
            os.system(key)
        

The only sticking point is this line:

try:
    ui = UInput({e.EV_KEY: KEYS.values()}, name="Picade-HAT", bustype=e.BUS_USB)

This tells the input subsystem what keys we want our device to support, but we’ve broken KEYS.values() in these hypothetical changes so this wont work. It would have to get complicated:

from itertools import chain
try:
    support_keys = [x for x in chain(*KEYS.values()) if type(x) is int]
    ui = UInput({e.EV_KEY: support_keys}, name="Picade-HAT", bustype=e.BUS_USB)
    

And… that should, in theory, get you up and running.

I may have made a typo or two above but broadly speaking you should be able to replace snippets of picadehatd with the code above and have the first setup with functional shift states.

I was able to get it working, Thanks!