Skip to content

Commit

Permalink
Merge pull request #376 from MiczFlor/develop
Browse files Browse the repository at this point in the history
GPIO sample scripts (alongside wiki changes)
  • Loading branch information
MiczFlor authored Dec 10, 2018
2 parents 848136e + f0b411a commit 1f0e035
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 42 deletions.
5 changes: 4 additions & 1 deletion htdocs/inc.controlPlayer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
print '<div class="playerWrapperCover" id="coverWrapper"></div>';
}
?>

<div id="controlWrapper"></div>

<script>
Expand All @@ -13,6 +14,7 @@
$('#coverWrapper').load('ajax.loadCover.php');";
}
?>

$('#controlWrapper').load('ajax.loadControls.php');
var refreshId = setInterval(function() {
<?php
Expand All @@ -21,7 +23,8 @@
$('#coverWrapper').load('ajax.loadCover.php?' + 1*new Date());";
}
?>

$('#controlWrapper').load('ajax.loadControls.php?' + 1*new Date());
}, 5000);
}, 2000);
});
</script>
31 changes: 31 additions & 0 deletions misc/sampleconfigs/gpio-buttons.py.rotaryencoder.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/python3
from gpiozero import Button
from signal import pause
from subprocess import check_call

# This script is compatible with any I2S DAC e.g. from Hifiberry, Justboom, ES9023, PCM5102A
# Only Buttons that have dissimilar functions as the two encoder are enabled

# 2018-10-15
# this script has the `pull_up=True` for all pins. See the following link for additional info:
# https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/259#issuecomment-430007446
#
# 2017-12-12
# This script was copied from the following RPi forum post:
# https://forum-raspberrypi.de/forum/thread/13144-projekt-jukebox4kids-jukebox-fuer-kinder/?postID=312257#post312257
# I have not yet had the time to test is, so I placed it in the misc folder.
# If anybody has ideas or tests or experience regarding this solution, please create pull requests or contact me.

def def_shutdown():
check_call("./scripts/playout_controls.sh -c=shutdown", shell=True)

def def_halt():
check_call("./scripts/playout_controls.sh -c=playerpause", shell=True)

shut = Button(3, hold_time=2)
halt = Button(24,pull_up=True)

shut.when_held = def_shutdown
halt.when_pressed = def_halt

pause()
3 changes: 3 additions & 0 deletions misc/sampleconfigs/gpio-buttons.py.sample
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ from gpiozero import Button
from signal import pause
from subprocess import check_call

# This script will block any I2S DAC e.g. from Hifiberry, Justboom, ES9023, PCM5102A
# due to the assignment of GPIO 19 and 21 to a buttons

# 2018-10-31
# Added the function on holding volume + - buttons to change the volume in 0.3s interval
#
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Phoniebox Idle Watchdog Countdown Service

[Service]
User=pi
Group=pi
Type=simple
WorkingDirectory=/home/pi/RPi-Jukebox-RFID
ExecStart=/home/pi/RPi-Jukebox-RFID/scripts/idle-watchdog-countdown.sh

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ After=network.target iptables.service firewalld.service
[Service]
Restart=always
WorkingDirectory=/home/pi/RPi-Jukebox-RFID
ExecStart=/home/pi/RPi-Jukebox-RFID/scripts/rotary-encoder.py
ExecStart=/usr/bin/python2 /home/pi/RPi-Jukebox-RFID/scripts/rotary-encoder.py
User=pi
Group=pi

[Install]
WantedBy=multi-user.target
51 changes: 51 additions & 0 deletions scripts/idle-watchdog-countdown.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash

# This is a mpd idle watchdog to shutdown the box.
#
# Phonieboxes without reliable system time can use this idle-watchdog-script to
# shutdown the box after a pre defined number of minutes.
# This script checks every 60 seconds if mpd is paying music with volume set to
# greater than 0. If not it decreases the pre-defined number of minutes and shut
# down the box if it reaches zero.
# Be aware that playing lots of short sequences (less than 60 seconds) could be
# undetected by this script and lead to an unwanted shutdown.

# Check for idle time settings. Assume to disable automatic shudown if not set.
if [ ! -r ./settings/Idle_Time_Before_Shutdown ]; then
logger "Idle_Time_Before_Shutdown is not set. Disable idle watchdog!"
exit 0
else
SHUTDOWNAFTER=$(cat ./settings/Idle_Time_Before_Shutdown | head -n 1)
fi

# Check if setting is a numeric value; else warn and disable watchdog.
[ "$SHUTDOWNAFTER" -eq "$SHUTDOWNAFTER" ] 2>/dev/null
if [ $? -ne 0 ]; then
logger "Invalid settings for Idle_Time_Before_Shutdown (not numeric). Disable idle watchdog!"
exit 0
fi

COUNTDOWN=$SHUTDOWNAFTER # initialize countdown value

# start the continuous loop
while [ $SHUTDOWNAFTER -gt 0 ]; do
# check if mpd is playing and volume is not 0
if [ $(mpc | egrep -c '^\[playing\]') -eq 1 ] && [ $(mpc | egrep -c '^volume:\s+0%') -eq 0 ]; then
if [ $COUNTDOWN -ne $SHUTDOWNAFTER ]; then
logger "mpd is playing audible again. Stop countdown to shutdown."
fi
COUNTDOWN=$SHUTDOWNAFTER # re-init countdown
else
if [ $COUNTDOWN -gt 0 ]; then
logger "mpd is NOT playing audible. Shutdown in $COUNTDOWN minutes."
else
logger "mpd was NOT playing audible for $SHUTDOWNAFTER minutes. Shutdown system!"
./scripts/playout_controls.sh -c=shutdownsilent
exit 0
fi
COUNTDOWN=$(expr $COUNTDOWN - 1)
fi
sleep 60
done

exit 0
27 changes: 3 additions & 24 deletions scripts/ky040.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,28 @@

class KY040:

def __init__(self, arg_clockPin, arg_dataPin, arg_switchPin=None, arg_rotaryCallbackCW=None, arg_rotaryCallbackCCW=None, arg_switchCallback=None, arg_rotaryBouncetime=100, arg_switchBouncetime=200):
def __init__(self, arg_clockPin, arg_dataPin, arg_rotaryCallbackCW=None, arg_rotaryCallbackCCW=None, arg_rotaryBouncetime=100, arg_switchBouncetime=100):
# persist values
self.clockPin = arg_clockPin
self.dataPin = arg_dataPin
self.switchPin = arg_switchPin
self.rotaryCallbackCW = arg_rotaryCallbackCW
self.rotaryCallbackCCW = arg_rotaryCallbackCCW
self.switchCallback = arg_switchCallback
self.rotaryBouncetime = arg_rotaryBouncetime
self.switchBouncetime = arg_switchBouncetime

# setup pins
# data and clock have pullups at the PCB
GPIO.setup(self.clockPin, GPIO.IN)
GPIO.setup(self.dataPin, GPIO.IN)

if None != self.switchPin:
GPIO.setup(self.switchPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(self.clockPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(self.dataPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def start(self):
GPIO.add_event_detect(self.clockPin, GPIO.FALLING, callback=self._clockCallback, bouncetime=self.rotaryBouncetime)

if None != self.switchPin:
GPIO.add_event_detect(self.switchPin, GPIO.FALLING, callback=self._switchCallback, bouncetime=self.switchBouncetime)

def stop(self):
GPIO.remove_event_detect(self.clockPin)

if None != self.switchPin:
GPIO.remove_event_detect(self.switchPin)

def _clockCallback(self, pin):
if GPIO.input(self.clockPin) == 0:
data = GPIO.input(self.dataPin)
if data == 1:
self.rotaryCallbackCCW()
else:
self.rotaryCallbackCW()

def _switchCallback(self, pin):
if None == self.switchPin:
return

if GPIO.input(self.switchPin) == 0:
self.switchCallback()

46 changes: 30 additions & 16 deletions scripts/rotary-encoder.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
#!/usr/bin/python3
# rotary volume knob
# rotary volume and track knob
# This script is compatible with any I2S DAC e.g. from Hifiberry, Justboom, ES9023, PCM5102A
# Please combine with corresponding gpio button script, which handels the button functionality of the encoder
# RPi-Jukebox-RFID/misc/sampleconfigs/gpio-buttons.py.rotaryencoder.sample

# these files belong all together:
# RPi-Jukebox-RFID/scripts/rotary-encoder.py
# RPi-Jukebox-RFID/scripts/ky040.py
# RPi-Jukebox-RFID/misc/sampleconfigs/phoniebox-rotary-encoder.service.stretch-default.sample
# RPi-Jukebox-RFID/misc/sampleconfigs/gpio-buttons.py.rotaryencoder.sample
# See wiki for more info: https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki

#
# circuit diagram
# circuit diagram for one of two possible encoders (volume), use GPIOs from code below for the tracks
# (capacitors are optionally)
#
# .---------------. .---------------.
# | | | |
# | CLK |------o---------------| GPIO 5 |
# | CLK |------o---------------| GPIO 5 |
# | | | | |
# | DT |------)----o----------| GPIO 6 |
# | DT |------)----o----------| GPIO 6 |
# | | | | | |
# | SW |------)----)----------| GPIO 13 |
# | SW |------)----)----------| GPIO 3 |
# | | | | | |
# | + |------)----)----------| 5V |
# | + |------)----)----------| 3.3V |
# | | | | | |
# | GND |------)----)----------| GND |
# | | | | | |
Expand All @@ -40,33 +45,42 @@
from subprocess import check_call


def rotaryChangeCW():
def rotaryChangeCWVol():
check_call("./scripts/playout_controls.sh -c=volumeup", shell=True)

def rotaryChangeCCW():
def rotaryChangeCCWVol():
check_call("./scripts/playout_controls.sh -c=volumedown", shell=True)

def switchPressed(dummy):
check_call("./scripts/playout_controls.sh -c=mute", shell=True)
def rotaryChangeCWTrack():
check_call("./scripts/playout_controls.sh -c=playernext", shell=True)

def rotaryChangeCCWTrack():
check_call("./scripts/playout_controls.sh -c=playerprev", shell=True)


if __name__ == "__main__":

CLOCKPIN = 5
DATAPIN = 6
SWITCHPIN = 13
CLOCKPINVol = 5
DATAPINVol = 6

CLOCKPINTrack = 22
DATAPINTrack = 23

GPIO.setmode(GPIO.BCM)

ky040 = KY040(CLOCKPIN, DATAPIN, SWITCHPIN, rotaryChangeCW, rotaryChangeCCW, switchPressed)
ky040Vol = KY040(CLOCKPINVol, DATAPINVol, rotaryChangeCWVol, rotaryChangeCCWVol)

ky040Track = KY040(CLOCKPINTrack, DATAPINTrack, rotaryChangeCWTrack, rotaryChangeCCWTrack)

ky040.start()
ky040Vol.start()
ky040Track.start()

try:
while True:
time.sleep(0.2)
finally:
ky040.stop()
ky040Vol.stop()
ky040Track.stop()
GPIO.cleanup()


Expand Down

0 comments on commit 1f0e035

Please sign in to comment.