• Save 15% on ALL SFF Network merch, until Dec 31st! Use code SFF2024 at checkout. Click here!

Stalled Iris 16 - RGB Vandal Button

The Dude

Chassis Packer
May 25, 2016
13
8
Not sure what kind of functions I'd actually implement. The only thing I have in mind are periodic blinks with different combinations of attack, sustain and release values, as well as always on. For more complicated blinking patterns, one could then play multiple functions on one channel.
I guess sine wave for HSV color space is a good start. This will give you breathing and rainbow effects, which is what RGB LEDs are all about :)
 
  • Like
Reactions: iFreilicht

jtd871

SFF Guru
Jun 22, 2015
1,166
851
If it hasn't already been implied by some of the previous posts, you could consider restricting some of the color space by (perhaps optionally) storing colors using say 6 or 7 bits per primary vs. 8, as most humans would likely have some difficulty perceiving a 1-bit color difference.

If you're up for variable-bit encoding, you could research a "quantized delta" or similar approach approach. I recall reading a paper on it for storing lossy but reasonably efficient representations of analog sound waveforms (for telephony applications?) some years ago...something similar could be implemented for the display function of the Iris (if you consider each LED as a pixel). Google seems to indicate that the 'correct' term of art is "sigma-delta modulation".
 
  • Like
Reactions: Biowarejak

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
I guess sine wave for HSV color space is a good start.

Generally for RGB rainbows, you probably want a ramp that loops (i.e. 0->1 and 1 wraps around to 0)
But yes for breathing sine wave is the best evar.

Just going off Theatre lighting console, using cue-based animations:

Colour space - (HSV or RGB)
Lights selected - (single value or "start end range")
Start value - (single value or "start end range")
End Value - (single value or "start end range")
offset value (single value or "start end range")
offset time (single value or "start end range")
Delay (single value or "start-end range") This delays the animation time by this amount. Delay only occurs on first loop.
Speed (animation length)
Ramp type:



here's an example cuelist for a simple spiral animation (lights turn on one at a time and stay on, until 1s, when all lights are on. Then everything turns off and it repeats.)
Cue 1: RGB Light1 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 0 Time (1.0) Ramp Ramp
Cue 2: RGB Light2 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 1/12 Time (1.0) Ramp Ramp
Cue 3: RGB Light3 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 2/12 Time (1.0) Ramp Ramp
Cue 4: RGB Light4 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 3/12 Time (1.0) Ramp Ramp
Cue 5: RGB Light5 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 4/12 Time (1.0) Ramp Ramp
Cue 6: RGB Light6 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 5/12 Time (1.0) Ramp Ramp
Cue 7: RGB Light7 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 6/12 Time (1.0) Ramp Ramp
Cue 8: RGB Light8 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 7/12 Time (1.0) Ramp Ramp
Cue 9: RGB Light9 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 8/12 Time (1.0) Ramp Ramp
Cue 10: RGB Light10 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 912 Time (1.0) Ramp Ramp
Cue 11: RGB Light11 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 10/12 Time (1.0) Ramp Ramp
Cue 12: RGB Light12 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 11/12 Time (1.0) Ramp Ramp

Here's an example cuelist for EXACTLY the same animation, done in one cue.
Cue1: RGB (Light1->Light12) StartValue (0,0,0), EndValue(255,255,255), OffsetValue 0, OffsetTime (0->1) Speed (1.0) Ramp Ramp

I reckon with something like this thats decently parameterized you could do 80-90% of user things in 1 cue. Obviously the downside is i they want bitmap style animations parameterized is not the way to go.

Total bytes for this encoding:
Colour space - (HSV or RGB) (1 byte)
Lights selected - (single value or "start end range") (2 byte) (can be reduced to 1 byte with some bitstuffing)
Start value - (single value or "start end range") (6 bytes)
End Value - (single value or "start end range") (6 bytes)
offset value (single value or "start end range") (6 bytes)
offset time (single value or "start end range") (4 bytes)
Delay (single value or "start-end range") This delays the animation time by this amount. Delay only occurs on first loop. (2 bytes)
Time (animation length in seconds) (2 bytes)
Ramp type: (2 bytes)

