Output expander duplicate channels

I think this is a bug, but it could easily be intentional for a reason I don’t understand.

If I set up an output expander like this, I get a pixel count of 250:
0: start: 0, pixels: 100
1: start: 0, pixels: 100
2: start: 100, pixels: 50

I’d expect to get a count of 150, with the first 100 pixels output to both channel 0 and channel 1. It’s not a blocker; we’re not running a giant number of pixels on this project, but it does affect frame rate. I can mitigate by ensuring the unused 150-250 range immediately sets hsv(0,0,0) and returns. But it would be more efficient to not have to do this.

The fix would be setting pixelCount by Max([start+pixels]) rather than Sum([pixels]). I don’t think it would be a breaking change, as nobody who’s set up that way can use those pixels anyway. Maybe it breaks clever mappings like a pyramid made using gaps in a single strand (like 2-3, 7-10, 12-18), but my guess is it wouldn’t.

Unfortunately, there’s currently no config that will skip calculating render() once for every pixel defined in the output expander, so returning early with your hsv(0,0,0) trick is probably your best option to keep FPS high.

If you want to override the pixelCount global variable in code, you can do that, but render() will still be called` 250 times per frame. Due to how scoping and execution order works, you’ll have to do it in two places:

var pixelCount = 150

// ...

export function beforeRender(delta) {
  pixelCount = 150
  // ...

You’ll also find that you can override the value of pixelCount from the “Pixels” setting on the settings page – you can set it to be smaller than the sum of the output expander channels’ pixel counts. In my experimentation, this resulted in unexpected behavior where not all pixels were calculated and output as I predicted they would be for such a duplicated index config, so I’d advise against that.

If you always want those first 200 pixels to be duplicates of what’s calculated for index 0-99 regardless of the pattern code, you could consider running them both off a single channel with a physical Y-bridged connection of their data line. Note that if your distance to first pixel is long, mismatched, or you’re running high clock speeds on APA102-type pixels, this can sometimes introduce signal reflections that will start to glitch pixels. I haven’t come up with much of a good way to predict whether this will happen, I tend to just wire it up and try it.

Thanks, that’s what I expected, but good to understand a little deeper. And yeah, we don’t want to hardwire the linked pixels, because then we can’t do clever things like 2d patterns later. Plus I don’t want to have to worry about reflections.

I don’t like the idea of overriding pixelCount (execution order…); I’ll store a maxPixels instead and we can key off that.