Browse Source

Improved neopixel-handling + single-LED-support

master
Torsten Stauder 4 years ago
parent
commit
7ee8c3fa4a
  1. 7
      src/Button.cpp
  2. 2
      src/Button.h
  3. 324
      src/Led.cpp
  4. 2
      src/revision.h

7
src/Button.cpp

@ -6,6 +6,8 @@
#include "Port.h" #include "Port.h"
#include "System.h" #include "System.h"
bool gButtonInitComplete = false;
// Only enable those buttons that are not disabled (99 or >115) // Only enable those buttons that are not disabled (99 or >115)
// 0 -> 39: GPIOs // 0 -> 39: GPIOs
// 100 -> 115: Port-expander // 100 -> 115: Port-expander
@ -159,14 +161,19 @@ void Button_Cyclic() {
if (!gButtons[i].currentState) { if (!gButtons[i].currentState) {
gButtons[i].isPressed = true; gButtons[i].isPressed = true;
gButtons[i].lastPressedTimestamp = currentTimestamp; gButtons[i].lastPressedTimestamp = currentTimestamp;
if (!gButtons[i].firstPressedTimestamp) {
gButtons[i].firstPressedTimestamp = currentTimestamp;
}
} else { } else {
gButtons[i].isReleased = true; gButtons[i].isReleased = true;
gButtons[i].lastReleasedTimestamp = currentTimestamp; gButtons[i].lastReleasedTimestamp = currentTimestamp;
gButtons[i].firstPressedTimestamp = 0;
} }
} }
gButtons[i].lastState = gButtons[i].currentState; gButtons[i].lastState = gButtons[i].currentState;
} }
} }
gButtonInitComplete = true;
Button_DoButtonActions(); Button_DoButtonActions();
} }

2
src/Button.h

@ -7,9 +7,11 @@ typedef struct {
bool isReleased : 1; bool isReleased : 1;
unsigned long lastPressedTimestamp; unsigned long lastPressedTimestamp;
unsigned long lastReleasedTimestamp; unsigned long lastReleasedTimestamp;
unsigned long firstPressedTimestamp;
} t_button; } t_button;
extern uint8_t gShutdownButton; extern uint8_t gShutdownButton;
extern bool gButtonInitComplete;
void Button_Init(void); void Button_Init(void);
void Button_Cyclic(void); void Button_Cyclic(void);

324
src/Led.cpp