total bytes per "cue": 31 bytes. I assumed using shorts instead of floats for time.

Using the same 31 bytes you can easily do RGB rainbows (use offset value)

You could enhance selection so you could select alternating/arbitrary LEDs rather than a range, by using a simple bit map. Ordering them for the cue would take more bits though if you aren't just assuming order is lowest LED to highest.

E.g. with 2 cues you could do RGB rainbow on odd LEDS + red pulse on Even LEDS
 

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
Another thing about Theatre lighting consoles is you can have Additive Cues. I.e. have a seperate cue for each of the RGB values. and it ends up mixing all the cues effects together with correct priority.

One example is have a cue that cycles through Hue, (you have to mark the cue as only modifying hue and not Saturation/intensity),
then anotehr cue to cycle through intensity. This gives you a rainbow with hue and then the intensity cue changes the brightness of leds between on/off/strobe/whatever.
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Generally for RGB rainbows, you probably want a ramp that loops (i.e. 0->1 and 1 wraps around to 0)
But yes for breathing sine wave is the best evar.

Just going off Theatre lighting console, using cue-based animations:

Colour space - (HSV or RGB)
Lights selected - (single value or "start end range")
Start value - (single value or "start end range")
End Value - (single value or "start end range")
offset value (single value or "start end range")
offset time (single value or "start end range")
Delay (single value or "start-end range") This delays the animation time by this amount. Delay only occurs on first loop.
Speed (animation length)
Ramp type:



here's an example cuelist for a simple spiral animation (lights turn on one at a time and stay on, until 1s, when all lights are on. Then everything turns off and it repeats.)
Cue 1: RGB Light1 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 0 Time (1.0) Ramp Ramp
Cue 2: RGB Light2 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 1/12 Time (1.0) Ramp Ramp
Cue 3: RGB Light3 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 2/12 Time (1.0) Ramp Ramp
Cue 4: RGB Light4 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 3/12 Time (1.0) Ramp Ramp
Cue 5: RGB Light5 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 4/12 Time (1.0) Ramp Ramp
Cue 6: RGB Light6 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 5/12 Time (1.0) Ramp Ramp
Cue 7: RGB Light7 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 6/12 Time (1.0) Ramp Ramp
Cue 8: RGB Light8 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 7/12 Time (1.0) Ramp Ramp
Cue 9: RGB Light9 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 8/12 Time (1.0) Ramp Ramp
Cue 10: RGB Light10 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 912 Time (1.0) Ramp Ramp
Cue 11: RGB Light11 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 10/12 Time (1.0) Ramp Ramp
Cue 12: RGB Light12 StartValue (0,0,0) EndValue (255,255,255), OffsetValue 0, OffsetTime 0.0 Delay 11/12 Time (1.0) Ramp Ramp

Here's an example cuelist for EXACTLY the same animation, done in one cue.
Cue1: RGB (Light1->Light12) StartValue (0,0,0), EndValue(255,255,255), OffsetValue 0, OffsetTime (0->1) Speed (1.0) Ramp Ramp

I reckon with something like this thats decently parameterized you could do 80-90% of user things in 1 cue. Obviously the downside is i they want bitmap style animations parameterized is not the way to go.

Total bytes for this encoding:

Colour space - (HSV or RGB) (1 byte)
Lights selected - (single value or "start end range") (2 byte) (can be reduced to 1 byte with some bitstuffing)
Start value - (single value or "start end range") (6 bytes)
End Value - (single value or "start end range") (6 bytes)
offset value (single value or "start end range") (6 bytes)
offset time (single value or "start end range") (4 bytes)
Delay (single value or "start-end range") This delays the animation time by this amount. Delay only occurs on first loop. (2 bytes)
Time (animation length in seconds) (2 bytes)
Ramp type: (2 bytes)

