Pixel Channel Demuxer / Splitter

bobsmith

Member
I have some props that are all relatively short (41 pixels each), and it's a real PIA to wire them in a daisy chain fashion, connecting the output data of one to the input data of the next. It would be much more convenient to wire them in a star pattern, where each prop has it's own wire from a central point, and data is only flowing in one direction - out to the prop. But it's a complete waste to use a 16 or 32 channel controller to only hang 41 pixels off of each port.

Currently I use 4 conductor cable (+12V, GND, Data In, and Data Out) with single ended data flowing over one wire in each direction. I currently have level shifters / line drivers on custom PCBs, but even then, at longer cable lengths, things get problematic. I recently spent a couple weeks and _really_ learned about termination (near end vs far end, etc etc), drive strengths, etc. etc. You'd figure being an EE, I'd already know about such things, but some things you don't TRULY know until you have a problem in front of you on the desk in the real world, and corrupt data, flickering LEDs, and the worst scope traces you've ever seen kicking your butt! I figured out how to solve my issues even driving single ended data over ~40ft cables, but I've had a different idea kicking around in my head for a while, and I finally decided to do something about it. I figured before I went ahead and made a new version of line driver / receiver PCBs to replace my existing ones with stronger drivers and proper termination, I wanted to try this other idea first...

For a long time, I thought it would be really useful to be able to split one data stream from one controller channel into many "virtual" smaller channels, each on an independent output. I know there are "smart" differential receivers that kind of do this, but you need a controller that supports "smart" receivers, and you lose some pixels on each port for the "smart" signalling (as well as the control protocol isn't open / documented), and even the smart receivers themselves aren't exactly cheap (I kind of have a crazy idea in mind to build a really distributed large display over a big area, and I would potentially need MANY of these, so cost is a factor). And they limit you to only a few sub-channels per controller channel. I want many more sub channels per channel, each with a programmable number of pixels per sub channel, and without needing any special controller support, or to steal any data spots in the data stream itself (but that obviously limits things to being pre-configured, or configured with an out of band communication channel).

A couple days ago, I ordered some development boards, and now I have a working prototype. I can take in WS2812 data stream in on one channel, and slice and dice it wherever I want, and output it chopped up on up to 30 separate channels. This will allow me to split my one channel of data into 41-pixel sub-channels, only run data in one direction to my props, and use differential line drivers and receivers and use the 2 data wires in my cable for a differential pair, rather than single ended data flowing in each direction.

Here's some scope screenshots of a 30 pixel test (generated using an espixelstick v4 running rainbow pattern from the built in pattern generator) on the top (red) trace, and being split in real time, first into a 15 pixel channel (yellow) and 10 pixel second channel (green), discarding the remaining input pixels
printf3_cropped_hard.png

and then split into 2 15 pixel sub channels, using all of the incoming data
printf5_cropped_hard.png

Here's a closer view at the transition from one channel to the next vs the input data - it's seamless
printf4_cropped_hard.png

I'm wondering if anyone else would find this kind of thing useful? Has anyone else done this before?

With this type of arrangement, you could hang any number of these off of a differential run, in a true "multi-tapped bus" fashion like actual RS485 is designed to be, and pick off arbitrarily determined ranges of pixel data to many separate local output channels at each "tap" all along the cable run, with no special controllers, and no smart receivers (but you'd have to pre-configure each "tap receiver", or an alternate method of configuring them would be required - I do have a few ideas in mind for that too).

Throwing it out there to see what people think!
 
Well, RobG posted something like this in May and it may be the same or similar to your idea. I don't know where he is in his development process though.
 
That does look very similar, but it looks like his implementation is a little different. Also looks like he's limited to 4 or 8 channels based on the hardware he's using. And it looks like he "routes" the pixel data off of the main bus and changes the original data stream, whereas I leave the main data stream intact, and just replicate it in a programmatic way onto the "tap channels" off of the bus. Two slightly different methods that almost do the same thing. I'm kind of curious what that micro controller is he's using...

Seems like there is a need for such a thing if multiple people have come up with the same idea independently, and almost at the same time :)
 
Hi Bob,
My implementation is limited to 8 channels, but you can daisy chain several boards to whatever you need, 8, 15, 22, 29...
It all started in 2017. There was some progress in 2019, but it was abandoned for several reasons.
There was also one implemented at around same time on XMEGA, but I cannot find it now.
 
This week I did some work on the configuration side of the project, and now it can be configured / reconfigured in real time from a serial terminal.
The configuration is a table with up to 32 entries of this format:

IndexPixelsBytes per PixelOutput Mask (HEX)
11030
23231
31030
43232

The above sample configuration would skip the first 10 pixels, output the next 32 pixels to channel 1, skip another 10 pixels, output the next 32 pixels to channel 2.

Bytes per pixel allows mixing RGB (3 bytes per pixel) and RGBW (4 bytes per pixel) data streams easily.
Output mask is a bit-mask in hexadecimal specifying which output ports each range should go to. It's possible to output a certain range of pixels to multiple ports simultaneously.

Here's a video showing setting the configuration, and the immediate change visible in the output data streams on the scope. Like the above screenshots, input data stream (now 738 pixels worth) is coming from a ESPixelStick on the red trace, output channels 1 and 2 are shown on the yellow and green traces respectively.

Pixel Slicer - WS2811 Datastreem Slicer Demuxer

Next I need to be able to save the config in flash, so once it's specified, it will remain in each device until it's changed, and then work on some PCB layouts that have level shifters, and various combinations of single ended and differential inputs and outputs. I was also thinking it would be handy to have all 4 channels from a standard differential port available as inputs, so in software you could chose which input channel to pull pixel data from.
 
The smart receivers solve two different problems:

1) How can I get channels further away from my controller than the standard pixel protocol allows?
2) How can I divide up the available channels of a port (which can be in the thousands) without having to daisy-chain the signal for all of those channels?

