The tint uses an abstract value from 0 to 255. When the user ramps the tint, it changes this value.
While setting the brightness, the tint value goes into a formula to convert it to a hardware control value. For example, if the tint is 100/255, and the brightness is 10, the hardware values are then 4 and 6.
- cool = ((brightness * tint) + 127) / 255
- warm = brightness - cool
Or with numbers…
- cool = ((10 * 100) / 127) / 255 = 4
- warm = 10 - 4 = 6
Since the hardware control values are all integers, the number of different tints possible increases with brightness. At a value of 2 brightness, the only possible values are 2:0, 1:1, and 0:2. With 3 brightness, it can be 3:0, 2:1, 1:2, or 3:0. And so on.
This is pretty simple so far, but in practice it gets more complicated. On PWM-based lights like the LT1, the hardware response is not linear… so it also has to add in a correction factor based on the current tint and brightness. The brightness dips at middle tints, as shown by the orange line here, and after adding a correction factor, it follows the blue line:
The correction function is a simple triangle wave which peaks in the middle, and gets added to the overall brightness values. So instead of having the hardware controls follow a straight line, they end up following a different shape of curve…
And there is likely to be an additional complication beyond that, on newer lights. I recently added a dynamic PWM thing to improve the resolution and ramp shape in low modes. This makes it so the hardware control values follow a more complex pattern. For example, here’s how the controls look on the KR4:
So if there was a tint-ramping light which also used high-precision dynamic PWM, the tint resolution would still be low at the bottom, but it would then increase quickly, turn around and become somewhat coarse again in the middle of the ramp, and then increase quickly again. The number of tints follows the orange line in that picture.
I did a test for this on my K9.3 prototype, and it works pretty well… but the code to implement it is pretty complex.
So… the tint ramping UI code really has no idea how many tint steps there will be. It’s a pretty complex calculation. Instead of trying to guess, the UI code just moves the abstract 0-to-255 “tint” value back and forth and lets the underlying hardware code interpret that however it needs to.
Currently, it moves that by 1 per frame, and the frames happen at 62 Hz because of hardware reasons. But it could move by 2 per frame, or 3, or 4, to speed things up… or it could move by 1 every 2 frames, or every 3 frames, etc, to slow things down. For a tint-ramp light, it’s nice to have high-precision control. But for a flood-throw-ramp light, speed seems more important than precision.
Another option is… depending on how the hardware works, it could just go to maximum throw mode (or perhaps maximum flood mode) at the top of the ramp, regardless of the current tint value. Like, on the K9.3 I tested with, there is a DD FET channel but it only powers one set of LEDs. So at the top of the ramp, that goes to full power no matter what the tint is. Tint ramping only works when the DD FET is off, using the two regulated power channels.
If that style is used, people could go to full throw mode and back just by activating turbo.
But I don’t know yet how this specific light will work. I’m just tossing up options for now, to see what sticks. I’m hoping for something simple though, because as dave1010 said, adding complexity to cover every possible preference is usually not a great solution.