total bytes per "cue": 31 bytes. I assumed using shorts instead of floats for time.

Using the same 31 bytes you can easily do RGB rainbows (use offset value)

You could enhance selection so you could select alternating/arbitrary LEDs rather than a range, by using a simple bit map. Ordering them for the cue would take more bits though if you aren't just assuming order is lowest LED to highest.

E.g. with 2 cues you could do RGB rainbow on odd LEDS + red pulse on Even LEDS

Very informative, thanks a lot! This seems like a useful solution space to take ideas from for this application. Each of the values deserves separate discussion in my eyes.

Colour space - (HSV or RGB) (1 byte)

Colour space is probably something I'd set globally for the configuration, it seems a little silly to specify it separately for each cue.

Lights selected - (single value or "start end range") (2 byte) (can be reduced to 1 byte with some bitstuffing)

Not sure if a range would be required for this. We only have 12 discrete lights, so in two bytes we could actually just have a bit flag for every single one of them, which gives a little more freedom. Otherwise you're right, 4 bits for start ID and 4 bits for end ID would be enough as well.

Start value - (single value or "start end range") (6 bytes)
End Value - (single value or "start end range") (6 bytes)

I renamed those to Start Colour and End Colour in my notes, but other than that, simple concept. You are right in that those would be mapped to a smaller colour space, 16bit would be more than enough, methinks. I guess if this contained a range, it would be linearly spread out across each light, correct? Can that even be done with colours?

offset value (single value or "start end range") (6 bytes)

So, what would this exactly do? Is that like an offset between the colours of each light? Again, how would using a range affect the value for each individual light in this cue?

offset time (single value or "start end range") (4 bytes)

What is the purpose of this one? How does a range affect the values?

Delay (single value or "start-end range") This delays the animation time by this amount. Delay only occurs on first loop. (2 bytes)

Here a range makes much more sense to me. For normal operation, a linear spread across is probably enough, but it might be interesting to have other options here as well.

Time (animation length in seconds) (2 bytes)

Ok, makes perfect sense. Actually, floating point numbers would have to be implemented in software anyway, it might be that the libraries for that actually support 16bit floats.

Ramp type: (2 bytes)

I really like the idea of having different ramp types, that makes the system very flexible!

Yesterday I managed to find out how I can make coherent gifs of animations, I'll get some ready when I have time, that'll make it easier to see how well this works for each of them.

Another thing about Theatre lighting consoles is you can have Additive Cues. I.e. have a seperate cue for each of the RGB values. and it ends up mixing all the cues effects together with correct priority.

One example is have a cue that cycles through Hue, (you have to mark the cue as only modifying hue and not Saturation/intensity),
then anotehr cue to cycle through intensity. This gives you a rainbow with hue and then the intensity cue changes the brightness of leds between on/off/strobe/whatever.

That should be implementable with special values. In a 16bit colour space, one could use 0 for each of the values to set it as "floating" so to speak. Very cool feature as well.
 

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
start value/end value + offset are just what the lighting software i use uses.
Remember these parameters are not just for colour but also for position/gobo/beam patterns etc.

That being said, here's an example where offset could be useful.

Let's say you want to do an Hue gradient that animates (i.e. H = 0->1, S = 1, V = 1. Light 1 starts from hue = 0, light 6 starts from hue = 0.5, every "time step", all lights += some constant to their hue value. The hues wrap).
Basically this (but with your LEDS):


How would you do this with JUST start/end values?
Lets say you did
Lights selected = ALL
StartColour(HSV) = (0, 255, 255) -> (255, 255, 255) //maps light 1 to start hue = 0, light
EndValue = (255,255,255) -> (512,255,255) //This can't be done because you can't store above 255!
Ramp = LinearRamp
Time = 1.0s

Here's the same thing, but using offsets
StartColour (HSV) = (0, 255, 255) -> (0,255,255) // maps all lights to start at 0 hue
EndValue(HSV)= (255,255,255) -> (255,255,255) //maps all lights to end at 1.0 hue
Offset = (0,0,0) -> (255,0,0) -> //adds an offset during calculation, which will wrap.
Ramp = LinearRamp
Time = 1.0s

Again, this system is still not perfect because it still only lets you do an offset of +- 1.0

Alternatively, you set it up so that start and end value can have values bigger than 255, and smaller than 0 (negative offsets) (i.e. 12 bit colour instead of 8 bit, and with higher bits wrapping around)

Hope that makes sense!
 

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
Not sure if a range would be required for this. We only have 12 discrete lights, so in two bytes we could actually just have a bit flag for every single one of them, which gives a little more freedom. Otherwise you're right, 4 bits for start ID and 4 bits for end ID would be enough as well.

The main reason for having start/end for selection is that you can select backwards. i.e. startlight = 12, endlight = 1. I think this can be solved 99% of the time by simply reversing start/end values, but sometimes, maybe not.
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
start value/end value + offset are just what the lighting software i use uses.
Remember these parameters are not just for colour but also for position/gobo/beam patterns etc.

That being said, here's an example where offset could be useful.

Let's say you want to do an Hue gradient that animates (i.e. H = 0->1, S = 1, V = 1. Light 1 starts from hue = 0, light 6 starts from hue = 0.5, every "time step", all lights += some constant to their hue value. The hues wrap).
Basically this (but with your LEDS):


How would you do this with JUST start/end values?
Lets say you did
Lights selected = ALL
StartColour(HSV) = (0, 255, 255) -> (255, 255, 255) //maps light 1 to start hue = 0, light
EndValue = (255,255,255) -> (512,255,255) //This can't be done because you can't store above 255!
Ramp = LinearRamp
Time = 1.0s

Here's the same thing, but using offsets
StartColour (HSV) = (0, 255, 255) -> (0,255,255) // maps all lights to start at 0 hue
EndValue(HSV)= (255,255,255) -> (255,255,255) //maps all lights to end at 1.0 hue
Offset = (0,0,0) -> (255,0,0) -> //adds an offset during calculation, which will wrap.
Ramp = LinearRamp
Time = 1.0s

Again, this system is still not perfect because it still only lets you do an offset of +- 1.0

Alternatively, you set it up so that start and end value can have values bigger than 255, and smaller than 0 (negative offsets) (i.e. 12 bit colour instead of 8 bit, and with higher bits wrapping around)

Hope that makes sense!

Ah that makes a lot of sense now, thanks!

The main reason for having start/end for selection is that you can select backwards. i.e. startlight = 12, endlight = 1. I think this can be solved 99% of the time by simply reversing start/end values, but sometimes, maybe not.

From your explanation it seems like swapping Start and End ID would be equal to using a negative offset. Even if that was supported, it's much more convenient and intuitive to simply swap Start and End ID to reverse the direction of an effect.

On the other hand, having separate flags for each colour gives a little more freedom, and with 12 lights we still have 4 bytes left, so a simple "reverse" flag would have the same effect without taking up additional space.

The more I think about this system, the better it sounds. Thank you so much for bringing this up!
 
  • Like
Reactions: Biowarejak

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
That's not a spoiler, that's a teaser for the show :D SPOILER: It's a very good show and you should watch it, it's only three seasons long anyway.

You're joking, but one could gain some space by compressing the whole configuration file, even if it's just a traditional top-down algorithm ;) However, the problem with such an idea might be that the information density is already quite high when engineering and file format to already be very small. And of course that decompression takes a little while. Too much complexity for a simple problem in my eyes.
 

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
Middle-out? XD

Just have two cues. one for lights 6->12 and one for cues 1->5.

Hell you could modularize it so that you can reference previous variables.
I.e. lights 1->6. Effect = 1 where effect is defined elsewhere
lights 12->7. effect = 1

