From 049d51ba8ed2d7f185061e274cc8af5ef37f8352 Mon Sep 17 00:00:00 2001 From: druckgott Date: Sat, 16 Nov 2024 18:49:59 +0100 Subject: [PATCH 1/2] add effect auroraWave for LED add effect auroraWave for LED --- src/main/cli/settings.c | 3 ++ src/main/io/ledstrip.c | 111 +++++++++++++++++++++++++++++++++++++++- src/main/io/ledstrip.h | 15 ++++-- 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 11a71fe277..485649df49 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -1394,6 +1394,9 @@ const clivalue_t valueTable[] = { { "ledstrip_brightness", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 5, 100 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_brightness) }, { "ledstrip_rainbow_delta", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, HSV_HUE_MAX }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_rainbow_delta) }, { "ledstrip_rainbow_freq", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 2000 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_rainbow_freq) }, + { "w_max_count_aurora", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 32 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, w_max_count_aurora) }, + { "w_width_factor_aurora", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 32 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, w_width_factor_aurora) }, + { "w_max_speed_aurora", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 1, 255 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, w_max_speed_aurora) }, #endif // PG_SDCARD_CONFIG diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 1f6ec0d45b..b875c39b22 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -96,6 +96,7 @@ static uint8_t previousProfileColorIndex = COLOR_UNDEFINED; #define LED_OVERLAY_RAINBOW_RATE_HZ 60 #define LED_OVERLAY_LARSON_RATE_HZ 60 +#define LED_OVERLAY_AURORA_RATE_HZ 60 #define LED_OVERLAY_BLINK_RATE_HZ 10 #define LED_OVERLAY_VTX_RATE_HZ 5 #define LED_OVERLAY_INDICATOR_RATE_HZ 5 @@ -132,7 +133,7 @@ const hsvColor_t hsv[] = { // macro to save typing on default colors #define HSV(color) (hsv[COLOR_ ## color]) -PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 3); +PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 4); void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) { @@ -151,6 +152,9 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) ledStripConfig->ledstrip_brightness = 100; ledStripConfig->ledstrip_rainbow_delta = 0; ledStripConfig->ledstrip_rainbow_freq = 120; + ledStripConfig->w_max_count_aurora = 6; + ledStripConfig->w_width_factor_aurora = 10; + ledStripConfig->w_max_speed_aurora = 50; #ifndef UNIT_TEST #ifdef LED_STRIP_PIN ledStripConfig->ioTag = IO_TAG(LED_STRIP_PIN); @@ -309,7 +313,7 @@ void updateLedBars(void) STATIC_UNIT_TESTED void updateLedCount(void) { - int count = 0, countRing = 0, countScanner= 0; + int count = 0, countRing = 0, countScanner= 0, countAurora= 0; for (int ledIndex = 0; ledIndex < LED_STRIP_MAX_LENGTH; ledIndex++) { const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; @@ -324,11 +328,16 @@ STATIC_UNIT_TESTED void updateLedCount(void) if (ledGetOverlayBit(ledConfig, LED_OVERLAY_LARSON_SCANNER)) countScanner++; + + if (ledGetOverlayBit(ledConfig, LED_OVERLAY_AURORA)) + countAurora++; + } ledCounts.count = count; ledCounts.ring = countRing; ledCounts.larson = countScanner; + ledCounts.aurora = countAurora; setUsedLedCount(ledCounts.count); } @@ -371,6 +380,7 @@ static const char overlayCodes[LED_OVERLAY_COUNT] = { [LED_OVERLAY_THROTTLE] = 'T', [LED_OVERLAY_RAINBOW] = 'Y', [LED_OVERLAY_LARSON_SCANNER] = 'O', + [LED_OVERLAY_AURORA] = 'X', [LED_OVERLAY_BLINK] = 'B', [LED_OVERLAY_VTX] = 'V', [LED_OVERLAY_INDICATOR] = 'I', @@ -1057,6 +1067,100 @@ static void applyRainbowLayer(bool updateNow, timeUs_t *timer) } } +typedef struct auroraWave_s { + uint16_t ttl; + uint16_t age; + float center; + float speedFactor; + uint16_t width; + bool goingLeft; + bool alive; +} auroraWave_t; + +static void initAuroraWave(auroraWave_t *wave, int segmentLength) { + wave->ttl = rand() % 1001 + 500; // Zufallszahl zwischen 500 und 1500 + wave->age = 0; + wave->width = rand() % (segmentLength / ledStripConfig()->w_width_factor_aurora) + (segmentLength / 20); // Zufallszahl für Breite + wave->center = (rand() % 101) / 100.0 * segmentLength; // Zufallszahl zwischen 0 und segmentLength + wave->speedFactor = (rand() % 21 + 10) / 100.0 * ledStripConfig()->w_max_speed_aurora / 255.0; // Zufallszahl für Geschwindigkeit + wave->goingLeft = rand() % 2 == 0; // Zufallswert 0 oder 1 + wave->alive = true; +} + +static void updateAuroraWave(auroraWave_t *wave, int segmentLength) { + if (wave->goingLeft) { + wave->center -= wave->speedFactor; + } else { + wave->center += wave->speedFactor; + } + + wave->age++; + if (wave->age > wave->ttl || wave->center + wave->width < 0 || wave->center - wave->width > segmentLength) { + wave->alive = false; + } +} + +static int brightnessForAuroraIndex(auroraWave_t *wave, uint8_t ledIndex) { + if (!wave->alive) return 0; + + float offset = fabs(ledIndex - wave->center); + if (offset > wave->width) { + return 0; + } + + float offsetFactor = offset / wave->width; + float ageFactor = (float)(wave->ttl - wave->age) / wave->ttl; + + return (int)((1 - offsetFactor) * ageFactor * 255); +} + +static void applyAuroraLayer(bool updateNow, timeUs_t *timer) { + static auroraWave_t *auroraWaves = NULL; + static uint8_t waveCount = 0; + + // Initialisierung nur einmal durchführen + if (auroraWaves == NULL) { + waveCount = ledStripConfig()->w_max_count_aurora; + auroraWaves = (auroraWave_t *)malloc(waveCount * sizeof(auroraWave_t)); + if (auroraWaves == NULL) { + // Fehler: Speicher konnte nicht allokiert werden + return; + } + + // Array initialisieren (optional, falls nötig) + for (int i = 0; i < waveCount; i++) { + auroraWaves[i].alive = false; // Beispielwert + } + } + + if (updateNow) { + for (int i = 0; i < waveCount; i++) { + if (!auroraWaves[i].alive) { + initAuroraWave(&auroraWaves[i], ledCounts.count); + } else { + updateAuroraWave(&auroraWaves[i], ledCounts.count); + } + } + *timer += HZ_TO_US(LED_OVERLAY_AURORA_RATE_HZ); + } + + for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { + int totalBrightness = 0; + const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; + + for (int j = 0; j < waveCount; j++) { + totalBrightness += brightnessForAuroraIndex(&auroraWaves[j], ledIndex); + } + + if (ledGetOverlayBit(ledConfig, LED_OVERLAY_AURORA)) { + hsvColor_t ledColor; + getLedHsv(ledIndex, &ledColor); + ledColor.v = totalBrightness > 255 ? 255 : totalBrightness; + setLedHsv(ledIndex, &ledColor); + } + } +} + typedef struct larsonParameters_s { uint8_t currentBrightness; int8_t currentIndex; @@ -1150,6 +1254,7 @@ typedef enum { timRainbow, timBlink, timLarson, + timAurora, timRing, timIndicator, #ifdef USE_VTX_COMMON @@ -1180,6 +1285,7 @@ static applyLayerFn_timed* layerTable[] = { [timRainbow] = &applyRainbowLayer, [timBlink] = &applyLedBlinkLayer, [timLarson] = &applyLarsonScannerLayer, + [timAurora] = &applyAuroraLayer, [timBattery] = &applyLedBatteryLayer, [timRssi] = &applyLedRssiLayer, #ifdef USE_GPS @@ -1210,6 +1316,7 @@ void updateRequiredOverlay(void) disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_RAINBOW) << timRainbow; disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_BLINK) << timBlink; disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_LARSON_SCANNER) << timLarson; + disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_AURORA) << timAurora; disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_WARNING) << timWarning; #ifdef USE_VTX_COMMON disabledTimerMask |= !isOverlayTypeUsed(LED_OVERLAY_VTX) << timVtx; diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index fc6d467a6c..981cb54171 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -34,18 +34,18 @@ #define LED_MODE_COUNT 6 #define LED_DIRECTION_COUNT 6 #define LED_BASEFUNCTION_COUNT 10 -#define LED_OVERLAY_COUNT 7 +#define LED_OVERLAY_COUNT 8 #define LED_SPECIAL_COLOR_COUNT 11 #define LED_POS_OFFSET 0 #define LED_FUNCTION_OFFSET 8 -#define LED_OVERLAY_OFFSET 12 -#define LED_COLOR_OFFSET 22 -#define LED_DIRECTION_OFFSET 26 +#define LED_OVERLAY_OFFSET 13 +#define LED_COLOR_OFFSET 23 +#define LED_DIRECTION_OFFSET 27 #define LED_POS_BITCNT 8 #define LED_FUNCTION_BITCNT 4 -#define LED_OVERLAY_BITCNT 10 +#define LED_OVERLAY_BITCNT 11 #define LED_COLOR_BITCNT 4 #define LED_DIRECTION_BITCNT 6 @@ -139,6 +139,7 @@ typedef enum { LED_OVERLAY_THROTTLE, LED_OVERLAY_RAINBOW, LED_OVERLAY_LARSON_SCANNER, + LED_OVERLAY_AURORA, LED_OVERLAY_BLINK, LED_OVERLAY_VTX, LED_OVERLAY_INDICATOR, @@ -168,6 +169,7 @@ typedef struct ledCounts_s { uint8_t count; uint8_t ring; uint8_t larson; + uint8_t aurora; uint8_t ringSeqLen; } ledCounts_t; @@ -185,6 +187,9 @@ typedef struct ledStripConfig_s { uint8_t ledstrip_brightness; uint16_t ledstrip_rainbow_delta; uint16_t ledstrip_rainbow_freq; + uint8_t w_max_count_aurora; + uint8_t w_width_factor_aurora; + uint8_t w_max_speed_aurora; } ledStripConfig_t; PG_DECLARE(ledStripConfig_t, ledStripConfig); From ac0edec76a26b4602feac197cc8e5e9840173493 Mon Sep 17 00:00:00 2001 From: druckgott Date: Fri, 22 Nov 2024 09:36:47 +0100 Subject: [PATCH 2/2] Update ledstrip.c --- src/main/io/ledstrip.c | 99 ++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 66 deletions(-) diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index b875c39b22..f27536f79d 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -1067,96 +1067,63 @@ static void applyRainbowLayer(bool updateNow, timeUs_t *timer) } } -typedef struct auroraWave_s { - uint16_t ttl; - uint16_t age; - float center; - float speedFactor; - uint16_t width; - bool goingLeft; - bool alive; +typedef struct { + uint16_t ttl, age, width; + float center, speedFactor; + bool goingLeft, alive; } auroraWave_t; static void initAuroraWave(auroraWave_t *wave, int segmentLength) { - wave->ttl = rand() % 1001 + 500; // Zufallszahl zwischen 500 und 1500 + wave->ttl = rand() % 1001 + 500; wave->age = 0; - wave->width = rand() % (segmentLength / ledStripConfig()->w_width_factor_aurora) + (segmentLength / 20); // Zufallszahl für Breite - wave->center = (rand() % 101) / 100.0 * segmentLength; // Zufallszahl zwischen 0 und segmentLength - wave->speedFactor = (rand() % 21 + 10) / 100.0 * ledStripConfig()->w_max_speed_aurora / 255.0; // Zufallszahl für Geschwindigkeit - wave->goingLeft = rand() % 2 == 0; // Zufallswert 0 oder 1 + wave->width = rand() % (segmentLength / ledStripConfig()->w_width_factor_aurora) + (segmentLength / 20); + wave->center = rand() / (float)RAND_MAX * segmentLength; + wave->speedFactor = (rand() % 21 + 10) / 2550.0 * ledStripConfig()->w_max_speed_aurora; + wave->goingLeft = rand() % 2; wave->alive = true; } static void updateAuroraWave(auroraWave_t *wave, int segmentLength) { - if (wave->goingLeft) { - wave->center -= wave->speedFactor; - } else { - wave->center += wave->speedFactor; - } - - wave->age++; - if (wave->age > wave->ttl || wave->center + wave->width < 0 || wave->center - wave->width > segmentLength) { - wave->alive = false; - } + wave->center += wave->goingLeft ? -wave->speedFactor : wave->speedFactor; + wave->alive = ++wave->age <= wave->ttl && wave->center + wave->width >= 0 && wave->center - wave->width <= segmentLength; } -static int brightnessForAuroraIndex(auroraWave_t *wave, uint8_t ledIndex) { - if (!wave->alive) return 0; - - float offset = fabs(ledIndex - wave->center); - if (offset > wave->width) { - return 0; - } - - float offsetFactor = offset / wave->width; - float ageFactor = (float)(wave->ttl - wave->age) / wave->ttl; - - return (int)((1 - offsetFactor) * ageFactor * 255); +static int brightnessForAuroraIndex(const auroraWave_t *wave, uint8_t ledIndex) { + float offset = fabsf(ledIndex - wave->center); + return (wave->alive && offset <= wave->width) + ? (int)((1 - offset / wave->width) * (wave->ttl - wave->age) / wave->ttl * 255) + : 0; } static void applyAuroraLayer(bool updateNow, timeUs_t *timer) { - static auroraWave_t *auroraWaves = NULL; + static auroraWave_t *waves = NULL; static uint8_t waveCount = 0; - // Initialisierung nur einmal durchführen - if (auroraWaves == NULL) { + if (!waves) { waveCount = ledStripConfig()->w_max_count_aurora; - auroraWaves = (auroraWave_t *)malloc(waveCount * sizeof(auroraWave_t)); - if (auroraWaves == NULL) { - // Fehler: Speicher konnte nicht allokiert werden - return; - } - - // Array initialisieren (optional, falls nötig) - for (int i = 0; i < waveCount; i++) { - auroraWaves[i].alive = false; // Beispielwert - } + if (!(waves = malloc(waveCount * sizeof(auroraWave_t)))) return; + memset(waves, 0, waveCount * sizeof(auroraWave_t)); // Initialisiert alle Wellen } if (updateNow) { - for (int i = 0; i < waveCount; i++) { - if (!auroraWaves[i].alive) { - initAuroraWave(&auroraWaves[i], ledCounts.count); - } else { - updateAuroraWave(&auroraWaves[i], ledCounts.count); - } - } + for (uint8_t i = 0; i < waveCount; i++) + waves[i].alive ? updateAuroraWave(&waves[i], ledCounts.count) + : initAuroraWave(&waves[i], ledCounts.count); *timer += HZ_TO_US(LED_OVERLAY_AURORA_RATE_HZ); } for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) { - int totalBrightness = 0; - const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; + int brightness = 0; + const ledConfig_t *config = &ledStripStatusModeConfig()->ledConfigs[ledIndex]; + + for (uint8_t i = 0; i < waveCount; i++) + brightness += brightnessForAuroraIndex(&waves[i], ledIndex); - for (int j = 0; j < waveCount; j++) { - totalBrightness += brightnessForAuroraIndex(&auroraWaves[j], ledIndex); - } - - if (ledGetOverlayBit(ledConfig, LED_OVERLAY_AURORA)) { - hsvColor_t ledColor; - getLedHsv(ledIndex, &ledColor); - ledColor.v = totalBrightness > 255 ? 255 : totalBrightness; - setLedHsv(ledIndex, &ledColor); + if (ledGetOverlayBit(config, LED_OVERLAY_AURORA)) { + hsvColor_t color; + getLedHsv(ledIndex, &color); + color.v = brightness > 255 ? 255 : brightness; + setLedHsv(ledIndex, &color); } } }