Combo button presses for buttonshim

Hi there. I’m making a small walkman of sorts for listening to music while I travel with my partner (the justboom DAC zero has two 3.5mm audio outputs so it can work with two sets of headphones at the same time). The buttonshim is perfect for this too, since it eliminates the need for a screen and is so small. There’s one hitch:

I can’t figure out how to program the buttonshim to handle combination button presses. In other words, it works great for assigning functions to single buttons (i.e. Button A is play/pause, etc). But it would be super useful if I could also assign functions to combinations (i.e. pressing Buttons A and E together turns it off). Is this possible?

I note that the python library says that I can “Attach a press handler to one or more buttons.” but I’m not sure if this means I can assign the same function to more than one button (i.e. Buttons A and B each play/pause music when they’re pressed separately) or if I can attach a unique function to a combination of buttons (i.e. Buttons A and B have their own functions when pressed separately, but when they’re pressed simultaneously they run a third set of commands). I’m a Raspbian newbie, so it’s entirely possible I’m just screwing up something basic like the syntax of a proper “list”.

I’d be grateful for any guidance or clarification.

Cheers!

Tim

I took a quick look see. You could likely program a button for two functions. Make it do one thing for a press, play/pause for example. And something else if you hold it down, like shutdown. I saw a hold function where you can set how many seconds its held down for.
http://docs.pimoroni.com/buttonshim/
buttonshim.on_hold(buttons, handler=None, hold_time=2)

I also see a “buttons – A single button, or a list of buttons”. That might just mean if you press this button or that button it does this? I don’t own a button shim so just a guess on my part.

Typically the easy way to handle a button press is to use the on_press handler. But a button press actually has 3 stages:

  • The button is pressed
  • The button is held
  • The button is released

At the moment, IIRC, all of our example demonstrate the use of a half button press and don’t show the sort of tricks you can perform by tracking which buttons are held and which are not.

You can, however, maintains some global state in your program to keep track of which buttons are held: IE ones for which there has been a press event but no corresponding release:


button_a_state = False

@buttonshim.on_press(buttonshim.BUTTON_A):
def press_button_a(button, is_pressed):
    global button_a_state
    button_a_state = True

@buttonshim.on_release(buttonshim.BUTTON_A):
def release_button_a(button, is_pressed):
    global button_a_state
    button_a_state = False

@buttonshim.on_press(buttonshim.BUTTON_B):
def press_button_b(button, is_pressed):
    if button_a_state:
        # Do thing we want to do if A is held while pressing B
    else:
        # Perform B's normal function

What about the?
buttonshim.on_hold(buttons, handler=None, hold_time=2)

That is, indeed, useful for triggering something after a sustained press. But since it only triggers after the hold_time it doesn’t tell you if a button is held down, but only if it has been held down. And that sentence hurts my brain even though I just typed it!

Yeah, if can get confusing. The sense hat has a 5 position switch, with similar options. Button pressed button released. It stands to reason if you pushed it, at some point you have to release it? And you can’t do one without the other? No hold function that I remember though.