Compare commits

..

7 commits

Author SHA1 Message Date
Thomas Kolb 373cdb5ce1 Update README; Fixed permissions 2023-08-11 21:27:15 +02:00
Thomas Kolb 4da8319928 rgbw_racers: new version by Julian
- racers now have a tail whose length depends on the racer’s speed
- speed is limited to ±2 LEDs/frame
2022-03-23 20:50:34 +01:00
Thomas Kolb f6cfbb12f3 Added rgbw_racers.py written by Julian 2022-03-19 20:06:54 +01:00
Thomas Kolb 8ae13d77e9 Added README 2022-03-18 19:57:45 +01:00
Thomas Kolb 662d8652b7 Added MIT license file 2022-03-18 19:53:37 +01:00
Thomas Kolb d39c046def Made rgbw_sinus.py the first example script for ZAMusiclight 2022-03-18 19:52:46 +01:00
Thomas Kolb e97ee59355 Removed scripts not suitable for the ZAM setup 2022-03-18 19:50:32 +01:00
20 changed files with 237 additions and 987 deletions

21
COPYING Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-2022 Thomas Kolb
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

7
README.md Normal file
View file

@ -0,0 +1,7 @@
# Skripte für ZAMusiclight
Dieser Ordner enthält Python-Skripte für das ZAMusiclight.
`rgbw_sinus.py` ist das erste Beispielskript und soll als Referenz dienen.
Weitere Information gibt es im [ZAM-Wiki](https://wiki.betreiberverein.de/books/projekte-aktuell/chapter/zamusiclight).

View file

@ -1,36 +0,0 @@
#!/usr/bin/env python
import sk6812
import time
import random
s = sk6812.SK6812("zybot", 2703)
s.set_fadestep(10)
colorcycle = [
(255, 0, 0, 0),
(0, 255, 0, 0),
(0, 0, 255, 0),
(0, 0, 0, 255),
(255, 0, 0, 255),
(0, 255, 0, 255),
(0, 0, 255, 255),
(255, 255, 255, 255),
]
k = 0
while True:
r = colorcycle[k][0]
g = colorcycle[k][1]
b = colorcycle[k][2]
w = colorcycle[k][3]
for i in range(300):
s.fade_color(i, r, g, b, w)
s.commit()
time.sleep(0.01)
k = (k + 1) % len(colorcycle)
time.sleep(1)

View file

@ -1,56 +0,0 @@
#!/usr/bin/env python3
import sk6812
import time
from random import randint
class Rocket:
def __init__(self, sk, color = [0,0,0,255], alt = 100, size = 10):
self.sk = sk
self.color = color
self.alt = alt
self.size = size
self.pos = 0
self.dist = 0
def draw(self):
if self.pos < self.alt:
# launching
self.sk.add_color(self.pos, 64, 32, 0, 0)
self.sk.add_color(self.pos+1, 64, 32, 0, 0)
self.pos += 2
elif self.dist < self.size:
# exploded
self.sk.set_color(self.alt, 0, 0, 0, 255)
self.sk.add_color(self.alt + self.dist, self.color[0], self.color[1], self.color[2], self.color[3])
self.sk.add_color(self.alt - self.dist, self.color[0], self.color[1], self.color[2], self.color[3])
self.dist += 1
num_modules = 300
interval = 0.05
w = sk6812.SK6812("zybot", 2703)
w.set_fadestep(1.00/interval)
w.set_num_modules(num_modules)
rockets = []
frame = 0
while True:
if frame % 30 == 0:
rockets.append(Rocket(w, [randint(0, 255), randint(0, 255), randint(0, 255), randint(0, 255)], randint(50, 249), randint(10, 50)))
for r in rockets:
r.draw()
for i in range(num_modules):
w.fade_color(i, 0, 0, 0, 0)
w.commit()
frame += 1
time.sleep(interval)

View file

@ -1,43 +0,0 @@
import numpy as np
# h = 0..359
# s = 0..255
# v = 0..511 (values above 255 add white channel)
def hsv2rgbw(h, s, v):
h %= 360
v_ = min(255, v)
# C = 0..255
C = (v_ * s) // 256
h_ = 128 * h // 60
# X = 0..255
X = C * (128 - abs(h_ % 256 - 128)) // 128
if h < 60:
r, g, b = C, X, 0
elif h < 120:
r, g, b = X, C, 0
elif h < 180:
r, g, b = 0, C, X
elif h < 240:
r, g, b = 0, X, C
elif h < 300:
r, g, b = X, 0, C
else:
r, g, b = C, 0, X
m = v_ - C
r += m
g += m
b += m
if v >= 256:
w = v - 255
else:
w = 0
return np.array([r, g, b, w])

View file

@ -1,42 +0,0 @@
#!/usr/bin/env python
import sk6812_multistrip as sk6812
import time
import math
import sys
import random
from hsv2rgbw import hsv2rgbw
import numpy as np
sk = sk6812.SK6812(sys.argv[1], 2703)
sk.set_fadestep(10)
interval = 1/30
nled = 16
nstrip = 8
h = 0
s = 192
v = 255
loop = 0
while True:
v = (loop // 30) % 255
# update colors
for led in range(nled):
for strip in range(nstrip):
color = hsv2rgbw(h + 360 * strip//nstrip, s, v)
color = color * 50 // 100
sk.set_color(strip, led, color[0], color[1], color[2], color[3])
sk.commit()
loop += 1
time.sleep(interval)

View file

@ -1,46 +0,0 @@
#!/usr/bin/env python3
import sk6812
import time
num_modules = 300
interval = 0.05
w = sk6812.SK6812("zybot", 2703)
w.set_fadestep(0.05/interval)
w.set_num_modules(num_modules)
# dictionary which maps {module: [r, g, b]}
set_colors = {}
curModule = [0, 0, 0, 0]
speed = [0.49, 0.65, 1, 0.81]
#countUp = [True, True, False]
while True:
set_colors = {}
set_colors[int(curModule[0])] = [0, 0, 0, 0]
set_colors[int(curModule[1])] = [0, 0, 0, 0]
set_colors[num_modules-1-int(curModule[2])] = [0, 0, 0, 0]
set_colors[num_modules-1-int(curModule[3])] = [0, 0, 0, 0]
set_colors[int(curModule[0])][0] = 255
set_colors[int(curModule[1])][1] = 255
set_colors[num_modules-1-int(curModule[2])][2] = 255
set_colors[num_modules-1-int(curModule[3])][3] = 255
for k in set_colors.keys():
w.add_color(k, set_colors[k][0], set_colors[k][1], set_colors[k][2], set_colors[k][3])
for i in range(num_modules):
w.fade_color(i, 0, 0, 0, 0)
w.commit()
for i in range(4):
curModule[i] += speed[i]
if curModule[i] >= num_modules:
curModule[i] -= num_modules
time.sleep(interval)

View file

@ -1,59 +0,0 @@
#!/usr/bin/env python3
import sk6812_multistrip as sk6812
import time
import sys
num_modules = 16
interval = 1/60
w = sk6812.SK6812(sys.argv[1], 2703)
w.set_fadestep(0.20/interval)
#w.set_num_modules(num_modules)
# dictionary which maps {module: [r, g, b]}
set_colors = {}
curModule = [0, 0, 0, 0]
#speed = [0.49, 0.65, 1, 0.81]
speed = [0.13, 0.17, 0.19, 0.21]
#countUp = [True, True, False]
brightness = 32
strip = 0
while True:
w.set_fadestep(0.10/interval)
set_colors = {}
set_colors[int(curModule[0])] = [0, 0, 0, 0]
set_colors[int(curModule[1])] = [0, 0, 0, 0]
#set_colors[num_modules-1-int(curModule[1])] = [0, 0, 0, 0]
set_colors[int(curModule[2])] = [0, 0, 0, 0]
set_colors[int(curModule[3])] = [0, 0, 0, 0]
#set_colors[num_modules-1-int(curModule[3])] = [0, 0, 0, 0]
set_colors[int(curModule[0])][0] = brightness
set_colors[int(curModule[1])][1] = brightness
#set_colors[num_modules-1-int(curModule[1])][1] = brightness
set_colors[int(curModule[2])][2] = brightness
set_colors[int(curModule[3])][3] = brightness
#set_colors[num_modules-1-int(curModule[3])][3] = brightness
for strip in range(8):
for k in set_colors.keys():
w.add_color(strip, k, set_colors[k][0], set_colors[k][1], set_colors[k][2], set_colors[k][3])
for i in range(num_modules):
w.fade_color(strip, i, 0, 0, 0, 0)
w.commit()
for i in range(4):
curModule[i] += speed[i]
if curModule[i] >= num_modules:
curModule[i] -= num_modules
time.sleep(interval)

View file

@ -1,24 +0,0 @@
#!/usr/bin/env python
import sk6812
import time
import random
s = sk6812.SK6812("zybot", 2703)
s.set_fadestep(2)
# dictionary which maps {module: [r, g, b]}
set_colors = {}
while True:
r = random.randint(0, 254)
g = random.randint(0, 254)
b = random.randint(0, 254)
w = random.randint(0, 254)
for i in range(300):
s.fade_color(i, r, g, b, w)
s.commit()
time.sleep(0.01)
#time.sleep(120)

View file

@ -1,118 +0,0 @@
#!/usr/bin/env python
import sk6812_multistrip as sk6812
import time
import math
import sys
import random
import numpy as np
s = sk6812.SK6812(sys.argv[1], 2703)
s.set_fadestep(10)
phase = 0
nled = 16
nstrip = 8
interval = 1.0/30
scale = 0.15
strip = 0
tiltphase = 0
ENERGY_MULT = 92
ENERGY_DIV = 100
MAXENERGY_ADD = 160
ENERGY_SUB = 7
ENERGY_PULL_MAX_PCT = 100
energy = np.zeros( (nled+1, nstrip), dtype=int )
energy_smooth = np.zeros( energy.shape, dtype=int )
COLORMAP_X = [ 0, 70, 120, 200, 225, 255]
COLORMAP_Y = [(0, 0, 0, 0), (128, 0, 0, 0), (192, 64, 0, 0), (255, 128, 0, 0), (255, 128, 0, 20), (255, 128, 0, 40)]
def colormap(x):
i = 0
while i < len(COLORMAP_X)-1 and COLORMAP_X[i+1] < x:
i += 1
if i >= len(COLORMAP_X)-1:
return np.array(COLORMAP_Y[len(COLORMAP_Y)-1])
start_x = COLORMAP_X[i]
end_x = COLORMAP_X[i+1]
start_col = np.array(COLORMAP_Y[i], dtype=int)
end_col = np.array(COLORMAP_Y[i+1], dtype=int)
col = (x - start_x) * 100 // (end_x - start_x) * (end_col - start_col) // 100 + start_col
return col
loop = 0
intensity = MAXENERGY_ADD
while True:
if loop % 5 == 0:
intensity = random.randint(MAXENERGY_ADD*3//4, MAXENERGY_ADD*5//4)
# inject random energy in bottom row
for i in range(nstrip):
energy[0, i] += random.randint(0, intensity)
# pull energy from the cell below
for led in range(nled, 0, -1):
for strip in range(nstrip):
wanted_energy = random.randint(0, ENERGY_PULL_MAX_PCT) * energy[led-1, strip] // 100
pulled_energy = min(wanted_energy, energy[led-1, strip])
energy[led, strip] += pulled_energy
energy[led-1, strip] -= pulled_energy
# decrease global amount of energy
for led in range(nled+1):
for strip in range(nstrip):
#energy[led, strip] *= ENERGY_MULT
#energy[led, strip] //= ENERGY_DIV
energy[led, strip] -= min(ENERGY_SUB, energy[led, strip])
# smooth the energy distribution
for led in range(nled):
for strip in range(nstrip):
strip_left = (strip + nstrip - 1) % nstrip
strip_right = (strip + nstrip + 1) % nstrip
led_above = led + 1
led_below = led - 1
energy_smooth[led, strip] = 100 * energy[led, strip]
energy_smooth[led, strip] += 30 * energy[led, strip_left]
energy_smooth[led, strip] += 30 * energy[led, strip_right]
gain = 160
if led_above < nled:
energy_smooth[led, strip] += 10 * energy[led_above, strip]
gain += 10
if led_below >= 0:
energy_smooth[led, strip] += 10 * energy[led_below, strip]
gain += 10
energy_smooth[led, strip] //= gain
# update colors
for led in range(nled):
for strip in range(nstrip):
color = colormap(energy_smooth[led, strip])**2//255
s.fade_color(strip, led, color[0], color[1], color[2], color[3])
s.commit()
loop += 1
time.sleep(interval)

View file

@ -1,131 +0,0 @@
#!/usr/bin/env python
import sk6812_multistrip as sk6812
import time
import math
import sys
import random
from hsv2rgbw import hsv2rgbw
import numpy as np
s = sk6812.SK6812(sys.argv[1], 2703)
phase = 0
nled = 16
nstrip = 8
interval = 1.0/30
scale = 0.15
strip = 0
tiltphase = 0
ENERGY_MULT = 92
ENERGY_DIV = 100
MAXENERGY_ADD = 160
ENERGY_SUB = 7
ENERGY_PULL_MAX_PCT = 100
HIGHLIGHT_OFFSET = -60
energy = np.zeros( (nled+1, nstrip), dtype=int )
energy_smooth = np.zeros( energy.shape, dtype=int )
COLORMAP_X = [ 0, 70, 120, 200, 225, 255]
COLORMAP_Y = [
(0, 255, 0),
(0, 255, 128),
(0, 255, 192),
(0, 192, 192),
(0, 128, 255),
(0, 128, 300)]
def colormap(x, h):
i = 0
while i < len(COLORMAP_X)-1 and COLORMAP_X[i+1] < x:
i += 1
if i >= len(COLORMAP_X)-1:
return hsv2rgbw(*COLORMAP_Y[len(COLORMAP_Y)-1])
start_x = COLORMAP_X[i]
end_x = COLORMAP_X[i+1]
start_col = np.array(COLORMAP_Y[i], dtype=int)
end_col = np.array(COLORMAP_Y[i+1], dtype=int)
col = (x - start_x) * 100 // (end_x - start_x) * (end_col - start_col) // 100 + start_col
col[0] = (col[0] + h + 360) % 360
return hsv2rgbw(*col)
loop = 0
intensity = MAXENERGY_ADD
while True:
s.set_fadestep(10)
if loop % 5 == 0:
intensity = random.randint(MAXENERGY_ADD*3//4, MAXENERGY_ADD*5//4)
# inject random energy in bottom row
for i in range(nstrip):
energy[0, i] += random.randint(0, intensity)
# pull energy from the cell below
for led in range(nled, 0, -1):
for strip in range(nstrip):
wanted_energy = random.randint(0, ENERGY_PULL_MAX_PCT) * energy[led-1, strip] // 100
pulled_energy = min(wanted_energy, energy[led-1, strip])
energy[led, strip] += pulled_energy
energy[led-1, strip] -= pulled_energy
# decrease global amount of energy
for led in range(nled+1):
for strip in range(nstrip):
#energy[led, strip] *= ENERGY_MULT
#energy[led, strip] //= ENERGY_DIV
energy[led, strip] -= min(ENERGY_SUB, energy[led, strip])
# smooth the energy distribution
for led in range(nled):
for strip in range(nstrip):
strip_left = (strip + nstrip - 1) % nstrip
strip_right = (strip + nstrip + 1) % nstrip
led_above = led + 1
led_below = led - 1
energy_smooth[led, strip] = 100 * energy[led, strip]
energy_smooth[led, strip] += 30 * energy[led, strip_left]
energy_smooth[led, strip] += 30 * energy[led, strip_right]
gain = 160
if led_above < nled:
energy_smooth[led, strip] += 10 * energy[led_above, strip]
gain += 10
if led_below >= 0:
energy_smooth[led, strip] += 10 * energy[led_below, strip]
gain += 10
energy_smooth[led, strip] //= gain
# update colors
for led in range(nled):
for strip in range(nstrip):
color = colormap(energy_smooth[led, strip], (loop // 20) % 360)**2//255
s.fade_color(strip, led, color[0], color[1], color[2], color[3])
s.commit()
loop += 1
time.sleep(interval)

View file

@ -1,55 +0,0 @@
#!/usr/bin/env python3
import sk6812_multistrip as sk6812
import time
import math
import sys
s = sk6812.SK6812(sys.argv[1], 2703)
phase = 0
nled = 16
nstrip = 8
interval = 1.0/60
scale = 0.15
strip = 0
tiltphase = 0
seq = 0
rxseq = 0
lasttxtime = 0
while True:
rxseq = s.try_read_seq()
if rxseq != -1:
print(f"TX: {seq}, RX: {rxseq}")
now = time.time()
if rxseq >= seq - 3 or (lasttxtime < now - 0.5):
lasttxtime = now
for i in range(nled):
for strip in range(nstrip):
x = 2*math.pi * i / nled
y = 2*math.pi * strip * 2*math.sin(tiltphase) / nstrip
r = scale * (127 + 127 * math.sin(y + x + 283*phase + 0 * math.pi/2))
g = scale * (127 + 127 * math.sin(y + x + 293*phase + 1 * math.pi/2))
b = scale * (127 + 127 * math.sin(y + x + 307*phase + 2 * math.pi/2))
w = scale * 0.6 * (127 + 127 * math.sin(y + x + 311*phase + 3 * math.pi/2))
s.set_color((strip+0)%nstrip, i, r, g, b, w)
s.ack_request(seq)
seq += 1
s.commit()
phase += 2*math.pi * interval / (739*1)
tiltphase += 2*math.pi * interval / (471/2)
time.sleep(interval)

154
rgbw_racers.py Executable file
View file

@ -0,0 +1,154 @@
#!/usr/bin/env python
# encoding: utf-8
# Copyright (c) 2022 Julian Hammer
# This file is licensed under the terms of the MIT license. See COPYING for
# details.
# Importieren von sk6812_multistrip.py, welches das Netzwerkprotokoll für die
# LED-Leiste abstrahiert.
import sk6812_multistrip as sk6812
import time # für sleep()
import sys # zum Lesen der IP-Adresse aus den Kommandozeilenargumenten
import math
import random
import colorsys
# Konstanten
NLED = 150 # Anzahl der LEDs pro logischen Strip
NSTRIP = 2 # Anzahl der logischen Strips
# Objekt initialisieren
s = sk6812.SK6812(sys.argv[1], 2703)
# Wartezeit zwischen den Animationsschritten. Achtung, die LED-Leiste arbeitet
# immer mit 60 FPS! Dies ist insbesondere bei Verwendung von fade_color()
# relevant.
interval = 1.0/60
last_frame = [(0,0,0,0)] * NLED * NSTRIP
def hsv2rgb(h,s,v):
return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v))
def random_color():
return list(hsv2rgb(random.random(), 1, 1)) + [random.randint(0,255)]
def loc2sl(loc):
# translates 1d-coordinate (loc) to
# (strip, led) with:
# (0,0) ... (0, 149) (1, 149) ... (1, 0)
strip = loc // NLED
led = loc % NLED
if strip == 1:
led = NLED - led
return strip, led
MAXLOC = NLED*NSTRIP
racers = [
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.3),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.5),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.5),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.5),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*0.5),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*2),
dict(loc=random.randint(0,299), color=random_color(), speed=(random.random()-0.5)*2),
]
# Clear all leds at start
for loc in range(MAXLOC):
strip, led = loc2sl(loc)
s.set_color(strip, led, 0,0,0,0)
if loc % 150 == 0:
s.commit()
s.commit()
print("{:>10} {:>8} {:>8}".format("frame", "AVG", "MAX"))
# Hauptschleife
f = 0 # frame counter
clear_leds = []
while True:
for strip, led in clear_leds:
# Clear leds
s.set_color(strip, led, 0,0,0,0)
clear_leds = []
for r in racers:
# Update location
r['loc'] += r['speed']
# Reverse at ends (0 and MAXLOC-1)
if r['loc'] >= MAXLOC:
r['loc'] = MAXLOC - (r['loc'] % MAXLOC)
r['speed'] *= -1
if r['loc'] < 0:
r['loc'] *= -1
r['speed'] *= -1
# Interpolate color linearly between two leds
strip, led = loc2sl(int(r['loc']))
s.add_color(strip, led, *tuple([int(c*(math.ceil(r['loc'])-r['loc'])) for c in r['color']]))
clear_leds.append((strip, led))
strip, led = loc2sl(math.ceil(r['loc']))
s.add_color(strip, led, *tuple([int(c*(r['loc']-int(r['loc']))) for c in r['color']]))
clear_leds.append((strip, led))
# Add tail of speed-depending length and logarithmicly decaying brightness
tail = r['speed'] * 10
if tail > 0:
tail_range = range(1, int(tail))
else:
tail_range = range(-1, int(tail), -1)
for i in tail_range:
if not 0 <= int(r['loc'])-i < MAXLOC:
continue
strip, led = loc2sl(int(r['loc'])-i)
color = tuple([int(c / (abs(i)*(abs(tail)/2)) ) for c in r['color'][:3]]+[0]) # blackout white
s.add_color(strip, led, *color)
clear_leds.append((strip, led))
# last tail segment is interpolated
if tail_range:
if not 0 <= int(r['loc'])-i < MAXLOC:
continue
last_loc = r['loc']-i
strip, led = loc2sl(math.ceil(last_loc))
s.add_color(strip, led, *tuple([int(c*(last_loc-int(last_loc))) for c in color]))
clear_leds.append((strip, led))
# Random speed variation, limited to [-2, 2] interval
r['speed'] = max(-2, min(2, r['speed'] + (random.random()-0.5)*0.01))
# Use speed to define W-intensity ("whiteness")
r['color'][3] = min(int(abs(r['speed'])*128), 255)
if f % 600 == 0:
print("{:>10} {:>8.2f} {:>8.2f}".format(
f,
sum([abs(r['speed']) for r in racers])/len(racers),
max([abs(r['speed']) for r in racers])))
s.commit()
# Warte bis zum nächsten Frame
time.sleep(interval)
f += 1

