commit 99e164bfd0c52ca416745e8eab05bc2fefe8d41b
parent d946424604e3872f9e28c087d26e82a22f5100df
Author: Gerd Beuster <gerd@frombelow.net>
Date: Sat, 1 Aug 2020 11:32:04 +0200
Adapted for Raspberry Pi Zero W
Diffstat:
5 files changed, 79 insertions(+), 38 deletions(-)
diff --git a/README.txt b/README.txt
@@ -0,0 +1,25 @@
+Installation
+============
+
+The following packages are required:
+python3-flask python3-pip python3-rpi.gpio python3-pygame xvfb
+
+Run as root:
+pip3 install rpi_ws281x
+
+Running
+=======
+
+Start manually with
+sudo FLASK_APP=main.py flask run --host=0.0.0.0
+
+To start automatically, add
+cd /home/pi/20191224_raspi_ws2811/; FLASK_APP=main.py nohup flask run --host=0.0.0.0 &
+to rc.local.
+
+BUGS
+====
+
+When connecting LED strip via SPI (Pin 10), some patterns turn the LED
+strip on with full power. Do not use! Add a 5 A fuse in power line of
+LED strip!
diff --git a/flowing_colors.py b/flowing_colors.py
@@ -119,7 +119,7 @@ class FlowingColorsRGB(patterns.Pattern):
self.strip.setPixelColor(self.xy2i(x, y),
Color(int(r[x][y]), int(g[x][y]), int(b[x][y])))
self.strip.show()
- time.sleep(.1)
+ # time.sleep(.1)
def sin_x_y_avg(self, period_offset, m_out):
# period_offset are passed as instances of RandomWalker. We have to get the
@@ -168,4 +168,4 @@ class FlowingColorsHSV(FlowingColorsRGB):
(r, g, b) = hsv2rgb((h[x][y]+self.hue_offset.val) % 360, 1, 1)
self.strip.setPixelColor(self.xy2i(x, y), Color(int(r), int(g), int(b)))
self.strip.show()
- time.sleep(.1)
+ # time.sleep(.1)
diff --git a/main.py b/main.py
@@ -36,15 +36,21 @@ LED_MATRIX_WIDTH = 34.7
LED_MATRIX_HEIGHT = 21
LED_STRIP_SNAKE = False
-# LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!) - requires root!
-LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0) - user must be in group gpio!
+LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!) - requires root!
+# WARNING! Does not work reliably when connected via SPI interface.
+# LED strip turns full power with some patterns! DO NOT USE!
+# LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0) - user must be in group gpio!
LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10 # DMA channel to use for generating signal (try 10)
# Set to 0 for darkest and 255 for brightest
# LED_BRIGHTNESS = 255
+# LED_BRIGHTNESS = 128
+# LED_BRIGHTNESS = 96 # Max brightness for 720 LEDs with a 5 A fuse
+# LED_BRIGHTNESS = 64
+# LED_BRIGHTNESS = 32
# LED_BRIGHTNESS = 16
-LED_BRIGHTNESS = 8
-# LED_BRIGHTNESS = 4
+# LED_BRIGHTNESS = 8
+LED_BRIGHTNESS = 4
# LED_BRIGHTNESS = 2
# LED_BRIGHTNESS = 1
LED_INVERT = False # True to invert the signal (when using NPN transistor level shift)
@@ -59,15 +65,17 @@ LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53
# numbers can be used to pass additional information for a specific
# mode.
-MODE_RGB = 0
-MODE_WORM = 1
-MODE_CELLULAR_AUTOMATON = 2
-MODE_BLUE_GREEN_FLAMES = 3
-MODE_FLOW_RGB = 4
-MODE_FLOW_HSV = 5
-MODE_TEST_PATTERN = 6
-
-mode = [MODE_BLUE_GREEN_FLAMES]
+MODE_OFF = 0
+MODE_RGB = 1
+MODE_WORM = 2
+MODE_CELLULAR_AUTOMATON = 3
+MODE_BLUE_GREEN_FLAMES = 4
+MODE_FLOW_RGB = 5
+MODE_FLOW_HSV = 6
+MODE_TEST_PATTERN = 7
+
+mode = [MODE_OFF]
+#mode = [MODE_BLUE_GREEN_FLAMES]
#mode = [MODE_WORM]
#mode = [MODE_CELLULAR_AUTOMATON]
#mode = [MODE_FLOW_RGB]
@@ -91,6 +99,7 @@ def run(cmd_queue=None):
p.stop()
current_mode = mode
p = {
+ MODE_OFF : patterns.Off,
MODE_RGB : patterns.RGB,
MODE_WORM : patterns.Worm,
MODE_CELLULAR_AUTOMATON : cellular_automaton.CellularAutomaton,
@@ -112,19 +121,27 @@ run.start()
# Run webserver in this process
app = Flask(__name__)
+# Default colors
+red = 0
+green = 0
+blue = 0
@app.route('/', methods=['GET', 'POST'])
@app.route('/index.php', methods=['GET', 'POST'])
def hello_world():
# In general, we accept both GET and POST request,
# but for technical reasons, RGB values come only as GET requests.
- (r, g, b) = (int(request.args.get('red', '0')),
- int(request.args.get('green', '0')),
- int(request.args.get('blue', '0')))
+ global red
+ global green
+ global blue
+ (red, green, blue) = (int(request.args.get('red', red)),
+ int(request.args.get('green', green)),
+ int(request.args.get('blue', blue)))
mode = request.args.get('mode', None)
if not mode:
mode = request.form.get('mode', None)
if mode != None:
- mode_number = {'rgb': [MODE_RGB, r, g, b],
+ mode_number = {'off': [MODE_OFF],
+ 'rgb': [MODE_RGB, red, green, blue],
'worm': [MODE_WORM],
'cellular': [MODE_CELLULAR_AUTOMATON],
'flames': [MODE_BLUE_GREEN_FLAMES],
@@ -133,5 +150,4 @@ def hello_world():
'test': [MODE_TEST_PATTERN]
}[mode]
cmd_queue.put(mode_number)
- # pdb.set_trace()
- return render_template('index.html')
+ return render_template('index.html', red=red, green=green, blue=blue)
diff --git a/patterns.py b/patterns.py
@@ -43,6 +43,10 @@ class Pattern():
i += x
return math.floor(i)
+class Off(Pattern):
+ def __init__(self, strip, led_matrix_width, led_matrix_height, led_strip_snake, opts=None):
+ Pattern.__init__(self, strip=strip, led_matrix_width=led_matrix_width, led_matrix_height=led_matrix_height, led_strip_snake = led_strip_snake, opts=opts)
+ self.clear_strip()
class TestPattern(Pattern):
@@ -52,12 +56,6 @@ class TestPattern(Pattern):
def __init__(self, strip, led_matrix_width, led_matrix_height, led_strip_snake, opts=None):
Pattern.__init__(self, strip=strip, led_matrix_width=led_matrix_width, led_matrix_height=led_matrix_height, led_strip_snake = led_strip_snake, opts=opts)
- # Initialize dummy display
- os.environ["SDL_VIDEODRIVER"] = "dummy"
- subprocess.Popen(["Xvfb", ":1", "-screen", "0", "1024x768x24"],
- stderr=subprocess.DEVNULL)
- time.sleep(1)
- os.environ["DISPLAY"] = ":1"
pygame.display.init()
self.x = 0
@@ -81,10 +79,12 @@ class TestPattern(Pattern):
class RGB(Pattern):
def __init__(self, strip, led_matrix_width, led_matrix_height, led_strip_snake, opts=None):
Pattern.__init__(self, strip=strip, led_matrix_width=led_matrix_width, led_matrix_height=led_matrix_height, led_strip_snake = led_strip_snake, opts=opts)
- (r, g, b) = opts
+ (self.r, self.g, self.b) = opts
+
+ def step(self):
for i in range(math.ceil(self.led_matrix_width*self.led_matrix_height)):
- strip.setPixelColor(i, Color(r, g, b))
- strip.show()
+ self.strip.setPixelColor(i, Color(self.r, self.g, self.b))
+ self.strip.show()
@@ -131,4 +131,3 @@ class Worm(Pattern):
time.sleep(.04)
-
diff --git a/templates/index.html b/templates/index.html
@@ -2,7 +2,7 @@
<html lang="de">
<head>
<meta charset="utf-8">
- <title>LED-Steuerung</title>
+ <title>LED-Säule</title>
<style>
button{width:10em;}
@media only screen and (max-device-width: 1024px){
@@ -17,16 +17,17 @@ button{font-size : 190%; width:10em;}
</style>
</head>
<body>
- <h1>LED-Steuerung</h1>
- <form action="/" method="POST">
+ <h1>LED-Säule</h1>
+ <form action="/" method="POST">
<div class="slidecontainer">
- R <input type="range" min="0" max="255" value="0" class="slider" id="slider_red">
+ R <input type="range" min="0" max="255" value="{{ red }}" class="slider" id="slider_red">
<label id="label_red"></label><br />
- G <input type="range" min="0" max="255" value="0" class="slider" id="slider_green">
+ G <input type="range" min="0" max="255" value="{{ green }}" class="slider" id="slider_green">
<label id="label_green"></label><br />
- B <input type="range" min="0" max="255" value="0" class="slider" id="slider_blue">
+ B <input type="range" min="0" max="255" value="{{ blue }}" class="slider" id="slider_blue">
<label id="label_blue"></label><br />
</div><br />
+ <button type="submit" name="mode" value="off">Aus</button><br /><br />
<button type="submit" name="mode" value="worm">Wurm</button><br /><br />
<button type="submit" name="mode" value="cellular">Zellulärer Automat</button><br /><br />
<button type="submit" name="mode" value="flames">Feuer</button><br /><br />
@@ -34,9 +35,9 @@ button{font-size : 190%; width:10em;}
<button type="submit" name="mode" value="flow_hsv">Flow (HSV)</button><br /><br />
<button type="submit" name="mode" value="test">Testmuster</button><br /><br />
</form>
- <p><a href="config.html"</a>Konfigurieren</a></p>
<!-- Update slider on the fly -->
<script>
+ <!-- Handle RGB sliders -->
var slider_red = document.getElementById("slider_red");
var label_red = document.getElementById("label_red");
var slider_green = document.getElementById("slider_green");