SPI first LED is green

  • Hi friends,
    I found out this behaviour compiled on OPI, ws2812b LEDs via SPI (MOSI, 19pin), master (GitHub-69f4b32/6445c35-1481143098. When I run hyperiond (no grabber, just rainbow color effect), first LED stays green. In these scenarios, just first LED is problematic:
    - if I pick black static color, first led is GREEN
    - if I pick red color, first LED is yellowish
    - if I pick blue color, first LED is blue, too
    - if I pick green color, first LED is green, too
    - if I use usb grabber, first led behaviour is the same as above
    - if I uplug power from LEDs, terminate hyperion then power leds on again, start hyperion again, first LED is green again.


    I tried downloaded version V1.03.2 (brindosch-99d9396/d3713a8-1469452981) on RPi and there is first led always off regardless the color I choose.


    I think there must be problem on the first LED somewhere in hyperion core for spi. Any idea how to solve it?

  • Did the level shifter make any difference to this symptom ?


    What level shift are you using ?


    No, with/without it is behaviour the same (on opi). On Rpi I must use levelshifter because without my LEDs are not working correctly (valid for spi, but via pwm leds work even without levelshifter).
    Tried my own levelshifter as well as bought from ebay.

  • Hmm...


    Does it look like it's a green level of 128 ?


    If so, it implies the first bit of the DMA transfer is being corrupted and always seen as a '1'.


    The ws2812 is clearly not a spi device so this driver is using the SPI interface in a non standard way and this depends on some assumptions:
    - the transfer is done by the Pi in one continuous stream (DMA)
    - the bits are clocked out at a constant speed (Pi core clock speed changes mid transfer will break this)
    - there are no glitches on startup.
    None of these matter on a clocked proper SPI interface as the data only has to be valid on the clock edges.


    How much patience do you have ?
    If "not much" then I'd recommend getting a cheap arduino and using USB.

  • Use Hyperion-remote -c 008000 to set the whole strip to green 128 and see if the 1st led matches the rest.


    It's probably not a Hyperion defect - it's either a kernel spi driver issue or a fundamental hardware limitation on the OPi so a fix might be slow or never.


    I don't suppose you have an oscilloscope ?

  • 008000 - 1st matches the rest (all green).
    0000FF- 1st matches the rest (all blue)
    FF0000- all red, but 1st yellowish


    oscilloscope - unfortunatelly, I don't have here, I have just multimeter.

  • but on the other hand, no idea why first led has similar symptoms on RPi3, too (1st LED is white or completely off).
    Maybe some idea how to use pwm on OPi? According to my opinion it would fix these troubles.

  • Sorry - I'm getting confused with all the permutations !


    Let's focus on the rpi3 - it's more in my comfort zone !


    What is your home made level shifter ?
    Those Ebay mosfet ones are terrible for this use case.


    Do you have a good ground connection between the Pi the leds and the power supply ?


    How many leds are on the strip ?

  • Thanks, so on RPi3:
    - with level shifter - first LED is always off, other LEDs work ok
    - without level shifter - after I start hyperiond (without framegrabber, without v4l2grabber) - for 2 seconds I see rainbow and then all leds go to white. With hyperion-remote I can set any color (tested red, green, blue) and for fraction of second all leds go to specified color (first one is ok in specified color too), but after that they go white again


    Level shifter - made by friend of mine via gpio pins (pins3.V-5V, parts 4701, 1003, logic). I have one according to tutorial from this hyperion site, too.
    Ground - is ok, I rechecked it twice.
    I try with 5 up to 150 strip scenario.

  • Please, looks like closing data via spi are somehow corrupted for first led. I'd like to manually send data to leds. Please, How could I manually try to send other data to first and second LED? (I mean via scrpit, e.g. python, .sh, etc, and not via hyperion-remote)

  • https://github.com/penfold42/stuff/blob/master/ws2812_spi.c
    This was my 1st proof of concept code to test my idea before writing the Hyperion driver.


    I tried compiled version of your ws2812_spi.c but green channel is somehow always ON on first led (from connector end going to Pi).


    I am playing with your .c script. I tried to change 0b10001000 to 0b00001000 and now green channel on first LED is not set to ON, but other colors don't match testing pattern. Then I changed it to 0b01000100. It is a bit better (first led is changing too), but I don't know what these values mean and how it affects other leds - I have just found out consistency of color effect is altered with this change (last LEDs are not showing good pattern colors cca 8 leds at the end of 30leds long strip are miscolored and one is randomly off).


    I made few pictures with your ws2812_spi.c:
    Original pattern from ws2812_spi configuration:


    Rpi colors:


    OPi colors:


    Opi matches template pattern colors (but first led has always ON green channel - 1st led is not on my picture here). But RPi does not match template pattern colors.
    It is quite strange. Any idea how to change 0b10001000 on Opi to properly work first led?

  • Changing the bitpair table won't help - this sets the timing pulses for each bit.


    Do you have a good ground connection between the Pi and the led strip ?
    This could cause corruption on the 1st bit while things settle down.


    Another software change to try is sending the reset latch pulse at the start:
    Change:
    uint8_t tx[num_leds*3*4+3];
    To:
    uint8_t tx[num_leds*3*4+6];


    And change:
    unsigned spi_ptr=0;
    To:
    unsigned spi_ptr=3;

  • ground connection in my case is perfect.


    Change to:
    uint8_t tx[num_leds*3*4+6];
    unsigned spi_ptr=3;


    @penfold42, this really helped (thank You!), now everything seems to be fine, 1st LED included. I have no idea what these two values do, so I experimented with old line "uint8_t tx[num_leds*3*4+3];" and new line "unsigned spi_ptr=3;" and with this it works good, too.

  • unsigned spi_ptr=3;
    This tells it to skip the first 3 bytes of output data leaving it zero which should be interpreted as a reset pulse.


    The first line makes sure there's room for it. Without this, you run the risk of trashing memory - not a good thing!


    Ca you try one more thing ?
    Don't change this line back:
    unsigned spi_ptr=0;


    But make the other change (with +6).
    This gives us a reset pulse at the end but it's longer

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!