1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 16:25:31 +03:00

First cut of programmatically orientation lights using an LED strip

configuration that defines each LED's functions, orientation and
position in a grid.
This commit is contained in:
Dominic Clifton 2014-07-02 20:40:26 +01:00
parent af2f9a2655
commit de04acd7e1
2 changed files with 150 additions and 119 deletions

View file

@ -52,117 +52,71 @@
* 22..27 - rear left cluster, 22..24 left, 25..27 rear * 22..27 - rear left cluster, 22..24 left, 25..27 rear
*/ */
// FIXME this will work, but it's flash intensive and very customized typedef enum {
// a better solution would be to create an LED mapping and allow the user to specify it. LED_DISABLED = 0,
// e.g. "SSSEEESSSNNNNNNNNNNSSSWWWSSS" for north east south west facing leds, add U and D for up and downwards facing. LED_DIRECTION_NORTH = (1 << 0),
// additionally an led x/y position, so that sections can be lit individually. LED_DIRECTION_EAST = (1 << 1),
// e.g. "1,1:1,2:1,3:1,4:2,1:2,2..." LED_DIRECTION_SOUTH = (1 << 2),
// perhaps constrain the user by making them fit in a 5x5 grid (odd so you get a middle and small for easy processing) LED_DIRECTION_WEST = (1 << 3),
// a more granular effects can be achieved by using a larger grid. LED_DIRECTION_UP = (1 << 4),
static const rgbColor24bpp_t stripOrientation[] = LED_DIRECTION_DOWN = (1 << 5),
{ LED_FUNCTION_INDICATOR = (1 << 6),
{LED_RED}, LED_FUNCTION_BATTERY = (1 << 7),
{LED_RED}, LED_FUNCTION_MODE = (1 << 8)
{LED_RED}, } ledFlag_e;
{LED_PURPLE},
{LED_PURPLE},
{LED_PURPLE},
{LED_RED}, #define LED_X_BIT_OFFSET 4
{LED_RED}, #define LED_Y_BIT_OFFSET 0
{LED_RED},
{LED_GREEN},
{LED_GREEN},
{LED_GREEN},
{LED_WHITE}, #define LED_X_MASK (0xF0)
{LED_WHITE}, #define LED_Y_MASK (0x0F)
{LED_WHITE},
{LED_WHITE},
{LED_GREEN}, #define LED_X(ledConfig) ((ledConfig->xy & LED_X_MASK) >> LED_X_BIT_OFFSET)
{LED_GREEN}, #define LED_Y(ledConfig) ((ledConfig->xy & LED_Y_MASK) >> LED_Y_BIT_OFFSET)
{LED_GREEN},
{LED_RED},
{LED_RED},
{LED_RED},
{LED_BLUE}, #define LED_XY(x,y) (((x & LED_X_MASK) << LED_X_BIT_OFFSET) | ((y & LED_Y_MASK) << LED_Y_BIT_OFFSET))
{LED_BLUE},
{LED_BLUE},
{LED_RED},
{LED_RED},
{LED_RED}
};
static const rgbColor24bpp_t stripHorizon[] = typedef struct ledConfig_s {
{ uint8_t xy; // see LED_X/Y_MASK defines
{LED_BLUE}, uint16_t flags; // see ledFlag_e
{LED_BLUE}, } ledConfig_t;
{LED_BLUE},
{LED_BLUE},
{LED_BLUE},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW}
};
static const rgbColor24bpp_t stripAngle[] = static uint8_t ledGridWidth;
{ static uint8_t ledGridHeight;
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW}
};
static const rgbColor24bpp_t stripMag[] = static const ledConfig_t ledConfigs[WS2811_LED_STRIP_LENGTH] = {
{ { LED_XY( 9, 9), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{LED_PURPLE}, { LED_XY(10, 10), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{LED_PURPLE}, { LED_XY(11, 11), LED_DIRECTION_SOUTH | LED_FUNCTION_INDICATOR },
{LED_PURPLE}, { LED_XY(11, 11), LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR },
{LED_PURPLE}, { LED_XY(10, 10), LED_DIRECTION_EAST | LED_FUNCTION_MODE },
{LED_PURPLE}, { LED_XY( 9, 9), LED_DIRECTION_EAST | LED_FUNCTION_MODE },
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE}
};
static const rgbColor24bpp_t stripHeadfree[] = { LED_XY(10, 5), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE },
{ { LED_XY(11, 4), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE },
{LED_PINK}, { LED_XY(12, 3), LED_DIRECTION_SOUTH | LED_FUNCTION_INDICATOR },
{LED_PINK}, { LED_XY(12, 2), LED_DIRECTION_NORTH | LED_FUNCTION_INDICATOR },
{LED_PINK}, { LED_XY(11, 1), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{LED_PINK}, { LED_XY(10, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{LED_PINK},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE}
};
static const rgbColor24bpp_t stripReds[] = { LED_XY( 7, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ { LED_XY( 6, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{{ 32, 0, 0}}, { LED_XY( 5, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{{ 96, 0, 0}}, { LED_XY( 4, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{{160, 0, 0}},
{{224, 0, 0}}, { LED_XY( 2, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{{255, 0, 0}}, { LED_XY( 1, 1), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{{255, 0, 0}}, { LED_XY( 0, 2), LED_DIRECTION_NORTH | LED_FUNCTION_INDICATOR },
{{224, 0, 0}}, { LED_XY( 0, 3), LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR },
{{160, 0, 0}}, { LED_XY( 1, 4), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{{ 96, 0, 0}}, { LED_XY( 2, 5), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{{ 32, 0, 0}},
{ LED_XY( 2, 9), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{ LED_XY( 1, 10), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{ LED_XY( 0, 11), LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR },
{ LED_XY( 0, 11), LED_DIRECTION_SOUTH | LED_FUNCTION_INDICATOR },
{ LED_XY( 1, 10), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ LED_XY( 2, 9), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY }
}; };
uint32_t nextIndicatorFlashAt = 0; uint32_t nextIndicatorFlashAt = 0;
@ -171,6 +125,87 @@ uint32_t nextBatteryFlashAt = 0;
#define LED_STRIP_10HZ ((1000 * 1000) / 10) #define LED_STRIP_10HZ ((1000 * 1000) / 10)
#define LED_STRIP_5HZ ((1000 * 1000) / 5) #define LED_STRIP_5HZ ((1000 * 1000) / 5)
#define LED_DIRECTION_COUNT 6
struct modeColors_s {
rgbColor24bpp_t north;
rgbColor24bpp_t east;
rgbColor24bpp_t south;
rgbColor24bpp_t west;
rgbColor24bpp_t up;
rgbColor24bpp_t down;
};
typedef union {
rgbColor24bpp_t raw[LED_DIRECTION_COUNT];
struct modeColors_s colors;
} modeColors_t;
static const modeColors_t orientationColors = {
.raw = {
{LED_WHITE},
{LED_BLUE},
{LED_RED},
{LED_GREEN},
{LED_PURPLE},
{LED_CYAN}
}
};
void applyLEDModeLayer(void)
{
const ledConfig_t *ledConfig;
uint8_t highestYValueForNorth = (ledGridHeight / 2) - 1;
highestYValueForNorth &= ~(1 << 0); // make even
uint8_t lowestYValueForSouth = (ledGridHeight / 2) - 1;
if (lowestYValueForSouth & 1) {
lowestYValueForSouth = min(lowestYValueForSouth + 1, ledGridHeight - 1);
}
uint8_t ledIndex;
for (ledIndex = 0; ledIndex < WS2811_LED_STRIP_LENGTH; ledIndex++) {
ledConfig = &ledConfigs[ledIndex];
if (!(ledConfig->flags & LED_FUNCTION_MODE)) {
setLedColor(ledIndex, &black);
continue;
}
if (ledConfig->flags & LED_DIRECTION_NORTH && LED_Y(ledConfig) < highestYValueForNorth) {
setLedColor(ledIndex, &orientationColors.colors.north);
continue;
}
if (ledConfig->flags & LED_DIRECTION_SOUTH && LED_Y(ledConfig) >= lowestYValueForSouth) {
setLedColor(ledIndex, &orientationColors.colors.south);
continue;
}
setLedColor(ledIndex, &black);
}
/*
if (f.ARMED) {
setStripColors(stripOrientation);
} else {
setStripColors(stripReds);
}
if (f.HEADFREE_MODE) {
setStripColors(stripHeadfree);
#ifdef MAG
} else if (f.MAG_MODE) {
setStripColors(stripMag);
#endif
} else if (f.HORIZON_MODE) {
setStripColors(stripHorizon);
} else if (f.ANGLE_MODE) {
setStripColors(stripAngle);
}
*/
}
void updateLedStrip(void) void updateLedStrip(void)
{ {
if (!isWS2811LedStripReady()) { if (!isWS2811LedStripReady()) {
@ -193,23 +228,7 @@ void updateLedStrip(void)
// LAYER 1 // LAYER 1
if (f.ARMED) { applyLEDModeLayer();
setStripColors(stripOrientation);
} else {
setStripColors(stripReds);
}
if (f.HEADFREE_MODE) {
setStripColors(stripHeadfree);
#ifdef MAG
} else if (f.MAG_MODE) {
setStripColors(stripMag);
#endif
} else if (f.HORIZON_MODE) {
setStripColors(stripHorizon);
} else if (f.ANGLE_MODE) {
setStripColors(stripAngle);
}
// LAYER 2 // LAYER 2
@ -267,3 +286,13 @@ void updateLedStrip(void)
ws2811UpdateStrip(); ws2811UpdateStrip();
} }
void determineLedStripDimensions() {
// TODO iterate over ledConfigs and determine programatically
ledGridWidth = 12;
ledGridHeight = 12;
}
void ledStripInit(void) {
determineLedStripDimensions();
}

View file

@ -87,6 +87,7 @@ void beepcodeInit(failsafe_t *initialFailsafe);
void gpsInit(serialConfig_t *serialConfig, gpsConfig_t *initialGpsConfig, gpsProfile_t *initialGpsProfile, pidProfile_t *pidProfile); void gpsInit(serialConfig_t *serialConfig, gpsConfig_t *initialGpsConfig, gpsProfile_t *initialGpsProfile, pidProfile_t *pidProfile);
bool sensorsAutodetect(sensorAlignmentConfig_t *sensorAlignmentConfig, uint16_t gyroLpf, uint8_t accHardwareToUse, int16_t magDeclinationFromConfig); bool sensorsAutodetect(sensorAlignmentConfig_t *sensorAlignmentConfig, uint16_t gyroLpf, uint8_t accHardwareToUse, int16_t magDeclinationFromConfig);
void imuInit(void); void imuInit(void);
void ledStripInit(void);
void loop(void); void loop(void);
@ -226,6 +227,7 @@ void init(void)
if (feature(FEATURE_LED_STRIP)) { if (feature(FEATURE_LED_STRIP)) {
ws2811LedStripInit(); ws2811LedStripInit();
ledStripInit();
} }
if (feature(FEATURE_TELEMETRY)) if (feature(FEATURE_TELEMETRY))