mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-24 00:35:39 +03:00
Add support for LED thrust ring. (St7ven)
This commit includes various fixed not included in the original pull request.
This commit is contained in:
parent
d2536e3792
commit
ddc7a39fa2
3 changed files with 179 additions and 35 deletions
|
@ -111,6 +111,7 @@ Note: It is perfectly possible to configure an LED to have all directions `NESWU
|
||||||
* `I` - `I`ndicator.
|
* `I` - `I`ndicator.
|
||||||
* `A` - `A`rmed state.
|
* `A` - `A`rmed state.
|
||||||
* `T` - `T`hrust state.
|
* `T` - `T`hrust state.
|
||||||
|
* `R` - `R`ing thrust state.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -171,6 +172,24 @@ This mode fades the LED current LED color to the previous/next color in the HSB
|
||||||
throttle is in the middle position the color is unaffected, thus it can be mixed with orientation colors to indicate orientation and throttle at
|
throttle is in the middle position the color is unaffected, thus it can be mixed with orientation colors to indicate orientation and throttle at
|
||||||
the same time.
|
the same time.
|
||||||
|
|
||||||
|
#### Thrust ring state
|
||||||
|
|
||||||
|
This mode is allows you to use a 12, 16 or 24 leds ring (e.g. NeoPixel ring) for an afterburner effect. When armed the leds use the following sequences: 2 On, 4 Off, 2 On, 4 Off, and so on. The light pattern rotates clockwise as throttle increases.
|
||||||
|
|
||||||
|
A better effect is acheived when LEDs configured for thrust ring have no other functions.
|
||||||
|
|
||||||
|
LED direction and X/Y positions are irrelevant for thrust ring LED state. The order of the LEDs that have the state determines how the LED behaves.
|
||||||
|
|
||||||
|
Each LED of the ring can be a different color. The color can be selected between the 15 colors availables.
|
||||||
|
|
||||||
|
For example, led 0 is set as a `R`ing thrust state led in color 13 as follow.
|
||||||
|
|
||||||
|
```
|
||||||
|
led 0 2,2::R:13
|
||||||
|
```
|
||||||
|
|
||||||
|
LED strips and rings can be combined.
|
||||||
|
|
||||||
## Positioning
|
## Positioning
|
||||||
|
|
||||||
Cut the strip into sections as per diagrams below. When the strips are cut ensure you reconnect each output to each input with cable where the break is made.
|
Cut the strip into sections as per diagrams below. When the strips are cut ensure you reconnect each output to each input with cable where the break is made.
|
||||||
|
|
|
@ -55,6 +55,7 @@ static failsafe_t* failsafe;
|
||||||
static void ledStripDisable(void);
|
static void ledStripDisable(void);
|
||||||
|
|
||||||
//#define USE_LED_ANIMATION
|
//#define USE_LED_ANIMATION
|
||||||
|
//#define USE_LED_RING_DEFAULT_CONFIG
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
#ifdef USE_LED_ANIMATION
|
#ifdef USE_LED_ANIMATION
|
||||||
|
@ -63,6 +64,7 @@ static uint32_t nextAnimationUpdateAt = 0;
|
||||||
|
|
||||||
static uint32_t nextIndicatorFlashAt = 0;
|
static uint32_t nextIndicatorFlashAt = 0;
|
||||||
static uint32_t nextWarningFlashAt = 0;
|
static uint32_t nextWarningFlashAt = 0;
|
||||||
|
static uint32_t nextRotationUpdateAt = 0;
|
||||||
|
|
||||||
#define LED_STRIP_20HZ ((1000 * 1000) / 20)
|
#define LED_STRIP_20HZ ((1000 * 1000) / 20)
|
||||||
#define LED_STRIP_10HZ ((1000 * 1000) / 10)
|
#define LED_STRIP_10HZ ((1000 * 1000) / 10)
|
||||||
|
@ -225,23 +227,44 @@ static const modeColorIndexes_t baroModeColors = {
|
||||||
uint8_t ledGridWidth;
|
uint8_t ledGridWidth;
|
||||||
uint8_t ledGridHeight;
|
uint8_t ledGridHeight;
|
||||||
uint8_t ledCount;
|
uint8_t ledCount;
|
||||||
|
uint8_t ledsInRingCount;
|
||||||
|
|
||||||
ledConfig_t *ledConfigs;
|
ledConfig_t *ledConfigs;
|
||||||
|
hsvColor_t *colors;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_LED_RING_DEFAULT_CONFIG
|
||||||
const ledConfig_t defaultLedStripConfig[] = {
|
const ledConfig_t defaultLedStripConfig[] = {
|
||||||
{ CALCULATE_LED_XY( 2, 2), LED_DIRECTION_SOUTH | LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
{ CALCULATE_LED_XY( 2, 2), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 2, 1), LED_DIRECTION_EAST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 2, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 2, 0), LED_DIRECTION_NORTH | LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
{ CALCULATE_LED_XY( 2, 0), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 0), LED_DIRECTION_NORTH | LED_FUNCTION_FLIGHT_MODE },
|
{ CALCULATE_LED_XY( 1, 0), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 0, 0), LED_DIRECTION_NORTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
{ CALCULATE_LED_XY( 0, 0), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 0, 1), LED_DIRECTION_WEST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 0, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 0, 2), LED_DIRECTION_SOUTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
{ CALCULATE_LED_XY( 0, 2), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 2), LED_DIRECTION_SOUTH | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 1, 2), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
const ledConfig_t defaultLedStripConfig[] = {
|
||||||
|
{ CALCULATE_LED_XY( 2, 2), 0, LED_DIRECTION_SOUTH | LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
||||||
|
{ CALCULATE_LED_XY( 2, 1), 0, LED_DIRECTION_EAST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 2, 0), 0, LED_DIRECTION_NORTH | LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
||||||
|
{ CALCULATE_LED_XY( 1, 0), 0, LED_DIRECTION_NORTH | LED_FUNCTION_FLIGHT_MODE },
|
||||||
|
{ CALCULATE_LED_XY( 0, 0), 0, LED_DIRECTION_NORTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
||||||
|
{ CALCULATE_LED_XY( 0, 1), 0, LED_DIRECTION_WEST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 0, 2), 0, LED_DIRECTION_SOUTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
|
||||||
|
{ CALCULATE_LED_XY( 1, 2), 0, LED_DIRECTION_SOUTH | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 1, 1), 0, LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 1, 1), 0, LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 1, 1), 0, LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
{ CALCULATE_LED_XY( 1, 1), 0, LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -258,12 +281,13 @@ typedef enum {
|
||||||
X_COORDINATE,
|
X_COORDINATE,
|
||||||
Y_COORDINATE,
|
Y_COORDINATE,
|
||||||
DIRECTIONS,
|
DIRECTIONS,
|
||||||
FUNCTIONS
|
FUNCTIONS,
|
||||||
|
RING_COLORS
|
||||||
} parseState_e;
|
} parseState_e;
|
||||||
|
|
||||||
#define PARSE_STATE_COUNT 4
|
#define PARSE_STATE_COUNT 5
|
||||||
|
|
||||||
static const char chunkSeparators[PARSE_STATE_COUNT] = {',', ':', ':', '\0' };
|
static const char chunkSeparators[PARSE_STATE_COUNT] = {',', ':', ':',':', '\0' };
|
||||||
|
|
||||||
static const char directionCodes[] = { 'N', 'E', 'S', 'W', 'U', 'D' };
|
static const char directionCodes[] = { 'N', 'E', 'S', 'W', 'U', 'D' };
|
||||||
#define DIRECTION_COUNT (sizeof(directionCodes) / sizeof(directionCodes[0]))
|
#define DIRECTION_COUNT (sizeof(directionCodes) / sizeof(directionCodes[0]))
|
||||||
|
@ -276,14 +300,15 @@ static const uint8_t directionMappings[DIRECTION_COUNT] = {
|
||||||
LED_DIRECTION_DOWN
|
LED_DIRECTION_DOWN
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char functionCodes[] = { 'I', 'W', 'F', 'A', 'T' };
|
static const char functionCodes[] = { 'I', 'W', 'F', 'A', 'T', 'R' };
|
||||||
#define FUNCTION_COUNT (sizeof(functionCodes) / sizeof(functionCodes[0]))
|
#define FUNCTION_COUNT (sizeof(functionCodes) / sizeof(functionCodes[0]))
|
||||||
static const uint16_t functionMappings[FUNCTION_COUNT] = {
|
static const uint16_t functionMappings[FUNCTION_COUNT] = {
|
||||||
LED_FUNCTION_INDICATOR,
|
LED_FUNCTION_INDICATOR,
|
||||||
LED_FUNCTION_WARNING,
|
LED_FUNCTION_WARNING,
|
||||||
LED_FUNCTION_FLIGHT_MODE,
|
LED_FUNCTION_FLIGHT_MODE,
|
||||||
LED_FUNCTION_ARM_STATE,
|
LED_FUNCTION_ARM_STATE,
|
||||||
LED_FUNCTION_THROTTLE
|
LED_FUNCTION_THROTTLE,
|
||||||
|
LED_FUNCTION_THRUST_RING
|
||||||
};
|
};
|
||||||
|
|
||||||
// grid offsets
|
// grid offsets
|
||||||
|
@ -327,13 +352,24 @@ void determineOrientationLimits(void)
|
||||||
|
|
||||||
void updateLedCount(void)
|
void updateLedCount(void)
|
||||||
{
|
{
|
||||||
|
const ledConfig_t *ledConfig;
|
||||||
uint8_t ledIndex;
|
uint8_t ledIndex;
|
||||||
ledCount = 0;
|
ledCount = 0;
|
||||||
|
ledsInRingCount = 0;
|
||||||
|
|
||||||
for (ledIndex = 0; ledIndex < MAX_LED_STRIP_LENGTH; ledIndex++) {
|
for (ledIndex = 0; ledIndex < MAX_LED_STRIP_LENGTH; ledIndex++) {
|
||||||
if (ledConfigs[ledIndex].flags == 0 && ledConfigs[ledIndex].xy == 0) {
|
|
||||||
|
ledConfig = &ledConfigs[ledIndex];
|
||||||
|
|
||||||
|
if (ledConfig->flags == 0 && ledConfig->xy == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ledCount++;
|
ledCount++;
|
||||||
|
|
||||||
|
if ((ledConfig->flags & LED_FUNCTION_THRUST_RING)) {
|
||||||
|
ledsInRingCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,6 +446,15 @@ bool parseLedStripConfig(uint8_t ledIndex, const char *config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RING_COLORS:
|
||||||
|
if (atoi(chunk) < CONFIGURABLE_COLOR_COUNT) {
|
||||||
|
ledConfig->color = atoi(chunk);
|
||||||
|
} else {
|
||||||
|
ledConfig->color = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseState++;
|
parseState++;
|
||||||
|
@ -433,11 +478,13 @@ void generateLedConfig(uint8_t ledIndex, char *ledConfigBuffer, size_t bufferSiz
|
||||||
char directions[DIRECTION_COUNT];
|
char directions[DIRECTION_COUNT];
|
||||||
uint8_t index;
|
uint8_t index;
|
||||||
uint8_t mappingIndex;
|
uint8_t mappingIndex;
|
||||||
|
|
||||||
ledConfig_t *ledConfig = &ledConfigs[ledIndex];
|
ledConfig_t *ledConfig = &ledConfigs[ledIndex];
|
||||||
|
|
||||||
memset(ledConfigBuffer, 0, bufferSize);
|
memset(ledConfigBuffer, 0, bufferSize);
|
||||||
memset(&functions, 0, sizeof(functions));
|
memset(&functions, 0, sizeof(functions));
|
||||||
memset(&directions, 0, sizeof(directions));
|
memset(&directions, 0, sizeof(directions));
|
||||||
|
//memset(&ringColors, 0 ,sizeof(ringColors));
|
||||||
|
|
||||||
for (mappingIndex = 0, index = 0; mappingIndex < FUNCTION_COUNT; mappingIndex++) {
|
for (mappingIndex = 0, index = 0; mappingIndex < FUNCTION_COUNT; mappingIndex++) {
|
||||||
if (ledConfig->flags & functionMappings[mappingIndex]) {
|
if (ledConfig->flags & functionMappings[mappingIndex]) {
|
||||||
|
@ -451,7 +498,7 @@ void generateLedConfig(uint8_t ledIndex, char *ledConfigBuffer, size_t bufferSiz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(ledConfigBuffer, "%u,%u:%s:%s", GET_LED_X(ledConfig), GET_LED_Y(ledConfig), directions, functions);
|
sprintf(ledConfigBuffer, "%u,%u:%s:%s:%u", GET_LED_X(ledConfig), GET_LED_Y(ledConfig), directions, functions, ledConfig->color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyDirectionalModeColor(const uint8_t ledIndex, const ledConfig_t *ledConfig, const modeColorIndexes_t *modeColors)
|
void applyDirectionalModeColor(const uint8_t ledIndex, const ledConfig_t *ledConfig, const modeColorIndexes_t *modeColors)
|
||||||
|
@ -529,7 +576,9 @@ void applyLedModeLayer(void)
|
||||||
|
|
||||||
ledConfig = &ledConfigs[ledIndex];
|
ledConfig = &ledConfigs[ledIndex];
|
||||||
|
|
||||||
setLedHsv(ledIndex, &hsv_black);
|
if (!(ledConfig->flags & LED_FUNCTION_THRUST_RING)) {
|
||||||
|
setLedHsv(ledIndex, &hsv_black);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(ledConfig->flags & LED_FUNCTION_FLIGHT_MODE)) {
|
if (!(ledConfig->flags & LED_FUNCTION_FLIGHT_MODE)) {
|
||||||
if (ledConfig->flags & LED_FUNCTION_ARM_STATE) {
|
if (ledConfig->flags & LED_FUNCTION_ARM_STATE) {
|
||||||
|
@ -682,7 +731,7 @@ void applyLedThrottleLayer()
|
||||||
uint8_t ledIndex;
|
uint8_t ledIndex;
|
||||||
for (ledIndex = 0; ledIndex < ledCount; ledIndex++) {
|
for (ledIndex = 0; ledIndex < ledCount; ledIndex++) {
|
||||||
ledConfig = &ledConfigs[ledIndex];
|
ledConfig = &ledConfigs[ledIndex];
|
||||||
if(!(ledConfig->flags & LED_FUNCTION_THROTTLE)) {
|
if (!(ledConfig->flags & LED_FUNCTION_THROTTLE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,15 +744,77 @@ void applyLedThrottleLayer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LED_ANIMATION
|
int applyLedThrustRingLayer(void)
|
||||||
static uint8_t frameCounter = 0;
|
|
||||||
|
|
||||||
static uint8_t previousRow;
|
|
||||||
static uint8_t currentRow;
|
|
||||||
static uint8_t nextRow;
|
|
||||||
|
|
||||||
static void updateLedAnimationState(void)
|
|
||||||
{
|
{
|
||||||
|
uint8_t oppositeLedIndex = ledsInRingCount >> 1;
|
||||||
|
uint8_t ledIndex;
|
||||||
|
int returnedValue = 1;
|
||||||
|
int throttleScaled = scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 1, 10);
|
||||||
|
static uint8_t rotationPhase = 0;
|
||||||
|
static bool nextLedOn = false;
|
||||||
|
hsvColor_t ringColor;
|
||||||
|
const ledConfig_t *ledConfig;
|
||||||
|
|
||||||
|
|
||||||
|
for (ledIndex = 0; ledIndex < ledCount; ledIndex++) {
|
||||||
|
|
||||||
|
ledConfig = &ledConfigs[ledIndex];
|
||||||
|
|
||||||
|
ringColor = colors[ledConfig->color];
|
||||||
|
|
||||||
|
if ((ledConfig->flags & LED_FUNCTION_THRUST_RING)) {
|
||||||
|
|
||||||
|
if (!ARMING_FLAG(ARMED)) {
|
||||||
|
|
||||||
|
if (nextLedOn == false) {
|
||||||
|
nextLedOn = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nextLedOn = false;
|
||||||
|
ringColor = hsv_black;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnedValue = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (rotationPhase == ((oppositeLedIndex) - 1)) {
|
||||||
|
if (!((ledIndex == rotationPhase) || (ledIndex == (rotationPhase + oppositeLedIndex))
|
||||||
|
|| (ledIndex == (rotationPhase +1)) || (ledIndex == 0))) {
|
||||||
|
ringColor = hsv_black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!((ledIndex == rotationPhase) || (ledIndex == (rotationPhase + oppositeLedIndex))
|
||||||
|
|| (ledIndex == (rotationPhase +1)) || (ledIndex == (rotationPhase + oppositeLedIndex +1 )))) {
|
||||||
|
ringColor = hsv_black;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Led stay on
|
||||||
|
}
|
||||||
|
|
||||||
|
returnedValue = throttleScaled;
|
||||||
|
}
|
||||||
|
setLedHsv(ledIndex, &ringColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotationPhase >= (oppositeLedIndex - 1)) {
|
||||||
|
rotationPhase = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rotationPhase++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_LED_ANIMATION
|
||||||
|
void updateLedAnimationState(void)
|
||||||
|
{
|
||||||
|
static uint8_t frameCounter = 0;
|
||||||
|
|
||||||
|
static uint8_t previousRow;
|
||||||
|
static uint8_t currentRow;
|
||||||
|
static uint8_t nextRow;
|
||||||
uint8_t animationFrames = ledGridHeight;
|
uint8_t animationFrames = ledGridHeight;
|
||||||
|
|
||||||
previousRow = (frameCounter + animationFrames - 1) % animationFrames;
|
previousRow = (frameCounter + animationFrames - 1) % animationFrames;
|
||||||
|
@ -741,7 +852,8 @@ static void applyLedAnimationLayer(void)
|
||||||
|
|
||||||
void updateLedStrip(void)
|
void updateLedStrip(void)
|
||||||
{
|
{
|
||||||
if (!(ledStripInitialised && isWS2811LedStripReady())) {
|
|
||||||
|
if (!(ledStripInitialised && isWS2811LedStripReady())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,12 +874,14 @@ void updateLedStrip(void)
|
||||||
uint32_t now = micros();
|
uint32_t now = micros();
|
||||||
|
|
||||||
bool indicatorFlashNow = indicatorFlashNow = (int32_t)(now - nextIndicatorFlashAt) >= 0L;
|
bool indicatorFlashNow = indicatorFlashNow = (int32_t)(now - nextIndicatorFlashAt) >= 0L;
|
||||||
bool warningFlashNow =warningFlashNow = (int32_t)(now - nextWarningFlashAt) >= 0L;
|
bool warningFlashNow = warningFlashNow = (int32_t)(now - nextWarningFlashAt) >= 0L;
|
||||||
|
bool rotationUpdateNow = (int32_t)(now - nextRotationUpdateAt) >= 0L;
|
||||||
#ifdef USE_LED_ANIMATION
|
#ifdef USE_LED_ANIMATION
|
||||||
bool animationUpdateNow = animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L;
|
bool animationUpdateNow = animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L;
|
||||||
#endif
|
#endif
|
||||||
if (!(
|
if (!(
|
||||||
indicatorFlashNow ||
|
indicatorFlashNow ||
|
||||||
|
rotationUpdateNow ||
|
||||||
warningFlashNow
|
warningFlashNow
|
||||||
#ifdef USE_LED_ANIMATION
|
#ifdef USE_LED_ANIMATION
|
||||||
|| animationUpdateNow
|
|| animationUpdateNow
|
||||||
|
@ -812,10 +926,16 @@ void updateLedStrip(void)
|
||||||
nextAnimationUpdateAt = now + LED_STRIP_20HZ;
|
nextAnimationUpdateAt = now + LED_STRIP_20HZ;
|
||||||
updateLedAnimationState();
|
updateLedAnimationState();
|
||||||
}
|
}
|
||||||
|
|
||||||
applyLedAnimationLayer();
|
applyLedAnimationLayer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (rotationUpdateNow) {
|
||||||
|
|
||||||
|
int animationSpeedScaled = applyLedThrustRingLayer();
|
||||||
|
|
||||||
|
nextRotationUpdateAt = now + LED_STRIP_5HZ/animationSpeedScaled; // TODO will be changed with more specifics animation
|
||||||
|
}
|
||||||
|
|
||||||
ws2811UpdateStrip();
|
ws2811UpdateStrip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +955,7 @@ bool parseColor(uint8_t index, const char *colorConfig)
|
||||||
if (val > HSV_HUE_MAX) {
|
if (val > HSV_HUE_MAX) {
|
||||||
ok = false;
|
ok = false;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
colors[index].h = val;
|
colors[index].h = val;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MAX_LED_STRIP_LENGTH 32
|
#define MAX_LED_STRIP_LENGTH 32
|
||||||
|
#define CONFIGURABLE_COLOR_COUNT 16
|
||||||
|
|
||||||
#define LED_X_BIT_OFFSET 4
|
#define LED_X_BIT_OFFSET 4
|
||||||
#define LED_Y_BIT_OFFSET 0
|
#define LED_Y_BIT_OFFSET 0
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
#define CALCULATE_LED_X(x) ((x & LED_XY_MASK) << LED_X_BIT_OFFSET)
|
#define CALCULATE_LED_X(x) ((x & LED_XY_MASK) << LED_X_BIT_OFFSET)
|
||||||
#define CALCULATE_LED_Y(y) ((y & LED_XY_MASK) << LED_Y_BIT_OFFSET)
|
#define CALCULATE_LED_Y(y) ((y & LED_XY_MASK) << LED_Y_BIT_OFFSET)
|
||||||
|
|
||||||
|
|
||||||
#define CALCULATE_LED_XY(x,y) (CALCULATE_LED_X(x) | CALCULATE_LED_Y(y))
|
#define CALCULATE_LED_XY(x,y) (CALCULATE_LED_X(x) | CALCULATE_LED_Y(y))
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -44,7 +46,8 @@ typedef enum {
|
||||||
LED_FUNCTION_WARNING = (1 << 7),
|
LED_FUNCTION_WARNING = (1 << 7),
|
||||||
LED_FUNCTION_FLIGHT_MODE = (1 << 8),
|
LED_FUNCTION_FLIGHT_MODE = (1 << 8),
|
||||||
LED_FUNCTION_ARM_STATE = (1 << 9),
|
LED_FUNCTION_ARM_STATE = (1 << 9),
|
||||||
LED_FUNCTION_THROTTLE = (1 << 10)
|
LED_FUNCTION_THROTTLE = (1 << 10),
|
||||||
|
LED_FUNCTION_THRUST_RING = (1 << 11),
|
||||||
} ledFlag_e;
|
} ledFlag_e;
|
||||||
|
|
||||||
#define LED_DIRECTION_BIT_OFFSET 0
|
#define LED_DIRECTION_BIT_OFFSET 0
|
||||||
|
@ -54,17 +57,18 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
typedef struct ledConfig_s {
|
typedef struct ledConfig_s {
|
||||||
uint8_t xy; // see LED_X/Y_MASK defines
|
uint8_t xy; // see LED_X/Y_MASK defines
|
||||||
|
uint8_t color; // see colors (config_master)
|
||||||
uint16_t flags; // see ledFlag_e
|
uint16_t flags; // see ledFlag_e
|
||||||
} ledConfig_t;
|
} ledConfig_t;
|
||||||
|
|
||||||
extern uint8_t ledCount;
|
extern uint8_t ledCount;
|
||||||
|
|
||||||
#define CONFIGURABLE_COLOR_COUNT 16
|
|
||||||
|
|
||||||
|
|
||||||
bool parseLedStripConfig(uint8_t ledIndex, const char *config);
|
bool parseLedStripConfig(uint8_t ledIndex, const char *config);
|
||||||
void updateLedStrip(void);
|
void updateLedStrip(void);
|
||||||
|
void updateLedRing(void);
|
||||||
|
|
||||||
void applyDefaultLedStripConfig(ledConfig_t *ledConfig);
|
void applyDefaultLedStripConfig(ledConfig_t *ledConfig);
|
||||||
void generateLedConfig(uint8_t ledIndex, char *ledConfigBuffer, size_t bufferSize);
|
void generateLedConfig(uint8_t ledIndex, char *ledConfigBuffer, size_t bufferSize);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue