Mixing RGB & GBR strings off the one controller...?

I have two different types of ws2811/12 attached in series off the one controller. Trouble is, first one is RGB, and the second is GBR colour ordering.

How do I code to translate the HSV’s color order, for pixel numbers over the length of the first segment: e.g. in essence…

if pixelIndex > lengthOfFirstSegment then secondSegmentHSV = translateHSVassumedToBeRGBtoGBR(RGBdisplayColour)

The two strings are physically different, which is required for the application, so I can’t just make the two segments the same type. And I want to run the same pattern (and edit existing ones) over the whole length.

? :slight_smile:

Doable, but annoying.

You might be better off converting HSV to RGB, then just flipping the RGB to GBR.

There are algos for HSV to RGB. @jeff did one here

I mean you could convert to RGB, flip to GBR and reconvert back to HSV, but if you are modifying the pattern and adding logic anyway, just catch the HSV call, convert to RGB, then use RGB(g, b, r) and avoid the 2nd converting back for speed.

If you’re only doing it to one pattern, I agree with @scruffynerf: rewrite the render function of that one pattern and be done with it. But if you have a lot of patterns, and want to keep adding more as you come across them, then it would be useful to have a snippet of code that would be easy to stitch into each new pattern…

Something like this:

////////////////
//  hsv2rgb conversion from: https://forum.electromage.com/t/hsv-to-individual-r-individual-g-inividual-b-funstions/193/2
//
var _r, _g, _b;
function hsv2rgb(hh, ss, vv) {
    h = hh % 1
    s = clamp(ss, 0, 1) 
    v = clamp(vv, 0, 1) 
    i = floor(h * 6)
    f = h * 6 - i
    p = v * (1 - s)
    q = v * (1 - (s * f))
    t = v * (1 - (s * (1 - f)))

    if      (i == 0) { _r = v; _g = t; _b = p } 
    else if (i == 1) { _r = q; _g = v; _b = p } 
    else if (i == 2) { _r = p; _g = v; _b = t } 
    else if (i == 3) { _r = p; _g = q; _b = v } 
    else if (i == 4) { _r = t; _g = p; _b = v } 
    else if (i == 5) { _r = v; _g = p; _b = q }  
}
//
////////////////

////////////////
//  rgb2hsv conversion from: https://www.programmingalgorithms.com/algorithm/rgb-to-hsv/
//
var _h, _s, _v;
function rgb2hsv(rr, gg, bb) {
  _v = max(max(rr,gg),bb);
  mins = min(min(rr,gg),bb);
  delta = _v - mins;
  if (_v == 0) _s = 0; else _s = delta/_v;
  if (_s == 0) _h = 0; else {
    Cr = (_v - rr) / delta;
    Cg = (_v - gg) / delta;
    Cb = (_v - bb) / delta;
    if (rr == _v) _h = Cb - Cg;
    if (gg == _v) _h = 2 + Cr - Cb;
    if (bb == _v) _h = 4 + Cg - Cr;
    _h /= 6;
    if (_h < 0) _h += 1;
  }
}
//
////////////////

////////////////
//  Here's where the magic happens
//
function stripChanges(index) { return (index < pixelCount / 2); } //  return True at the place where your strip changes formats.
function rgbMunged(rr, gg, bb, index) { if (stripChanges(index)) rgb(rr, gg, bb); else rgb(gg, bb, rr); }
function hsvMunged(hh, ss, vv, index) { if (stripChanges(index)) hsv(hh, ss, vv); else {
    hsv2rgb(h, s, v);
    //  You can simply call the RGB renderer and swap order of the RGB arguments:
    //  rgb(_g, _b, _r);
    //  or you can re-convert the RGB back to HSV and use the HSV renderer:
    rgb2hsv(_g, _b, _r);
    h = _h; s = _s; v = _v;
    hsv(_h, _s, _v);
  }
}

export function render(index) {
  //  Sample pattern to produce pure Rs, Gs & Bs 
  h = (index % 3) / 3; s = 1; v = 1;
  //  replace existing pattern renderer with a call to our special one.
  hsvMunged(h, s, v, index);
}

To adjust a pattern to your strip’s unique geometry, all you need to do is replace every call to rgb(r, g, b) with rgbMunged(r, g, b, index) and every call to hsv(h, s, v) with hsvMunged(h, s, v, index).

1 Like

I don’t have access to a PB at the moment, but couldn’t you just add 1/3 to every hue if the index is past the transition point?

if (index >= transitionIndex) h += .333
hsv(h, s, v)
3 Likes

Geez, guys… you’re all awesome. So helpful, and so quick to respond. Really appreciate your inputs, thanks. I’ll try some experiments based on your suggestions, over the weekend, and repost about the results. :slight_smile:

If @jeff’s simple trick (adding .33 to hue shifts it such that the color is correct on GBR strip, brilliant thought btw…) works, then you can use the munge function technique of @pixie without all of the conversion stuff, to make it really small and simple. If it’s HSV, then add .33, if it’s RGB, shift it to GBR. 3 tiny new functions to add to each pattern, that’s pretty nice.