This project is handling the second item above, and seems like a great alternative to what's out there.

It would also be cool to have it incorporate the first item. I have a very spread-out display, and if items were close enough that I could use pixel protocols, I'd probably just daisy chain them and power inject. However, having alternatives to smart receivers (and all of their restrictions and cost) that would be something I'd be interested in.
 
My plan is to have daisy-chainable differential inputs, just like smart receivers do, but because these are passive to the input signal, there's no limit to how many of these you could have on the bus (well, up to the electrical spec of RS485 that says there should be a max of 32, 128, or 256 receivers (depending on the input impedance of the receivers) per bus). I'm also thinking of having differential OR single ended outputs to each prop. My main use case of this is for many props in trees, and the cables get long to get to the top of the tree. Differential outputs on the output channels is a priority for me for that reason.

bus_topology.png

I have custom line driver / receiver boards already that are just as wide as a LED tape strip is, and I will make another revision of those that takes differential data in, and drives the strip with single ended.
strip_receivers.jpg

Pros:
  • More splitters per bus than smart receivers - no limit other than electrical signal integrity
  • More outputs per slicer than smart receivers - up to 20 output ports (though I haven't finalized on the number yet) on each slicer
  • Can be used with ANY controller - doesn't need "smart receiver" support (and any controller can have differential outputs with a simple driver board added)
  • Robust differential signalling right up to props
  • Each prop is independent - a failure of a pixel in a prop only affects the remainder of that prop, not everything past it
  • Easy to power inject as every prop has independent connection to splitter
  • Easier wiring as no need to daisy chain data output of one prop to data input of the next
  • Easy to re-configure - if you move a prop physically, just change configuration of the slicer(s), or if props have positional dependence (like hanging in a tree) and need to be in a certain order (top to bottom and or left to right) but don't get placed in the same position every year when setting up, can change the order at the slicer without having to change anything in the sequence
  • Can have duplicate props that are physically far apart use the same pixel channels (not sure if this is useful in practice)
Cons:
  • Slicers not configured through the data stream, so need to configure each one independently when setting it up for the first time
Originally I was thinking of just having 1 input selectable on each slicer, so you'd select whether you want to take data from which differential input channel, but then I realized that I could just run 4 'slicers' in parallel, so you could take data from all 4 input channels - sort of how a smart receiver works, but more flexible. It wouldn't allow you to mix data from multiple input channels onto a single output, but you could have groups of outputs that are pulling data from each of the input channels. I.E.
IndexInputPixelsBytes per PixelOutput Channel
111030
213031
311030
413032
5210030
6210033
7315030
835034

From input 1, skip first 10 pixels, output next 30 on output 1, skip 10 pixels, output next 30 on 2
From input 2, skip first 100 pixels, output next 100 pixels on output 3
From input 3, skip first 150 pixels, output next 50 on output 4

This will take a little work in the firmware, but shouldn't be too difficult to implement. The only restriction, to make it easier to implement is for each input (1 to 4), the outputs need to be a contiguous group, so input 1 maps to outputs 1 to x, and input 2 maps to outputs x+1 to y, and input 3 maps to outputs y+1 to z, etc etc.

I'm hoping to do some PCB layouts this week and get those sent off for manufacturing soon, as I really need to get this project done, and move on to other things I need to be working on. My base configuration would be 4ch of differential inputs to 20 (most likely) channels of diff / single outputs. I'll be targeting replacing this existing "backplane" with the new board, integrating the differential receiver, and the slicer, and everything else onto the one PCB that fits in the enclosures I typically use. Probably also going to have a version (or one board that can do either) that takes an ESP32 with sd card slot running espixelstick firmware that can act as a remote FPP player playing the sequence from the local SD card with timing sync over wifi from the master FPP rather than wired differential inputs, as I have some places I can't get a physical data cable to and only have power there.

backplane.jpg

Would smaller configurations also be useful? 4ch diff inputs to 4 outputs? 8 outputs? Is there a particular small enclosure that people commonly use that would be good to target this to fit into? What's the best output terminals? Just the standard 3 or 4 pin green phoenix connectors that most controllers use for single ended output channels? For this one style of prop I have, I settled on 4 pin mini-fit-jr connectors, and I'll mostly stick with that as I don't want to change the cables or re-terminate the ends on the existing ones, but in future, I think I'm going to standardize on using RJ45 plugs, as I can buy those pre-terminated with outdoor rated cable, and cut them in half, and end up with 2 prop cables with no crimping the ends myself which saves a lot of time.

Suggestions welcome before the PCB layouts get done!
 
Another "pro" that I forgot to add (but can't edit the previous post as it's been too long now) is better use of controller ports. Load all your controller ports up to the full ~800 pixels per port.

I feel like a lot of controller ports end up being used for a small number of pixels and wasting the full capacity of the port because it facilitates easier wiring, and then you end up having to buy much larger controllers with tons of ports. With this method, you can load up the controller ports fully, better utilize the controller, and still have easy wiring per prop with sliced "sub-ports".
 
> I feel like a lot of controller ports end up being used for a small number of pixels and wasting the full capacity of the port because it facilitates easier wiring

Absolutely.
 
So currently you configure them over rs232 with a simple command line interface. I was also thinking of making a little handheld "remote" that could plug into the board, and gives you a small OLED and a rotary encoder to be able to go through the table and make edits rather than needing a full PC or laptop. Easier to do when you're up on a ladder. You would just have one remote that you plug into each controller to program it.

It could also be done with bluetooth (or zigbee, or anything else that can do serial over whatever), but that seems needlessly complicated for what it is.

This is what the interface looks like currently (this is with just one global input able to be specified - I had the idea to add the input per table row and run 4 slicers simultaneously just over the weekend and haven't had a chance to implement it in the firmware yet):
interface_0.png
interface_1.png
interface_2.png
interface_3.png
interface_4.png
 
Back
Top