Using OLA and the older python2 adafruit dotstar library: https://github.com/adafruit/Adafruit_DotStar_Pi
I have 690 pixels daisy chained with dotstars of different lengths.
I'm kind of pinned between two issues - at 32mHz spi there's a bunch of really bad multicolored flicker happening, just noise. Does this suggest anything? Data line is like 1 meter long, I have like a 150 ohm resistor in series on each wire before going into the dotstar. Power jumps running long the length between different strips.
If I go as low as 4mHz, it looks great. But while receiving on 1 universe, with updates coming in at 100 hz, .show() lags a lot at 690 pixels. In other words, the sine wave fade up and down I'm sending happens, just more slowly and with a time delay that gets bigger and bigger. But at like 350 pixel length it's fine.
Is this expected performance, or am I doing something wrong? I wanted to be able to receive on 6 universes. With 6 universes running, even 10hz updates starts producing both noise and lag.
I've tried increasing the spi buffer but I don't really know what that's for, didn't make a difference. Also sending raw colors didn't seem to improve perf appreciably.
How can I get this level of performance? With this number of strips, are people bitbanging but then using multiple pins and then running each out to different strips?
Here's my code:
Code: Select all
#!/usr/bin/env python
"""
Receives dmx over ethernet (e1.31/sACN) and outputs dotstar LED strip control
via SPI.
"""
import time
from dotstar import Adafruit_DotStar
from ola.ClientWrapper import ClientWrapper
from functools import partial
# Scale brightness by percent 0 to 100
BRIGHTNESS_SCALAR = 80
NUM_PIXELS = 690 # Number of LEDs in strip(s)
# NUM_PIXELS = 144 # Number of LEDs in strip(s)
UNIVERSES_LIST = [15, 16, 17, 3, 2, 4] # order doesn't matter
# SPI (pins 10=MOSI, 11=SCLK)
# Full pi clock speed:
# strip = Adafruit_DotStar(NUM_PIXELS)
# More conservative 32MHz SPI:
strip = Adafruit_DotStar(NUM_PIXELS, 4000000, order="bgr")
# If colors are wrong, try adjusting order of rgb letters above
strip.begin() # Initialize pins for output
strip.setBrightness(BRIGHTNESS_SCALAR) # Limit brightness
strip.show() # Refresh strip
# OLA calls this per universe whenever a new piece of data is received over sACN
def NewData(universe, data):
u = universe
print(data)
strip.show() # Refresh strip
values = enumerate(data)
rgb = []
pixel_i = 0
pixel_offset = 0
# each universe controls up to a certain index (not necessarily using full universe):
max_u_pixel = 512
if u is 15:
pixel_offset = 0
max_u_pixel = 282
if u is 16:
pixel_offset = 94
max_u_pixel = 392
elif u is 17:
pixel_offset = 226
max_u_pixel = 393
elif u is 2:
pixel_offset = 390
max_u_pixel = 429
elif u is 4:
pixel_offset = 643
max_u_pixel = 512
elif u is 3:
max_u_pixel = 429
# if universe is 3, also see below
for i, val in values:
# Keeps us from setting values in other universe's territory
if (i < max_u_pixel):
rgb_index = i % 3
# Every 3rd index, set the pixel color
if i != 0 and rgb_index == 0:
if u is 3:
if i < 331:
pixel_offset = 533
elif i >= 331:
pixel_offset = 357
# Send values for previous 3 indexes to pixel
strip.setPixelColor(pixel_i + pixel_offset, rgb[0], rgb[1], rgb[2])
# Start over
rgb = []
rgb.append(val)
pixel_i += 1
else:
rgb.append(val)
wrapper = ClientWrapper()
client = wrapper.Client()
for u in UNIVERSES_LIST:
client.RegisterUniverse(u, client.REGISTER, partial(NewData, u))
wrapper.Run()