Skip to content

Commit b33ba8e

Browse files
committed
Fix RGBW management for FastLED (ESP32-C2,C3,C5,C6,S3)
1 parent f285bdb commit b33ba8e

6 files changed

Lines changed: 95 additions & 88 deletions

File tree

include/leds.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
namespace Leds {
88
void applyLedConfig();
99
int getLedsNumber();
10-
void checkDeleyedRender();
10+
void checkDelayedRender();
1111
void renderLed(bool isNewFrame);
12-
void synchronizeLedsToVolatileStateBeforeDeleyedRender();
12+
void synchronizeLedsToVolatileStateBeforeDelayedRender();
1313

1414
template<bool applyBrightness>
1515
void setLed(int index, uint8_t r, uint8_t g, uint8_t b);

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Hyperk
22

3-
Hyperk is a minimalist, high-performance uni-platform WiFi LED driver for ESP8266, ESP32 (S2, S3, C3, C6), Raspberry Pi Pico W (RP2040, RP2350). Designed as a lightweight and streamlined component that avoids unnecessary complexity, it delivers low‑latency performance and integrates smoothly with platforms such as HyperHDR, while offering essential home‑automation capabilities through a clean, modern codebase.
3+
Hyperk is a minimalist, high-performance uni-platform WiFi LED driver for ESP8266, ESP32 (S2, S3, C2, C3, C5, C6), Raspberry Pi Pico W (RP2040, RP2350). Designed as a lightweight and streamlined component that avoids unnecessary complexity, it delivers low‑latency performance and integrates smoothly with platforms such as HyperHDR, while offering essential home‑automation capabilities through a clean, modern codebase.
44

55
## Installation
66

src/leds.cpp

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787

8888
namespace Leds{
8989
volatile bool delayedRender = false;
90+
uint16_t briPlus = 256;
9091

9192
int getLedsNumber()
9293
{
@@ -140,7 +141,7 @@ namespace Leds{
140141
return true;
141142
}
142143

143-
void synchronizeLedsToVolatileStateBeforeDeleyedRender()
144+
void synchronizeLedsToVolatileStateBeforeDelayedRender()
144145
{
145146
if (delayedRender || !canRender())
146147
return;
@@ -150,9 +151,7 @@ namespace Leds{
150151
{
151152
updated = true;
152153
Log::debug("Updating brightness to: ", Volatile::state.brightness);
153-
#ifdef USE_FASTLED
154-
FastLED.setBrightness(Volatile::state.brightness);
155-
#endif
154+
briPlus = Volatile::state.brightness + 1;
156155
}
157156

158157
if (Volatile::clearUpdatedPowerOnState())
@@ -174,7 +173,13 @@ namespace Leds{
174173
auto b = (Volatile::state.on) ? Volatile::state.staticColor.blue : 0;
175174

176175
#ifdef USE_FASTLED
177-
fill_solid(leds, getLedsNumber(), CRGB(r, g, b));
176+
for(int i = 0; i < getLedsNumber(); i++) {
177+
if (Volatile::state.brightness != 255)
178+
setLed<true>(i, r, g, b);
179+
else
180+
setLed<false>(i, r, g, b);
181+
}
182+
178183
FastLED.show();
179184
#else
180185
if (dotstar == nullptr && neopixel == nullptr && neopixelRgbw == nullptr)
@@ -209,6 +214,9 @@ namespace Leds{
209214
#ifdef USE_FASTLED
210215
if (FastLED.count())
211216
{
217+
if (cfgLedType == LedType::SK6812) {
218+
setParamsAndPrepareCalibration(calGain, calRed, calGreen, calBlue);
219+
}
212220
return;
213221
}
214222

@@ -243,10 +251,9 @@ namespace Leds{
243251

244252
if (fastLedsType == LedType::SK6812)
245253
{
254+
setParamsAndPrepareCalibration(calGain, calRed, calGreen, calBlue);
246255
virtualLedsNumber = (fastLedsNumber * 4 + 2) / 3;
247-
const size_t bytesToAllocate = virtualLedsNumber * 3;
248-
leds = reinterpret_cast<CRGB*>(new uint8_t[bytesToAllocate]);
249-
memset(leds, 0, bytesToAllocate);
256+
leds = new CRGB[virtualLedsNumber];
250257
}
251258
else
252259
{
@@ -257,63 +264,64 @@ namespace Leds{
257264
{
258265
switch (cfgLedDataPin) {
259266
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
260-
case 0: FastLED.addLeds<WS2812, 0, GRB>(leds, virtualLedsNumber); break;
267+
case 0: FastLED.addLeds<WS2812, 0, RGB>(leds, virtualLedsNumber); break;
261268
#endif
262-
case 1: FastLED.addLeds<WS2812, 1, GRB>(leds, virtualLedsNumber); break;
263-
case 2: FastLED.addLeds<WS2812, 2, GRB>(leds, virtualLedsNumber); break;
269+
case 1: FastLED.addLeds<WS2812, 1, RGB>(leds, virtualLedsNumber); break;
270+
case 2: FastLED.addLeds<WS2812, 2, RGB>(leds, virtualLedsNumber); break;
264271
#if !defined(CONFIG_IDF_TARGET_ESP32S3)
265-
case 3: FastLED.addLeds<WS2812, 3, GRB>(leds, virtualLedsNumber); break;
272+
case 3: FastLED.addLeds<WS2812, 3, RGB>(leds, virtualLedsNumber); break;
266273
#endif
267-
case 4: FastLED.addLeds<WS2812, 4, GRB>(leds, virtualLedsNumber); break;
268-
case 5: FastLED.addLeds<WS2812, 5, GRB>(leds, virtualLedsNumber); break;
269-
case 6: FastLED.addLeds<WS2812, 6, GRB>(leds, virtualLedsNumber); break;
270-
case 7: FastLED.addLeds<WS2812, 7, GRB>(leds, virtualLedsNumber); break;
274+
case 4: FastLED.addLeds<WS2812, 4, RGB>(leds, virtualLedsNumber); break;
275+
case 5: FastLED.addLeds<WS2812, 5, RGB>(leds, virtualLedsNumber); break;
276+
case 6: FastLED.addLeds<WS2812, 6, RGB>(leds, virtualLedsNumber); break;
277+
case 7: FastLED.addLeds<WS2812, 7, RGB>(leds, virtualLedsNumber); break;
271278
#if !defined(CONFIG_IDF_TARGET_ESP32C2)
272-
case 8: FastLED.addLeds<WS2812, 8, GRB>(leds, virtualLedsNumber); break;
279+
case 8: FastLED.addLeds<WS2812, 8, RGB>(leds, virtualLedsNumber); break;
273280
#endif
274-
case 10: FastLED.addLeds<WS2812, 10, GRB>(leds, virtualLedsNumber); break;
281+
case 10: FastLED.addLeds<WS2812, 10, RGB>(leds, virtualLedsNumber); break;
275282
#if defined(CONFIG_IDF_TARGET_ESP32C6)
276-
case 15: FastLED.addLeds<WS2812, 15, GRB>(leds, virtualLedsNumber); break;
277-
case 18: FastLED.addLeds<WS2812, 18, GRB>(leds, virtualLedsNumber); break;
278-
case 19: FastLED.addLeds<WS2812, 19, GRB>(leds, virtualLedsNumber); break;
279-
case 20: FastLED.addLeds<WS2812, 20, GRB>(leds, virtualLedsNumber); break;
280-
case 21: FastLED.addLeds<WS2812, 21, GRB>(leds, virtualLedsNumber); break;
281-
case 22: FastLED.addLeds<WS2812, 22, GRB>(leds, virtualLedsNumber); break;
283+
case 15: FastLED.addLeds<WS2812, 15, RGB>(leds, virtualLedsNumber); break;
284+
case 18: FastLED.addLeds<WS2812, 18, RGB>(leds, virtualLedsNumber); break;
285+
case 19: FastLED.addLeds<WS2812, 19, RGB>(leds, virtualLedsNumber); break;
286+
case 20: FastLED.addLeds<WS2812, 20, RGB>(leds, virtualLedsNumber); break;
287+
case 21: FastLED.addLeds<WS2812, 21, RGB>(leds, virtualLedsNumber); break;
288+
case 22: FastLED.addLeds<WS2812, 22, RGB>(leds, virtualLedsNumber); break;
282289
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
283-
case 16: FastLED.addLeds<WS2812, 16, GRB>(leds, virtualLedsNumber); break;
284-
case 17: FastLED.addLeds<WS2812, 17, GRB>(leds, virtualLedsNumber); break;
285-
case 18: FastLED.addLeds<WS2812, 18, GRB>(leds, virtualLedsNumber); break;
286-
case 48: FastLED.addLeds<WS2812, 48, GRB>(leds, virtualLedsNumber); break;
290+
case 16: FastLED.addLeds<WS2812, 16, RGB>(leds, virtualLedsNumber); break;
291+
case 17: FastLED.addLeds<WS2812, 17, RGB>(leds, virtualLedsNumber); break;
292+
case 18: FastLED.addLeds<WS2812, 18, RGB>(leds, virtualLedsNumber); break;
293+
case 48: FastLED.addLeds<WS2812, 48, RGB>(leds, virtualLedsNumber); break;
287294
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
288-
case 20: FastLED.addLeds<WS2812, 20, GRB>(leds, virtualLedsNumber); break;
289-
case 21: FastLED.addLeds<WS2812, 21, GRB>(leds, virtualLedsNumber); break;
295+
case 20: FastLED.addLeds<WS2812, 20, RGB>(leds, virtualLedsNumber); break;
296+
case 21: FastLED.addLeds<WS2812, 21, RGB>(leds, virtualLedsNumber); break;
290297
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
291-
case 11: FastLED.addLeds<WS2812, 11, GRB>(leds, virtualLedsNumber); break;
292-
case 27: FastLED.addLeds<WS2812, 27, GRB>(leds, virtualLedsNumber); break;
298+
case 11: FastLED.addLeds<WS2812, 11, RGB>(leds, virtualLedsNumber); break;
299+
case 27: FastLED.addLeds<WS2812, 27, RGB>(leds, virtualLedsNumber); break;
293300
#endif
294301
default:
295-
FastLED.addLeds<WS2812, 2, GRB>(leds, virtualLedsNumber);
302+
FastLED.addLeds<WS2812, 2, RGB>(leds, virtualLedsNumber);
296303
break;
297304
}
298305
}
299306
else
300307
{ // SPI (APA102 / SK9822)
301308
switch (cfgLedDataPin) {
302309
#if defined(CONFIG_IDF_TARGET_ESP32S3)
303-
case 11: FastLED.addLeds<APA102, 11, 12, BGR>(leds, virtualLedsNumber); break;
310+
case 11: FastLED.addLeds<APA102, 11, 12, BRG>(leds, virtualLedsNumber); break;
304311
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
305-
case 7: FastLED.addLeds<APA102, 7, 6, BGR>(leds, virtualLedsNumber); break;
312+
case 7: FastLED.addLeds<APA102, 7, 6, BRG>(leds, virtualLedsNumber); break;
306313
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
307-
case 6: FastLED.addLeds<APA102, 6, 5, BGR>(leds, virtualLedsNumber); break;
314+
case 6: FastLED.addLeds<APA102, 6, 5, BRG>(leds, virtualLedsNumber); break;
308315
#endif
309316

310317
default:
311318
Log::debug("!!! FATAL ERROR: Invalid LED Data Pin. Must use Hardware SPI pins. !!!");
312-
FastLED.addLeds<APA102, 7, 6, BGR>(leds, virtualLedsNumber);
319+
FastLED.addLeds<APA102, 7, 6, BRG>(leds, virtualLedsNumber);
313320
}
314321
}
315322

316-
FastLED.setBrightness(Volatile::state.brightness);
323+
FastLED.setBrightness(255);
324+
317325
#else
318326
if (cfgLedType == LedType::WS2812 || cfgLedType == LedType::SK6812)
319327
{ // clockless
@@ -352,24 +360,36 @@ namespace Leds{
352360
Volatile::updateStaticColor(cfg.led.r, cfg.led.g, cfg.led.b);
353361
}
354362

363+
inline uint8_t scaleBri(uint8_t v)
364+
{
365+
return (static_cast<uint16_t>(v) * briPlus) >> 8;
366+
}
367+
355368
template<bool applyBrightness>
356369
void setLed(int index, uint8_t r, uint8_t g, uint8_t b)
357370
{
358371
#ifdef USE_FASTLED
372+
if constexpr (applyBrightness) {
373+
r = scaleBri(r);
374+
g = scaleBri(g);
375+
b = scaleBri(b);
376+
}
377+
359378
if (fastLedsType == LedType::SK6812)
360379
{
361380
if (index >= fastLedsNumber) return;
362381
const RgbwColor calibrated = rgb2rgbw(r, g, b);
363382
uint16_t i = index * 4;
364-
reinterpret_cast<uint8_t*>(leds)[i] = calibrated.G;
365-
reinterpret_cast<uint8_t*>(leds)[i + 1] = calibrated.R;
366-
reinterpret_cast<uint8_t*>(leds)[i + 2] = calibrated.B;
367-
reinterpret_cast<uint8_t*>(leds)[i + 3] = calibrated.W;
383+
auto raw = reinterpret_cast<uint8_t*>(leds);
384+
raw[i] = calibrated.G;
385+
raw[i + 1] = calibrated.R;
386+
raw[i + 2] = calibrated.B;
387+
raw[i + 3] = calibrated.W;
368388
}
369389
else
370390
{
371391
if (index >= fastLedsNumber) return;
372-
leds[index] = CRGB(r, g, b);
392+
leds[index] = CRGB(g, r, b);
373393
}
374394
#else
375395
if (dotstar != nullptr)
@@ -397,19 +417,27 @@ namespace Leds{
397417
void setLedW(int index, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
398418
{
399419
#ifdef USE_FASTLED
420+
if constexpr (applyBrightness) {
421+
r = scaleBri(r);
422+
g = scaleBri(g);
423+
b = scaleBri(b);
424+
w = scaleBri(w);
425+
}
426+
400427
if (fastLedsType == LedType::SK6812)
401428
{
402429
if (index >= fastLedsNumber) return;
403430
uint16_t i = index * 4;
404-
reinterpret_cast<uint8_t*>(leds)[i] = g;
405-
reinterpret_cast<uint8_t*>(leds)[i + 1] = r;
406-
reinterpret_cast<uint8_t*>(leds)[i + 2] = b;
407-
reinterpret_cast<uint8_t*>(leds)[i + 3] = w;
431+
auto raw = reinterpret_cast<uint8_t*>(leds);
432+
raw[i] = g;
433+
raw[i + 1] = r;
434+
raw[i + 2] = b;
435+
raw[i + 3] = w;
408436
}
409437
else
410438
{
411439
if (index >= fastLedsNumber) return;
412-
leds[index] = CRGB(r, g, b);
440+
leds[index] = CRGB(g, r, b);
413441
}
414442
#else
415443
if (dotstar != nullptr)
@@ -433,7 +461,7 @@ namespace Leds{
433461
#endif
434462
}
435463

436-
void checkDeleyedRender()
464+
void checkDelayedRender()
437465
{
438466
if (delayedRender)
439467
{
@@ -491,10 +519,7 @@ namespace Leds{
491519
}
492520

493521
template void setLed<false>(int, uint8_t, uint8_t, uint8_t);
494-
template void setLedW<false>(int, uint8_t, uint8_t, uint8_t, uint8_t);
495-
496-
#ifndef USE_FASTLED
497-
template void setLed<true>(int, uint8_t, uint8_t, uint8_t);
498-
template void setLedW<true>(int, uint8_t, uint8_t, uint8_t, uint8_t);
499-
#endif
522+
template void setLedW<false>(int, uint8_t, uint8_t, uint8_t, uint8_t);
523+
template void setLed<true>(int, uint8_t, uint8_t, uint8_t);
524+
template void setLedW<true>(int, uint8_t, uint8_t, uint8_t, uint8_t);
500525
}

src/manager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ void managerLoop()
6161
{
6262
Volatile::checkStreamTimeout();
6363

64-
Leds::synchronizeLedsToVolatileStateBeforeDeleyedRender();
65-
Leds::checkDeleyedRender();
64+
Leds::synchronizeLedsToVolatileStateBeforeDelayedRender();
65+
Leds::checkDelayedRender();
6666

6767
if (_pendingReboot)
6868
{

src/udp_receiver.cpp

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,9 @@ void handleDDP(WiFiUDP& udp) {
5959
return;
6060
}
6161

62-
#ifdef USE_FASTLED
63-
const bool brightnessControl = false;
64-
auto setPixel = Leds::setLed<false>;
65-
auto setPixelW = Leds::setLedW<false>;
66-
#else
67-
const bool brightnessControl = (Volatile::state.brightness != 255);
68-
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
69-
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
70-
#endif
62+
const bool brightnessControl = (Volatile::state.brightness != 255);
63+
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
64+
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
7165

7266
uint8_t buffer[packetSize];
7367
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);
@@ -134,15 +128,9 @@ void handleRealTime(WiFiUDP& udp) {
134128
return;
135129
}
136130

137-
#ifdef USE_FASTLED
138-
const bool brightnessControl = false;
139-
auto setPixel = Leds::setLed<false>;
140-
auto setPixelW = Leds::setLedW<false>;
141-
#else
142-
const bool brightnessControl = (Volatile::state.brightness != 255);
143-
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
144-
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
145-
#endif
131+
const bool brightnessControl = (Volatile::state.brightness != 255);
132+
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
133+
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
146134

147135
uint8_t buffer[packetSize];
148136
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);
@@ -198,15 +186,9 @@ void handleRAW(WiFiUDP& udp)
198186
return;
199187
}
200188

201-
#ifdef USE_FASTLED
202-
const bool brightnessControl = false;
203-
auto setPixel = Leds::setLed<false>;
204-
auto setPixelW = Leds::setLedW<false>;
205-
#else
206-
const bool brightnessControl = (Volatile::state.brightness != 255);
207-
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
208-
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
209-
#endif
189+
const bool brightnessControl = (Volatile::state.brightness != 255);
190+
auto setPixel = brightnessControl ? Leds::setLed<true> : Leds::setLed<false>;
191+
auto setPixelW = brightnessControl ? Leds::setLedW<true> : Leds::setLedW<false>;
210192

211193
uint8_t buffer[packetSize];
212194
uint8_t* endBuffer = &(buffer[0]) + udp.read(buffer, packetSize);

version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.2-alpha.6
1+
0.0.2-alpha.7

0 commit comments

Comments
 (0)