main.py (5187B)
1 #!/usr/bin/env python3 2 3 from multiprocessing import Queue, Process 4 from flask import Flask, render_template, request 5 from rpi_ws281x import PixelStrip, Color 6 import math 7 8 # Patterns 9 import patterns 10 import cellular_automaton 11 import blue_green_flames 12 import flowing_colors 13 14 # LED strip/matrix configuration 15 16 # Matrix 17 #LED_MATRIX_WIDTH = 16 18 #LED_MATRIX_HEIGHT = 16 19 # Is row layout of LEDs is left-right, right-left, left-right, ... 20 # or left-right, left-right, left-right, ...? 21 #LED_STRIP_SNAKE = True 22 23 # Strip 24 #LED_MATRIX_WIDTH = 299 25 #LED_MATRIX_HEIGHT = 1 26 #LED_STRIP_SNAKE = False 27 28 # Pipe with 5 m LED strip, density 60 LEDs / m 29 #LED_MATRIX_WIDTH = 14.5 30 #LED_MATRIX_HEIGHT = 21 31 #LED_STRIP_SNAKE = False 32 33 # Pipe with 5 m LED strip, density 144 LEDs / m 34 LED_MATRIX_WIDTH = 34.7 35 LED_MATRIX_HEIGHT = 21 36 LED_STRIP_SNAKE = False 37 38 LED_PIN = 18 # GPIO pin connected to the pixels (18 uses PWM!) - requires root! 39 # WARNING! Does not work reliably when connected via SPI interface. 40 # LED strip turns full power with some patterns! DO NOT USE! 41 # LED_PIN = 10 # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0) - user must be in group gpio! 42 LED_FREQ_HZ = 800000 # LED signal frequency in hertz (usually 800khz) 43 LED_DMA = 10 # DMA channel to use for generating signal (try 10) 44 # Set to 0 for darkest and 255 for brightest 45 # LED_BRIGHTNESS = 255 46 # LED_BRIGHTNESS = 128 47 # LED_BRIGHTNESS = 96 # Max brightness for 720 LEDs with a 5 A fuse 48 # LED_BRIGHTNESS = 64 49 # LED_BRIGHTNESS = 32 50 # LED_BRIGHTNESS = 16 51 # LED_BRIGHTNESS = 8 52 LED_BRIGHTNESS = 4 53 # LED_BRIGHTNESS = 2 54 # LED_BRIGHTNESS = 1 55 LED_INVERT = False # True to invert the signal (when using NPN transistor level shift) 56 LED_CHANNEL = 0 # set to '1' for GPIOs 13, 19, 41, 45 or 53 57 58 59 60 # Pattern display 61 62 # The mode is passed to the run function via a queue. Modes are passed 63 # as lists, where the first element is the mode number and subsquent 64 # numbers can be used to pass additional information for a specific 65 # mode. 66 67 MODE_OFF = 0 68 MODE_RGB = 1 69 MODE_WORM = 2 70 MODE_CELLULAR_AUTOMATON = 3 71 MODE_BLUE_GREEN_FLAMES = 4 72 MODE_FLOW_RGB = 5 73 MODE_FLOW_HSV = 6 74 MODE_TEST_PATTERN = 7 75 76 mode = [MODE_OFF] 77 #mode = [MODE_BLUE_GREEN_FLAMES] 78 #mode = [MODE_WORM] 79 #mode = [MODE_CELLULAR_AUTOMATON] 80 #mode = [MODE_FLOW_RGB] 81 #mode = [MODE_FLOW_HSV] 82 83 def run(cmd_queue=None): 84 global mode 85 # Create NeoPixel object with appropriate configuration. 86 strip = PixelStrip(math.ceil(LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT), LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL) 87 # Intialize the library (must be called once before other functions). 88 strip.begin() 89 # This will be immediately replaced by the actual initial mode. 90 p = patterns.Pattern(strip, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT, LED_STRIP_SNAKE) 91 current_mode = [-1] 92 try: 93 while True: 94 while cmd_queue and (not cmd_queue.empty()): 95 mode = cmd_queue.get_nowait() 96 if current_mode != mode: 97 # External mode switch 98 p.stop() 99 current_mode = mode 100 p = { 101 MODE_OFF : patterns.Off, 102 MODE_RGB : patterns.RGB, 103 MODE_WORM : patterns.Worm, 104 MODE_CELLULAR_AUTOMATON : cellular_automaton.CellularAutomaton, 105 MODE_BLUE_GREEN_FLAMES : blue_green_flames.BlueGreenFlames, 106 MODE_FLOW_RGB : flowing_colors.FlowingColorsRGB, 107 MODE_FLOW_HSV : flowing_colors.FlowingColorsHSV, 108 MODE_TEST_PATTERN : patterns.TestPattern 109 }[current_mode[0]](strip, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT, LED_STRIP_SNAKE, current_mode[1:]) 110 p.step() 111 except KeyboardInterrupt: 112 p.clear_strip() 113 p.stop() 114 115 # Run patterns in separate process 116 cmd_queue = Queue() 117 run = Process(target=run, args=(cmd_queue,)) 118 run.start() 119 120 # Run webserver in this process 121 app = Flask(__name__) 122 123 # Default colors 124 red = 0 125 green = 0 126 blue = 0 127 @app.route('/', methods=['GET', 'POST']) 128 @app.route('/index.php', methods=['GET', 'POST']) 129 def hello_world(): 130 # In general, we accept both GET and POST request, 131 # but for technical reasons, RGB values come only as GET requests. 132 global red 133 global green 134 global blue 135 (red, green, blue) = (int(request.args.get('red', red)), 136 int(request.args.get('green', green)), 137 int(request.args.get('blue', blue))) 138 mode = request.args.get('mode', None) 139 if not mode: 140 mode = request.form.get('mode', None) 141 if mode != None: 142 mode_number = {'off': [MODE_OFF], 143 'rgb': [MODE_RGB, red, green, blue], 144 'worm': [MODE_WORM], 145 'cellular': [MODE_CELLULAR_AUTOMATON], 146 'flames': [MODE_BLUE_GREEN_FLAMES], 147 'flow_rgb': [MODE_FLOW_RGB], 148 'flow_hsv': [MODE_FLOW_HSV], 149 'test': [MODE_TEST_PATTERN] 150 }[mode] 151 cmd_queue.put(mode_number) 152 return render_template('index.html', red=red, green=green, blue=blue)