View file

@ -1,35 +1,66 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8
# Copyright (c) 2019-2022 Thomas Kolb
# This file is licensed under the terms of the MIT license. See COPYING for
# details.
# Importieren von sk6812_multistrip.py, welches das Netzwerkprotokoll für die
# LED-Leiste abstrahiert.
import sk6812_multistrip as sk6812 import sk6812_multistrip as sk6812
import time
import math
import sys
import time # für sleep()
import sys # zum Lesen der IP-Adresse aus den Kommandozeilenargumenten
import math
# Konstanten
NLED = 150 # Anzahl der LEDs pro logischen Strip
NSTRIP = 2 # Anzahl der logischen Strips
# Objekt initialisieren
s = sk6812.SK6812(sys.argv[1], 2703) s = sk6812.SK6812(sys.argv[1], 2703)
phase = 0 # Wartezeit zwischen den Animationsschritten. Achtung, die LED-Leiste arbeitet
nled = 16 # immer mit 60 FPS! Dies ist insbesondere bei Verwendung von fade_color()
nstrip = 8 # relevant.
interval = 1.0/60 interval = 1.0/60
scale = 0.1 # Globale Skalierung für die Helligkeit.
scale = 0.5
strip = 0 # Startzeitpunkt der Animation
t0 = time.time()
# Hauptschleife
while True: while True:
for i in range(nled): # hole die aktuelle Zeit seit dem Start
x = 2*math.pi * i / nled t = time.time() - t0
r = scale * (127 + 127 * math.sin(x + 8*phase + 0 * math.pi/2))
g = scale * (127 + 127 * math.sin(x + 4*phase + 1 * math.pi/2))
b = scale * (127 + 127 * math.sin(x + 2*phase + 2 * math.pi/2))
w = scale * (127 + 127 * math.sin(x + 1*phase + 3 * math.pi/2))
for strip in range(nstrip): # umskalieren in einen langsam fortschreitenden Phasenwert
phase = t * 2*math.pi / 739.0
# Laufe über alle LEDs in allen Strips ...
for strip in range(NSTRIP):
for i in range(NLED):
# ... berechne für jede LED eine individuelle Farbe ...
# Der Wertebereich ist 0 bis 255 für jeden Kanal. Es gibt vier
# Kanäle: rot, grün, blau und weiß. Da weiß um einiges intensiver
# als die anderen Kanäle ist, wird dieser hier pauschal auf 60%
# gedimmt.
x = 2*math.pi * i / NLED
r = scale * (127 + 127 * math.sin(x + 283*phase + 0 * math.pi/2))
g = scale * (127 + 127 * math.sin(x + 293*phase + 1 * math.pi/2))
b = scale * (127 + 127 * math.sin(x + 307*phase + 2 * math.pi/2))
w = scale * 0.6 * (127 + 127 * math.sin(x + 311*phase + 3 * math.pi/2))
# ... und setze diese direkt
s.set_color(strip, i, r, g, b, w) s.set_color(strip, i, r, g, b, w)
s.commit() s.commit() # sendet alle bisherigen Befehle an die LED-Leiste. Muss
# spätestens nach 210 Befehlen aufgerufen werden!
phase += 2*math.pi * interval / 10 # Warte bis zum nächsten Frame
time.sleep(interval) time.sleep(interval)