Or if you think order is "that" important you simply have a linked list of lights in the order - but that is very space consuming (4 bits per item, so i guess max size = 48 bits/ 6 bytes
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
Hell you could modularize it so that you can reference previous variables.
I.e. lights 1->6. Effect = 1 where effect is defined elsewhere
lights 12->7. effect = 1

Hm, interesting idea. I do have three bits left in the header, so one could just be a "pointer flag" of sorts. Would save additional space and make mirrored or patterned effects (2 spinning dots instead of one) much easier to make.

What just occurred to me: How would one make a "bouncing" animation with cues? Say, we have a dot rotating clockwise for one rotation, then counterclockwise for the next.
 

|||

King of Cable Management
Sep 26, 2015
775
759
This all is compression...aligning patterns and other techniques to save data space. That's what reminded me of that Silicon Valley scene ;)

P.S. You can make it 0 thru 11 (although I'd understand if you wanted to correlate it to the number positions of a clock)

 

Phuncz

Lord of the Boards
SFFn Staff
May 9, 2015
5,958
4,957
The clocks in Europe are the same as in the US, so 12 positions will do nicely :)
 

iFreilicht

FlexATX Authority
Original poster
Feb 28, 2015
3,243
2,361
freilite.com
If you're doing it based on clocks, it should be 24.

The clocks in Europe are the same as in the US, so 12 positions will do nicely :)

Well, italian clocks had all 24 hours on them at one point, but I don't have space for that at all. 12 is already pushing it to the limit of what's possible with my resources.

That being said, 24 is a good number of LEDs for a larger version because it has 8 divisors. 12 has 6 and is already a local maximum of the divisor function and has a large number of numerical/symmetrical properties. 18 and 20 are also candidates, but they're not quite as nice.

Really, anything that divides by 12 is a nice number, it's quite weird that very few cultures are/were using duodecimal systems.
 
  • Like
Reactions: Phuncz
Mar 6, 2017
501
454
There's 24 hours in a day, but if you can only fit 12 on the smaller version, there's nothing wrong with that. Who knows, if there are going to be multiple versions, I may end up buying both!
 
Last edited:
  • Like
Reactions: Biowarejak

XeaLouS

Cable-Tie Ninja
Dec 29, 2015
180
123
Hm, interesting idea. I do have three bits left in the header, so one could just be a "pointer flag" of sorts. Would save additional space and make mirrored or patterned effects (2 spinning dots instead of one) much easier to make.

What just occurred to me: How would one make a "bouncing" animation with cues? Say, we have a dot rotating clockwise for one rotation, then counterclockwise for the next.

In the lighting software I use (hog 4), there are cues and cue lists.

These "Cue Lists" have a bunch of cues with the following features:
  • Name (not necessary....)
  • Fade In Time(.e.g it adds an intensity multiplier to the cues values. might not be necessary for this system)
  • Wait time (how long from previous cue before we start this cue. Values include "manual", time in seconds, and "follow"
    • Manual is because this is used in theatres and the operator hits next
    • Time in seconds is useful if u want to start playing cue2 while cue1 is still fading in
    • follow plays the cue as soon as the previous one has finished fading in
  • "Go list": this is where you enter in a previously defined cue to actually fade up.
    • Go list: start a list
    • Release list: all lights that this list was touching now get "nulled"
    • Other things but probably not relevant for now.

So imagine you already have a cue for rotation clock wise, then another cue for rotation clockwise, you have a "cue list"

Cue List 1
Cue1: RotationClockwise cue / FadeTime 0s/ WaitTime 0s

Cue List 2
Cue1: RotationCCW cue / FadeTime 0s/ WaitTime 0s

Cue List 3
Cue1: FadeTime 0s / Wait Time 0s / GO LIST "Cue List 1"
Cue2: FadeTime 0s / Wait Time 1s / RELEASE LIST "Cue LIST 1" GO LIST "CUE LIST 2"
Cue3: Wait Time 1s / Release List "CUE LIST 2"

Hope that makes sense!
------------------------------------------------------------------
Another solution could be to add double-hooped "mark-on" curve that is parameterized to have delays. Though this is fairly specific. With the whole heavyweight cuelist system, you can play arbitrary cues in arbitrary orders with stacking.