joosteto / ws2812-spi

python routines to program the WS2812 RGB LED chips on the raspberry, using the hardware SPI MOSI.
GNU Affero General Public License v3.0
59 stars 23 forks source link

Driving more than 5 pixels on a orange pi zero #6

Open melazarus opened 6 years ago

melazarus commented 6 years ago

I'm experiencing some issues when driving 6 or more pixels.

It seems that the SPI lib or hardware inserts a small delay of 5µs eacht 60-70 bytes transferred. screenshot

I don't think this is an issue with the ws2812-spi lib but I'm hoping anyone here has some clue of what may be happening here.

thanks

pietrodn commented 6 years ago

I have the same problem on a NanoPi Air, which uses the Allwinner H3 CPU. It works fine up to 5 pixels, but when I use 6 pixels or more, all of them start flickering.

pietrodn commented 6 years ago

I solved this problem by replacing the spi.xfer() call with spi.writebytes() and applying the tweak in #2. Now I am able to drive more than 90 LEDs on the NanoPi Air: they are stable and without any problem.

Code:

# Initialize SPI with the correct frequency
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = int(4/1.05e-6)

def write2812(spi, colors):
        # Optimized version of the `write2812_pylist4` function at:
        # https://github.com/joosteto/ws2812-spi/blob/master/ws2812.py
        # with this fix (0x00 at the beginning): https://github.com/joosteto/ws2812-spi/issues/2
        tx = [0x00] + [
            ((byte >> (2 * ibit + 1)) & 1) * 0x60 +
            ((byte >> (2 * ibit + 0)) & 1) * 0x06 +
            0x88
            for rgb in colors
            for byte in (rgb.g, rgb.r, rgb.b)  # the LED strip is GRB
            for ibit in range(3, -1, -1)
        ]

        # Using xfer() or xfer2() in place of writebytes() causes the LEDs to flicker after the 5th one
        # reports of this bug:
        # 1) https://github.com/doceme/py-spidev/issues/72
        # 2) https://github.com/joosteto/ws2812-spi/issues/6
        spi.writebytes(tx)
bogdanvb commented 3 weeks ago

Solving the problem with the first LED when controlling ws2812 via spi on nanopi neo.

Thanks to your help, I came up with a code so that the first LED (ws2812) on Nanopi neo would work correctly and not turn green. This code reduces the length of the first bit of data to a normal value. Code:


import spidev
import ws2812
import time

Initialize SPI with the correct frequency

spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = int(4/1.05e-6)

def write2812(spi, colors):

Optimized version of the write2812_pylist4 function at:

   # https://github.com/joosteto/ws2812-spi/blob/master/ws2812.py
   # with this fix (0x00 at the beginning): https://github.com/joosteto/ws2812-spi/issues/2
   tx = [0x00] + [
       ((byte >> (2 * ibit + 1)) & 1) * 0x60 +
       ((byte >> (2 * ibit + 0)) & 1) * 0x06 +
       0x88
       for rgb in colors
       for byte in (rgb[0], rgb[1], rgb[2])  # the LED strip is GRB
       for ibit in range(3, -1, -1)
   ]

   # Using xfer() or xfer2() in place of writebytes() causes the LEDs to flicker after the 5th one
   # reports of this bug:
   # 1) https://github.com/doceme/py-spidev/issues/72
   # 2) https://github.com/joosteto/ws2812-spi/issues/6

   #spi.writebytes(tx)
   spi.xfer(tx)

            # three diods

write2812(spi, [[0,10,0], [0,10,0], [0, 10, 0]]) time.sleep(0.5)

write2812(spi, [[100,0,0], [100,0,0], [100, 0, 0]]) time.sleep(0.5)

write2812(spi, [[0,0,10], [0,0,10], [0, 0, 10]]) time.sleep(0.5)

write2812(spi, [[0,0,0], [0,0,0], [0, 0, 0]])