View file

@ -1,34 +0,0 @@
#!/usr/bin/env python3
import sk6812_multistrip as sk6812
import time
import math
import sys
num_modules = 16
num_strips = 8
interval = 1/20
w = sk6812.SK6812(sys.argv[1], 2703)
color = [0x20, 0x40, 0x00, 0x10]
cur_strip = 0
while True:
w.set_fadestep(int(0.80/interval))
for k in range(num_modules):
f = 1#math.sin(math.pi * k / num_modules)
w.add_color(cur_strip, k, f*color[0], f*color[1], f*color[2], f*color[3])
for strip in range(8):
for i in range(num_modules):
w.fade_color(strip, i, 0, 0, 0, 0)
w.commit()
cur_strip += 1
cur_strip %= num_strips
time.sleep(interval)

View file

@ -1,79 +0,0 @@
#!/usr/bin/env python3
import struct
import socket
import time
from random import random
class SK6812Command:
# command definitions
SET_COLOR = 0
FADE_COLOR = 1
ADD_COLOR = 2
SET_FADESTEP = 3
SET_NUM_MODS = 4
def __init__(self, action = SET_COLOR, module = 0, d0 = 0, d1 = 0, d2 = 0, d3 = 0):
self.action = int(action)
self.strip = 0 # FIXME
self.module = int(module)
self.d0 = int(d0)
self.d1 = int(d1)
self.d2 = int(d2)
self.d3 = int(d3)
def serialize(self):
return struct.pack(">BBHBBBB", self.action, self.strip, self.module, self.d0, self.d1, self.d2, self.d3)
class SK6812:
def __init__(self, host, port):
self.__commands = []
# create the UDP socket
family, socktype, proto, canonname, sockaddr = socket.getaddrinfo(host, port, 0, socket.SOCK_DGRAM)[0]
self.__socket = socket.socket(family, socktype, proto)
self.__socket.connect(sockaddr)
def commit(self):
# send the data
packet = b''
for command in self.__commands:
packet = packet + command.serialize()
if packet:
self.__socket.send(packet)
self.__commands = []
def set_fadestep(self, fadestep):
# add a "set fadestep" command
self.__commands.append(SK6812Command(SK6812Command.SET_FADESTEP, d0 = fadestep))
def set_color(self, module, r, g, b, w):
# add a "set color" command
self.__commands.append(SK6812Command(SK6812Command.SET_COLOR, module, r, g, b, w))
def fade_color(self, module, r, g, b, w):
# add a "fade to color" command
self.__commands.append(SK6812Command(SK6812Command.FADE_COLOR, module, r, g, b, w))
def add_color(self, module, r, g, b, w):
# add a "add to color" command
self.__commands.append(SK6812Command(SK6812Command.ADD_COLOR, module, r, g, b, w))
def set_num_modules(self, modules):
# add a "set number of modules" command
self.__commands.append(SK6812Command(SK6812Command.SET_NUM_MODS, d0 = (modules >> 24) & 0xFF, d1 = (modules >> 16) & 0xFF, d2 = (modules >> 8) & 0xFF, d3 = modules & 0xFF))
if __name__ == "__main__":
w = SK6812("192.168.2.222", 2703)
w.set_fadestep(1);
while True:
w.set_color(10, 255, 255, 255, 255)
for i in range(20):
w.fade_color(i, 0, 0, 0)
w.commit()
time.sleep(0.2)

View file

@ -1,5 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Copyright (c) 2019-2022 Thomas Kolb
# This file is licensed under the terms of the MIT license. See COPYING for
# details.
import struct import struct
import socket import socket
import time import time

View file

@ -1,161 +0,0 @@
#!/usr/bin/env python
import sk6812_multistrip as sk6812
import time
import math
import sys
import random
s = sk6812.SK6812(sys.argv[1], 2703)
phase = 0
nled = 16
nstrip = 8
interval = 1.0/60
#scale = 0.15
scale = 0.5
strip = 0
tiltphase = 0
#phase_speeds = [13, 23, 42, 5]
#phase_speeds = [37, 41, 43, 47]
phase_speeds = [701, 709, 719, 727]
class Framebuffer:
def __init__(self):
self.clear()
def clear(self):
self.r = [0] * (nstrip * nled)
self.g = [0] * (nstrip * nled)
self.b = [0] * (nstrip * nled)
self.w = [0] * (nstrip * nled)
def setpixel(self, strip, led, r, g, b, w):
idx = strip * nled + led
self.r[idx] = r
self.g[idx] = g
self.b[idx] = b
self.w[idx] = w
def addtopixel(self, strip, led, r, g, b, w):
idx = strip * nled + led
self.r[idx] += r
self.g[idx] += g
self.b[idx] += b
self.w[idx] += w
def render(self):
for strip in range(nstrip):
for led in range(nled):
idx = strip * nled + led
s.set_color(strip, led,
self.r[idx],
self.g[idx],
self.b[idx],
self.w[idx])
class Snowflake:
def __init__(self):
self.phase = random.random() * 2 * math.pi
self.frequency = 2*math.pi * 1
self.speed = random.random() * 0.1 + 0.05
self.radius = 1.1
self.radiussq = self.radius**2
self.pos_strip = self.base_pos_strip = random.randint(0, nstrip-1)
self.pos_led = nled-1+self.radius
def move(self):
self.phase += self.frequency * interval
self.pos_strip = self.base_pos_strip + 1 * math.sin(self.phase)
self.pos_led -= 0.1
def render(self, framebuffer):
for strip in range(int(math.floor(self.pos_strip-self.radius)), int(math.ceil(self.pos_strip+self.radius))):
for led in range(int(math.floor(self.pos_led-self.radius)), int(math.ceil(self.pos_led+self.radius))):
if led < 0 or led >= nled:
continue
distsq = (strip - self.pos_strip)**2 + (led - self.pos_led)**2
brightness = 1 - distsq / self.radiussq
if brightness < 0:
continue # brightness 0 -> no effect -> save some calculations
norm_strip = strip
while norm_strip < 0:
norm_strip += nstrip
while norm_strip >= nstrip:
norm_strip -= nstrip
framebuffer.addtopixel(norm_strip, led, 0, 0, int(32*brightness), int(48*brightness))
def has_fallen(self):
return self.pos_led < -self.radius
snowflakes = []
framebuffer = Framebuffer()
frame = 0
snowlevel = [0] * nstrip
while True:
# garbage collection
if True: #frame % 10 == 0:
visible_snowflakes = []
for flake in snowflakes:
if not flake.has_fallen():
visible_snowflakes.append(flake)
else:
idx = int(flake.base_pos_strip)
if idx < 0:
idx += nstrip
elif idx >= nstrip:
idx -= nstrip
snowlevel[idx] += 0.2
snowflakes = visible_snowflakes
# spawn new flakes
if random.random() < 0.1:
snowflakes.append(Snowflake())
framebuffer.clear()
# move and render the flakes
for flake in snowflakes:
flake.move()
flake.render(framebuffer)
# add snow on the ground
for strip in range(nstrip):
led = 0
level = snowlevel[strip]
while level > 0:
if level >= 1:
brightness = 1
else:
brightness = level
framebuffer.addtopixel(strip, led, 0, int(8*brightness), int(32*brightness), int(12*brightness))
level -= 1
led += 1
snowlevel[strip] *= 0.999
framebuffer.render()
s.commit()
time.sleep(interval)
frame += 1

