WS2812B Delay Splitter

Splts a WS2812B bitstream, delaying one side by a selectable number of LEDs

Similar projects worth following
This is a splitter for a WS2812B RGB LED bitstream where one side of the split is delayed by a selectable number of LEDs. It uses two components: a bypass cap and a Silego SLG46120V CMIC (a small mix-signal FPGA-like device). The CMIC copies the input verbatim to one output pin, and strips off a number of 24-bit pulse sequences before enabling the second output pin. The number of LEDs to delay is set with a series of 5 solder pads, giving it a range of 0-31 units.

The SLG46120V is TIE-NEE! As in 1.6mm x 1.6mm with 12 pads. I created the component in, laid out a PCB, and sent the exported gerber files off to OSHPark. After a mix-up (learning opportunity) concerning solder masks vs. paste files, I got a stencil ordered from OSH Stencils. I figured it's needed, given the size.. I am also building a test jig with pogo pins for programming it in-place using the GreenPAK3 Dev

This project uses a Silego GreenPAK CMIC to split a WS2812B data stream into two feeds, one identical to the input and one delayed by a selectable number of LEDs. This allows one to string lights in short strings hanging off a bus, kind of like icicle Christmas lights.

The Silego GreenPAK is a sort of FPGA that's got a very limited number of gates and can only be programmed once. The 12-pin SLG46120V used here is cheap, as you can get 5 for less than $1. I settled on that model because it had the largest number of DFFs, which I needed for the frequency dividers.

The GreenPAK Designer is a free download, and is used to layout the components, configure them, and connect them together, and create the bitstream used to program the chip. It also has the emulator portion that connects to the dev kit via USB for programming/debugging. The GreenPAK3 Dev Kit retails for $59 and includes 50 samples of each of four different chips.

