mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-13 19:40:31 +03:00
New led functions gps bar battery bar altitude (#13404)
* Add LED functions: Battery Bar, GPS Bar Battery Bar: Indicates the battery percentage with a loading bar style GPS Bar: Indicates the amount of locked GPS satellites with a loading bar style * LED altitude function Adds a new function: LED altitude. Sets the LED color based on the altitude, measured from the initialized position. * set led color to background if value decreases Even if the gps satellite count decreases at a later point in time, the LEDs update correctly now. It is the same for the battery level function. LEDs color changes more strongly now when based on altitude. * Added proper ifdefs for GPS and Barometer * fixed unittest and use estimate altitute - fixed unittest - cleaner indentation - the altitude function now uses the estimate function instead of the raw value (gps+barometer) * counters in struct, gps bar color gradient - Counters for the led bar are now handled in a structure. - Moved the led bar code to a seperate function that is only called when the led config changes. - improved usefulness of the gps led bar with less than 4 leds installed by adding a color gradient. * Update src/main/io/ledstrip.c Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * Update src/main/io/ledstrip.c Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * Update src/main/io/ledstrip.c Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * Update src/main/io/ledstrip.h Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * Update src/main/io/ledstrip.c Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * one min led for very low battery, use failsafe sats to interpolate - at least one led is lit up for the battery/gps bar at all time (to show color gradient, also making the function more useful when only applying it to 1 led). - gps bar now takes the failsafe min sats (or default 8) to interpolate between red and green. - rewrote the led codes to be less fragile - some structural changes that also adress comments on the pull request * fix code if no gps rescue is used fixes code if no gps rescue is used. sets the default min sats to 8. * Update src/main/io/ledstrip.c Co-authored-by: Petr Ledvina <ledvinap@gmail.com> * Fixes per review ledvinap * Fixes per review Ledvinap 2 * Update src/main/io/ledstrip.c * Update src/main/io/ledstrip.c --------- Co-authored-by: jonas-becker <jonas@Thinkpad> Co-authored-by: Petr Ledvina <ledvinap@gmail.com> Co-authored-by: Mark Haslinghuis <mark@numloq.nl>
This commit is contained in:
parent
5fd38528ba
commit
d1ffa46aa6
3 changed files with 122 additions and 7 deletions
|
@ -55,10 +55,12 @@
|
||||||
#include "fc/runtime_config.h"
|
#include "fc/runtime_config.h"
|
||||||
|
|
||||||
#include "flight/failsafe.h"
|
#include "flight/failsafe.h"
|
||||||
|
#include "flight/gps_rescue.h"
|
||||||
#include "flight/imu.h"
|
#include "flight/imu.h"
|
||||||
#include "flight/mixer.h"
|
#include "flight/mixer.h"
|
||||||
#include "flight/pid.h"
|
#include "flight/pid.h"
|
||||||
#include "flight/servos.h"
|
#include "flight/servos.h"
|
||||||
|
#include "flight/position.h"
|
||||||
|
|
||||||
#include "io/beeper.h"
|
#include "io/beeper.h"
|
||||||
#include "io/gimbal.h"
|
#include "io/gimbal.h"
|
||||||
|
@ -277,6 +279,34 @@ STATIC_UNIT_TESTED void updateDimensions(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ledBarIds {
|
||||||
|
LED_BAR_GPS,
|
||||||
|
LED_BAR_BATTERY,
|
||||||
|
LED_BAR_COUNT
|
||||||
|
};
|
||||||
|
static uint8_t ledBarStates[LED_BAR_COUNT] = {0};
|
||||||
|
|
||||||
|
void updateLedBars(void)
|
||||||
|
{
|
||||||
|
memset(ledBarStates, 0, sizeof(ledBarStates));
|
||||||
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
|
const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex];
|
||||||
|
int fn = ledGetFunction(ledConfig);
|
||||||
|
switch (fn) {
|
||||||
|
#ifdef USE_GPS
|
||||||
|
case LED_FUNCTION_GPS_BAR:
|
||||||
|
ledBarStates[LED_BAR_GPS]++;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case LED_FUNCTION_BATTERY_BAR:
|
||||||
|
ledBarStates[LED_BAR_BATTERY]++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STATIC_UNIT_TESTED void updateLedCount(void)
|
STATIC_UNIT_TESTED void updateLedCount(void)
|
||||||
{
|
{
|
||||||
int count = 0, countRing = 0, countScanner= 0;
|
int count = 0, countRing = 0, countScanner= 0;
|
||||||
|
@ -308,6 +338,7 @@ void reevaluateLedConfig(void)
|
||||||
updateDimensions();
|
updateDimensions();
|
||||||
updateLedRingCounts();
|
updateLedRingCounts();
|
||||||
updateRequiredOverlay();
|
updateRequiredOverlay();
|
||||||
|
updateLedBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get specialColor by index
|
// get specialColor by index
|
||||||
|
@ -316,9 +347,35 @@ static const hsvColor_t* getSC(ledSpecialColorIds_e index)
|
||||||
return &ledStripStatusModeConfig()->colors[ledStripStatusModeConfig()->specialColors.color[index]];
|
return &ledStripStatusModeConfig()->colors[ledStripStatusModeConfig()->specialColors.color[index]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char directionCodes[LED_DIRECTION_COUNT] = { 'N', 'E', 'S', 'W', 'U', 'D' };
|
static const char directionCodes[LED_DIRECTION_COUNT] = {
|
||||||
static const char baseFunctionCodes[LED_BASEFUNCTION_COUNT] = { 'C', 'F', 'A', 'L', 'S', 'G', 'R' };
|
[LED_DIRECTION_NORTH] = 'N',
|
||||||
static const char overlayCodes[LED_OVERLAY_COUNT] = { 'T', 'Y', 'O', 'B', 'V', 'I', 'W' };
|
[LED_DIRECTION_EAST] = 'E',
|
||||||
|
[LED_DIRECTION_SOUTH] = 'S',
|
||||||
|
[LED_DIRECTION_WEST] = 'W',
|
||||||
|
[LED_DIRECTION_UP] = 'U',
|
||||||
|
[LED_DIRECTION_DOWN] = 'D'
|
||||||
|
};
|
||||||
|
static const char baseFunctionCodes[LED_BASEFUNCTION_COUNT] = {
|
||||||
|
[LED_FUNCTION_COLOR] = 'C',
|
||||||
|
[LED_FUNCTION_FLIGHT_MODE] = 'F',
|
||||||
|
[LED_FUNCTION_ARM_STATE] = 'A',
|
||||||
|
[LED_FUNCTION_BATTERY] = 'L',
|
||||||
|
[LED_FUNCTION_RSSI] = 'S',
|
||||||
|
[LED_FUNCTION_GPS] = 'G',
|
||||||
|
[LED_FUNCTION_THRUST_RING] = 'R',
|
||||||
|
[LED_FUNCTION_GPS_BAR] = 'P',
|
||||||
|
[LED_FUNCTION_BATTERY_BAR] = 'E',
|
||||||
|
[LED_FUNCTION_ALTITUDE] = 'U'
|
||||||
|
};
|
||||||
|
static const char overlayCodes[LED_OVERLAY_COUNT] = {
|
||||||
|
[LED_OVERLAY_THROTTLE] = 'T',
|
||||||
|
[LED_OVERLAY_RAINBOW] = 'Y',
|
||||||
|
[LED_OVERLAY_LARSON_SCANNER] = 'O',
|
||||||
|
[LED_OVERLAY_BLINK] = 'B',
|
||||||
|
[LED_OVERLAY_VTX] = 'V',
|
||||||
|
[LED_OVERLAY_INDICATOR] = 'I',
|
||||||
|
[LED_OVERLAY_WARNING] = 'W'
|
||||||
|
};
|
||||||
|
|
||||||
#define CHUNK_BUFFER_SIZE 11
|
#define CHUNK_BUFFER_SIZE 11
|
||||||
bool parseLedStripConfig(int ledIndex, const char *config)
|
bool parseLedStripConfig(int ledIndex, const char *config)
|
||||||
|
@ -496,6 +553,8 @@ static const struct {
|
||||||
|
|
||||||
static void applyLedFixedLayers(void)
|
static void applyLedFixedLayers(void)
|
||||||
{
|
{
|
||||||
|
uint8_t ledBarCounters[LED_BAR_COUNT] = {0};
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = &ledStripStatusModeConfig()->ledConfigs[ledIndex];
|
||||||
hsvColor_t color = *getSC(LED_SCOLOR_BACKGROUND);
|
hsvColor_t color = *getSC(LED_SCOLOR_BACKGROUND);
|
||||||
|
@ -543,10 +602,39 @@ static void applyLedFixedLayers(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LED_FUNCTION_BATTERY:
|
case LED_FUNCTION_BATTERY:
|
||||||
|
case LED_FUNCTION_BATTERY_BAR:
|
||||||
color = HSV(RED);
|
color = HSV(RED);
|
||||||
hOffset += MAX(scaleRange(calculateBatteryPercentageRemaining(), 0, 100, -30, 120), 0);
|
hOffset += MAX(scaleRange(calculateBatteryPercentageRemaining(), 0, 100, -30, 120), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef USE_GPS
|
||||||
|
case LED_FUNCTION_GPS_BAR:
|
||||||
|
{
|
||||||
|
uint8_t minSats = 8;
|
||||||
|
#ifdef USE_GPS_RESCUE
|
||||||
|
minSats = gpsRescueConfig()->minSats;
|
||||||
|
#endif
|
||||||
|
if (gpsSol.numSat == 0 || !sensors(SENSOR_GPS)) {
|
||||||
|
color = HSV(RED);
|
||||||
|
} else {
|
||||||
|
if (gpsSol.numSat >= minSats) {
|
||||||
|
color = HSV(GREEN);
|
||||||
|
} else {
|
||||||
|
color = HSV(RED);
|
||||||
|
hOffset += MAX(scaleRange(gpsSol.numSat, 0, minSats, -30, 120), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_BARO) || defined(USE_GPS)
|
||||||
|
case LED_FUNCTION_ALTITUDE:
|
||||||
|
color = ledStripStatusModeConfig()->colors[ledGetColor(ledConfig)];
|
||||||
|
hOffset += MAX(scaleRange(getEstimatedAltitudeCm(), 0, 500, -30, 120), 0);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case LED_FUNCTION_RSSI:
|
case LED_FUNCTION_RSSI:
|
||||||
color = HSV(RED);
|
color = HSV(RED);
|
||||||
hOffset += MAX(scaleRange(getRssiPercent(), 0, 100, -30, 120), 0);
|
hOffset += MAX(scaleRange(getRssiPercent(), 0, 100, -30, 120), 0);
|
||||||
|
@ -560,9 +648,32 @@ static void applyLedFixedLayers(void)
|
||||||
const int auxInput = rcData[ledStripStatusModeConfig()->ledstrip_aux_channel];
|
const int auxInput = rcData[ledStripStatusModeConfig()->ledstrip_aux_channel];
|
||||||
hOffset += scaleRange(auxInput, PWM_RANGE_MIN, PWM_RANGE_MAX, 0, HSV_HUE_MAX + 1);
|
hOffset += scaleRange(auxInput, PWM_RANGE_MIN, PWM_RANGE_MAX, 0, HSV_HUE_MAX + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
color.h = (color.h + hOffset) % (HSV_HUE_MAX + 1);
|
color.h = (color.h + hOffset) % (HSV_HUE_MAX + 1);
|
||||||
setLedHsv(ledIndex, &color);
|
|
||||||
|
switch (fn) {
|
||||||
|
#ifdef USE_GPS
|
||||||
|
case LED_FUNCTION_GPS_BAR:
|
||||||
|
if (ledBarCounters[LED_BAR_GPS] < gpsSol.numSat || ledBarCounters[LED_BAR_GPS] == 0) {
|
||||||
|
ledBarCounters[LED_BAR_GPS]++;
|
||||||
|
setLedHsv(ledIndex, &color);
|
||||||
|
} else {
|
||||||
|
setLedHsv(ledIndex, getSC(LED_SCOLOR_BACKGROUND));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case LED_FUNCTION_BATTERY_BAR:
|
||||||
|
if (ledBarCounters[LED_BAR_BATTERY] < (calculateBatteryPercentageRemaining() * ledBarStates[LED_BAR_BATTERY]) / 100 || ledBarCounters[LED_BAR_BATTERY] == 0) {
|
||||||
|
ledBarCounters[LED_BAR_BATTERY]++;
|
||||||
|
setLedHsv(ledIndex, &color);
|
||||||
|
} else {
|
||||||
|
setLedHsv(ledIndex, getSC(LED_SCOLOR_BACKGROUND));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
setLedHsv(ledIndex, &color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#define LED_CONFIGURABLE_COLOR_COUNT 16
|
#define LED_CONFIGURABLE_COLOR_COUNT 16
|
||||||
#define LED_MODE_COUNT 6
|
#define LED_MODE_COUNT 6
|
||||||
#define LED_DIRECTION_COUNT 6
|
#define LED_DIRECTION_COUNT 6
|
||||||
#define LED_BASEFUNCTION_COUNT 7
|
#define LED_BASEFUNCTION_COUNT 10
|
||||||
#define LED_OVERLAY_COUNT 7
|
#define LED_OVERLAY_COUNT 7
|
||||||
#define LED_SPECIAL_COLOR_COUNT 11
|
#define LED_SPECIAL_COLOR_COUNT 11
|
||||||
|
|
||||||
|
@ -129,7 +129,10 @@ typedef enum {
|
||||||
LED_FUNCTION_BATTERY,
|
LED_FUNCTION_BATTERY,
|
||||||
LED_FUNCTION_RSSI,
|
LED_FUNCTION_RSSI,
|
||||||
LED_FUNCTION_GPS,
|
LED_FUNCTION_GPS,
|
||||||
LED_FUNCTION_THRUST_RING
|
LED_FUNCTION_THRUST_RING,
|
||||||
|
LED_FUNCTION_GPS_BAR,
|
||||||
|
LED_FUNCTION_BATTERY_BAR,
|
||||||
|
LED_FUNCTION_ALTITUDE
|
||||||
} ledBaseFunctionId_e;
|
} ledBaseFunctionId_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -391,6 +391,7 @@ bool rxIsReceivingSignal() { return true; }
|
||||||
bool isBeeperOn() { return false; };
|
bool isBeeperOn() { return false; };
|
||||||
|
|
||||||
uint8_t calculateBatteryPercentageRemaining() { return 0; }
|
uint8_t calculateBatteryPercentageRemaining() { return 0; }
|
||||||
|
uint32_t getEstimatedAltitudeCm() { return 0; }
|
||||||
|
|
||||||
bool sensors(uint32_t mask)
|
bool sensors(uint32_t mask)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue