led_pillar

Documentation: http://frombelow.net/projects/led_pillar/
Clone: git clone https://git.frombelow.net/led_pillar.git
Log | Files | Refs | Submodules | README | LICENSE

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)