adafruit / Adafruit_CircuitPython_NeoPixel

CircuitPython drivers for neopixels.
MIT License
304 stars 99 forks source link

NeoPixel_SPI unreliable #58

Closed tisfablab closed 4 years ago

tisfablab commented 4 years ago

I've tried to implement the SPI-Version of the NeoPixel library. My project uses audio (Raspberry Zero W with a Hifiberry Mini Amp), and I'm running out of alternatives for using color LEDs. (or am I missing something?)

But not all my color assignments to the pixels are showing.

So I've modified the blink program to test it thoroughly:

# This example shows how to create a single pixel with a specific color channel
# order and blink it.
# Most NeoPixels = neopixel.GRB or neopixel.GRBW
# The 8mm Diffused NeoPixel (PID 1734) = neopixel.RGB
import time
import board
import neopixel

# Configure the setup
COLOR = [ # color to blink
  (127, 0, 0), 
  (63, 63, 0),
  (0, 127, 0), 
  (0, 63, 63), 
  (0, 0, 127), 
  (63, 0, 63) 
  ]
CLEAR = (0, 0, 0)      # clear (or second color)
DELAY = 0.25           # blink rate in seconds

# Create the NeoPixel object
pixel = neopixel.NeoPixel_SPI(board.SPI(), 2, pixel_order=neopixel.RGB)

# Loop forever and blink the color
n = 0
while True:
    if n>5: n=0
    pixel.fill(COLOR[n])
    n=n+1
    time.sleep(DELAY)
    pixel.fill(CLEAR)
    time.sleep(DELAY)`

When running this program, the first iterations are missing, and after a few loops there appear gaps in the blink sequence. Is this due to some fault in the code or did I miss setting anything on my system? (SPI is enabled of course, and my Neopixel is attached to D10)

(I've installed the library with PIP on nov 30 2019)

ladyada commented 4 years ago

hi why are you trying NeoPixel SPI? im trying to figure out where its being suggested - for Pi its best to use plain NeoPixel library :)

tisfablab commented 4 years ago

I've tried using the "standard" NeoPixel class with board.D10 and board.D12 - but it did not work with my setup. (I know it works with board.D18, but that port is occupied by Hifiberry - and board.D21 as well)

I found a blog post from the end of October that that announced NeoPixel_SPI, and since I'm grasping for straws now I gave it a try. Of course, there's not much documentation for this class yet, but the code is documented well. (Only the _transmogrify method is black magic to me. :) )

ladyada commented 4 years ago

?? it should def work with D10, i think you're best off figuring out why. SPI neopixel here is a hack - not recommended for Pi!

@caternuson wanna add more not-for-pi warnings?

tisfablab commented 4 years ago

OK, thank you for the warning - I've tried again with "standard" NeoPixel class using D10. For this, I've changed one line, the rest remains the same:

# Create the NeoPixel object
pixel = neopixel.NeoPixel(board.D10, 2, pixel_order=neopixel.RGB)

The first few color changes work; then the led remains white. In my opinion, the result with NeoPixel_SPI was better. :)

I'm running max2play on a Raspberry Zero, have an NFC reader connected via I2C and a Hifiberry DAC is playing music (and I use a few other GPIO pins for input, but those shouldn't matter). Do you see anything here that might hamper WS2812 control?

ladyada commented 4 years ago

hard to know without an oscilloscope or logic analyzer output :/

tisfablab commented 4 years ago

OK, so there'll be some debugging to do. I'll try to find some time for it at the Maker Space, and if I find out anything I'll come back to you. Nevertheless many thanks!

dhalbert commented 4 years ago

@tisfablab Are you the same person as the poster in this thread? https://forums.adafruit.com/viewtopic.php?f=60&t=159137&p=784695. That person mentioned they were using RGBW strips. I asked that person to try pixel_order=neopixel.GRBW. If you are that person, did you try that?

tisfablab commented 4 years ago

@dhalbert no. I'm using single 5mm RGB WS281x I've tried setting the pixel order to RGBW as well. I just don't remember with which other permutation of settings version of NeoPixel class I used when I tried it - will retry. Thanks!

caternuson commented 4 years ago

This may be due to slight timing differences between WS2812 and SK6812. The current bit pattern was tuned for SK6812 timing.

WS2812: image

SK6812: image

@tisfablab If you know how to clone and use a local copy of this library, you could try tweaking the bit patterns here: https://github.com/adafruit/Adafruit_CircuitPython_NeoPixel/blob/25abbd50397d1a51ee1fbdeaf4d2dc4bf2b20007/neopixel.py#L316-L318 (I was thinking having those be user configurable might be a good feature to add.)

Also, just be sure, for the other approach, were you following this guide? https://learn.adafruit.com/neopixels-on-raspberry-pi

tisfablab commented 4 years ago

@caternuson , thanks!

I was not following the Neopixel guide but had tried a level shifter on my own - there was no difference with or without it. The trick with the diode is cool though!

By tweaking the bit patterns you mean I could lengthen signals by increasing the number of consecutive "1"s in the pattern, right? Cloning the library is not the problem for me, but understanding the hardware level stuff i.e. what you're doing here. In your table there's 4 signals (T0H, T1H, T0L, T1L), but your code only uses 2, right? Which ones?

caternuson commented 4 years ago

The bit patterns are used to mimic the expected data signal: https://learn.adafruit.com/assets/82416 more info: https://learn.adafruit.com/circuitpython-neopixels-using-spi#the-neopixel-spi-hack-1-4 Note how both patterns are just 1's (the TxH part of the signal) followed by 0s' (the TxL part of the signal).

The granular time resolution is pretty coarse since the entire time slice is divided by 8. But you can try adding / removing 1's to increase/decrease the T0H, T0L, T1H, T1L timings to maybe better match different requirements.

caternuson commented 4 years ago

@tisfablab Are you still having issues with this? Or what's the status quo in general?

tisfablab commented 4 years ago

@caternuson, I was not able to get that LED strip running with my project. I tried again with another Raspberry PI (same PS/setup/SD card), and it worked out of the box - I suppose my first unit was faulty.

Thank you for your support and all those tech details - I've learned a lot about NeoPixels and how the SPI hack works.

caternuson commented 4 years ago

OK. Bummer it didn't work on that one Pi for whatever reason. Thanks for reporting back and closing issue.