1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 16:25:31 +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:
St7ven 2015-01-01 16:04:01 +01:00 committed by Dominic Clifton
parent d2536e3792
commit ddc7a39fa2
3 changed files with 179 additions and 35 deletions

View file

@ -55,6 +55,7 @@ static failsafe_t* failsafe;
static void ledStripDisable(void);
//#define USE_LED_ANIMATION
//#define USE_LED_RING_DEFAULT_CONFIG
// timers
#ifdef USE_LED_ANIMATION
@ -63,6 +64,7 @@ static uint32_t nextAnimationUpdateAt = 0;
static uint32_t nextIndicatorFlashAt = 0;
static uint32_t nextWarningFlashAt = 0;
static uint32_t nextRotationUpdateAt = 0;
#define LED_STRIP_20HZ ((1000 * 1000) / 20)
#define LED_STRIP_10HZ ((1000 * 1000) / 10)
@ -225,23 +227,44 @@ static const modeColorIndexes_t baroModeColors = {
uint8_t ledGridWidth;
uint8_t ledGridHeight;
uint8_t ledCount;
uint8_t ledsInRingCount;
ledConfig_t *ledConfigs;
hsvColor_t *colors;
#ifdef USE_LED_RING_DEFAULT_CONFIG
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, 1), LED_DIRECTION_EAST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 2, 0), LED_DIRECTION_NORTH | LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
{ CALCULATE_LED_XY( 1, 0), LED_DIRECTION_NORTH | LED_FUNCTION_FLIGHT_MODE },
{ CALCULATE_LED_XY( 0, 0), LED_DIRECTION_NORTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
{ CALCULATE_LED_XY( 0, 1), LED_DIRECTION_WEST | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 0, 2), LED_DIRECTION_SOUTH | LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR | LED_FUNCTION_ARM_STATE },
{ CALCULATE_LED_XY( 1, 2), LED_DIRECTION_SOUTH | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_UP | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 1, 1), LED_DIRECTION_DOWN | LED_FUNCTION_FLIGHT_MODE | LED_FUNCTION_WARNING },
{ CALCULATE_LED_XY( 2, 2), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 2, 1), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 2, 0), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 1, 0), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 0, 0), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 0, 1), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 0, 2), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 1, 2), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
{ CALCULATE_LED_XY( 1, 1), 3, LED_FUNCTION_THRUST_RING},
{ 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,
Y_COORDINATE,
DIRECTIONS,
FUNCTIONS
FUNCTIONS,
RING_COLORS
} 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' };
#define DIRECTION_COUNT (sizeof(directionCodes) / sizeof(directionCodes[0]))
@ -276,14 +300,15 @@ static const uint8_t directionMappings[DIRECTION_COUNT] = {
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]))
static const uint16_t functionMappings[FUNCTION_COUNT] = {
LED_FUNCTION_INDICATOR,
LED_FUNCTION_WARNING,
LED_FUNCTION_FLIGHT_MODE,
LED_FUNCTION_ARM_STATE,
LED_FUNCTION_THROTTLE
LED_FUNCTION_THROTTLE,
LED_FUNCTION_THRUST_RING
};
// grid offsets
@ -327,13 +352,24 @@ void determineOrientationLimits(void)
void updateLedCount(void)
{
const ledConfig_t *ledConfig;
uint8_t ledIndex;
ledCount = 0;
ledsInRingCount = 0;
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;
}
ledCount++;
if ((ledConfig->flags & LED_FUNCTION_THRUST_RING)) {
ledsInRingCount++;
}
}
}
@ -410,6 +446,15 @@ bool parseLedStripConfig(uint8_t ledIndex, const char *config)
}
}
break;
case RING_COLORS:
if (atoi(chunk) < CONFIGURABLE_COLOR_COUNT) {
ledConfig->color = atoi(chunk);
} else {
ledConfig->color = 0;
}
break;
default :
break;
}
parseState++;
@ -433,11 +478,13 @@ void generateLedConfig(uint8_t ledIndex, char *ledConfigBuffer, size_t bufferSiz
char directions[DIRECTION_COUNT];
uint8_t index;
uint8_t mappingIndex;
ledConfig_t *ledConfig = &ledConfigs[ledIndex];
memset(ledConfigBuffer, 0, bufferSize);
memset(&functions, 0, sizeof(functions));
memset(&directions, 0, sizeof(directions));
//memset(&ringColors, 0 ,sizeof(ringColors));
for (mappingIndex = 0, index = 0; mappingIndex < FUNCTION_COUNT; 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)
@ -529,7 +576,9 @@ void applyLedModeLayer(void)
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_ARM_STATE) {
@ -682,7 +731,7 @@ void applyLedThrottleLayer()
uint8_t ledIndex;
for (ledIndex = 0; ledIndex < ledCount; ledIndex++) {
ledConfig = &ledConfigs[ledIndex];
if(!(ledConfig->flags & LED_FUNCTION_THROTTLE)) {
if (!(ledConfig->flags & LED_FUNCTION_THROTTLE)) {
continue;
}
@ -695,15 +744,77 @@ void applyLedThrottleLayer()
}
}
#ifdef USE_LED_ANIMATION
static uint8_t frameCounter = 0;
static uint8_t previousRow;
static uint8_t currentRow;
static uint8_t nextRow;
static void updateLedAnimationState(void)
int applyLedThrustRingLayer(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;
previousRow = (frameCounter + animationFrames - 1) % animationFrames;
@ -741,7 +852,8 @@ static void applyLedAnimationLayer(void)
void updateLedStrip(void)
{
if (!(ledStripInitialised && isWS2811LedStripReady())) {
if (!(ledStripInitialised && isWS2811LedStripReady())) {
return;
}
@ -762,12 +874,14 @@ void updateLedStrip(void)
uint32_t now = micros();
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
bool animationUpdateNow = animationUpdateNow = (int32_t)(now - nextAnimationUpdateAt) >= 0L;
#endif
if (!(
indicatorFlashNow ||
rotationUpdateNow ||
warningFlashNow
#ifdef USE_LED_ANIMATION
|| animationUpdateNow
@ -812,10 +926,16 @@ void updateLedStrip(void)
nextAnimationUpdateAt = now + LED_STRIP_20HZ;
updateLedAnimationState();
}
applyLedAnimationLayer();
#endif
if (rotationUpdateNow) {
int animationSpeedScaled = applyLedThrustRingLayer();
nextRotationUpdateAt = now + LED_STRIP_5HZ/animationSpeedScaled; // TODO will be changed with more specifics animation
}
ws2811UpdateStrip();
}
@ -835,6 +955,7 @@ bool parseColor(uint8_t index, const char *colorConfig)
if (val > HSV_HUE_MAX) {
ok = false;
continue;
}
colors[index].h = val;
break;