-
Notifications
You must be signed in to change notification settings - Fork 401
/
Copy pathgpio-buttons.py.sample
178 lines (138 loc) · 6.5 KB
/
gpio-buttons.py.sample
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env python3
import RPi.GPIO as GPIO
from signal import pause
from subprocess import check_call
import time
from time import sleep
# 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
#
# 2019-12-17
# Added support to detect RFID tag removal. Requires an appropriate switch
# makes no difference which hardware implementation you choose, could be a simple switch,
# or hidden magnetic switch or hacking the rfid reader as suggested here:
# https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/62
#
# 2019-05-14
# * Rewrite using RPi.GPIO for Raspberry pi zero compatibility.
# * Added power LED functionality
#
# 2018-10-31
# Added the function on holding volume + - buttons to change the volume in 0.3s interval
#
# 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.
# This function takes a holding time (fractional seconds), a channel, a GPIO state and an action reference (function).
# It checks if the GPIO is in the state since the function was called. If the state
# changes it return False. If the time is over the function returns True.
def checkGpioStaysInState(holdingTime, gpioChannel, gpioHoldingState):
# Get a reference start time (https://docs.python.org/3/library/time.html#time.perf_counter)
startTime = time.perf_counter()
# Continously check if time is not over
while(holdingTime >= (time.perf_counter() - startTime)):
# Return if state does not match holding state
if(gpioHoldingState != GPIO.input(gpioChannel)):
return False
# Else: Wait
return True
# Actions that call other processes of the phoniebox (Channel Parameter needed by RPi.GPIO)
def shutdown_action(channel):
check_call("./scripts/playout_controls.sh -c=shutdown", shell=True)
def vol0_action(channel):
check_call("./scripts/playout_controls.sh -c=mute", shell=True)
def volD_action(channel):
check_call("./scripts/playout_controls.sh -c=volumedown", shell=True)
def volU_action(channel):
check_call("./scripts/playout_controls.sh -c=volumeup", shell=True)
def next_action(channel):
check_call("./scripts/playout_controls.sh -c=playernext", shell=True)
def prev_action(channel):
check_call("./scripts/playout_controls.sh -c=playerprev", shell=True)
def halt_action(channel):
check_call("./scripts/playout_controls.sh -c=playerpause", shell=True)
def recordstart_action(channel):
check_call("./scripts/playout_controls.sh -c=recordstart", shell=True)
def recordstop_action(channel):
check_call("./scripts/playout_controls.sh -c=recordstop", shell=True)
def recordplaylatest_action(channel):
check_call("./scripts/playout_controls.sh -c=recordplaylatest", shell=True)
def rfidoff_action(channel):
check_call("./scripts/playout_controls.sh -c=playerpauseforce -v=0.5", shell=True)
# Handlers that handle special behavior of the push of a button
# When the shutdown button was held for more than 2 seconds LED flashed and afterwards
def shutdown_handler(channel):
# Detect holding of button
if checkGpioStaysInState(shutdownHoldTime, btn_shut, GPIO.LOW) is True:
# Blink LED
for x in range(0, 10):
GPIO.output(led_power, x & 1)
sleep(PledBlinkTime)
# Keep LED on until power off
GPIO.output(led_power, GPIO.HIGH)
# Shutdown afterwards
shutdown_action(channel)
# When the Volume Down button was held for more than 0.3 seconds every 0.3 seconds he will lower t$
def volU_handler(channel):
# Rise volume as requested
volU_action(channel)
# Detect holding of button
while checkGpioStaysInState(volumeHoldTime, btn_volU, GPIO.LOW):
volU_action(channel)
# When the Volume Up button was held for more than 0.3 seconds every 0.3 seconds he will call a ra$
def volD_handler(channel):
# Rise volume as requested
volD_action(channel)
# Detect holding of button
while checkGpioStaysInState(volumeHoldTime, btn_volD, GPIO.LOW):
volD_action(channel)
# Define the used pins of the raspberry board
btn_shut = 3
btn_vol0 = 13
btn_volU = 16
btn_volD = 19
btn_next = 26
btn_prev = 20
btn_halt = 21
led_power = 12
# btn_rfidoff =
# reco =
# play =
# Set GPIO numbering to BCM instead of board numbering
GPIO.setmode(GPIO.BCM)
# Bounce tolerance time for buttons
bouncetime = 200 # Milliseconds?
volumeHoldTime = 0.3 # Seconds
shutdownHoldTime = 2 # Seconds
PledBlinkTime = 0.3 # Seconds
# Set up GPIO pins and the power led
GPIO.setup(btn_shut, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_vol0, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_volU, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_volD, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_next, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_prev, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(btn_halt, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# GPIO.setup(btn_rfidoff, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(led_power, GPIO.OUT)
# Set standard events for the buttons. Callback functions define the actions of the events (THey are defined above)
GPIO.add_event_detect(btn_shut, GPIO.FALLING, callback=shutdown_handler, bouncetime=bouncetime)
GPIO.add_event_detect(btn_vol0, GPIO.FALLING, callback=vol0_action, bouncetime=bouncetime)
GPIO.add_event_detect(btn_volU, GPIO.FALLING, callback=volU_handler, bouncetime=bouncetime)
GPIO.add_event_detect(btn_volD, GPIO.FALLING, callback=volD_handler, bouncetime=bouncetime)
GPIO.add_event_detect(btn_next, GPIO.FALLING, callback=next_action, bouncetime=bouncetime)
GPIO.add_event_detect(btn_prev, GPIO.FALLING, callback=prev_action, bouncetime=bouncetime)
GPIO.add_event_detect(btn_halt, GPIO.FALLING, callback=halt_action, bouncetime=bouncetime)
# GPIO.add_event_detect(btn_rfidoff, GPIO.FALLING, callback=rfidoff_action, bouncetime=bouncetime)
# reco.when_pressed = recordstart_action
# reco.when_released = recordstop_action
# play.when_pressed = recordplaylatest_action
# Switch on power led after boot to indicate state "on" for phoniebox
GPIO.output(led_power, GPIO.HIGH)
pause()