Performance woes with 690 dotstar pixels from pi

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
joshkpeterson
 
Posts: 5
Joined: Fri Oct 15, 2010 2:44 am

Performance woes with 690 dotstar pixels from pi

Post by joshkpeterson »

I'm running on a 3B+ , essentially using the pi as an sACN receiver and to control some dotstars.

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()

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”