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.
This commit is contained in:
Bruce Luckcuck 2019-01-27 18:45:30 -05:00
parent 436892424c
commit 12a29eb7a9
5 changed files with 122 additions and 69 deletions

View File

@ -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

View File

@ -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[];

View File

@ -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 }
};

View File

@ -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

View File

@ -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);