From 12a29eb7a982329df3193ed5462fba5b1f240304 Mon Sep 17 00:00:00 2001 From: Bruce Luckcuck Date: Sun, 27 Jan 2019 18:45:30 -0500 Subject: [PATCH] Enhance ledstrip BEACON profile Added features to the BEACON ledstrip profile: Added a `ledstrip_beacon_color` to allow color selection rather than forcing to white. Added `ledstrip_beacon_period_ms` to configure the blink period in milliseconds. Smaller time periods mean faster blinking. Added `ledstrip_beacon_percent` to configure the "ON" time duty cycle. User can set to 100% to have the beacon display a solid color. 0% can be used to turn the becaon completely off. Added `ledstrip_beacon_armed_only` to allow the user to configure whether the beacon is only on when armed. Added `ledstrip_visual_beeper_color` to allow configuration of the visual beeper color. Added the new parameters to the CMS menu. Simplified the code and combined the RACE and BEACON profile processing. Added support for auutomatically displaying a beacon that indicates RX_SET or failsafe regardless of the other RACE or BEACON settings. --- src/main/cli/settings.c | 11 ++- src/main/cli/settings.h | 4 +- src/main/cms/cms_menu_ledstrip.c | 45 +++++++++--- src/main/io/ledstrip.c | 119 ++++++++++++++++++------------- src/main/io/ledstrip.h | 12 ++-- 5 files changed, 122 insertions(+), 69 deletions(-) diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 5096a32d79..e5774bc74f 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -437,7 +437,7 @@ static const char * const lookupTableLEDProfile[] = { #endif #endif -const char * const lookupTableLEDRaceColors[COLOR_COUNT] = { +const char * const lookupTableLedstripColors[COLOR_COUNT] = { "BLACK", "WHITE", "RED", @@ -568,7 +568,7 @@ const lookupTableEntry_t lookupTables[] = { #endif #ifdef USE_LED_STRIP LOOKUP_TABLE_ENTRY(lookupTableLEDProfile), - LOOKUP_TABLE_ENTRY(lookupTableLEDRaceColors), + LOOKUP_TABLE_ENTRY(lookupTableLedstripColors), #endif LOOKUP_TABLE_ENTRY(lookupTableGyroFilterDebug), @@ -1079,9 +1079,14 @@ const clivalue_t valueTable[] = { // PG_LED_STRIP_CONFIG #ifdef USE_LED_STRIP { "ledstrip_visual_beeper", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_visual_beeper) }, + { "ledstrip_visual_beeper_color",VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_visual_beeper_color) }, { "ledstrip_grb_rgb", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_RGB_GRB }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_grb_rgb) }, { "ledstrip_profile", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LED_PROFILE }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_profile) }, - { "ledstrip_race_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LED_RACE_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledRaceColor) }, + { "ledstrip_race_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_race_color) }, + { "ledstrip_beacon_color", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_LEDSTRIP_COLOR }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_color) }, + { "ledstrip_beacon_period_ms", VAR_UINT16 | MASTER_VALUE, .config.minmax = { 50, 10000 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_period_ms) }, + { "ledstrip_beacon_percent", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, 100 }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_percent) }, + { "ledstrip_beacon_armed_only", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_LED_STRIP_CONFIG, offsetof(ledStripConfig_t, ledstrip_beacon_armed_only) }, #endif // PG_SDCARD_CONFIG diff --git a/src/main/cli/settings.h b/src/main/cli/settings.h index cec73d1756..a1024a41fa 100644 --- a/src/main/cli/settings.h +++ b/src/main/cli/settings.h @@ -133,7 +133,7 @@ typedef enum { #endif #ifdef USE_LED_STRIP TABLE_LED_PROFILE, - TABLE_LED_RACE_COLOR, + TABLE_LEDSTRIP_COLOR, #endif TABLE_GYRO_FILTER_DEBUG, LOOKUP_TABLE_COUNT @@ -224,4 +224,4 @@ extern const char * const lookupTableMagHardware[]; extern const char * const lookupTableRangefinderHardware[]; -extern const char * const lookupTableLEDRaceColors[]; +extern const char * const lookupTableLedstripColors[]; diff --git a/src/main/cms/cms_menu_ledstrip.c b/src/main/cms/cms_menu_ledstrip.c index 88b3bf1cd7..ed3fba012a 100644 --- a/src/main/cms/cms_menu_ledstrip.c +++ b/src/main/cms/cms_menu_ledstrip.c @@ -48,8 +48,15 @@ #ifdef USE_LED_STRIP static uint8_t cmsx_FeatureLedstrip; -static uint8_t cmsx_LedProfile; -static uint8_t cmsx_RaceColor; +static uint8_t cmsx_ledProfile; +static uint8_t cmsx_ledRaceColor; +static uint8_t cmsx_ledBeaconColor; +static uint16_t cmsx_ledBeaconPeriod; +static uint8_t cmsx_ledBeaconOnPercent; +static uint8_t cmsx_ledBeaconArmedOnly; +static uint8_t cmsx_ledVisualBeeper; +static uint8_t cmsx_ledVisualBeeperColor; + const char * const ledProfileNames[LED_PROFILE_COUNT] = { "RACE", "BEACON", @@ -61,8 +68,14 @@ const char * const ledProfileNames[LED_PROFILE_COUNT] = { static long cmsx_Ledstrip_OnEnter(void) { cmsx_FeatureLedstrip = featureIsEnabled(FEATURE_LED_STRIP) ? 1 : 0; - cmsx_LedProfile = getLedProfile(); - cmsx_RaceColor = getLedRaceColor(); + cmsx_ledProfile = getLedProfile(); + cmsx_ledRaceColor = ledStripConfig()->ledstrip_race_color; + cmsx_ledBeaconColor = ledStripConfig()->ledstrip_beacon_color; + cmsx_ledBeaconPeriod = ledStripConfig()->ledstrip_beacon_period_ms; + cmsx_ledBeaconOnPercent = ledStripConfig()->ledstrip_beacon_percent; + cmsx_ledBeaconArmedOnly = ledStripConfig()->ledstrip_beacon_armed_only; + cmsx_ledVisualBeeper = ledStripConfig()->ledstrip_visual_beeper; + cmsx_ledVisualBeeperColor = ledStripConfig()->ledstrip_visual_beeper_color; return 0; } @@ -78,18 +91,30 @@ static long cmsx_Ledstrip_OnExit(const OSD_Entry *self) featureDisable(FEATURE_LED_STRIP); } - setLedProfile(cmsx_LedProfile); - setLedRaceColor(cmsx_RaceColor); + setLedProfile(cmsx_ledProfile); + ledStripConfigMutable()->ledstrip_race_color = cmsx_ledRaceColor; + ledStripConfigMutable()->ledstrip_beacon_color = cmsx_ledBeaconColor; + ledStripConfigMutable()->ledstrip_beacon_period_ms = cmsx_ledBeaconPeriod; + ledStripConfigMutable()->ledstrip_beacon_percent = cmsx_ledBeaconOnPercent; + ledStripConfigMutable()->ledstrip_beacon_armed_only = cmsx_ledBeaconArmedOnly; + ledStripConfigMutable()->ledstrip_visual_beeper = cmsx_ledVisualBeeper; + ledStripConfigMutable()->ledstrip_visual_beeper_color = cmsx_ledVisualBeeperColor; return 0; } static OSD_Entry cmsx_menuLedstripEntries[] = { - { "-- LED STRIP --", OME_Label, NULL, NULL, 0 }, - { "ENABLED", OME_Bool, NULL, &cmsx_FeatureLedstrip, 0 }, - { "PROFILE", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_LedProfile, LED_PROFILE_COUNT-1, ledProfileNames }, 0 }, - { "RACE COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_RaceColor, COLOR_COUNT-1, lookupTableLEDRaceColors }, 0 }, + { "-- LED STRIP --", OME_Label, NULL, NULL, 0 }, + { "ENABLED", OME_Bool, NULL, &cmsx_FeatureLedstrip, 0 }, + { "PROFILE", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledProfile, LED_PROFILE_COUNT - 1, ledProfileNames }, 0 }, + { "RACE COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledRaceColor, COLOR_COUNT - 1, lookupTableLedstripColors }, 0 }, + { "BEACON COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledBeaconColor, COLOR_COUNT -1, lookupTableLedstripColors }, 0 }, + { "BEACON PERIOD", OME_UINT16,NULL, &(OSD_UINT16_t){ &cmsx_ledBeaconPeriod, 50, 10000, 10 }, 0 }, + { "BEACON ON %", OME_UINT8, NULL, &(OSD_UINT8_t){ &cmsx_ledBeaconOnPercent, 0, 100, 1 }, 0 }, + { "BEACON ARMED ONLY",OME_Bool, NULL, &cmsx_ledBeaconArmedOnly, 0 }, + { "VISUAL BEEPER", OME_Bool, NULL, &cmsx_ledVisualBeeper, 0 }, + { "VISUAL COLOR", OME_TAB, NULL, &(OSD_TAB_t){ &cmsx_ledVisualBeeperColor, COLOR_COUNT - 1, lookupTableLedstripColors }, 0 }, { "BACK", OME_Back, NULL, NULL, 0 }, { NULL, OME_END, NULL, NULL, 0 } }; diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 784f3de950..c19b455cef 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -80,15 +80,15 @@ PG_REGISTER_WITH_RESET_FN(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 0); +#define COLOR_UNDEFINED 255 + hsvColor_t *colors; const modeColorIndexes_t *modeColors; specialColorIndexes_t specialColors; static bool ledStripInitialised = false; static bool ledStripEnabled = false; -static uint8_t previousBeaconColorIndex = COLOR_BLACK; -static uint8_t previousRaceColorIndex = COLOR_BLACK; -static timeUs_t raceColorUpdateTimeUs = 0; +static uint8_t previousProfileColorIndex = COLOR_UNDEFINED; void ledStripDisable(void); @@ -96,11 +96,12 @@ void ledStripDisable(void); #define MAX_TIMER_DELAY (5 * 1000 * 1000) -#define BEACON_FLASH_PERIOD_MS 1000 // 1000ms -#define BEACON_FLASH_ON_TIME 100 // 100ms -#define RACE_COLOR_UPDATE_INTERVAL_US 1e6 // normally updates when color changes but this is a 1 second forced update +#define PROFILE_COLOR_UPDATE_INTERVAL_US 1e6 // normally updates when color changes but this is a 1 second forced update -#define VISUAL_BEEPER_COLOR COLOR_ORANGE +#define VISUAL_BEEPER_COLOR COLOR_WHITE + +#define BEACON_FAILSAFE_PERIOD_US 250 // 2Hz +#define BEACON_FAILSAFE_ON_PERCENT 50 // 50% duty cycle #if LED_MAX_STRIP_LENGTH > WS2811_LED_STRIP_LENGTH # error "Led strip length must match driver" @@ -174,7 +175,12 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) #else ledStripConfig->ledstrip_profile = LED_PROFILE_RACE; #endif - ledStripConfig->ledRaceColor = COLOR_ORANGE; + ledStripConfig->ledstrip_race_color = COLOR_ORANGE; + ledStripConfig->ledstrip_beacon_color = COLOR_WHITE; + ledStripConfig->ledstrip_beacon_period_ms = 500; // 0.5 second (2hz) + ledStripConfig->ledstrip_beacon_percent = 50; // 50% duty cycle + ledStripConfig->ledstrip_beacon_armed_only = false; // blink always + ledStripConfig->ledstrip_visual_beeper_color = VISUAL_BEEPER_COLOR; #ifndef UNIT_TEST ledStripConfig->ioTag = timerioTagGetByUsage(TIM_USE_LED, 0); #endif @@ -582,7 +588,7 @@ static void applyLedWarningLayer(bool updateNow, timeUs_t *timer) } } else { if (isBeeperOn()) { - warningColor = &hsv[VISUAL_BEEPER_COLOR]; + warningColor = &hsv[ledStripConfig()->ledstrip_visual_beeper_color]; } } @@ -1081,34 +1087,64 @@ static void applyStatusProfile(timeUs_t now) { static uint8_t selectVisualBeeperColor(uint8_t colorIndex) { if (ledStripConfig()->ledstrip_visual_beeper && isBeeperOn()) { - return VISUAL_BEEPER_COLOR; + return ledStripConfig()->ledstrip_visual_beeper_color; } else { return colorIndex; } } -static void applyBeaconProfile(void) -{ - const bool beaconState = millis() % (BEACON_FLASH_PERIOD_MS) < BEACON_FLASH_ON_TIME; - uint8_t colorIndex = (beaconState) ? COLOR_WHITE : COLOR_BLACK; - colorIndex = selectVisualBeeperColor(colorIndex); +static void applySimpleProfile(timeUs_t currentTimeUs) +{ + static timeUs_t colorUpdateTimeUs = 0; + uint8_t colorIndex = COLOR_BLACK; + bool blinkLed = false; + bool visualBeeperOverride = true; + unsigned flashPeriod; + unsigned onPercent; - if (colorIndex != previousBeaconColorIndex) { - previousBeaconColorIndex = colorIndex; + if (IS_RC_MODE_ACTIVE(BOXBEEPERON) || failsafeIsActive()) { + // RX_SET or failsafe - force the beacon on and override the profile settings + blinkLed = true; + visualBeeperOverride = false; // prevent the visual beeper from interfering + flashPeriod = BEACON_FAILSAFE_PERIOD_US; + onPercent = BEACON_FAILSAFE_ON_PERCENT; + colorIndex = ledStripConfig()->ledstrip_visual_beeper_color; + } else { + switch (ledStripConfig()->ledstrip_profile) { + case LED_PROFILE_RACE: + colorIndex = ledStripConfig()->ledstrip_race_color; + break; + + case LED_PROFILE_BEACON: { + if (!ledStripConfig()->ledstrip_beacon_armed_only || ARMING_FLAG(ARMED)) { + flashPeriod = ledStripConfig()->ledstrip_beacon_period_ms; + onPercent = ledStripConfig()->ledstrip_beacon_percent; + colorIndex = ledStripConfig()->ledstrip_beacon_color; + blinkLed = true; + } + break; + } + + default: + break; + } + } + + if (blinkLed) { + const unsigned onPeriod = flashPeriod * onPercent / 100; + const bool beaconState = (millis() % flashPeriod) < onPeriod; + colorIndex = (beaconState) ? colorIndex : COLOR_BLACK; + } + + if (visualBeeperOverride) { + colorIndex = selectVisualBeeperColor(colorIndex); + } + + if ((colorIndex != previousProfileColorIndex) || (currentTimeUs >= colorUpdateTimeUs)) { setStripColor(&hsv[colorIndex]); ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); - } -} - -static void applyRaceProfile(timeUs_t currentTimeUs) -{ - uint8_t colorIndex = selectVisualBeeperColor(ledStripConfig()->ledRaceColor); - // refresh the color if it changes or at least every 1 second - if ((colorIndex != previousRaceColorIndex) || (currentTimeUs >= raceColorUpdateTimeUs)) { - setStripColor(&hsv[colorIndex]); - ws2811UpdateStrip((ledStripFormatRGB_e) ledStripConfig()->ledstrip_grb_rgb); - previousRaceColorIndex = colorIndex; - raceColorUpdateTimeUs = currentTimeUs + RACE_COLOR_UPDATE_INTERVAL_US; + previousProfileColorIndex = colorIndex; + colorUpdateTimeUs = currentTimeUs + PROFILE_COLOR_UPDATE_INTERVAL_US; } } @@ -1127,7 +1163,7 @@ void ledStripUpdate(timeUs_t currentTimeUs) } else if (!IS_RC_MODE_ACTIVE(BOXLEDLOW)) { ledStripEnabled = true; } - + if (ledStripEnabled) { switch (ledStripConfig()->ledstrip_profile) { #ifdef USE_LED_STRIP_STATUS_MODE @@ -1136,14 +1172,12 @@ void ledStripUpdate(timeUs_t currentTimeUs) break; } #endif - case LED_PROFILE_RACE: { - applyRaceProfile(currentTimeUs); - break; - } + case LED_PROFILE_RACE: case LED_PROFILE_BEACON: { - applyBeaconProfile(); + applySimpleProfile(currentTimeUs); break; } + default: break; } @@ -1244,8 +1278,7 @@ void ledStripEnable(void) void ledStripDisable(void) { ledStripEnabled = false; - previousRaceColorIndex = COLOR_BLACK; - previousBeaconColorIndex = COLOR_BLACK; + previousProfileColorIndex = COLOR_UNDEFINED; setStripColor(&HSV(BLACK)); if (ledStripInitialised) { ws2811UpdateStrip((ledStripFormatRGB_e)ledStripConfig()->ledstrip_grb_rgb); @@ -1264,16 +1297,4 @@ void setLedProfile(uint8_t profile) ledStripConfigMutable()->ledstrip_profile = profile; } } - -uint8_t getLedRaceColor(void) -{ - return ledStripConfig()->ledRaceColor; -} - -void setLedRaceColor(uint8_t color) -{ - if (color <= COLOR_DEEP_PINK) { - ledStripConfigMutable()->ledRaceColor = color; - } -} #endif diff --git a/src/main/io/ledstrip.h b/src/main/io/ledstrip.h index 49ebba14ab..0acdc496d4 100644 --- a/src/main/io/ledstrip.h +++ b/src/main/io/ledstrip.h @@ -176,13 +176,17 @@ typedef struct ledStripConfig_s { hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT]; modeColorIndexes_t modeColors[LED_MODE_COUNT]; specialColorIndexes_t specialColors; - uint8_t ledstrip_visual_beeper; // suppress LEDLOW mode if beeper is on + uint8_t ledstrip_visual_beeper; uint8_t ledstrip_aux_channel; ioTag_t ioTag; ledStripFormatRGB_e ledstrip_grb_rgb; ledProfile_e ledstrip_profile; - colorId_e ledRaceColor; - + colorId_e ledstrip_race_color; + colorId_e ledstrip_beacon_color; + uint16_t ledstrip_beacon_period_ms; + uint8_t ledstrip_beacon_percent; + uint8_t ledstrip_beacon_armed_only; + colorId_e ledstrip_visual_beeper_color; } ledStripConfig_t; PG_DECLARE(ledStripConfig_t, ledStripConfig); @@ -230,5 +234,3 @@ void updateRequiredOverlay(void); uint8_t getLedProfile(void); void setLedProfile(uint8_t profile); -uint8_t getLedRaceColor(void); -void setLedRaceColor(uint8_t color);