diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/src/main.cpp b/src/main.cpp index a0bbc6f..4f18fe3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,3 @@ -// #define DEBUG 1 - #include <user_settings.h> #include <header.h> @@ -12,10 +10,16 @@ CRGB leds[LED_COUNT]; Timezone CopenhagenTime; +// Used for hue shift each minute +// https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors int hue = 0; int max_brightness = 255; +// Hold state if an led is on, to check if it should be faded on / off, or if it already is in desired state bool on_state[SEGMENT_COUNT * DIGIT_COUNT] = {false}; +// Segment naming scheme, corresponds to LED strip soldering order, standardized on Wikipeadia +// https://en.wikipedia.org/wiki/Seven-segment_display#/media/File:7_Segment_Display_with_Labeled_Segments.svg +// Last bit unused typedef enum : uint8_t { seg_a = 1<<0, // 00000001 seg_b = 1<<1, // 00000010 @@ -26,10 +30,11 @@ typedef enum : uint8_t { seg_g = 1<<6 } segments; +// uint8_t symbols[] = { - /* 0 */ seg_a | seg_b | seg_c | seg_d | seg_e | seg_f, - /* 1 */ seg_b | seg_c, - /* 2 */ seg_a | seg_b | seg_g | seg_e | seg_d, + /* 0 */ seg_a | seg_b | seg_c | seg_d | seg_e | seg_f, // 00111111 + /* 1 */ seg_b | seg_c, // 00000110 + /* 2 */ seg_a | seg_b | seg_g | seg_e | seg_d, // ... /* 3 */ seg_a | seg_b | seg_g | seg_c | seg_d, /* 4 */ seg_f | seg_g | seg_c | seg_b, /* 5 */ seg_a | seg_f | seg_g | seg_c | seg_d, @@ -41,6 +46,7 @@ uint8_t symbols[] = { /* C */ seg_a | seg_f | seg_e | seg_d }; +// Which segments should change color in this frame of the animation uint8_t spin_animation[] = { seg_a, seg_b, @@ -60,8 +66,9 @@ uint8_t dual_spin_animation[] = { seg_f | seg_c, }; +// Fades all at once void display_symbols(uint8_t *symbols_mask) { - // Fades all at once + // Loop over each brightness state and apply it to all elements if it's not already the desired state for (int brightness = 0; brightness <= max_brightness; brightness ++) { for (uint8_t digit_index = 0; digit_index < DIGIT_COUNT; digit_index++) { // Counts up by bitshifting @@ -69,10 +76,11 @@ void display_symbols(uint8_t *symbols_mask) { for (int segment_index = 0; segment_index < SEGMENT_COUNT; segment_index++) { int digit_offset = digit_index * SEGMENT_COUNT; + // LEDS can be offsed by START_INDEX, state array isn't int led_raw_index = digit_offset + segment_index; int led_index = START_OFFSET + led_raw_index; + // Get this LEDs previous state to see if it should be changed bool previously_on = on_state[led_raw_index]; - // Compare the current segment bit with the mask for the symbol bool turn_on = symbols_mask[digit_index] & seg_counter; @@ -82,37 +90,48 @@ void display_symbols(uint8_t *symbols_mask) { // Previously on, allow hue change leds[led_index] = CHSV(hue, SATURATION, max_brightness); } else { + // Previously off, gradually increase brightness with loop e.g. 0-255 leds[led_index] = CHSV(hue, SATURATION, brightness); } } else { // Turn off LED if(previously_on) { + // Previously on, gradually decrease brightness with a negative of the loop e.g. 255-0 leds[led_index] = CHSV(hue, SATURATION, max_brightness - brightness); } } + // Last loop itteration, save current LED state if (brightness == max_brightness) { on_state[led_raw_index] = turn_on; } - + + // Increment segment counter used with bit mask comparison by bitshifting seg_counter = seg_counter<<1; } } + + // Push changes of entire LED array to LEDs FastLED.show(); delay(2); } } +// Show a four digit number, by fading on LEDs void display_number(int number) { + // Build up entire bit mask, so all can be faded on at once uint8_t symbols_mask[DIGIT_COUNT]; // Start from the last digit for (int digit_index = DIGIT_COUNT - 1; digit_index >= 0; digit_index--) { + // Get only last digit symbols_mask[digit_index] = symbols[number % 10]; + // Pop last digit number /= 10; } display_symbols(symbols_mask); } +// Instantly changes. Binary, no fade void display_symbol(int digit_index, uint8_t symbol) { // Counts up by bitshifting uint8_t seg_counter = 1; @@ -120,54 +139,58 @@ void display_symbol(int digit_index, uint8_t symbol) { int offset = digit_index * SEGMENT_COUNT; int led_index = START_OFFSET + offset + segment_index; - // Compare the current segment bit with the mask for the symbol + // Compare the current segment bit with the bit mask for the symbol if (symbol & seg_counter) { // Turn on LED leds[led_index] = CHSV(hue, SATURATION, max_brightness); FastLED.show(); } + // Increment segment counter used with bit mask comparison by bitshifting seg_counter = seg_counter<<1; } } +// Change hue of 0-7 segments per frame each digit displays the same void play_animation(uint8_t *animation, int animation_size, int segment_delay) { for (int i = 0; i < animation_size; i++){ for (int digit_index = 0; digit_index < 4; digit_index++) { display_symbol(digit_index, animation[i]); } - - hue += 16; + + hue += 16; // Increment HSV hue a lot for rainbow vomit FastLED.show(); delay(segment_delay); } } +// Check the time, and display it on the clock void update_clock() { // Format the time as a 4-digit integer int timeInt = CopenhagenTime.dateTime("Hi").toInt(); // Sadly string format display_number(timeInt); - hue++; + hue++; // Increment HSV hue } void setup() { + // Setup LEDs FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, LED_COUNT).setCorrection( TypicalLEDStrip ); FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, LED_COUNT); // GRB ordering is assumed // Turn off all LEDs FastLED.clear(); - #ifdef DEBUG Serial.begin(9600); - #endif setServer(NTP_SERVER); - WiFi.setHostname("7-segment-esp-ws2811"); //define hostname + WiFi.setHostname(HOSTNAME); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.print("Connecting"); while (WiFi.status() != WL_CONNECTED) { + // Play animation untill connected to WiFi, or animation timeout is reached + // Will continue attempting to connect to WiFi if (millis() < WIFI_CONN_ANI_TIMEOUT) { play_animation(spin_animation, sizeof(spin_animation), 100); } else { @@ -217,19 +240,23 @@ void loop() { // Only update on each hole minute to avoid flickering int seconds = CopenhagenTime.dateTime("s").toInt(); int minutes = CopenhagenTime.dateTime("i").toInt(); - - if(minutes == 59 && seconds >= 55) { //if(minutes == 59 && seconds >= 55) { + + // Play animation 5 seconds before hour change + if(minutes == 59 && seconds >= 55) { play_animation(dual_spin_animation, sizeof(spin_animation), 50); FastLED.clear(); } + // Do nothing untill minute change if(seconds != 0) { delay(10); return; } - + + // Minute changed update_clock(); - + + // Wait untill minute change check won't be triggered again delay(1000); } |