The internals are covered in more detail in the project logs below. To summarize, the internal RC oscillator will trigger a reset when more than 10 microseconds have passed. The first pulse on D-In brings it out of reset until the next 10us blank. A counter creates a pulse every 24 input pulses, which is fed into a series of frequency dividers allowing a binary count up to 31 (2^5 - 1). The FD stages are compared to input pins (solder jumpers to ground) and raise another signal if all inputs match. When matching and the D-In pulse drops, a latch enables all following D-In pulses to also forward to D-Delay, until the next reset.

  • 1 × SLG46120V Silego SLG46120V CMIC
  • 1 × Capacitor 0.1uF 15V 0603 ceramic capacitor
  • 3 × 1x3 Header 2.54mm pitch 1x3 header

  • First prototype

    Pete11/25/2015 at 03:12 0 comments

    I finally got some time to work on this again. I put together the jig, soldered a blank CMIC and cap onto one of the boards, and tried to get it working with the dev kit; no dice. That's ok, I can still use the dev kit to program a chip then assemble it. First lesson learned: while the 3-pin headers look nice, there's not enough pad extending from the drill hole for the iron tip to reach. I had to use more flux than usual and just run the solder down the pogo pins until the heat spread to the pads as well. Ugly...

    So, that was my next task. I'm glad I got the stencil, as it worked great. Since both components are on one side, it's easy enough to fry them. Second lesson learned: the capacitors are taller, and the small amount of solder paste left by using the stencil did not reliably adhere them. Other than that, the frypan worked great.

    Next task: time to try it out. The DOut leg worked great. The DDelay leg flashed weirdly; With no delay, it appeared to be out of sync. Progressing lights were three-LEDs wide instead of two, illumination was too high, and coller was off. On the plus side, the overall pattern was recognizable. I suspect it's not enabling output on a 24-bit boundary, but on some other point in the data stream. Third lesson learned: don't program and populate all your prototype boards until you know if it works or not.

    Time to break out my new logic analyzer.

  • Parts are in!

    Pete11/10/2015 at 14:03 0 comments

    All the parts are in for the original 0.5x0.7" splitter, including the caps, stencil, paste, and test/programming jig with pogo pins. Now its just a matter of pulling out the spare toaster oven and testing it out as a reflow oven.

    I've never done reflow soldering yet, nor worked with anything as fine as the 0.4cm pitch CMIC, so it's all new, and a little bit scary. Ah well.. nothing like expanding your comfort zone!

  • Tiny PCB (with links)

    Pete11/03/2015 at 18:44 0 comments

    Since I had inadvertently deleted my original project and needed to spin a new board anyway, I shrunk it down to a 0.4x0.5" board. I had to rearrange the SJ pins some to route everything, so it's now got the following pinout:

    46120 pinPCB function Programming function
    1Vcc (all three 1x3 headers)Vcc
    4n/a (tied to pin 3)
    7Gnd (all three 1x3 headers)Gnd
    8SJ8Mode Control
    11n/a (tied to pin 12)

    Note that pins 11 and 4 are tied to neighboring pins due to the proximity of their vias. That shouldn't cause any issues during programming... I hope. Once programmed, those pins are not used, so have high impedance and should be fine.

    This layout, once again, ensures that the DIn connector and the five floating SJ pads can be used to program the CMIC after it's soldered to the board (but before any jumpers are closed).

    These boards are tiny, and a set of three costs only $1 from OSHPark. I'm considering an entry in the square-inch contest, if nothing else to get more visibility for it. Unfortunately, I can only export gerbers from, not .sch/.brd files, so I'd have to fire up something like KiCAD and spin yet another version for them... At least I manually edited the silkscreen layers before uploading to OSHPark so they're not so cluttered.

  • Data Flow Description

    Pete10/28/2015 at 16:13 0 comments

    Here's a text description of how it all works, or at least should work. I've tested it on the dev kit by slowing down the oscillator, increasing the clock dividers, and upping the delay count until it resets after more than a second, then feeding a repeating 0.1s-on/0.4s-off pattern in on pin-1. I enable the LEDs on the dev board for the output pins, and pull-down jumper pins to set the delay. By slowing it down that much, I can count the pulses on D-Out and visually see how many come out before they appear on D-Delay. Now I just need to get the boards, solder parts on, and feed it a real bitstream...

    To understand the text below, refresh your memory on logic truth tables and print out the logic diagram so you can follow the flow below while identifying the logic gates by name. 2-L0 is a short way of identifying 2-bit LUT0.

    Oscillator/reset latch:

    The oscillator can run at either 25kHz or 2MHz. Since this will be used to detect a quiet period of around 10us, a clock with a 40us pulse doesn't work, so it's configured for 2MHz (0.5us pulse). This pulse is used as the clock for DLY3 which is configured to delay only on falling edges. Assuming for the moment that nReset is high, DLY3 input follows D-In. As long DLY3 Output is high and D-In is receiving pulses, the rising edges of D-In restart the delay. When pulses stop and D-In goes low, after the delay, DLY3 output goes low. This triggers 3-L6 (acting as a RS Latch) to go low as well. However, the nReset signal this outputs is fed back into 2-L0 feeding DLY3 and ensures that DLY3 is fed a high signal. Since there's no delay on rising edges, DLY3 goes high again, and effectively generates a nResetPulse. 3-L6 stays latched low until the next D-In pulse, when nReset goes high and the reset state is lifted.

    3-byte pulse generator:

    D-In is fed as a clock signal to CNT1. Since CNT1 has a 3-cycle delay on reset and a 1-cycle delay on count completion, to make sure it always counts to 24 pulses, 2-L4 ensures it is restarted when either nResetPulse goes low OR every 24 pulses. After each 3-byte pulse or reset, CNT1 takes three clocks to reset and then counts to 21 before generating the next rising edge. P DLY is configured as a rising edge detector and outputs a 91ns pulse at the start of every 24th pulse.

    5-bit frequency divider:

    The 3-byte pulse is fed into a series of 5 D flip-flops that act as frequency dividers. The DFF's output is inverted and fed into its input. Since the three separate DFF cells don't have both Q and nQ, they're configured in nQ mode. This inverted input of nBit1, nBit2, and nBit4 is handled in the pin comparison logic below. Bits 8 and 16 are a little more complex, as they're generated by feeding the PipeDelay a de Bruijn sequence (n=2, s=2). After reset, the first two PipeDelay DFF states are (0, 0). By feeding a sequence of [1, 1, 0] as input, the outputs of internal DFFs 1 and 2 cycle through values of [(0, 0), (1, 0), (1, 1), (0, 1)], each one unique. Note that the second DFF does represent bit16 correctly, but the first DFF only matches bit8 for the first two entries in the sequence and is inverted for the second two. Therefore, Bit8 can be determined by an XNOR of both PipeDelay DFFs, which is included in the pin comparison logic below.

    Pin comparisons/match detect:

    After propagating through the DFFs, the five DFF states can be used to determine how many 3BytePulse signals have been seen since the last reset. There is comparison logic to compare each bit from the DFFs to its corresponding input pin. All these individual bit signals are combined with AND logic to raise a signal only when all five match. Note that, as the signal propagates through the DFFs, the individual bit values aren't necessarily correct until that propagation is complete. This may generate momentary spikes of positive output which must be accounted for below.

    Enable latch:

    As long as D-In is high, the 4-L0 latch will ignore the match signal from above. This gives time for the signals to propagate...

    Read more »

  • A hiccup in how Counters work

    Pete10/25/2015 at 23:53 0 comments

    So I got my GreenPAK3 Dev Kit in the mail and started simulating things on it. I ran into an issue in that the counters start out on for three clock cycles before starting their counting loop. It wouldn't work to count three-byte blocks by counting off the first 24 bits, then the next 22, next 22, etc., so something else was needed. I think I've found a solution that works whereby I just reset the counter, not only at every reset interval between bitstreams, but after every three-byte block. That way I always get the 3-cycle startup pulse.

    This issue also affected the reset interval counter, as it would start in its triggered state and wouldn't reset during the first three bits. For that, I ended up switching the counter to delay mode, and as long as DIn is oscillating, it stays in its last state until it stops for the reset interval and the output goes low. I added a 2bit LUT on the input so that as soon as it goes low it brings it high again for the next cycle, and reworked the latch fed by the delay cell.

    I've generated a print editor snapshot which better shows the contents of each LUT and which input corresponds with which entry in the LUT. By itself, it would allow someone to recreate the circuit from a new GreenPAK Designer project.

    Now for some more simulations and testing...

  • Board Layout

    Pete10/23/2015 at 19:57 0 comments

    Stupid I had several versions of the board and somehow deleted the current one instead of one of the older ones! I still have all the gerber files, though, and was able to order 9 of them from OSHPark.. I'll just have to trace out which pins connect to which pads. I think I have them right for the test jig, but will wait until I receive them and can verify before I order the jig boards.

    I think its:

    3SJ 4
    8SJ 8
    9SJ 16
    10SJ 1
    12SJ 2

    They're not very logical here, but there were a couple of priorities in deciding which pin should go where: 1) I wanted the pins used for programming the CMIC to be on D-In and the solder jumpers, 2) pin2 is Vpp (programming voltage) and input only, so I figured that should be D-In, 3) the power traces from D-In to D-Delay should be as wide as possible, and 4) with those constraints and minimal size in mind, I tried to make the board layout as simple as I could by rearranging which SJ went to which CMIC pin.

    That's one of the nice things about this, and FPGAs in general. It's easy to move pins around to make the board layout simple, rather than needing to design the board to whatever pin order the chip designer went with.

