adafruit / Adafruit_DotStar_Pi

DotStar module for Python on Raspberry Pi
GNU General Public License v3.0
60 stars 30 forks source link

.show() is slow at 8mHz #25

Closed joshkpeterson closed 5 years ago

joshkpeterson commented 5 years ago

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

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. At like 350 pixel length it's fine. Is this expected performance, or am I doing something wrong?

I've tried increasing the spi buffer but I don't really know what that's for, didn't make a difference.

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: `#!/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()`

ladyada commented 5 years ago

you try the newer circuitpython library, you can change the SPI frequency and you can 'fairly' easily set up 2 SPI buses, so at least you can cut your strip in half. but yeah, you either get fast SPI (maybe too fast for dotstar) or slow bitbang

joshkpeterson commented 5 years ago

Thanks for your help!

If you have a minute could you elaborate on "spi too fast for dotstar" - are you talking about with circuitpython or are you saying in general 32mhz is above dotstar's capability to parse?

(At the time of writing, OLA doesn't support python 3 but for people reading this in the future theyre working on it)

On Tue, Nov 13, 2018 at 12:41 AM ladyada notifications@github.com wrote:

you try the newer circuitpython library, you can change the SPI frequency and you can 'fairly' easily set up 2 SPI buses, so at least you can cut your strip in half. but yeah, you either get fast SPI (maybe too fast for dotstar) or slow bitbang

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_DotStar_Pi/issues/25#issuecomment-438144131, or mute the thread https://github.com/notifications/unsubscribe-auth/ACMBsgPGusB0xPKEsPldtCGIGloxkx1Hks5uulungaJpZM4Ya7LZ .

ladyada commented 5 years ago

the longer the dotstar strip, the slower you have to clock it - the later chips can't catch up.

joshkpeterson commented 5 years ago

How much slower is bitbanging?

On Tue, Nov 13, 2018 at 1:13 AM ladyada notifications@github.com wrote:

the longer the dotstar strip, the slower you have to clock it - the later chips can't catch up.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_DotStar_Pi/issues/25#issuecomment-438149935, or mute the thread https://github.com/notifications/unsubscribe-auth/ACMBsuqoRMb_wv2FxKvSq3Hb5cMpQVf0ks5uumMTgaJpZM4Ya7LZ .