Raspberry PI controllable Christmas Tree
up vote
19
down vote
favorite
After having the scales, thermometer and a coffeemaker connected to the internet, it is finally time for Christmas Tree to become smarter.
Hardware
- 6ft Christmas Tree
An addressable WS2811 LED strip (3x50 was good enough for this tree size)
Raspberry Pi Zero W
Voltage level shifter (3.3V to 5V)- Power Supply
Software
- used rpi_ws281x Python samples as a base library for controlling the LEDs
Flask app served at a specific port which is forwarded to the internet (to control via IFTTT)
webcolorslibrary to map between color names and RGB values
Currently, I've only implemented a few actions/patterns:
- wipe with a specific color (given as a color name)
- "rainbow" pattern
"crazy" pattern (also called "theater chase" in the
rpi_ws281xsamples)"stop" - turn off - all LEDs black
The Code
Flask part
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
Aside from Google Home & Alexa voice control abilities like "Okay Google - Turn the Christmas Tree green" and "Okay Google - Make a rainbow", it is a lot of fun connecting that with motion sensors and other smart devices.
What do you think about the overall design of the LEDStrip class and the flask app? What do you think I can improve? I would also appreciate any ideas about the ways I can continue making it more fun this Christmas.
Note that there is already a plenty of things to address security-wise.
python python-2.x flask raspberry-pi
add a comment |
up vote
19
down vote
favorite
After having the scales, thermometer and a coffeemaker connected to the internet, it is finally time for Christmas Tree to become smarter.
Hardware
- 6ft Christmas Tree
An addressable WS2811 LED strip (3x50 was good enough for this tree size)
Raspberry Pi Zero W
Voltage level shifter (3.3V to 5V)- Power Supply
Software
- used rpi_ws281x Python samples as a base library for controlling the LEDs
Flask app served at a specific port which is forwarded to the internet (to control via IFTTT)
webcolorslibrary to map between color names and RGB values
Currently, I've only implemented a few actions/patterns:
- wipe with a specific color (given as a color name)
- "rainbow" pattern
"crazy" pattern (also called "theater chase" in the
rpi_ws281xsamples)"stop" - turn off - all LEDs black
The Code
Flask part
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
Aside from Google Home & Alexa voice control abilities like "Okay Google - Turn the Christmas Tree green" and "Okay Google - Make a rainbow", it is a lot of fun connecting that with motion sensors and other smart devices.
What do you think about the overall design of the LEDStrip class and the flask app? What do you think I can improve? I would also appreciate any ideas about the ways I can continue making it more fun this Christmas.
Note that there is already a plenty of things to address security-wise.
python python-2.x flask raspberry-pi
I'm wondering why yourColourNotFoundExceptionneeds to callChristmas Error. Can it not be just set up asclass ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.
– 13ros27
Dec 23 '17 at 9:43
Or could you doColourNotFoundException = Exception("")
– 13ros27
Dec 23 '17 at 10:02
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23
add a comment |
up vote
19
down vote
favorite
up vote
19
down vote
favorite
After having the scales, thermometer and a coffeemaker connected to the internet, it is finally time for Christmas Tree to become smarter.
Hardware
- 6ft Christmas Tree
An addressable WS2811 LED strip (3x50 was good enough for this tree size)
Raspberry Pi Zero W
Voltage level shifter (3.3V to 5V)- Power Supply
Software
- used rpi_ws281x Python samples as a base library for controlling the LEDs
Flask app served at a specific port which is forwarded to the internet (to control via IFTTT)
webcolorslibrary to map between color names and RGB values
Currently, I've only implemented a few actions/patterns:
- wipe with a specific color (given as a color name)
- "rainbow" pattern
"crazy" pattern (also called "theater chase" in the
rpi_ws281xsamples)"stop" - turn off - all LEDs black
The Code
Flask part
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
Aside from Google Home & Alexa voice control abilities like "Okay Google - Turn the Christmas Tree green" and "Okay Google - Make a rainbow", it is a lot of fun connecting that with motion sensors and other smart devices.
What do you think about the overall design of the LEDStrip class and the flask app? What do you think I can improve? I would also appreciate any ideas about the ways I can continue making it more fun this Christmas.
Note that there is already a plenty of things to address security-wise.
python python-2.x flask raspberry-pi
After having the scales, thermometer and a coffeemaker connected to the internet, it is finally time for Christmas Tree to become smarter.
Hardware
- 6ft Christmas Tree
An addressable WS2811 LED strip (3x50 was good enough for this tree size)
Raspberry Pi Zero W
Voltage level shifter (3.3V to 5V)- Power Supply
Software
- used rpi_ws281x Python samples as a base library for controlling the LEDs
Flask app served at a specific port which is forwarded to the internet (to control via IFTTT)
webcolorslibrary to map between color names and RGB values
Currently, I've only implemented a few actions/patterns:
- wipe with a specific color (given as a color name)
- "rainbow" pattern
"crazy" pattern (also called "theater chase" in the
rpi_ws281xsamples)"stop" - turn off - all LEDs black
The Code
Flask part
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
Aside from Google Home & Alexa voice control abilities like "Okay Google - Turn the Christmas Tree green" and "Okay Google - Make a rainbow", it is a lot of fun connecting that with motion sensors and other smart devices.
What do you think about the overall design of the LEDStrip class and the flask app? What do you think I can improve? I would also appreciate any ideas about the ways I can continue making it more fun this Christmas.
Note that there is already a plenty of things to address security-wise.
python python-2.x flask raspberry-pi
python python-2.x flask raspberry-pi
edited Dec 23 '17 at 15:51
asked Dec 23 '17 at 4:30
alecxe
14.7k53378
14.7k53378
I'm wondering why yourColourNotFoundExceptionneeds to callChristmas Error. Can it not be just set up asclass ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.
– 13ros27
Dec 23 '17 at 9:43
Or could you doColourNotFoundException = Exception("")
– 13ros27
Dec 23 '17 at 10:02
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23
add a comment |
I'm wondering why yourColourNotFoundExceptionneeds to callChristmas Error. Can it not be just set up asclass ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.
– 13ros27
Dec 23 '17 at 9:43
Or could you doColourNotFoundException = Exception("")
– 13ros27
Dec 23 '17 at 10:02
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23
I'm wondering why your
ColourNotFoundException needs to call Christmas Error. Can it not be just set up as class ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.– 13ros27
Dec 23 '17 at 9:43
I'm wondering why your
ColourNotFoundException needs to call Christmas Error. Can it not be just set up as class ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.– 13ros27
Dec 23 '17 at 9:43
Or could you do
ColourNotFoundException = Exception("")– 13ros27
Dec 23 '17 at 10:02
Or could you do
ColourNotFoundException = Exception("")– 13ros27
Dec 23 '17 at 10:02
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23
add a comment |
1 Answer
1
active
oldest
votes
up vote
12
down vote
accepted
- I would suggest to separate the concerns of coloring and animating. Now, in particular
theater_chase_rainbowduplicates code from other methods. Instead, havetheater_chasetake a color array as parameter. If you then add some animation styles and color schemes you can have $O(n^2)$ amount of fun trying all combinations.
It seems to me that in this code
i + qcan overflowled_countif it is not a multiple of 3:
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
Instead, I would use
for i in range(q, self.led_count, 3):
self.strip.setPixelColor(i, color)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f183485%2fraspberry-pi-controllable-christmas-tree%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
- I would suggest to separate the concerns of coloring and animating. Now, in particular
theater_chase_rainbowduplicates code from other methods. Instead, havetheater_chasetake a color array as parameter. If you then add some animation styles and color schemes you can have $O(n^2)$ amount of fun trying all combinations.
It seems to me that in this code
i + qcan overflowled_countif it is not a multiple of 3:
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
Instead, I would use
for i in range(q, self.led_count, 3):
self.strip.setPixelColor(i, color)
add a comment |
up vote
12
down vote
accepted
- I would suggest to separate the concerns of coloring and animating. Now, in particular
theater_chase_rainbowduplicates code from other methods. Instead, havetheater_chasetake a color array as parameter. If you then add some animation styles and color schemes you can have $O(n^2)$ amount of fun trying all combinations.
It seems to me that in this code
i + qcan overflowled_countif it is not a multiple of 3:
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
Instead, I would use
for i in range(q, self.led_count, 3):
self.strip.setPixelColor(i, color)
add a comment |
up vote
12
down vote
accepted
up vote
12
down vote
accepted
- I would suggest to separate the concerns of coloring and animating. Now, in particular
theater_chase_rainbowduplicates code from other methods. Instead, havetheater_chasetake a color array as parameter. If you then add some animation styles and color schemes you can have $O(n^2)$ amount of fun trying all combinations.
It seems to me that in this code
i + qcan overflowled_countif it is not a multiple of 3:
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
Instead, I would use
for i in range(q, self.led_count, 3):
self.strip.setPixelColor(i, color)
- I would suggest to separate the concerns of coloring and animating. Now, in particular
theater_chase_rainbowduplicates code from other methods. Instead, havetheater_chasetake a color array as parameter. If you then add some animation styles and color schemes you can have $O(n^2)$ amount of fun trying all combinations.
It seems to me that in this code
i + qcan overflowled_countif it is not a multiple of 3:
for i in range(0, self.led_count, 3):
self.strip.setPixelColor(i + q, color)
Instead, I would use
for i in range(q, self.led_count, 3):
self.strip.setPixelColor(i, color)
edited 12 mins ago
alecxe
14.7k53378
14.7k53378
answered Dec 23 '17 at 12:37
Janne Karila
9,7031430
9,7031430
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f183485%2fraspberry-pi-controllable-christmas-tree%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I'm wondering why your
ColourNotFoundExceptionneeds to callChristmas Error. Can it not be just set up asclass ColourNotFoundException(BaseException): pass. P.S Sorry if the question is stupid, I didn't even know you could do that.– 13ros27
Dec 23 '17 at 9:43
Or could you do
ColourNotFoundException = Exception("")– 13ros27
Dec 23 '17 at 10:02
@13ros27 I've just a got a habit of defining custom exceptions this way, to ease debugging and to provide better readability in error-handling and modularity. In my case, it's just one custom exception except the base one but I expect (pun intended) the module to grow and accounted for that..thanks!
– alecxe
Dec 23 '17 at 20:23