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
*/
// FIXME this will work, but it's flash intensive and very customized
// a better solution would be to create an LED mapping and allow the user to specify it.
// e.g. "SSSEEESSSNNNNNNNNNNSSSWWWSSS" for north east south west facing leds, add U and D for up and downwards facing.
// additionally an led x/y position, so that sections can be lit individually.
// e.g. "1,1:1,2:1,3:1,4:2,1:2,2..."
// perhaps constrain the user by making them fit in a 5x5 grid (odd so you get a middle and small for easy processing)
// a more granular effects can be achieved by using a larger grid.
static const rgbColor24bpp_t stripOrientation[] =
{
{LED_RED},
{LED_RED},
{LED_RED},
{LED_PURPLE},
{LED_PURPLE},
{LED_PURPLE},
typedef enum {
LED_DISABLED = 0,
LED_DIRECTION_NORTH = (1 << 0),
LED_DIRECTION_EAST = (1 << 1),
LED_DIRECTION_SOUTH = (1 << 2),
LED_DIRECTION_WEST = (1 << 3),
LED_DIRECTION_UP = (1 << 4),
LED_DIRECTION_DOWN = (1 << 5),
LED_FUNCTION_INDICATOR = (1 << 6),
LED_FUNCTION_BATTERY = (1 << 7),
LED_FUNCTION_MODE = (1 << 8)
} ledFlag_e;
{LED_RED},
{LED_RED},
{LED_RED},
{LED_GREEN},
{LED_GREEN},
{LED_GREEN},
#define LED_X_BIT_OFFSET 4
#define LED_Y_BIT_OFFSET 0
{LED_WHITE},
{LED_WHITE},
{LED_WHITE},
{LED_WHITE},
#define LED_X_MASK (0xF0)
#define LED_Y_MASK (0x0F)
{LED_GREEN},
{LED_GREEN},
{LED_GREEN},
{LED_RED},
{LED_RED},
{LED_RED},
#define LED_X(ledConfig) ((ledConfig->xy & LED_X_MASK) >> LED_X_BIT_OFFSET)
#define LED_Y(ledConfig) ((ledConfig->xy & LED_Y_MASK) >> LED_Y_BIT_OFFSET)
{LED_BLUE},
{LED_BLUE},
{LED_BLUE},
{LED_RED},
{LED_RED},
{LED_RED}
};
#define LED_XY(x,y) (((x & LED_X_MASK) << LED_X_BIT_OFFSET) | ((y & LED_Y_MASK) << LED_Y_BIT_OFFSET))
static const rgbColor24bpp_t stripHorizon[] =
{
{LED_BLUE},
{LED_BLUE},
{LED_BLUE},
{LED_BLUE},
{LED_BLUE},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW}
};
typedef struct ledConfig_s {
uint8_t xy; // see LED_X/Y_MASK defines
uint16_t flags; // see ledFlag_e
} ledConfig_t;
static const rgbColor24bpp_t stripAngle[] =
{
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_CYAN},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW},
{LED_YELLOW}
};
static uint8_t ledGridWidth;
static uint8_t ledGridHeight;
static const rgbColor24bpp_t stripMag[] =
{
{LED_PURPLE},
{LED_PURPLE},
{LED_PURPLE},
{LED_PURPLE},
{LED_PURPLE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE}
};
static const ledConfig_t ledConfigs[WS2811_LED_STRIP_LENGTH] = {
{ LED_XY( 9, 9), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ LED_XY(10, 10), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ LED_XY(11, 11), LED_DIRECTION_SOUTH | LED_FUNCTION_INDICATOR },
{ LED_XY(11, 11), LED_DIRECTION_EAST | LED_FUNCTION_INDICATOR },
{ LED_XY(10, 10), LED_DIRECTION_EAST | LED_FUNCTION_MODE },
{ LED_XY( 9, 9), LED_DIRECTION_EAST | LED_FUNCTION_MODE },
static const rgbColor24bpp_t stripHeadfree[] =
{
{LED_PINK},
{LED_PINK},
{LED_PINK},
{LED_PINK},
{LED_PINK},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE},
{LED_ORANGE}
};
{ LED_XY(10, 5), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE },
{ LED_XY(11, 4), LED_DIRECTION_SOUTH | LED_FUNCTION_MODE },
{ LED_XY(12, 3), LED_DIRECTION_SOUTH | LED_FUNCTION_INDICATOR },
{ LED_XY(12, 2), LED_DIRECTION_NORTH | LED_FUNCTION_INDICATOR },
{ LED_XY(11, 1), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{ LED_XY(10, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
static const rgbColor24bpp_t stripReds[] =
{
{{ 32, 0, 0}},
{{ 96, 0, 0}},
{{160, 0, 0}},
{{224, 0, 0}},
{{255, 0, 0}},
{{255, 0, 0}},
{{224, 0, 0}},
{{160, 0, 0}},
{{ 96, 0, 0}},
{{ 32, 0, 0}},
{ 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 },
{ LED_XY( 5, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ LED_XY( 4, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE | LED_FUNCTION_BATTERY },
{ LED_XY( 2, 0), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{ LED_XY( 1, 1), LED_DIRECTION_NORTH | LED_FUNCTION_MODE },
{ LED_XY( 0, 2), LED_DIRECTION_NORTH | LED_FUNCTION_INDICATOR },
{ LED_XY( 0, 3), LED_DIRECTION_WEST | LED_FUNCTION_INDICATOR },
{ LED_XY( 1, 4), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{ LED_XY( 2, 5), LED_DIRECTION_WEST | LED_FUNCTION_MODE },
{ 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;
@ -171,6 +125,87 @@ uint32_t nextBatteryFlashAt = 0;
#define LED_STRIP_10HZ ((1000 * 1000) / 10)
#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)
{
if (!isWS2811LedStripReady()) {
@ -193,23 +228,7 @@ void updateLedStrip(void)
// LAYER 1
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);
}
applyLEDModeLayer();
// LAYER 2
@ -267,3 +286,13 @@ void updateLedStrip(void)
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);
bool sensorsAutodetect(sensorAlignmentConfig_t *sensorAlignmentConfig, uint16_t gyroLpf, uint8_t accHardwareToUse, int16_t magDeclinationFromConfig);
void imuInit(void);
void ledStripInit(void);
void loop(void);
@ -226,6 +227,7 @@ void init(void)
if (feature(FEATURE_LED_STRIP)) {
ws2811LedStripInit();
ledStripInit();
}
if (feature(FEATURE_TELEMETRY))