@ -139,6 +139,7 @@ static void Led_Task(void *parameter) {
static bool volumeChangeShown = false; static bool volumeChangeShown = false;
static bool showEvenError = false; static bool showEvenError = false;
static bool turnedOffLeds = false; static bool turnedOffLeds = false;
static bool singleLedStatus = false;
static uint8_t ledPosWebstream = 0; static uint8_t ledPosWebstream = 0;
static uint8_t ledSwitchInterval = 5; // time in secs (webstream-only) static uint8_t ledSwitchInterval = 5; // time in secs (webstream-only)
static uint8_t webstreamColor = 0; static uint8_t webstreamColor = 0;
@ -164,7 +165,9 @@ static void Led_Task(void *parameter) {
vTaskDelay(portTICK_RATE_MS * 10); vTaskDelay(portTICK_RATE_MS * 10);
continue; continue;
} }
if (!LED_INDICATOR_IS_SET(LedIndicatorType::BootComplete)) { // Rotates orange unless boot isn't complete
// Multi-LED: rotates orange unless boot isn't complete
// Single-LED: blinking orange
if (!LED_INDICATOR_IS_SET(LedIndicatorType::BootComplete)) {
FastLED.clear(); FastLED.clear();
for (uint8_t led = 0; led < NUM_LEDS; led++) { for (uint8_t led = 0; led < NUM_LEDS; led++) {
if (showEvenError) { if (showEvenError) {
@ -197,19 +200,41 @@ static void Led_Task(void *parameter) {
lastLedBrightness = Led_Brightness; lastLedBrightness = Led_Brightness;
} }
// LEDs growing red as long button for sleepmode is pressed.
// Multi-LED: growing red as long button for sleepmode is pressed.
// Single-LED: red when pressed and flashing red when long interval-duration is reached
if (gShutdownButton < (sizeof(gButtons) / sizeof(gButtons[0])) - 1) { // Only show animation, if CMD_SLEEPMODE was assigned to BUTTON_n_LONG + button is pressed if (gShutdownButton < (sizeof(gButtons) / sizeof(gButtons[0])) - 1) { // Only show animation, if CMD_SLEEPMODE was assigned to BUTTON_n_LONG + button is pressed
if (!gButtons[gShutdownButton].currentState) {
FastLED.clear();
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Red;
if (gButtons[gShutdownButton].currentState) {
if (!gButtons[gShutdownButton].currentState && (millis() - gButtons[gShutdownButton].firstPressedTimestamp >= 150) && gButtonInitComplete) {
if (NUM_LEDS == 1) {
FastLED.clear();
if (millis() - gButtons[gShutdownButton].firstPressedTimestamp <= intervalToLongPress) {
leds[0] = CRGB::Red;
FastLED.show(); FastLED.show();
delay(5);
break;
} else {
if (singleLedStatus) {
leds[0] = CRGB::Red;
} else {
leds[0] = CRGB::Black;
}
FastLED.show();
singleLedStatus = !singleLedStatus;
vTaskDelay(portTICK_RATE_MS * 50);
}
} else {
if (millis() - gButtons[gShutdownButton].firstPressedTimestamp >= intervalToLongPress) {
vTaskDelay(portTICK_RATE_MS * 50);
continue;
}
FastLED.clear();
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Red;
if (gButtons[gShutdownButton].currentState) {
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 5);
break;
}
FastLED.show();
vTaskDelay(intervalToLongPress / NUM_LEDS * portTICK_RATE_MS);
} }
FastLED.show();
vTaskDelay(intervalToLongPress / NUM_LEDS * portTICK_RATE_MS);
} }
} }
} else { } else {
@ -219,32 +244,65 @@ static void Led_Task(void *parameter) {
} }
} }
// Multi-LED: all leds flash red 1x
// Single-LED: led flashes red 5x
if (LED_INDICATOR_IS_SET(LedIndicatorType::Error)) { // If error occured (e.g. RFID-modification not accepted) if (LED_INDICATOR_IS_SET(LedIndicatorType::Error)) { // If error occured (e.g. RFID-modification not accepted)
LED_INDICATOR_CLEAR(LedIndicatorType::Error); LED_INDICATOR_CLEAR(LedIndicatorType::Error);
notificationShown = true; notificationShown = true;
FastLED.clear(); FastLED.clear();
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Red;
if (NUM_LEDS == 1) {
for (uint8_t cnt = 0; cnt < 5; cnt++) {
FastLED.clear();
if (singleLedStatus) {
leds[0] = CRGB::Red;
} else {
leds[0] = CRGB::Black;
}
FastLED.show();
singleLedStatus = !singleLedStatus;
vTaskDelay(portTICK_RATE_MS * 100);
}
} else {
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Red;
}
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 200);
} }
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 200);
} }
// Multi-LED: all leds flash green 1x
// Single-LED: led flashes green 5x
if (LED_INDICATOR_IS_SET(LedIndicatorType::Ok)) { // If action was accepted if (LED_INDICATOR_IS_SET(LedIndicatorType::Ok)) { // If action was accepted
LED_INDICATOR_CLEAR(LedIndicatorType::Ok); LED_INDICATOR_CLEAR(LedIndicatorType::Ok);
notificationShown = true; notificationShown = true;
FastLED.clear(); FastLED.clear();
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Green;
if (NUM_LEDS == 1) {
for (uint8_t cnt = 0; cnt < 5; cnt++) {
FastLED.clear();
if (singleLedStatus) {
leds[0] = CRGB::Green;
} else {
leds[0] = CRGB::Black;
}
FastLED.show();
singleLedStatus = !singleLedStatus;
vTaskDelay(portTICK_RATE_MS * 100);
}
} else {
for (uint8_t led = 0; led < NUM_LEDS; led++) {
leds[Led_Address(led)] = CRGB::Green;
}
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 400);
} }
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 400);
} }
#ifdef MEASURE_BATTERY_VOLTAGE #ifdef MEASURE_BATTERY_VOLTAGE
if (LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning)) { // Flashes red three times if battery-voltage is low
// Single + Multiple LEDs: flashes red three times if battery-voltage is low
if (LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning)) {
LED_INDICATOR_CLEAR(LedIndicatorType::VoltageWarning); LED_INDICATOR_CLEAR(LedIndicatorType::VoltageWarning);
notificationShown = true; notificationShown = true;
for (uint8_t i = 0; i < 3; i++) { for (uint8_t i = 0; i < 3; i++) {
@ -265,6 +323,8 @@ static void Led_Task(void *parameter) {
} }
} }
// Single-LED: indicates voltage coloured between gradient green (high) => red (low)
// Multi-LED: number of LEDs indicates voltage-level with having green >= 60% ; orange < 60% + >= 30% ; red < 30%
if (LED_INDICATOR_IS_SET(LedIndicatorType::Voltage)) { if (LED_INDICATOR_IS_SET(LedIndicatorType::Voltage)) {
LED_INDICATOR_CLEAR(LedIndicatorType::Voltage); LED_INDICATOR_CLEAR(LedIndicatorType::Voltage);
float currentVoltage = Battery_GetVoltage(); float currentVoltage = Battery_GetVoltage();
@ -275,18 +335,29 @@ static void Led_Task(void *parameter) {
LED_INDICATOR_SET(LedIndicatorType::Error); LED_INDICATOR_SET(LedIndicatorType::Error);
break; break;
} else { } else {
uint8_t numLedsToLight = ((float)vDiffCurrent / vDiffIndicatorRange) * NUM_LEDS;
FastLED.clear(); FastLED.clear();
for (uint8_t led = 0; led < numLedsToLight; led++) {
if (((float)numLedsToLight / NUM_LEDS) >= 0.6) {
leds[Led_Address(led)] = CRGB::Green;
} else if (((float)numLedsToLight / NUM_LEDS) <= 0.6 && ((float)numLedsToLight / NUM_LEDS) >= 0.3) {
leds[Led_Address(led)] = CRGB::Orange;
if (NUM_LEDS == 1) {
if ((float) vDiffCurrent / vDiffIndicatorRange >= 0.6) {
leds[0] = CRGB::Green;
} else if ((float) vDiffCurrent / vDiffIndicatorRange < 0.6 && (float) vDiffCurrent / vDiffIndicatorRange >= 0.3) {
leds[0] = CRGB::Orange;
} else { } else {
leds[Led_Address(led)] = CRGB::Red;
leds[0] = CRGB::Red;
} }
FastLED.show(); FastLED.show();
vTaskDelay(portTICK_RATE_MS * 20);
} else {
uint8_t numLedsToLight = ((float)vDiffCurrent / vDiffIndicatorRange) * NUM_LEDS;
for (uint8_t led = 0; led < numLedsToLight; led++) {
if (((float)numLedsToLight / NUM_LEDS) >= 0.6) {
leds[Led_Address(led)] = CRGB::Green;
} else if (((float)numLedsToLight / NUM_LEDS) < 0.6 && ((float)numLedsToLight / NUM_LEDS) >= 0.3) {
leds[Led_Address(led)] = CRGB::Orange;
} else {
leds[Led_Address(led)] = CRGB::Red;
}
FastLED.show();
vTaskDelay(portTICK_RATE_MS * 20);
}
} }
for (uint8_t i = 0; i <= 100; i++) { for (uint8_t i = 0; i <= 100; i++) {
@ -300,14 +371,20 @@ static void Led_Task(void *parameter) {
} }
#endif #endif
// Single-LED: led indicates loudness between green (low) => red (high)
// Multiple-LEDs: number of LEDs indicate loudness; gradient is shown between green (low) => red (high)
if (hlastVolume != AudioPlayer_GetCurrentVolume()) { // If volume has been changed if (hlastVolume != AudioPlayer_GetCurrentVolume()) { // If volume has been changed
uint8_t numLedsToLight = map(AudioPlayer_GetCurrentVolume(), 0, AudioPlayer_GetMaxVolume(), 0, NUM_LEDS); uint8_t numLedsToLight = map(AudioPlayer_GetCurrentVolume(), 0, AudioPlayer_GetMaxVolume(), 0, NUM_LEDS);
hlastVolume = AudioPlayer_GetCurrentVolume(); hlastVolume = AudioPlayer_GetCurrentVolume();
volumeChangeShown = true; volumeChangeShown = true;
FastLED.clear(); FastLED.clear();
for (int led = 0; led < numLedsToLight; led++) { // (Inverse) color-gradient from green (85) back to (still) red (245) using unsigned-cast
leds[Led_Address(led)].setHue((uint8_t)(85 - ((double)95 / NUM_LEDS) * led));
if (NUM_LEDS == 1) {
leds[0].setHue((uint8_t)(85 - (90 * ((double)AudioPlayer_GetCurrentVolume() / (double)AudioPlayer_GetMaxVolumeSpeaker()))));
} else {
for (int led = 0; led < numLedsToLight; led++) { // (Inverse) color-gradient from green (85) back to (still) red (250) using unsigned-cast
leds[Led_Address(led)].setHue((uint8_t)(85 - ((double)90 / NUM_LEDS) * led));
}
} }
FastLED.show(); FastLED.show();
@ -323,67 +400,81 @@ static void Led_Task(void *parameter) {
} }
} }
// < 4 LEDs: doesn't make sense at all
// >= 4 LEDs: collapsing ring (blue => black)
if (LED_INDICATOR_IS_SET(LedIndicatorType::Rewind)) { if (LED_INDICATOR_IS_SET(LedIndicatorType::Rewind)) {
LED_INDICATOR_CLEAR(LedIndicatorType::Rewind); LED_INDICATOR_CLEAR(LedIndicatorType::Rewind);
for (uint8_t i = NUM_LEDS - 1; i > 0; i--) {
leds[Led_Address(i)] = CRGB::Black;
FastLED.show();
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
break;
} else {
vTaskDelay(portTICK_RATE_MS * 30);
}
}
}
if (LED_INDICATOR_IS_SET(LedIndicatorType::PlaylistProgress)) {
LED_INDICATOR_CLEAR(LedIndicatorType::PlaylistProgress);
if (gPlayProperties.numberOfTracks > 1 && gPlayProperties.currentTrackNumber < gPlayProperties.numberOfTracks) {
uint8_t numLedsToLight = map(gPlayProperties.currentTrackNumber, 0, gPlayProperties.numberOfTracks - 1, 0, NUM_LEDS);
FastLED.clear();
for (uint8_t i = 0; i < numLedsToLight; i++) {
leds[Led_Address(i)] = CRGB::Blue;
if (NUM_LEDS >= 4) {
for (uint8_t i = NUM_LEDS - 1; i > 0; i--) {
leds[Led_Address(i)] = CRGB::Black;
FastLED.show(); FastLED.show();
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
break; break;
} else { } else {
vTaskDelay(portTICK_RATE_MS * 30); vTaskDelay(portTICK_RATE_MS * 30);
} }
} }
}
}
for (uint8_t i = 0; i <= 100; i++) {
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
break;
} else {
vTaskDelay(portTICK_RATE_MS * 15);
// < 4 LEDs: doesn't make sense at all
// >= 4 LEDs: growing ring (black => blue); relative number of LEDs indicate playlist-progress
if (LED_INDICATOR_IS_SET(LedIndicatorType::PlaylistProgress)) {
LED_INDICATOR_CLEAR(LedIndicatorType::PlaylistProgress);
if (NUM_LEDS >= 4) {
if (gPlayProperties.numberOfTracks > 1 && gPlayProperties.currentTrackNumber < gPlayProperties.numberOfTracks) {
uint8_t numLedsToLight = map(gPlayProperties.currentTrackNumber, 0, gPlayProperties.numberOfTracks - 1, 0, NUM_LEDS);
FastLED.clear();
for (uint8_t i = 0; i < numLedsToLight; i++) {
leds[Led_Address(i)] = CRGB::Blue;
FastLED.show();
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
break;
} else {
vTaskDelay(portTICK_RATE_MS * 30);
}
} }
}
for (uint8_t i = numLedsToLight; i > 0; i--) {
leds[Led_Address(i) - 1] = CRGB::Black;
FastLED.show();
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
break;
for (uint8_t i = 0; i <= 100; i++) {
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
break;
} else {
vTaskDelay(portTICK_RATE_MS * 15);
}
} }
else {
vTaskDelay(portTICK_RATE_MS * 30);
for (uint8_t i = numLedsToLight; i > 0; i--) {
leds[Led_Address(i) - 1] = CRGB::Black;
FastLED.show();
#ifdef MEASURE_BATTERY_VOLTAGE
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || LED_INDICATOR_IS_SET(LedIndicatorType::VoltageWarning) || LED_INDICATOR_IS_SET(LedIndicatorType::Voltage) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#else
if (hlastVolume != AudioPlayer_GetCurrentVolume() || lastLedBrightness != Led_Brightness || LED_INDICATOR_IS_SET(LedIndicatorType::Error) || LED_INDICATOR_IS_SET(LedIndicatorType::Ok) || !gButtons[gShutdownButton].currentState || System_IsSleepRequested()) {
#endif
break;
}
else {
vTaskDelay(portTICK_RATE_MS * 30);
}
} }
} }
} }
} }
// Skip playmodes if shutdown-button is pressed as this leads to ugly indications
if (!gButtons[gShutdownButton].currentState && gShutdownButton != 99) {
vTaskDelay(portTICK_RATE_MS * 20);
continue;
}
switch (gPlayProperties.playMode) { switch (gPlayProperties.playMode) {
case NO_PLAYLIST: // If no playlist is active (idle) case NO_PLAYLIST: // If no playlist is active (idle)
if (System_GetOperationMode() == OPMODE_BLUETOOTH) { if (System_GetOperationMode() == OPMODE_BLUETOOTH) {
@ -427,24 +518,36 @@ static void Led_Task(void *parameter) {
case BUSY: // If uC is busy (parsing SD-card) case BUSY: // If uC is busy (parsing SD-card)
ledBusyShown = true; ledBusyShown = true;
for (uint8_t i = 0; i < NUM_LEDS; i++) {
if (NUM_LEDS == 1) {
FastLED.clear(); FastLED.clear();
if (Led_Address(i) == 0) {
singleLedStatus = !singleLedStatus;
if (singleLedStatus) {
leds[0] = CRGB::BlueViolet; leds[0] = CRGB::BlueViolet;
leds[NUM_LEDS / 4] = CRGB::BlueViolet;
leds[NUM_LEDS / 2] = CRGB::BlueViolet;
leds[NUM_LEDS / 4 * 3] = CRGB::BlueViolet;
} else { } else {
leds[Led_Address(i) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 4) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 4 * 3) % NUM_LEDS] = CRGB::BlueViolet;
leds[0] = CRGB::Black;
} }
FastLED.show(); FastLED.show();
if (gPlayProperties.playMode != BUSY) {
break;
vTaskDelay(portTICK_RATE_MS * 100);
} else {
for (uint8_t i = 0; i < NUM_LEDS; i++) {
FastLED.clear();
if (Led_Address(i) == 0) {
leds[0] = CRGB::BlueViolet;
leds[NUM_LEDS / 4] = CRGB::BlueViolet;
leds[NUM_LEDS / 2] = CRGB::BlueViolet;
leds[NUM_LEDS / 4 * 3] = CRGB::BlueViolet;
} else {
leds[Led_Address(i) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 4) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::BlueViolet;
leds[(Led_Address(i) + NUM_LEDS / 4 * 3) % NUM_LEDS] = CRGB::BlueViolet;
}
FastLED.show();
if (gPlayProperties.playMode != BUSY) {
break;
}
vTaskDelay(portTICK_RATE_MS * 50);
} }
vTaskDelay(portTICK_RATE_MS * 50);
} }
break; break;
@ -467,24 +570,32 @@ static void Led_Task(void *parameter) {
redrawProgress = true; redrawProgress = true;
} }
// Single-LED: led indicates between gradient green (beginning) => red (end)
// Multiple-LED: growing number of leds indicate between gradient green (beginning) => red (end)
if (!gPlayProperties.isWebstream) { if (!gPlayProperties.isWebstream) {
if (gPlayProperties.currentRelPos != lastPos || redrawProgress) { if (gPlayProperties.currentRelPos != lastPos || redrawProgress) {
redrawProgress = false; redrawProgress = false;
lastPos = gPlayProperties.currentRelPos; lastPos = gPlayProperties.currentRelPos;
uint8_t numLedsToLight = map(gPlayProperties.currentRelPos, 0, 98, 0, NUM_LEDS);
FastLED.clear(); FastLED.clear();
for (uint8_t led = 0; led < numLedsToLight; led++) {
if (System_AreControlsLocked()) {
leds[Led_Address(led)] = CRGB::Red;
} else if (!gPlayProperties.pausePlay) { // Hue-rainbow
leds[Led_Address(led)].setHue((uint8_t)(85 - ((double)95 / NUM_LEDS) * led));
if (NUM_LEDS == 1) {
leds[0].setHue((uint8_t)(85 - ((double)90 / 100) * (double)gPlayProperties.currentRelPos));
} else {
uint8_t numLedsToLight = map(gPlayProperties.currentRelPos, 0, 98, 0, NUM_LEDS);
for (uint8_t led = 0; led < numLedsToLight; led++) {
if (System_AreControlsLocked()) {
leds[Led_Address(led)] = CRGB::Red;
} else if (!gPlayProperties.pausePlay) { // Hue-rainbow
leds[Led_Address(led)].setHue((uint8_t)(85 - ((double)90 / NUM_LEDS) * led));
}
} }
} }
if (gPlayProperties.pausePlay) { if (gPlayProperties.pausePlay) {
leds[Led_Address(0)] = CRGB::Orange; leds[Led_Address(0)] = CRGB::Orange;
leds[(Led_Address(NUM_LEDS / 4)) % NUM_LEDS] = CRGB::Orange;
leds[(Led_Address(NUM_LEDS / 2)) % NUM_LEDS] = CRGB::Orange;
leds[(Led_Address(NUM_LEDS / 4 * 3)) % NUM_LEDS] = CRGB::Orange;
if (NUM_LEDS > 1) {
leds[(Led_Address(NUM_LEDS / 4)) % NUM_LEDS] = CRGB::Orange;
leds[(Led_Address(NUM_LEDS / 2)) % NUM_LEDS] = CRGB::Orange;
leds[(Led_Address(NUM_LEDS / 4 * 3)) % NUM_LEDS] = CRGB::Orange;
}
break; break;
} }
} }
@ -501,14 +612,23 @@ static void Led_Task(void *parameter) {
} }
if (System_AreControlsLocked()) { if (System_AreControlsLocked()) {
leds[Led_Address(ledPosWebstream)] = CRGB::Red; leds[Led_Address(ledPosWebstream)] = CRGB::Red;
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::Red;
if (NUM_LEDS > 1) {
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::Red;
}
} else if (!gPlayProperties.pausePlay) { } else if (!gPlayProperties.pausePlay) {
leds[Led_Address(ledPosWebstream)].setHue(webstreamColor);
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS].setHue(webstreamColor++);
} else if (gPlayProperties.pausePlay)
{
leds[Led_Address(ledPosWebstream)] = CRGB::Orange;
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::Orange;
if (NUM_LEDS == 1) {
leds[0].setHue(webstreamColor++);
} else {
leds[Led_Address(ledPosWebstream)].setHue(webstreamColor);
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS].setHue(webstreamColor++);
}
} else if (gPlayProperties.pausePlay) {
if (NUM_LEDS == 1) {
leds[0] = CRGB::Orange;
} else {
leds[Led_Address(ledPosWebstream)] = CRGB::Orange;
leds[(Led_Address(ledPosWebstream) + NUM_LEDS / 2) % NUM_LEDS] = CRGB::Orange;
}
} }
} }
} }

2
src/revision.h

@ -1,4 +1,4 @@
#ifndef __REVISION_H__ #ifndef __REVISION_H__
#define __REVISION_H__ #define __REVISION_H__
constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210816-2";
constexpr const char softwareRevision[] PROGMEM = "Software-revision: 20210911-1";
#endif #endif
Loading…
Cancel
Save