313 lines
9 KiB
C++
313 lines
9 KiB
C++
|
|
#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<WS2812B, PIN_PIXELS, GRB>(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();
|
|
}
|
|
}
|
|
}
|
|
|