#include "LEDPatterns.h" #include static enum LEDMode animMode = NONE; static uint8_t frameCounter = 0; // various things for the different modes static int8_t flash; static int8_t flashDirection; typedef struct { uint8_t value[3]; uint8_t direction; } RGBFader; static RGBFader followers[LED_COUNT]; typedef struct { const uint8_t rgb[3]; uint8_t leds[2]; uint8_t levels[2]; } KnobLights; static KnobLights knobs[2] = { // Aqua, top left LEDs {{0,1,1}, {0,1}, {BRIGHTNESS_LEVELS-1, 0}}, // Pink, top right LEDs {{1,0,1}, {6,7}, {0, BRIGHTNESS_LEVELS-1}} }; // Called every 1ms void led_frame(void) { if(++frameCounter < LED_MS_PER_FRAME) { return; } frameCounter = 0; switch(animMode) { case INIT_FLASH: if(flashDirection) { flash+=3; if(flash >= BRIGHTNESS_LEVELS - 1) { flash = BRIGHTNESS_LEVELS - 1; flashDirection = 0; } } else { flash-=3; if(flash <= 0) { led_anim_follower(); flash = 0; } } uint8_t bright = pgm_read_byte(&ledLogCurve[flash]); led_set_all(bright, bright/2, 0); break; case FOLLOWER: for(uint8_t led = 0; led < LED_COUNT; led++) { uint8_t followDir; RGBFader* follow; follow = followers + led; followDir = follow->direction; for(uint8_t i = 0; i < 3; i++) { if(followDir & 1) { if(follow->value[i]++ >= BRIGHTNESS_LEVELS - 1) { follow->value[i] = BRIGHTNESS_LEVELS - 1; follow->direction <<= 1; if(follow->direction == 0b1000) { follow->direction = 0b001; } } } else { if(follow->value[i] > 0) { follow->value[i]--; } } followDir >>= 1; } led_set(led, follow->value[0], follow->value[1], follow->value[2]); } break; case BREATHE: default: break; } led_set_all(0,0,0); for(uint8_t i = 0; i < 2; i++) { for(uint8_t led = 0; led < 2; led++) { uint8_t r = knobs[i].levels[led] * knobs[i].rgb[0]; uint8_t g = knobs[i].levels[led] * knobs[i].rgb[1]; uint8_t b = knobs[i].levels[led] * knobs[i].rgb[2]; led_set_max(ledCircleMap[knobs[i].leds[led]], r, g, b); } } } void led_knob_indiv(KnobLights* knob, int8_t value) { /* This is annoying and repetitive but don't think there's a nicer way */ if(value > 0) { knob->levels[0] += value; if(value > knob->levels[1]) { // Not properly doing rollover since the knob doesn't spin that fast knob->levels[1] = 0; } else { knob->levels[1] -= value; } if(knob->levels[0] > BRIGHTNESS_LEVELS) { knob->levels[0] = 0; knob->levels[1] = BRIGHTNESS_LEVELS - 1; knob->leds[1] = knob->leds[0]; if(knob->leds[0] > 0) { knob->leds[0]--; } else { knob->leds[0] = LED_COUNT - 1; } } } else if(value < 0) { if(-value > knob->levels[0]) { knob->levels[0] = 0; } else { knob->levels[0] += value; } knob->levels[1] -= value; if(knob->levels[1] > BRIGHTNESS_LEVELS) { knob->levels[0] = BRIGHTNESS_LEVELS - 1; knob->levels[1] = 0; knob->leds[0] = knob->leds[1]; knob->leds[1]++; knob->leds[1] %= LED_COUNT; } } } void led_knobs_update(int8_t left, int8_t right) { led_knob_indiv(&knobs[0], left*2); led_knob_indiv(&knobs[1], right*2); } void led_anim_flash(void) { animMode = INIT_FLASH; // starting at 2 stops us getting a frame of red flash = 2; flashDirection = 1; } void led_anim_follower(void) { // Generated by FollowerGen.py static uint8_t PROGMEM followStart[][4] = { {63, 0, 0, 0b010}, {40, 0, 23, 0b001}, {39, 24, 0, 0b010}, {16, 0, 47, 0b001}, {15, 48, 0, 0b010}, {0, 7, 56, 0b100}, {0, 55, 8, 0b100}, {0, 31, 32, 0b100}, }; animMode = FOLLOWER; for(uint8_t i = 0; i < LED_COUNT; i++) { for(uint8_t j = 0; j < 3; j++) { followers[i].value[j] = pgm_read_byte(&followStart[i][j]); } followers[i].direction = pgm_read_byte(&followStart[i][3]); } }