硬件
6英尺圣诞树
可寻址的WS2811 LED灯带(3x50足以满足此树的大小)
Raspberry Pi零W
电压电平转换器(3.3V至5V)
电源
软件
将rpi_ws281x Python示例用作控制LED的基本库
在特定端口上提供的Flask应用程序,该应用程序转发到Internet(通过IFTTT控制) )
webcolors
库可在颜色名称和RGB值之间进行映射/> 用特定颜色擦拭(以颜色名称命名)
“彩虹”图案
“疯狂”图案(在
rpi_ws281x
示例中也称为“剧院追逐”)“停止”-熄灭-所有LED变黑
代码
烧瓶部分
from flask import Flask
from libs import LEDStrip
app = Flask(__name__)
led_strip = LEDStrip(count=150)
@app.route('/wipe/<color>')
def wipe_color(color):
led_strip.color_wipe(color)
return "Wipe with {color} - success!".format(color=color)
@app.route('/rainbow')
def rainbow():
led_strip.rainbow()
led_strip.rainbow_cycle()
return "Rainbow animation executed successfully!"
@app.route('/crazy')
def crazy():
led_strip.theater_chase_rainbow()
return "Crazy christmas tree animation executed successfully!"
@app.route('/stop')
def stop():
led_strip.clear()
return "Christmas tree was turned off!"
libs.py
import time
from webcolors import name_to_rgb
from neopixel import *
from exceptions import ColorNotFoundException
def wheel(pos):
"""Generate rainbow colors across 0-255 positions."""
if pos < 85:
return Color(pos * 3, 255 - pos * 3, 0)
elif pos < 170:
pos -= 85
return Color(255 - pos * 3, 0, pos * 3)
else:
pos -= 170
return Color(0, pos * 3, 255 - pos * 3)
class LEDStrip:
def __init__(self, count,
pin=18, frequency=800000,
dma=5, brightness=255,
invert=False, channel=0,
strip_type=ws.WS2811_STRIP_RGB):
"""
LED strip abstraction class.
:param count: number of LED pixels
:param pin: GPIO pin connected to the pixels (18 uses PWM!)
:param frequency: LED signal frequency in hertz (usually 800khz)
:param dma: DMA channel to use for generating signal
:param brightness: set to 0 for darkest and 255 for brightest
:param invert: True to invert the signal (when using NPN transistor level shift)
:param channel: set to '1' for GPIOs 13, 19, 41, 45 or 53
:param strip_type: strip type and colour ordering
"""
self.led_count = count
self.strip = Adafruit_NeoPixel(count, pin, frequency, dma, invert, brightness, channel, strip_type)
self.strip.begin()
def clear(self):
self.color_wipe("black")
def color_wipe(self, color, wait_ms=30):
"""Wipe color across display a pixel at a time."""
try:
color_value = Color(*name_to_rgb(color))
except ValueError:
raise ColorNotFoundException("Color {color} not found.".format(color=color))
for led_number in range(self.led_count):
self.strip.setPixelColor(led_number, color_value)
self.strip.show()
time.sleep(wait_ms / 1000.0)
def theater_chase(self, color, wait_ms=50, iterations=10):
"""Movie theater light style chaser animation."""
for j in range(iterations):
for q in range(3):
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
self.strip.show()
time.sleep(wait_ms / 1000.0)
for led_number in range(0, self.led_count, 3):
self.strip.setPixelColor(led_number + q, 0)
def rainbow(self, wait_ms=20, iterations=1):
"""Draw rainbow that fades across all pixels at once."""
for j in range(256 * iterations):
for led_number in range(self.led_count):
self.strip.setPixelColor(led_number, wheel((led_number + j) & 255))
self.strip.show()
time.sleep(wait_ms / 1000.0)
def rainbow_cycle(self, wait_ms=20, iterations=5):
"""Draw rainbow that uniformly distributes itself across all pixels."""
for j in range(256 * iterations):
for led_number in range(self.led_count):
self.strip.setPixelColor(led_number, wheel((int(led_number * 256 / self.led_count) + j) & 255))
self.strip.show()
time.sleep(wait_ms / 1000.0)
def theater_chase_rainbow(self, wait_ms=50):
"""Rainbow movie theater light style chaser animation."""
for j in range(256):
for q in range(3):
for led_number in range(0, self.led_count, 3):
self.strip.setPixelColor(led_number + q, wheel((led_number + j) % 255))
self.strip.show()
time.sleep(wait_ms / 1000.0)
for led_number in range(0, self.led_count, 3):
self.strip.setPixelColor(led_number + q, 0)
exceptions.py
class ChristmasError(BaseException):
pass
class ColorNotFoundException(ChristmasError):
pass
除了Google Home和Alexa语音控制功能外,例如“ Okay Google-Turn the Christmas “绿树成荫”和“好的Google-创造彩虹”,将其与运动传感器和其他智能设备连接起来非常有趣。
您对
LEDStrip
类和flask应用程序的总体设计有何看法?您认为我可以改善什么?我也很感激关于如何在圣诞节期间继续使它变得更有趣的任何想法。请注意,已经有很多事情可以解决安全问题。
#1 楼
我建议将着色和动画处理分开。现在,特别是
theater_chase_rainbow
复制了其他方法中的代码。而是让theater_chase
将颜色数组作为参数。如果再添加一些动画样式和配色方案,则可以尝试所有组合获得\ $ O(n ^ 2)\ $的乐趣。在我看来,这段代码
i + q
可能溢出led_count
如果不是3的倍数,那么我会使用for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
/>
评论
我想知道为什么您的ColourNotFoundException需要调用Christmas Error。不能仅将其设置为ColourNotFoundException(BaseException)类:pass。 P.S对不起,如果这个问题很愚蠢,我什至不知道你能做到。或者你可以做ColourNotFoundException = Exception(“”)
@ 13ros27我已经习惯了以这种方式定义自定义异常,以简化调试并在错误处理和模块化方面提供更好的可读性。就我而言,这只是一个自定义例外,除了基本例外,但我希望(双关语意)模块会增加并解决这一问题。.谢谢!