From 32ce3ea56bc12be2d8e653c3275827a457e92e11 Mon Sep 17 00:00:00 2001 From: DJ Sundog Date: Tue, 21 Jul 2020 18:26:21 -0700 Subject: [PATCH] add first bits of input handling, tie it to the display handling - run `python3 SoundslabInput.py` for whole shebang for right now --- SoundslabDisplay.py | 9 +-- SoundslabInput.py | 131 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 SoundslabInput.py diff --git a/SoundslabDisplay.py b/SoundslabDisplay.py index 3621df5..4e609e7 100644 --- a/SoundslabDisplay.py +++ b/SoundslabDisplay.py @@ -9,7 +9,7 @@ import musicpd from math import floor class SoundslabDisplay: - def __init__(self): + def __init__(self, player_client): self.screen_size = 240, 240 self.spi_speed_mhz = 80 self.st7789 = ST7789( @@ -25,9 +25,10 @@ class SoundslabDisplay: self.current_menu = Image.new("RGBA", self.screen_size, (0, 0, 0, 0)) self.fg_color = (255, 255, 255, 211) self.bg_color = (0, 0, 0, 127) - # set up connection to mpd here - TODO: this belongs elsewhere and should be passed or pulled in - self.player_client = musicpd.MPDClient() - self.player_client.connect() + + # the connection to mpd passed in + self.player_client = player_client + # track battery voltage over time so we can figure out if we're charging the battery or not self.previous_voltage = 0.0 # track currently playing song's art path to eliminate unnecessary reloads of the same image file diff --git a/SoundslabInput.py b/SoundslabInput.py new file mode 100644 index 0000000..a219af7 --- /dev/null +++ b/SoundslabInput.py @@ -0,0 +1,131 @@ +import signal +import RPi.GPIO as GPIO +from SoundslabDisplay import SoundslabDisplay +import time +import musicpd + +# connect to mpd +player_client = musicpd.MPDClient() +player_client.connect() + +# The buttons on Pirate Audio are connected to pins 5, 6, 16 and 24 +# Boards prior to 23 January 2020 used 5, 6, 16 and 20 +# try changing 24 to 20 if your Y button doesn't work. +BUTTONS = [5, 6, 16, 24, 17, 27, 22, 23, 20] + +# These correspond to buttons A, B, X and Y then the five-way switch positions +LABELS = ['NW', 'SW', 'NE', 'SE', 'UP', 'SELECT', 'LF', 'DN', 'RT'] + +# Set up RPi.GPIO with the "BCM" numbering scheme +GPIO.setmode(GPIO.BCM) + +# Buttons connect to ground when pressed, so we should set them up +# with a "PULL UP", which weakly pulls the input signal to 3.3V. +GPIO.setup(BUTTONS, GPIO.IN, pull_up_down=GPIO.PUD_UP) + +# some button handlers +def NE(): + # play/pause toggle + global player_client + status = player_client.status() + if status['state'] == "play": + print("pausing") + player_client.pause(1) + elif status['state'] == "pause": + print("resuming") + player_client.pause(0) + else: # state == "stop" + print("playing") + player_client.play() + +def SW(): + # previous track + global player_client + status = player_client.status() + if float(status['elapsed']) > 5.0: + # restart track + print("restart current track") + player_client.seekcur(0) + else: + # go to previous track + print("previous track") + player_client.previous() + +def NW(): + # open menu + pass + +def SE(): + # next track + global player_client + print("next track") + player_client.next() + +def UP(): + # volume up 10% + global player_client + print("vol up") + status = player_client.status() + if int(status['volume']) < 100: + player_client.setvol(int(status['volume']) + 10) + +def DN(): + # volume down 10% + global player_client + print("vol down") + status = player_client.status() + if int(status['volume']) > 0: + player_client.setvol(int(status['volume']) - 10) + +def LF(): + # seek back 10s + pass + +def RT(): + # seek forward 10s + pass + +def SELECT(): + # display lock/unlock + pass + +# This is a dictionary of the combination of pins and labels +LABELLED_BUTTONS = { + 5: NW, + 6: SW, + 16: NE, + 24: SE, + 17: UP, + 27: SELECT, + 22: LF, + 23: DN, + 20: RT +} + +# "handle_button" will be called every time a button is pressed +# It receives one argument: the associated input pin. +def handle_button(pin): + label = LABELS[BUTTONS.index(pin)] + print("Button press detected on pin: {} label: {}".format(pin, label)) + func = LABELLED_BUTTONS.get(pin) + func() + +# Loop through out buttons and attach the "handle_button" function to each +# We're watching the "FALLING" edge (transition from 3.3V to Ground) and +# picking a generous bouncetime of 100ms to smooth out button presses. +for pin in BUTTONS: + GPIO.add_event_detect(pin, GPIO.FALLING, handle_button, bouncetime=100) + +# initialize the display +display = SoundslabDisplay(player_client) + +while True: + # test album art + display.updateAlbumArt() + # test setting up the overlay + display.updateOverlay() + # test pushing the update to the display + display.updateDisplay() + # wait before continuing + time.sleep(1.0) +