View all 6 project logs

  • 1
    Step 1

    Order PCBs, stencil, and capacitors

  • 2
    Step 2

    Order Silego GreenPAK3 Development Kit

  • 3
    Step 3

    Program CMIC with development kit

View all 6 instructions

Enjoy this project?



Hakaday wrote 03/22/2023 at 19:03 point

Each pixel copies what it receives on DataIn onto DataOut, but only after it strips off the first 24 pulses (8 each for R, G, and B) for its own LEDs.  The intent was to have this device strip off a predetermined multiple of 24 pulses on the delay out, similar to having that many pixels inline.  Unfortunately, I never got it working.  I didn't have a working oscilloscope at the time, and have been too busy since to come back to this project, but still believe it has the capability of being the lowest cost solution for doing this.

@will if you just want to duplicate pixels, eg. have a curtain where the top pixel on all lines is the same, then all you need is a few buffers.  This is intended to delay the output so for example the Out line starts at the first pixel but the delay line starts at pixel 32.

Renard Plus used to sell a Pixel Splitter board with three outputs.  The original idea came from this post:  I've looked at STM hardware as well, as their advanced timer peripheral has four CCR outputs.  It should work, but I just don't have time to fully develop it.

  Are you sure? yes | no

Will Tatam wrote 03/22/2023 at 10:19 point

I was looking for something similar to create a curtain style matrix. Came across this project, looks to be just what I'd need. One question however, why do you choose to delay the split output? The controller controls the frame rate, so why you not want the second string updating at the same point as the first?

  Are you sure? yes | no

Jamie Nelson wrote 01/27/2023 at 03:27 point

@Pete i know this is super old now but I’m looking for something that does this. Did you ever update this process? Or find a commercial replacement ?

  Are you sure? yes | no

Will Tatam wrote 03/22/2023 at 10:20 point

Did you find anything commercial?

  Are you sure? yes | no

Pete wrote 10/25/2015 at 21:04 point

they used to have one-click board ordering without the need to export gerbers and send to your shop of choice. Now they have a button to download a zip full of gerber files. 

I'm out of logic blocks on the CMIC. I might have to drop it down to 0-15 instead of 0-31 using 4 of the 5 jumpers. 

  Are you sure? yes | no

davedarko wrote 10/25/2015 at 18:27 point

Does come with export functions now? I started with them myself but turned to eagle after a while. Mainly because I figured they use OSHPark as well and added a 5USD fee.

Is there a reason that you chose to skip 0-31? I'd imagine that higher values would be interesting as well. 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates