Skip to content

Commit b57087e

Browse files
authored
Merge pull request #82 from Legion2/improve-colors
Improve colors for video lighting
2 parents dc7fadf + 40771e1 commit b57087e

File tree

6 files changed

+111
-51
lines changed

6 files changed

+111
-51
lines changed

src/FastLEDController.cpp

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,6 @@ uint8_t FastLEDController::getLEDCount(uint8_t channel)
6262
return channelData[channel].ledCount;
6363
}
6464

65-
void FastLEDController::addColors(CRGB* leds, const CRGB& color, const uint8_t* values, uint8_t length) {
66-
for (int i = 0; i < length; i++) {
67-
leds[i] += color % values[i];
68-
}
69-
}
70-
7165
int FastLEDController::applySpeed(int duration, byte speed) {
7266
switch (speed)
7367
{
@@ -82,16 +76,11 @@ int FastLEDController::applySpeed(int duration, byte speed) {
8276
}
8377
}
8478

85-
/*
86-
returns the current step of the animation
87-
*/
8879
int FastLEDController::animation_step(int duration, int steps) {
8980
int currentStep = ((currentUpdate % duration) / ((float)duration)) * steps;
9081
return currentStep;
9182
}
92-
/*
93-
returns the number of steps since the last update
94-
*/
83+
9584
int FastLEDController::animation_step_count(int duration, int steps) {
9685
long lastAnimationNumber = lastUpdate / duration;
9786
long currentAnimationNumber = currentUpdate / duration;
@@ -140,7 +129,7 @@ bool FastLEDController::updateLEDs()
140129
int step = animation_step(duration, 256);
141130
int move = group.direction == GROUP_DIRECTION_FORWARD ? -3 : 3;
142131
for (int i = 0; i < groupLedCount; i++) {
143-
channelData[channelId].leds[group.ledIndex + i] = CHSV(step + (i * move), 255, 255) % channel.brightness;
132+
channelData[channelId].leds[group.ledIndex + i] = CHSV(step + (i * move), 255, 255);
144133
}
145134
updated = true;
146135
}
@@ -174,7 +163,7 @@ bool FastLEDController::updateLEDs()
174163
scale = 255;
175164
}
176165

177-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1.lerp8(group.color2, scale) % channel.brightness);
166+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1.lerp8(group.color2, scale));
178167
updated = true;
179168
}
180169
break;
@@ -200,7 +189,7 @@ bool FastLEDController::updateLEDs()
200189
scale = 255 - scale;
201190
}
202191

203-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1 % scale % channel.brightness);
192+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1 % scale);
204193
updated = true;
205194
}
206195
break;
@@ -245,15 +234,15 @@ bool FastLEDController::updateLEDs()
245234
else {
246235
scale = 255 - ease8InOutApprox((distanceWave * 4) * 256);
247236
}
248-
channelData[channelId].leds[group.ledIndex + i] = (color % scale) % channel.brightness;
237+
channelData[channelId].leds[group.ledIndex + i] = (color % scale);
249238
}
250239
updated = true;
251240
}
252241
break;
253242
}
254243
case GROUP_MODE_Static:
255244
{
256-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1 % channel.brightness);
245+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, group.color1);
257246
updated = true;
258247
break;
259248
}
@@ -282,7 +271,7 @@ bool FastLEDController::updateLEDs()
282271
color = group.color3;
283272
}
284273

285-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, color % channel.brightness);
274+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, color);
286275
updated = true;
287276
break;
288277
}
@@ -309,7 +298,7 @@ bool FastLEDController::updateLEDs()
309298
if (led >= groupLedCount) {
310299
led = steps - led - 1;
311300
}
312-
channelData[channelId].leds[group.ledIndex + led] = group.color1 % channel.brightness;
301+
channelData[channelId].leds[group.ledIndex + led] = group.color1;
313302
}
314303
updated = true;
315304
}
@@ -322,7 +311,7 @@ bool FastLEDController::updateLEDs()
322311
if (count > 0) {
323312
int step = animation_step(duration, 3);
324313
for (int i = 0; i < groupLedCount; i++) {
325-
channelData[channelId].leds[group.ledIndex + i] = (i + step) % 3 > 0 ? group.color1 % channel.brightness : CRGB::Black;
314+
channelData[channelId].leds[group.ledIndex + i] = (i + step) % 3 > 0 ? group.color1 : CRGB::Black;
326315
}
327316
updated = true;
328317
}
@@ -345,7 +334,7 @@ bool FastLEDController::updateLEDs()
345334
}
346335
}
347336

