1

如果这不是问的正确地方,我深表歉意,但我进行了一些搜索,但找不到太多可以为我指明正确方向的地方。我不太确定要搜索什么。我是 python 和一般编程的新手,但通常可以做足够的谷歌搜索和窃取其他代码片段来让我的项目运行。但是,我在这里遇到了一些障碍。

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

这一切目前都有效,只是它显然只运行每种模式一次。我在一个while循环中完成了这一切,它只是永远循环了第一个选择的模式,我无法关闭它或切换模式。我还想也许我应该使用多处理,并且我研究过让它工作,但我不知道如何在进程启动后停止它。

这是灯带脚本:

(“关闭”模式只是一个黑色图像。我确信有一种更清洁的方法可以做到这一点,但我也不确定如何做到这一点)

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)

我再次在这里有点不知所措,这可能是简单的修复,或者我可能完全错误地接近它,但任何和所有的帮助将不胜感激。我是解决此类问题的完整初学者。谢谢

4

1 回答 1

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()
于 2017-04-25T06:04:11.450 回答