View file

@ -1,37 +0,0 @@
#!/usr/bin/env python3
import sk6812_multistrip as sk6812
import math
import sys
import time
s = sk6812.SK6812(sys.argv[1], 2703)
nled = 16
nstrip = 8
interval = 1/30
for led in range(nled):
for strip in range(nstrip):
s.fade_color(strip, led, 0, 0, 0, 0)
s.commit()
loop = 0
while True:
intensity = int(64 * math.sin(2*math.pi * (loop * interval) * 0.25)**2)
r = 0
g = 0
b = intensity
w = 0
for strip in range(nstrip):
s.set_color(strip, 0, r, g, b, w)
s.commit()
time.sleep(interval)
loop += 1

View file

@ -1,46 +0,0 @@
#!/usr/bin/env python3
import sk6812_multistrip as sk6812
import math
import sys
import time
import random
s = sk6812.SK6812(sys.argv[1], 2703)
s.set_fadestep(1)
s.commit()
time.sleep(3)
s.set_fadestep(1)
nled = 16
nstrip = 8
interval = 1/20
for led in range(nled):
for strip in range(nstrip):
s.fade_color(strip, led, 0, 0, 0, 0)
s.commit()
loop = 0
while loop < nled:
led = loop
for strip in range(nstrip):
intensity = 48 + random.randint(0, 32)
g = 0
r = intensity * loop // nled
b = 1*(intensity - intensity * loop // nled) / 2
w = 0
s.set_color(strip, led, r, g, b, w)
s.fade_color(strip, led, 0, 0, 0, 0)
s.commit()
time.sleep(interval)
loop += 1