348-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, step == 0 ? group.color1 % channel.brightness : CRGB::Black);
337+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, step == 0 ? group.color1 : CRGB::Black);
349338
updated = true;
350339
}
351340
break;
@@ -365,12 +354,12 @@ bool FastLEDController::updateLEDs()
365354
}
366355

367356
if (group.direction == GROUP_DIRECTION_FORWARD) {
368-
fill_solid(&channelData[channelId].leds[group.ledIndex], step + 1, group.color1 % channel.brightness);
369-
fill_solid(&channelData[channelId].leds[group.ledIndex + step + 1], groupLedCount - (step + 1), group.color2 % channel.brightness);
357+
fill_solid(&channelData[channelId].leds[group.ledIndex], step + 1, group.color1);
358+
fill_solid(&channelData[channelId].leds[group.ledIndex + step + 1], groupLedCount - (step + 1), group.color2);
370359
}
371360
else {
372-
fill_solid(&channelData[channelId].leds[group.ledIndex + groupLedCount - (step + 1)], step + 1, group.color1 % channel.brightness);
373-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount - (step + 1), group.color2 % channel.brightness);
361+
fill_solid(&channelData[channelId].leds[group.ledIndex + groupLedCount - (step + 1)], step + 1, group.color1);
362+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount - (step + 1), group.color2);
374363
}
375364
updated = true;
376365
}
@@ -382,7 +371,7 @@ bool FastLEDController::updateLEDs()
382371
int count = animation_step_count(duration, 256);
383372
if (count > 0) {
384373
int step = animation_step(duration, 256);
385-
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, CHSV(step, 255, 255) % channel.brightness);
374+
fill_solid(&channelData[channelId].leds[group.ledIndex], groupLedCount, CHSV(step, 255, 255));
386375
updated = true;
387376
}
388377
break;
@@ -396,6 +385,7 @@ bool FastLEDController::updateLEDs()
396385
#endif
397386
break;
398387
}
388+
nscale8_video(&channelData[channelId].leds[group.ledIndex], groupLedCount, channel.brightness);
399389
}
400390
}
401391
break;
@@ -404,10 +394,9 @@ bool FastLEDController::updateLEDs()
404394
{
405395
if (trigger_update) {
406396
auto& data = channelData[channelId];
407-
fill_solid(data.leds, data.ledCount, CRGB::Black);
408-
addColors(data.leds, CRGB::Red, data.valuesBuffer[0], data.ledCount);
409-
addColors(data.leds, CRGB::Green, data.valuesBuffer[1], data.ledCount);
410-
addColors(data.leds, CRGB::Blue, data.valuesBuffer[2], data.ledCount);
397+
for (int i = 0; i < data.ledCount; i++) {
398+
data.leds[i] = CRGB(data.valuesBuffer[0][i], data.valuesBuffer[1][i], data.valuesBuffer[2][i]);
399+
}
411400
updated = true;
412401
}
413402
break;

src/FastLEDController.h

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,46 @@ class FastLEDController : public LEDController {
2828
struct ChannelData {
2929
uint8_t ledCount = 0;
3030
CRGB* leds = nullptr;
31-
// store an array for each color, used for software playback
31+
/**
32+
* store an array for each color, used for software playback
33+
*/
3234
uint8_t* valuesBuffer[3] = { nullptr };
33-
// current temperature
35+
/**
36+
* current temperature
37+
*/
3438
uint16_t temp;
3539
void (*onUpdateCallback)(void) = nullptr;
3640
};
3741

3842
public:
39-
// Create a new FastLEDController and specify if the EEPROM of the Arduino should be used. See the other contructor for more details.
43+
/**
44+
* Create a new FastLEDController and specify if the EEPROM of the Arduino should be used. See the other contructor for more details.
45+
*
46+
* @param useEEPROM specify if the EEPROM should be used
47+
*/
4048
FastLEDController(bool useEEPROM);
41-
// Create a new FastLEDController and specify if the EEPROM of the Arduino should be used to store persistent information like
42-
// the Hardware Lighting. If enabled, the hardware lighting configured in iCUE works without a USB connection and even after a
43-
// restart of the Arduino. Also the the TemperatureController used for temperature related lighting can be passed here.
49+
/**
50+
* Create a new FastLEDController and specify if the EEPROM of the Arduino should be used to store persistent information like
51+
* the Hardware Lighting. If enabled, the hardware lighting configured in iCUE works without a USB connection and even after a
52+
* restart of the Arduino. Also the the TemperatureController used for temperature related lighting can be passed here.
53+
*
54+
* @param temperatureController used for temperature based lighting
55+
* @param useEEPROM specify if the EEPROM should be used
56+
*/
4457
FastLEDController(TemperatureController* temperatureController, bool useEEPROM);
4558
~FastLEDController();
4659
virtual void addLEDs(uint8_t channel, CRGB* leds, uint8_t count);
4760
CRGB* getLEDs(uint8_t channel);
4861
uint8_t getLEDCount(uint8_t channel);
4962
virtual bool updateLEDs();
5063
virtual size_t getEEPROMSize();
51-
// Register an update hook, which is exectuted after a channel has been updated. This can be used to apply transforamtions to the
52-
// channel before the data is displayed by FastLED. The first argument is the channel for which the hook is registered, the second
53-
// argument is the callback, which is a void function with no arguments.
64+
/**
65+
* Register an update hook, which is exectuted after a channel has been updated. This can be used to apply transforamtions to the
66+
* channel before the data is displayed by FastLED.
67+
*
68+
* @param channel the channel for which the hook is registered
69+
* @param callback the callback, which is executed after the update
70+
*/
5471
void onUpdateHook(uint8_t channel, void (*callback)(void));
5572
protected:
5673
TemperatureController* const temperatureController;
@@ -63,9 +80,22 @@ class FastLEDController : public LEDController {
6380
long currentUpdate = 0;
6481

6582
int applySpeed(int duration, byte speed);
83+
/**
84+
* Calculates the index of the current step of the animation.
85+
*
86+
* @param duration the duration on the animation
87+
* @param steps the number of steps of the animation
88+
* @return the current step of the animation
89+
*/
6690
int animation_step(int duration, int steps);
91+
/**
92+
* Calculates the number of steps of the animation, since the last update of the animation.
93+
*
94+
* @param duration the duration on the animation
95+
* @param steps the number of steps of the animation
96+
* @return the number of steps since the last update
97+
*/
6798
int animation_step_count(int duration, int steps);
68-
void addColors(CRGB* leds, const CRGB& color, const uint8_t* values, uint8_t length);
6999

70100
const bool useEEPROM;
71101
bool load() override;

src/FastLEDControllerUtils.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
#include "FastLEDControllerUtils.h"
1717
#include <math.h>
18+
#include <FastLED.h>
1819

1920
void CLP::transformLLFanToStrip(FastLEDController* controller, uint8_t channelIndex)
2021
{
@@ -80,3 +81,13 @@ void CLP::reverse(FastLEDController* controller, uint8_t channelIndex)
8081
leds[maxIndex - ledIndex] = temp;
8182
}
8283
}
84+
85+
void CLP::gammaCorrection(FastLEDController* controller, uint8_t channelIndex) {
86+
auto leds = controller->getLEDs(channelIndex);
87+
auto count = controller->getLEDCount(channelIndex);
88+
for (int ledIndex = 0; ledIndex < count; ledIndex++) {
89+
leds[ledIndex].r = dim8_video(leds[ledIndex].r);
90+
leds[ledIndex].g = dim8_video(leds[ledIndex].g);
91+
leds[ledIndex].b = dim8_video(leds[ledIndex].b);
92+
}
93+
}

src/FastLEDControllerUtils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,12 @@ namespace CLP
6060
* @param channelIndex the index of the channel you want to reverse
6161
*/
6262
void reverse(FastLEDController* controller, uint8_t channelIndex);
63+
64+
/**
65+
* Simple gamma correction with gamma value 2. This approximation of the gamma correction is sufficient for most led strips.
66+
*
67+
* @param controller the FastLEDController controlling the LEDs
68+
* @param channelIndex the index of the channel
69+
*/
70+
void gammaCorrection(FastLEDController* controller, uint8_t channelIndex);
6371
}

src/LEDController.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,14 @@ void LEDController::reset()
199199
save();
200200
}
201201

202-
uint8_t LEDController::getLEDStripMask(uint8_t channel, uint8_t set)
202+
uint8_t LEDController::getLEDStripMask(uint8_t channel, uint8_t groupIndex)
203203
{
204-
return channels[channel].groups[set].ledCount;
204+
return channels[channel].groups[groupIndex].ledCount;
205205
}
206206

207-
bool LEDController::setLEDGroup(uint8_t channel, uint8_t set, LEDGroup& group)
207+
bool LEDController::setLEDGroup(uint8_t channel, uint8_t groupIndex, LEDGroup& group)
208208
{
209-
channels[channel].groups[set] = group;
209+
channels[channel].groups[groupIndex] = group;
210210
return true;
211211
}
212212

src/LEDController.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,14 @@
6565
#define GROUP_TEMP_GROUP_EXTERNAL 255
6666

6767
struct LEDGroup {
68-
byte ledIndex = 0;//start index of the leds of this group
69-
byte ledCount = 0;//number of leds in this group
68+
/**
69+
* start index of the leds of this group
70+
*/
71+
byte ledIndex = 0;
72+
/**
73+
* number of leds in this group
74+
*/
75+
byte ledCount = 0;
7076
byte mode = GROUP_MODE_Rainbow_Wave;
7177
byte speed = GROUP_SPEED_HIGH;
7278
byte direction = GROUP_DIRECTION_FORWARD;
@@ -104,18 +110,34 @@ class LEDController : public ILEDController {
104110
virtual void reset();
105111
protected:
106112
LEDChannel channels[CHANNEL_NUM];
107-
// Indicates that the configuration of the channels has been changed and should be saved
113+
/**
114+
* Indicates that the configuration of the channels has been changed and should be saved
115+
*/
108116
bool trigger_save = false;
109117

110-
//Trigger update of the LEDs
118+
/**
119+
* Trigger update of the LEDs
120+
*/
111121
virtual void triggerLEDUpdate() = 0;
112-
// The led count of the group
113-
virtual uint8_t getLEDStripMask(uint8_t channel, uint8_t set);
122+
/**
123+
* The led count of the group
124+
*
125+
* @param channel the channel index
126+
* @param group the group index
127+
* @return the number of leds in the group
128+
*/
129+
virtual uint8_t getLEDStripMask(uint8_t channel, uint8_t group);
114130
// The temperature in hundredths of a degree Celsius.
115131
virtual void setLEDExternalTemperature(uint8_t channel, uint16_t temp) = 0;
116-
virtual bool setLEDGroup(uint8_t channel, uint8_t set, LEDGroup& group);
132+
virtual bool setLEDGroup(uint8_t channel, uint8_t groupIndex, LEDGroup& group);
117133
virtual void setLEDColorValues(uint8_t channel, uint8_t color, uint8_t offset, const uint8_t* values, size_t len) = 0;
118134
virtual bool setLEDMode(uint8_t channel, uint8_t mode);
135+
/**
136+
* The brightness of the channel. This only applies to HW lighting.
137+
*
138+
* @param channel the channel index
139+
* @param brightness the brightness in the range 0-255
140+
*/
119141
virtual bool setLEDBrightness(uint8_t channel, uint8_t brightness);
120142
// The type of led controller: WS2812B or UCS1903
121143
// one of PORT_TYPE_*

0 commit comments

Comments
 (0)