264 lines
7.5 KiB
Python
264 lines
7.5 KiB
Python
import time
|
||
import threading
|
||
from rpi_ws281x import PixelStrip, Color
|
||
import RPi.GPIO as GPIO
|
||
|
||
####################TO DO´s##########################
|
||
# 1. Multithread for separating blinker and animation
|
||
# 2. Button interrupt for longer animations (rainbow/police)
|
||
# 3. Optimize Police animation
|
||
####################################################
|
||
|
||
# LED strip configuration:
|
||
numpix = 20
|
||
segment = 4
|
||
delay = 0.15
|
||
brightness = 100
|
||
anzahl_animationen = 5
|
||
LED_PIN = 18
|
||
|
||
# Setup
|
||
strip_blinker = PixelStrip(numpix, LED_PIN, brightness=brightness)
|
||
strip_animation = PixelStrip(numpix, LED_PIN, brightness=brightness)
|
||
strip_blinker.begin()
|
||
strip_animation.begin()
|
||
|
||
# Button and switch GPIO setup
|
||
button_pin = 16
|
||
toggle_switch_left_pin = 20
|
||
toggle_switch_right_pin = 21
|
||
|
||
# Cleanup GPIO to avoid "channel already in use" errors
|
||
GPIO.cleanup()
|
||
|
||
GPIO.setmode(GPIO.BCM)
|
||
GPIO.setup(button_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||
GPIO.setup(toggle_switch_left_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||
GPIO.setup(toggle_switch_right_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||
|
||
blinker_links = False
|
||
blinker_rechts = False
|
||
animation_NR = 0
|
||
reset_animation = False
|
||
|
||
# Define colors
|
||
blank = Color(0, 0, 0)
|
||
white = Color(255, 255, 255)
|
||
red = Color(255, 0, 0)
|
||
orange = Color(255, 127, 0)
|
||
yellow = Color(255, 255, 0)
|
||
lime = Color(127, 255, 0)
|
||
green = Color(0, 255, 0)
|
||
teal = Color(0, 255, 127)
|
||
cyan = Color(0, 255, 255)
|
||
sky_blue = Color(0, 127, 255)
|
||
blue = Color(0, 0, 255)
|
||
indigo = Color(127, 0, 255)
|
||
magenta = Color(255, 0, 255)
|
||
pink = Color(255, 0, 127)
|
||
|
||
colors = [red, orange, yellow, lime, green, teal, cyan, sky_blue, blue, indigo, magenta, pink]
|
||
|
||
############ Blinker Links ###################
|
||
def blink_links():
|
||
global blinker_links
|
||
while blinker_links:
|
||
print('BLINKER LINKS')
|
||
for x in reversed(range(segment)):
|
||
if not blinker_links:
|
||
break
|
||
strip_blinker.setPixelColor(x, yellow)
|
||
strip_blinker.show()
|
||
time.sleep(delay)
|
||
if not blinker_links:
|
||
break
|
||
time.sleep(2 * delay)
|
||
for y in range(segment):
|
||
strip_blinker.setPixelColor(y, blank)
|
||
strip_blinker.show()
|
||
|
||
for y in range(segment):
|
||
strip_blinker.setPixelColor(y, blank)
|
||
strip_blinker.show()
|
||
|
||
############ Blinker Rechts ##################
|
||
def blink_rechts():
|
||
global blinker_rechts
|
||
startpoint = numpix - segment
|
||
while blinker_rechts:
|
||
print('BLINKER RECHTS')
|
||
for x in range(segment):
|
||
if not blinker_rechts:
|
||
break
|
||
strip_blinker.setPixelColor(startpoint + x, yellow)
|
||
strip_blinker.show()
|
||
time.sleep(delay)
|
||
if not blinker_rechts:
|
||
break
|
||
time.sleep(2 * delay)
|
||
for y in range(segment):
|
||
strip_blinker.setPixelColor(startpoint + y, blank)
|
||
strip_blinker.show()
|
||
|
||
for y in range(segment):
|
||
strip_blinker.setPixelColor(startpoint + y, blank)
|
||
strip_blinker.show()
|
||
|
||
############ 0.Animation Licht aus ################
|
||
def licht_aus():
|
||
global reset_animation
|
||
for i in range(segment, numpix):
|
||
strip_animation.setPixelColor(i, blank)
|
||
strip_animation.show()
|
||
while not reset_animation:
|
||
time.sleep(delay)
|
||
|
||
############### 1.Animation Licht an ###############
|
||
def fernlicht_an():
|
||
global reset_animation
|
||
for i in range(segment, numpix):
|
||
strip_animation.setPixelColor(i, white)
|
||
strip_animation.show()
|
||
while not reset_animation:
|
||
time.sleep(delay)
|
||
licht_aus()
|
||
|
||
############### 2.Animation Rainbow ###############
|
||
def rainbow():
|
||
global reset_animation
|
||
for i in range(len(colors)):
|
||
for j in range(segment, numpix):
|
||
strip_animation.setPixelColor(j, colors[i])
|
||
strip_animation.show()
|
||
time.sleep(delay)
|
||
if reset_animation:
|
||
licht_aus()
|
||
return
|
||
|
||
############### 3.Animation Police ###############
|
||
def police():
|
||
global reset_animation
|
||
blue_segment = [4, 5, 6, 10, 11, 12]
|
||
red_segment = [7, 8, 9, 13, 14, 15]
|
||
for segment, color in [(blue_segment, blue), (red_segment, red)]:
|
||
for i in segment:
|
||
strip_animation.setPixelColor(i, color)
|
||
strip_animation.show()
|
||
|
||
time.sleep(delay * 2)
|
||
if reset_animation:
|
||
licht_aus()
|
||
return
|
||
|
||
############### 4.Animation Kit ###############
|
||
def kit():
|
||
global reset_animation
|
||
kit_delay = 0.01
|
||
strip_animation.show()
|
||
|
||
# Left to Right
|
||
for x in range(segment, numpix - 2):
|
||
strip_animation.setPixelColor(x + 1, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x + 2, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x, blank)
|
||
time.sleep(kit_delay)
|
||
strip_animation.setPixelColor(x + 1, blank)
|
||
time.sleep(kit_delay)
|
||
strip_animation.setPixelColor(x + 2, blank)
|
||
strip_animation.show()
|
||
if reset_animation:
|
||
licht_aus()
|
||
return
|
||
|
||
# Right to Left
|
||
for x in reversed(range(segment + 1, numpix - 2)):
|
||
strip_animation.setPixelColor(x + 1, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x + 2, red)
|
||
time.sleep(kit_delay)
|
||
strip_animation.show()
|
||
strip_animation.setPixelColor(x, blank)
|
||
time.sleep(kit_delay)
|
||
strip_animation.setPixelColor(x + 1, blank)
|
||
time.sleep(kit_delay)
|
||
strip_animation.setPixelColor(x + 2, blank)
|
||
strip_animation.show()
|
||
if reset_animation:
|
||
licht_aus()
|
||
return
|
||
|
||
# INTERRUPT HANDLERS
|
||
|
||
# Blinker Links
|
||
def switch_left_up(channel):
|
||
global blinker_links, blinker_rechts
|
||
if blinker_rechts:
|
||
blinker_rechts = False
|
||
if blinker_links:
|
||
return
|
||
blinker_links = True
|
||
threading.Thread(target=blink_links).start()
|
||
|
||
def switch_left_down(channel):
|
||
global blinker_links
|
||
blinker_links = False
|
||
|
||
GPIO.add_event_detect(toggle_switch_left_pin, GPIO.RISING, callback=switch_left_up)
|
||
GPIO.add_event_detect(toggle_switch_left_pin, GPIO.FALLING, callback=switch_left_down)
|
||
|
||
# Blinker Rechts
|
||
def switch_right_up(channel):
|
||
global blinker_rechts, blinker_links
|
||
if blinker_links:
|
||
blinker_links = False
|
||
if blinker_rechts:
|
||
return
|
||
blinker_rechts = True
|
||
threading.Thread(target=blink_rechts).start()
|
||
|
||
def switch_right_down(channel):
|
||
global blinker_rechts
|
||
blinker_rechts = False
|
||
|
||
GPIO.add_event_detect(toggle_switch_right_pin, GPIO.RISING, callback=switch_right_up)
|
||
GPIO.add_event_detect(toggle_switch_right_pin, GPIO.FALLING, callback=switch_right_down)
|
||
|
||
# Button Interrupt
|
||
def button_pressed(channel):
|
||
global debouncing, animation_NR, reset_animation
|
||
animation_NR = (animation_NR + 1) % anzahl_animationen
|
||
reset_animation = True
|
||
|
||
GPIO.add_event_detect(button_pin, GPIO.FALLING, callback=button_pressed, bouncetime=200)
|
||
|
||
# Ensure GPIO cleanup on exit
|
||
import atexit
|
||
atexit.register(GPIO.cleanup)
|
||
|
||
# Main loop
|
||
try:
|
||
while True:
|
||
if animation_NR == 0:
|
||
licht_aus()
|
||
elif animation_NR == 1:
|
||
fernlicht_an()
|
||
elif animation_NR == 2:
|
||
rainbow()
|
||
elif animation_NR == 3:
|
||
police()
|
||
elif animation_NR == 4:
|
||
kit()
|
||
time.sleep(0.1)
|
||
except KeyboardInterrupt:
|
||
GPIO.cleanup()
|