#include "led_clock.hpp" void led_clock::init( unsigned test_at_start) { pinMode(PIN_BUZZER, OUTPUT); digitalWrite(PIN_BUZZER,HIGH); pixels_test = test_at_start; init_test_pixel(); init_ringsecs(); init_ringmins(); init_pointers(); init_numbers(); //Serial.printf("Init pixels - first:%d last:%d number:%d outsidetoinside:%d\n", element_first_pixel, element_last_pixel, element_number_pixels, element_outside2inside); } void led_clock::init_ringmins() { // init all the seconds shown on the ring Serial.println("Init minutes on outer ring ..."); unsigned int current_first_led = 1; for(uint8_t num = 0; num < NUM_MINUTES; num++) { if(num%15 == 0) ringmins[num].init(pixels, current_first_led-1, 3, color[COL_MINUTE]); else ringmins[num].init(pixels, current_first_led, NUM_RING_MIN_PIXELS, color[COL_MINUTE]); actmins[num].init(pixels, current_first_led, 1, color[COL_ACTMIN]); ringmins[num].clean(); if(pixels_test & TEST_MINS) { ringmins[num].test(true); actmins[num].test(true); } current_first_led += NUM_RING_PIXELS/NUM_MINUTES; } } void led_clock::init_ringsecs() { // init all the seconds shown on the ring Serial.println("Init seconds on outer ring ..."); unsigned int current_first_led = 0; for(uint8_t num = 0; num < NUM_SECONDS; num++) { ringsecs[num].init(pixels, current_first_led, NUM_RING_SEC_PIXELS, color[colorsecs]); ringsecs[num].clean(); if(pixels_test & TEST_SECS) ringsecs[num].test(true); current_first_led += NUM_RING_SEC_PIXELS; } } void led_clock::init_numbers() { // init all the numbers Serial.println("Init numbers ..."); unsigned int current_first_led = NUM_RING_PIXELS + NUM_POINTERS_PIXELS; for(uint8_t num = 0; num < NUM_NUMBERS; num++) { uint8_t real_num = num == 11? 0 : num + 1; number[real_num].init(pixels, current_first_led, NUM_NUMBER_PIXELS[num],color[COL_NUM]); number[real_num].clean(); if(pixels_test & TEST_NUMS) number[real_num].test(true); current_first_led += NUM_NUMBER_PIXELS[num]; } } void led_clock::init_show_ring_wifi(){ for(uint8_t num = 0; num < NUM_POINTERS; num++) { pointer[num].run_init(); } } void led_clock::show_ring_wifi(bool wifi){ hue_color huecolor = wifi == true? color[COL_WIFI]: color[COL_NOWIFI]; for(uint8_t ring = 0; ring < NUM_POINTER_PIXELS; ring++) { FastLED.clearData(); for(uint8_t num = 0; num < NUM_POINTERS; num++) { pointer[num].run(huecolor, wifi); } show(); delay(100); } } void led_clock::init_pointers() { Serial.println("Init pointers ..."); // init all the pointers - each as 6 leds, starts at 12,11,10 ... 1, each even is inversed (goes from outside into center) unsigned int current_first_led = NUM_RING_PIXELS; bool is_insideoutside = false; for(int8_t num = NUM_POINTERS-1; num >= 0; num--) { uint8_t real_num = num == 11? 0 : num + 1; is_insideoutside = num%2==0? false:true; pointer[real_num].init(pixels, current_first_led, NUM_POINTER_PIXELS ,color[COL_HOUR],is_insideoutside); pointer[real_num].clean(); if(pixels_test & TEST_PTRS) pointer[real_num].test(); current_first_led += NUM_POINTER_PIXELS; } } void led_clock::init_test_pixel() { pixels = (CRGB*) malloc(NUM_ALL_PIXELS * sizeof(CRGB) ); FastLED.clearData(); FastLED.addLeds(pixels, NUM_ALL_PIXELS); // GRB ordering is typical FastLED.clear(true); Serial.printf("Init LED pixels %d \n",NUM_ALL_PIXELS); if(pixels_test & TEST_PIXELS) for(unsigned char col = COL_SECOND; col < COL_LAST; col++) { unsigned int pixel = 0; for(pixel = 0; pixel < NUM_ALL_PIXELS; pixel++) { if(pixel > 0) { pixels[pixel-1] = CHSV(0,0,0); } pixels[pixel] = CHSV(color[col].hue, color[col].sat, color[col].bright); show(); } FastLED.clear(true); } } void led_clock::tick_tock() { digitalWrite(PIN_BUZZER,HIGH); delay(1); digitalWrite(PIN_BUZZER,LOW); } void led_clock::draw_minute_ring(uint8_t minnr) { if(minnr % 5 != 0) ringmins[minnr].fill(ringmins[minnr].elements_huecolor.hue, ringmins[minnr].elements_huecolor.sat, ringmins[minnr].elements_huecolor.bright/8); else ringmins[minnr].fill(ringmins[minnr].elements_huecolor.hue, ringmins[minnr].elements_huecolor.sat, ringmins[minnr].elements_huecolor.bright/2); } void led_clock::draw_unused_minute_ring(uint8_t minnr) { if(minnr % 5 != 0) ringmins[minnr].fill(COLOR_OFFMINS.hue, COLOR_OFFMINS.sat, COLOR_OFFMINS.bright/64); else ringmins[minnr].fill(COLOR_OFFMINS.hue, COLOR_OFFMINS.sat, COLOR_OFFMINS.bright/4); } void led_clock::show_minute( uint8_t minute ) { for(uint8_t minnr = 0; minnr < NUM_MINUTES; minnr++) { if(minnr < minute) draw_minute_ring(minnr); else draw_unused_minute_ring(minnr); } actmins[minute].fill(COLOR_ACTMIN); } void led_clock::animate_new_minute( uint8_t minute , uint8_t second, uint8_t hour) { uint8_t old_minute = last_value(minute, 0, NUM_MINUTES); FastLED.clearData(); show_minute( old_minute ); show_hour( hour, old_minute); show_second(second); show(); for(uint8_t minnr = 1; minnr < minute; minnr++) { ringmins[minnr].fill(); if(minnr > 1){ draw_minute_ring(minnr-1); } show(); } show_minute( minute ); show(); } void led_clock::animate_new_hour( uint8_t minute , uint8_t second, uint8_t hour) { uint8_t old_hour = hour==0?11:hour-1; uint8_t old_minute = NUM_MINUTES-1; FastLED.clearData(); show_minute( old_minute ); show_hour( old_hour, old_minute); ringsecs[second].fill(); show(); for(uint8_t minnr = 1; minnr < NUM_MINUTES; minnr++) { ringmins[minnr].clean(); show(); } } void led_clock::show_hour( uint8_t hour, uint8_t minute) { uint8_t next_hour = hour == 11? 0:hour+1; uint8_t brightness = number[hour].elements_huecolor.bright; uint8_t basebrightness = brightness/6; uint8_t minutebrightness = (brightness-basebrightness)/NUM_MINUTES; uint8_t fractionbrightness = minutebrightness * minute; uint8_t numbrightness = (uint8_t)(basebrightness + fractionbrightness); //Serial.printf("Show hour: minute=%d, basebright=%d, mintebright=%d, fractionbright=%d, bright=%d\n", minute, basebrightness, minutebrightness, fractionbrightness, numbrightness ); for(uint8_t num = 0; num < NUM_NUMBERS;num++) { if(num != hour && num != next_hour) { number[num].fill(COLOR_OFFHOURS); } } number[hour].fill(number[hour].elements_huecolor.hue, number[hour].elements_huecolor.sat,brightness-numbrightness); number[next_hour].fill(number[next_hour].elements_huecolor.hue, number[next_hour].elements_huecolor.sat,numbrightness); pointer[hour].ffill(NUM_MINUTES-minute, NUM_MINUTES); pointer[next_hour].ffill(minute, NUM_MINUTES); } uint8_t led_clock::last_value( uint8_t value, uint8_t minvalue, uint8_t maxvalue) { uint8_t lvalue = value == minvalue ? maxvalue : value - 1; return(lvalue); } uint8_t led_clock::next_value( uint8_t value, uint8_t minvalue, uint8_t maxvalue) { uint8_t nvalue = value == maxvalue ? minvalue : value + 1; return(nvalue); } void led_clock::show_second( uint8_t second) { uint8_t second_m1 = last_value(second,0,59); uint8_t second_m2 = last_value(second_m1,0,59); uint8_t brightness = ringsecs[second].elements_huecolor.bright; ringsecs[second].fill(); ringsecs[second_m1].fill(ringsecs[second_m1].elements_huecolor.hue, ringsecs[second_m1].elements_huecolor.sat,brightness/4); ringsecs[second_m2].fill(ringsecs[second_m1].elements_huecolor.hue, ringsecs[second_m1].elements_huecolor.sat,brightness/16); } void led_clock::showtime(uint8_t hour, uint8_t minute, uint8_t second, bool time_isvalid, bool is_connected) { if(prv_second != second) { if(time_isvalid == true) { if(is_connected == true) { colorsecs = COL_SECOND; } else { colorsecs = COL_SECOND_NOWIFI; } } else { colorsecs = COL_SECONDS_NOSYNC; } prv_second = second; hour = hour > 11?hour-12:hour; //Serial.printf("%02d : %02d : %02d \n" , hour, minute, second); if(millis() - prv_millis >= 950) { tick_tock(); prv_millis = millis(); } if(second == 0) { if(minute!=0) { animate_new_minute( minute , second, hour); } else { animate_new_hour( minute , second, hour); } } else { FastLED.clearData(); show_minute( minute ); show_second( second); actmins[minute].fill(COLOR_ACTMIN); show_hour( hour, minute); show(); } } }