Raspberry Pi - Python&使用Adafruit DotStar LEDS进行烧瓶网络控制

时间:2017-04-18 17:29:26

标签: python flask raspberry-pi led adafruit

如果这不是一个正确的问题,请道歉,但我做了一些搜索,并没有找到太多指向我正确的方向。我不太清楚要搜索什么。我一般是python和编程的新手,但通常可以做足够的谷歌搜索和窃取其他代码片段来让我的项目运行。不过我在这里遇到了一些障碍。

我需要使用烧瓶网络浏览器应用程序控制Adafruit DotStar lighttrip。我已经能够让烧瓶应用程序工作,我已经做了一个简单的概念验证,打开和关闭LED等等,我可以启动我的灯光脚本,但我试图为灯光运行的代码需要循环,仍然能够改变“模式”。我有几个不同的图像显示在灯条上,我希望能够选择正在播放哪一个,但现在主要是我希望能够启动和停止“随机播放”模式。如果我在while循环中运行模块,它只是永远循环,我不能将参数更改为不同的“模式”。我建立了一个基于Adafruit的DotStar库的简单脚本(特别是视觉脚本的图像持久性,我只是使用PNG图像作为不同灯光“地图”的地图)。

这一切目前都有效,除了它只能显然运行一次模式。我在一个循环中完成了所有这一切,它只是永远循环第一个选定的模式,我无法将其关闭或切换模式。我也想过也许我应该使用多处理,然后我开始研究它是否正常工作,但是一旦它开始,我就无法弄清楚如何停止它。

这是灯条脚本:

('关闭'模式只是一个黑色图像。我确信这是一个更干净的方法,但我不知道如何做到这一点)

import Image
from dotstar import Adafruit_DotStar
import random

def lightstrip(mode):
    loopLength = 120        #loop length in pixels

    fade  = "/home/pi/lightshow/images/fade.png"
    sparkle = "/home/pi/lightshow/images/sparkle.png"
    steeplechase = "/home/pi/lightshow/images/steeplechase.png"
    bump = "/home/pi/lightshow/images/bump.png"
    spaz = "/home/pi/lightshow/images/spaz.png"
    sine = "/home/pi/lightshow/images/sine.png"
    bounce = "/home/pi/lightshow/images/bounce.png"
    off = "/home/pi/lightshow/images/null.png"

    numpixels = 30
    datapin   = 23
    clockpin  = 24
    strip     = Adafruit_DotStar(numpixels, 100000)

    rOffset = 3
    gOffset = 2
    bOffset = 1

    strip.begin()

    if mode == 1:
        options = [fade, sparkle, steeplechase, bump, spaz, sine, bounce]
        print "Shuffling All..."
    if mode == 2:
        options = [bump, spaz, sine, bounce]
        print "Shuffling Dance..."
    if mode == 3:
        options = [fade, sparkle, steeplechase]
        print "Shuffling Chill..."
    if mode == 0:
        choice = off
        print "Lightstrip off..."

    if mode != 0:
        choice = random.choice(options)
    print "Loading..."
    img       = Image.open(choice).convert("RGB")
    pixels    = img.load()
    width     = img.size[0]
    height    = img.size[1]
    print "%dx%d pixels" % img.size

    # Calculate gamma correction table, makes mid-range colors look 'right':
    gamma = bytearray(256)
    for i in range(256):
        gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5)

    # Allocate list of bytearrays, one for each column of image.
    # Each pixel REQUIRES 4 bytes (0xFF, B, G, R).
    print "Allocating..."
    column = [0 for x in range(width)]
    for x in range(width):
        column[x] = bytearray(height * 4)

    # Convert entire RGB image into column-wise BGR bytearray list.
    # The image-paint.py example proceeds in R/G/B order because it's counting
    # on the library to do any necessary conversion.  Because we're preparing
    # data directly for the strip, it's necessary to work in its native order.
    print "Converting..."
    for x in range(width):          # For each column of image...
        for y in range(height): # For each pixel in column...
            value             = pixels[x, y]    # Read pixel in image
            y4                = y * 4           # Position in raw buffer
            column[x][y4]     = 0xFF            # Pixel start marker
            column[x][y4 + rOffset] = gamma[value[0]] # Gamma-corrected R
            column[x][y4 + gOffset] = gamma[value[1]] # Gamma-corrected G
            column[x][y4 + bOffset] = gamma[value[2]] # Gamma-corrected B

    print "Displaying..."
    count = loopLength
    while (count > 0):

        for x in range(width):         # For each column of image...
            strip.show(column[x])  # Write raw data to strip
            count = count - 1

用于运行Web应用程序的main.py脚本:

from flask import *
from lightshow import *
from multiprocessing import Process
import RPi.GPIO as GPIO
import Image
from dotstar import Adafruit_DotStar
import random
import time

app = Flask(__name__)


@app.route("/")
def hello():
    return render_template('index.html')

@app.route("/lightstrip/1", methods=['POST'])
def shuffleall():
    lightstrip(1)
    return ('', 204)

@app.route("/lightstrip/2", methods=['POST'])   
def shuffledance():
    lightstrip(2)
    return ('', 204)

@app.route("/lightstrip/3", methods=['POST'])
def shufflechill():
    lightstrip(3)
    return ('', 204)

@app.route("/lightstrip/0", methods=['POST'])
def off():
    lightstrip(0)   
    return ('', 204)



if __name__ == "__main__":
    app.run(host='0.0.0.0', debug=True)

我再次在这里有点亏,这可能是一个简单的修复,或者我可能正在接近它完全错误,但任何和所有的帮助将不胜感激。我是一个完全初学者,可以解决这样的问题。谢谢

1 个答案:

答案 0 :(得分:0)

以下是一个示例,说明如何使用multiprocessingpsutil启动和停止流程。在此示例中,task_runner会在开始新进程之前终止所有正在运行的进程。

from flask import Flask
import multiprocessing
import psutil

app = Flask(__name__)

def blink(var):
    while True:
        # do stuff
        print(var)

def task_runner(var):
    processes = psutil.Process().children()
    for p in processes:
        p.kill()
    process = multiprocessing.Process(target=blink, args=(var,))
    process.start()

@app.route("/red")
def red():
    task_runner('red')
    return 'red started'

@app.route("/blue")
def blue():
    task_runner('blue')
    return 'blue started'

if __name__ == "__main__":
    app.run()

对于您的问题,task_runner看起来像:

def task_runner(mode):
    processes = psutil.Process().children()
    for p in processes:
        p.kill()
    process = multiprocessing.Process(target=lightstrip, args=(mode,))
    process.start()