blaz-r / pi_pico_neopixel

Pi Pico library for NeoPixel led-strip written in MicroPython. Works with ws2812b (RGB) and sk6812 (RGBW).
MIT License
254 stars 54 forks source link

Very buggy for 35762-OP LED - help needed #17

Closed luccadibe closed 9 months ago

luccadibe commented 10 months ago

I'm trying to run the examples on a Pi Pico W with an array of 10 LEDs (https://www.mpja.com/download/35762opdata.pdf) . I thought these are compatible with this library. Maybe they aren't?

When I run the rainbow.py example , it runs OK the first time, then all leds bug out, flicker and for some reason stay red. The brightness function also seems not to work at all.

Congratulations on the project, really cool idea.

blaz-r commented 10 months ago

Hello. Looking at the diagrams, I'm not sure this library is really compatible. These are the timings from your pdf: image

these are from ws2812b: image so you'd need to tune the state automaton program, to suit these timings, which might not be that easy since the one existing is already a bit imprecise on timing: https://github.com/blaz-r/pi_pico_neopixel/blob/8012e3b6a66185f72ced740b1cf776548ea05def/neopixel.py#L6-L19

There is some code I have written a while ago that you can probably adjust for your timings. First you'll need to use state machine with following frequency to get 10ns cycles:

rp2.StateMachine(state_machine, ws2812_update, freq=100_000_000, sideset_base=Pin(pin))

instead of these two here: https://github.com/blaz-r/pi_pico_neopixel/blob/8012e3b6a66185f72ced740b1cf776548ea05def/neopixel.py#L92-L97

then the timings adjusted for cycles in the following program

T0H = 35-> 6 * 5

T0L = 136 -> ~ 27 * 5

T1H = 136-> 27 * 5

T1L = 35-> 6 * 5

so I think a final PIO program would look like this:

# PIO state machine for RGB. Pulls 24 bits (rgb -> 3 * 8bit) automatically
@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)
def ws2812_update():
    #T0H = 35->  6 * 5
    #T0L = 136 -> ~ 27 * 5

    #T1H = 136-> 27 * 5
    #T1L = 35-> 6 * 5

    # every cycle is 10ns
    # nop() [2] takes 5 cycles

    # when using set(y, num), num is 1 less than the actual number of cycles
    # because jmp(y_dec, label) check for 0

    wrap_target()
    label("bitloop")
    out(x, 1)                       .side(1)
    jmp(not_x, "zero")              .side(1)

    ## ONE ------------------------------------
    label("one")

    #T1H
    set(y, 26)
    label("one_high_loop")
    nop()                           .side(1)    [2]
    jmp(y_dec, "one_high_loop")     .side(1)    [1]

    #T1L
    set(y, 5)
    label("one_low_loop")
    nop()                           .side(0)    [2]
    jmp(y_dec, "one_low_loop")      .side(0)    [1]

    jmp("bitloop")                  .side(0)

    ## ZERO ------------------------------------

    label("zero")    

    #T0H
    set(y, 5)
    label("zero_high_loop")
    nop()                           .side(1)    [2]
    jmp(y_dec, "zero_high_loop")    .side(1)    [1]

    #T0L
    set(y, 26)
    label("zero_low_loop")
    nop()                           .side(0)    [2]
    jmp(y_dec, "zero_low_loop")     .side(0)    [1]

    wrap()

I can't really verify this, and it's been a while since I've written this 😅 but it could work.

Hope this helped.

luccadibe commented 9 months ago

Thank you so much for you quick answer! I'll test it and try to debug.