first final version

This commit is contained in:
fenoglio 2020-05-19 01:45:07 +02:00
parent a18b76a972
commit 8665de69c3
24 changed files with 623 additions and 191 deletions

View File

@ -1 +1 @@
04494c3f57e718d0fb8180e31fe62686bf2f9497
94af52e4db3390bb54a2a626f0a18eeee0e8d30f

View File

@ -10,7 +10,16 @@
"c:/Users/jnoack/Documents/GITs/infinityledclock/vscode/infclock/src",
"C:/Users/jnoack/.platformio/lib/FastLED_ID126",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"C:/Users/jnoack/.platformio/lib/WifiManager_ID567",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"C:/Users/jnoack/.platformio/lib/Timezone_ID76/src",
"C:/Users/jnoack/.platformio/lib/Time_ID44",
"C:/Users/jnoack/.platformio/lib/RTC_ID274/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/tools/sdk/libc/xtensa-lx106-elf/include",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
@ -19,21 +28,18 @@
"C:/Users/jnoack/.platformio/lib/Adafruit NeoPixel_ID28",
"C:/Users/jnoack/.platformio/lib/DS3231_ID1379",
"C:/Users/jnoack/.platformio/lib/ESP32Servo_ID4744/src",
"C:/Users/jnoack/.platformio/lib/RTC_ID274/src",
"C:/Users/jnoack/.platformio/lib/LibXSVF_ID6585/src",
"C:/Users/jnoack/.platformio/lib/RemoteDebug_ID1266/src",
"C:/Users/jnoack/.platformio/lib/SoftwareWire_ID832",
"C:/Users/jnoack/.platformio/lib/TimerOne_ID131",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266LLMNR",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266NetBIOS",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SdFat/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS/src",
@ -47,7 +53,6 @@
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
"C:/Users/jnoack/.platformio/packages/tool-unity",
""
@ -59,7 +64,16 @@
"c:/Users/jnoack/Documents/GITs/infinityledclock/vscode/infclock/src",
"C:/Users/jnoack/.platformio/lib/FastLED_ID126",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"C:/Users/jnoack/.platformio/lib/WifiManager_ID567",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"C:/Users/jnoack/.platformio/lib/Timezone_ID76/src",
"C:/Users/jnoack/.platformio/lib/Time_ID44",
"C:/Users/jnoack/.platformio/lib/RTC_ID274/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/tools/sdk/libc/xtensa-lx106-elf/include",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
@ -68,21 +82,18 @@
"C:/Users/jnoack/.platformio/lib/Adafruit NeoPixel_ID28",
"C:/Users/jnoack/.platformio/lib/DS3231_ID1379",
"C:/Users/jnoack/.platformio/lib/ESP32Servo_ID4744/src",
"C:/Users/jnoack/.platformio/lib/RTC_ID274/src",
"C:/Users/jnoack/.platformio/lib/LibXSVF_ID6585/src",
"C:/Users/jnoack/.platformio/lib/RemoteDebug_ID1266/src",
"C:/Users/jnoack/.platformio/lib/SoftwareWire_ID832",
"C:/Users/jnoack/.platformio/lib/TimerOne_ID131",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266LLMNR",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266NetBIOS",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SdFat/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS/src",
@ -96,18 +107,17 @@
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker/src",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
"C:/Users/jnoack/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
"C:/Users/jnoack/.platformio/packages/tool-unity",
""
]
},
"defines": [
"PLATFORMIO=40201",
"PLATFORMIO=40303",
"ESP8266",
"ARDUINO_ARCH_ESP8266",
"ARDUINO_ESP8266_WEMOS_D1MINIPRO",
"F_CPU=80000000L",
"F_CPU=160000000L",
"__ets__",
"ICACHE_FLASH",
"ARDUINO=10805",

View File

@ -7,6 +7,14 @@ class led_clock : protected elements
{
private:
static const unsigned int PIN_BUZZER = D0;
static const int TICK_FREQ = 40;
static const int TICK_DLY = 13;
static const int TOCK_FREQ = 15;
static const int TOCK_DLY = 35;
bool tick_not_tock = true;
static const uint8_t PIN_PIXELS = D3; //6;
static const uint16_t NUM_RING_PIXELS = 180U;
@ -22,39 +30,68 @@ private:
const uint16_t NUM_NUMBERS_PIXELS = NUM_NUMBER_PIXELS[0] + NUM_NUMBER_PIXELS[1] + NUM_NUMBER_PIXELS[2] + NUM_NUMBER_PIXELS[3] + NUM_NUMBER_PIXELS[4] + NUM_NUMBER_PIXELS[5] + NUM_NUMBER_PIXELS[6] + NUM_NUMBER_PIXELS[7] + NUM_NUMBER_PIXELS[8] + NUM_NUMBER_PIXELS[9] + NUM_NUMBER_PIXELS[10] + NUM_NUMBER_PIXELS[11];
const uint16_t NUM_ALL_PIXELS = NUM_RING_PIXELS + NUM_POINTERS_PIXELS + NUM_NUMBERS_PIXELS;
const hue_color COLOR_SECS = {HUE_GREEN,255,128}; // green
const hue_color COLOR_HOURS = {HUE_RED,255,128}; // red
const hue_color COLOR_MINS = {HUE_BLUE,255,128}; // blue
const hue_color COLOR_NUMS = {0,0,255}; // white
enum color_type {COL_SECOND = 0, COL_MINUTE, COL_HOUR, COL_NUM, COL_LAST};
hue_color color[COL_LAST] = {COLOR_SECS, COLOR_MINS, COLOR_HOURS, COLOR_NUMS};
static const uint16_t NUM_INNER_RINGS = NUM_POINTER_PIXELS;
static const uint16_t NUM_INNER_RING_PIXELS = NUM_POINTERS;
unsigned int prv_second = 0 ;
unsigned int prv_millis = 0 ;
const hue_color COLOR_SECS = {HUE_GREEN,255,128};
const hue_color COLOR_HOURS = {0,0,128};
const hue_color COLOR_MINS = {HUE_BLUE,255,128};
const hue_color COLOR_NUMS = {0,0,255};
const hue_color COLOR_SECS_NOSYNC = {HUE_RED,255,128};
const hue_color COLOR_SECS_NOWIFI = {HUE_ORANGE,255,128};
const hue_color COLOR_NOWIFI = {HUE_RED,255,128};
const hue_color COLOR_WIFI = {HUE_GREEN,255,128};
const hue_color COLOR_OFFHOURS = {HUE_GREEN,255,64};
const hue_color COLOR_OFFMINS = {HUE_RED,255,128};
const hue_color COLOR_ACTMIN = {0,0,128};
enum color_type {COL_SECOND = 0, COL_SECOND_NOWIFI, COL_SECONDS_NOSYNC, COL_MINUTE, COL_HOUR, COL_NUM, COL_WIFI, COL_NOWIFI, COL_OFFHOURS, COL_OFFMINS, COL_ACTMIN, COL_LAST};
hue_color color[COL_LAST] = {COLOR_SECS, COLOR_SECS_NOWIFI , COLOR_SECS_NOSYNC , COLOR_MINS, COLOR_HOURS, COLOR_NUMS, COLOR_WIFI, COLOR_NOWIFI, COLOR_OFFHOURS, COLOR_OFFMINS, COLOR_ACTMIN};
CRGB * pixels;
elements number[NUM_NUMBERS];
elements pointer[NUM_POINTERS];
elements ringsecs[NUM_SECONDS];
elements ringmins[NUM_MINUTES];
elements actmins[NUM_MINUTES];
unsigned int pixels_test;
bool timeissynced = false;
bool isconnected = false;
color_type colorsecs = COL_SECOND;
void init_ringmins(void);
void init_ringsecs(void);
void init_numbers(void);
void init_pointers(void);
void init_test_pixel(void);
uint8_t last_value( uint8_t value, uint8_t minvalue, uint8_t maxvalue);
uint8_t next_value( uint8_t value, uint8_t minvalue, uint8_t maxvalue);
void show_second( uint8_t second);
void show_hour( uint8_t hour, uint8_t minute);
void show_minute( uint8_t minute );
void animate_new_minute( uint8_t minute , uint8_t second, uint8_t hour);
void animate_new_hour( uint8_t minute , uint8_t second, uint8_t hour);
void draw_minute_ring(uint8_t minnr);
void draw_unused_minute_ring(uint8_t minnr);
void tick_tock();
public:
enum test_type {TEST_NONE=0, TEST_PIXELS=1, TEST_SECS=2, TEST_MINS=4,TEST_PTRS=8,TEST_NUMS=16, TEST_ALL = 31};
void init(unsigned test_at_start = TEST_NONE);
void init(hue_color color_secs, hue_color color_mins, hue_color color_hours, hue_color color_nums, unsigned test_at_start);
void showtime(uint8_t hour, uint8_t minute, uint8_t second);
void showtime(uint8_t hour, uint8_t minute, uint8_t second, bool time_synced, bool is_connected);
void init_show_ring_wifi();
void show_ring_wifi( bool wifi);
};

View File

@ -0,0 +1,55 @@
#include <Wire.h>
#include <RtcDS3231.h>
#include <stdlib.h>
#include <ESP8266HTTPClient.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <Timezone.h>
static const String TIMEURL = "http://api.itsblue.de/time.php";
static const String MONTH_STR[12] = {"Jan","Feb","Mar","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"};
class led_clock_time
{
private:
RtcDS3231<TwoWire> * Rtc;
bool timedebug = 0;
bool rtc_ready = false;
uint32_t int_second = 0;
uint32_t int_minute = 0;
uint32_t int_hour = 0;
uint16_t int_year = 0;
bool timeisvalid = false;
uint32_t lastwrittentortc = 0;
static const uint32_t WAITBEFOREWRITERTCAGAIN_MS = 100;
static const uint32_t NTP_SYNC_CYCLE_SECS = 600;
static const uint16_t NTP_SYNC_MAX_TRIES = 10;
time_t timelastsync_ntptime = 0; /// last time got form the sync time server
time_t epoch = 0; /// epoch time got from the server - or adjusted with millis()
time_t timelastsync = 0; /// last time sync in processor time (millis())
bool timesynced = false; /// set to true if time was synced
time_t timestamp = 0;
HTTPClient * http;
WiFiManager wifiManager;
long captivepotal_timeout = 60; /// in seconds
bool isconnected = false;
bool wasalreadyconnected = false;
bool rtc_init();
bool rtc_settime(RtcDateTime newtime);
bool rtc_gettime(void);
void dbg_gettime(void);
bool connectWifi();
bool syncTime();
public:
void init(bool debug = false);
bool gettime(uint32_t *hour, uint32_t *minute, uint32_t *second);
bool isConnectedToWifi();
bool isTimenSynced();
};

View File

@ -25,6 +25,8 @@ public:
uint8_t element_number_pixels, elements_fraction;
hue_color elements_huecolor;
int32_t element_current_pixel = -1;
bool element_outside2inside = false;
CRGB *element_pixels;
@ -32,6 +34,8 @@ public:
void test(uint8_t huecolor, uint8_t saturation = SATURATION, uint8_t brightness = BRIGHTNESS, bool all_at_once = false);
void test(hue_color huecolor, bool all_at_once = false);
void test( bool all_at_once = false);
void run_init();
void run(hue_color huecolor, bool to_outside);
void fill(uint8_t huecolor, uint8_t saturation = SATURATION, uint8_t brightness = BRIGHTNESS);
void fill(hue_color huecolor);
void fill(void);

View File

@ -14,3 +14,4 @@ framework = arduino
platform_packages =
platform = espressif8266
monitor_speed = 115200
board_build.f_cpu = 160000000L

View File

@ -3,16 +3,11 @@
void led_clock::init( unsigned test_at_start)
{
init(COLOR_SECS , COLOR_MINS , COLOR_HOURS , COLOR_NUMS, test_at_start);
}
void led_clock::init(hue_color color_secs, hue_color color_mins, hue_color color_hours, hue_color color_nums, unsigned test_at_start)
{
pinMode(PIN_BUZZER, OUTPUT);
digitalWrite(PIN_BUZZER,HIGH);
pixels_test = test_at_start;
color[COL_SECOND] = color_secs;
color[COL_MINUTE] = color_mins;
color[COL_HOUR] = color_hours;
color[COL_NUM] = color_nums;
init_test_pixel();
init_ringsecs();
@ -29,10 +24,17 @@ void led_clock::init_ringmins() {
unsigned int current_first_led = 1;
for(uint8_t num = 0; num < NUM_MINUTES; num++)
{
ringmins[num].init(pixels, current_first_led, NUM_RING_MIN_PIXELS, color[COL_MINUTE]);
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;
}
}
@ -43,7 +45,7 @@ void led_clock::init_ringsecs() {
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[COL_SECOND]);
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);
@ -66,6 +68,29 @@ void led_clock::init_numbers() {
}
}
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)
@ -76,7 +101,7 @@ void led_clock::init_pointers() {
{
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_MINUTE],is_insideoutside);
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();
@ -88,7 +113,7 @@ void led_clock::init_test_pixel()
{
pixels = (CRGB*) malloc(NUM_ALL_PIXELS * sizeof(CRGB) );
FastLED.clearData();
FastLED.addLeds<WS2812B, PIN_PIXELS, RGB>(pixels, NUM_ALL_PIXELS); // GRB ordering is typical
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)
@ -108,45 +133,64 @@ void led_clock::init_test_pixel()
}
}
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 < minute; minnr++)
for(uint8_t minnr = 0; minnr < NUM_MINUTES; minnr++)
{
if(minnr % 5 == 0)
{
ringmins[minnr].fill(ringmins[minnr].elements_huecolor.hue, ringmins[minnr].elements_huecolor.sat, ringmins[minnr].elements_huecolor.bright/2);
}
if(minnr < minute)
draw_minute_ring(minnr);
else
{
ringmins[minnr].fill(ringmins[minnr].elements_huecolor.hue, ringmins[minnr].elements_huecolor.sat, ringmins[minnr].elements_huecolor.bright/8);
}
draw_unused_minute_ring(minnr);
}
ringmins[minute].fill();
actmins[minute].fill(COLOR_ACTMIN);
}
void led_clock::animate_new_minute( uint8_t minute , uint8_t second, uint8_t hour)
{
uint8_t old_minute = minute==0?NUM_MINUTES-1:minute-1;
uint8_t old_minute = last_value(minute, 0, NUM_MINUTES);
FastLED.clearData();
show_minute( old_minute );
show_hour( hour, old_minute);
ringsecs[second].fill();
show_second(second);
show();
for(uint8_t minnr = 1; minnr < minute; minnr++)
{
ringmins[minnr].fill();
if(minnr > 1){
if(minnr-1 % 5 != 0)
ringmins[minnr-1].fill(ringmins[minnr-1].elements_huecolor.hue, ringmins[minnr-1].elements_huecolor.sat, ringmins[minnr-1].elements_huecolor.bright/8);
else
ringmins[minnr-1].fill(ringmins[minnr-1].elements_huecolor.hue, ringmins[minnr-1].elements_huecolor.sat, ringmins[minnr-1].elements_huecolor.bright/2);
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;
@ -177,6 +221,14 @@ void led_clock::show_hour( uint8_t hour, uint8_t minute)
//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);
@ -184,8 +236,56 @@ void led_clock::show_hour( uint8_t hour, uint8_t minute)
}
void led_clock::showtime(uint8_t hour, uint8_t minute, uint8_t second)
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)
@ -202,9 +302,11 @@ void led_clock::showtime(uint8_t hour, uint8_t minute, uint8_t second)
{
FastLED.clearData();
show_minute( minute );
ringsecs[second].fill();
show_second( second);
actmins[minute].fill(COLOR_ACTMIN);
show_hour( hour, minute);
show();
}
}
}

View File

@ -0,0 +1,292 @@
#include "led_clock_time.hpp"
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
Timezone CE(CEST, CET);
void led_clock_time::init(bool debug)
{
Serial.println();
http = new HTTPClient();
timedebug = debug;
Serial.println("Try to connect to wifi first time ... maybe captive portal will b started ...");
connectWifi(); // isconnected should be true after here if not in debug mode ...
Serial.printf("Connection status : %s\n", isconnected == true?"connected":"not connected");
wasalreadyconnected = isconnected;
rtc_ready = rtc_init(); // at least timeisvalid should be true after here ...
if(timeisvalid == false)
{
if(isconnected == false)
{
//nothing to show ... keep waiting forever in the captive portal ...
captivepotal_timeout = 0;
Serial.println("RTC time is not valid and there is no connection to Wifi - will go into cpative portal mode and wait for valid config. Please connect via Wifi to 'BlueLedclock'.");
connectWifi();
}
}
}
bool led_clock_time::rtc_init()
{
bool rc = true;
Rtc = new RtcDS3231<TwoWire>(Wire);
Rtc->Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Serial.println();
Serial.println("RTC init ...");
if (!Rtc->IsDateTimeValid())
{
if (Rtc->LastError() != 0)
{
Serial.print("RTC communications error = ");
Serial.println(Rtc->LastError());
return(false);
}
else
{
Serial.println("RTC lost confidence in the DateTime!");
if(false == rtc_settime(compiled))
{
return(false);
}
}
}
if (!Rtc->GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc->SetIsRunning(true);
}
Serial.println("Check RTC time - set to accurate time if needed and possible.");
if(false == syncTime())
{
RtcDateTime now = Rtc->GetDateTime();
if (now.TotalSeconds() < compiled.TotalSeconds())
{
rc = rtc_settime(compiled);
}
}
Rtc->Enable32kHzPin(false);
Rtc->SetSquareWavePin(DS3231SquareWavePin_ModeNone);
rc = rtc_gettime();
Serial.printf("RTC time is: %d:%d:%d . Valid time bit is set to '%s'\n", int_hour, int_minute, int_second, timeisvalid==true?"true":"false");
if(rc == false)
{
Serial.println("RTC setup finished with a failure! Time couldn't set to actual value!");
}
else
{
Serial.println("RTC setup finished with success!");
}
return(rc);
}
bool led_clock_time::rtc_settime(RtcDateTime newtime)
{
bool rc = false;
if((millis() - lastwrittentortc > WAITBEFOREWRITERTCAGAIN_MS) || (lastwrittentortc ==0))
{
lastwrittentortc = millis();
//Serial.println("Try to write time to RTC.");
Rtc->SetDateTime(newtime);
RtcDateTime gettime = Rtc->GetDateTime();
if (newtime.TotalSeconds() <= gettime.TotalSeconds())
{
rc = true;
}
else
{
Serial.printf("Current RTC read time (%d) is smaller than the provided time (%d) that was written before to RTC. This is not correct!", gettime.TotalSeconds(), newtime.TotalSeconds());
}
}
else
{
rc = true;
}
if(rc == false)
{
Serial.println("RTC set time finished with a failure! Time couldn't set to actual value!");
timeisvalid = false;
}
else
{
timeisvalid = true;
}
return(rc);
}
bool led_clock_time::gettime(uint32_t *hour, uint32_t *minute, uint32_t *second)
{
if(0 == timedebug)
{
syncTime();
rtc_gettime();
}
else
{
dbg_gettime();
}
*hour = int_hour;
*second = int_second;
*minute = int_minute;
return(timeisvalid);
}
bool led_clock_time::rtc_gettime(void)
{
bool rc = true;
RtcDateTime now = Rtc->GetDateTime();
int_second = now.Second();
int_minute = now.Minute();
int_hour = now.Hour();
if((int_hour == 0) && (int_minute == 0) && (int_second == 0) && (now.Year() == 2000))
{
rc = false;
timeisvalid = false;
Serial.printf("RTC is stucked at %02d:%02d:%02d %02d.%02d.%04d this is a failure! Time couldn't set to actual value!\n", int_hour, int_minute, int_second, now.Day(), now.Month(), now.Year());
}
return(rc);
}
void led_clock_time::dbg_gettime(void)
{
timeisvalid = 0;
timesynced = false;
int_second = int_second + 1;
if(int_second > 59)
{
int_second = 0;
int_minute++;
if(int_minute > 59)
{
int_minute = 0;
int_hour++;
if(int_hour > 11)
{
int_hour = 0;
}
}
}
}
bool led_clock_time::connectWifi()
{
if(timedebug == false)
{
if ((WiFi.status() != WL_CONNECTED))
{
isconnected = false;
Serial.printf("Looking for Wifi: captive portal is open for about %ld seconds.\n",captivepotal_timeout );
wifiManager.setDebugOutput(false);
//sets timeout until configuration portal gets turned off
wifiManager.setTimeout(captivepotal_timeout); //in seconds
captivepotal_timeout = 30;
//and goes into a blocking loop awaiting configuration
if(false == wifiManager.autoConnect("BlueLedClock")) {
Serial.println("Failed to connect to WiFi and hit timeout ... (reset clock to retry). ");
}
else
{
Serial.println("Connect to WiFi. ");
isconnected = true;
}
}
else
{
isconnected = true;
}
}
else
{
isconnected = false;
}
return isconnected;
}
bool led_clock_time::isConnectedToWifi()
{
if ((WiFi.status() != WL_CONNECTED))
{
if(wasalreadyconnected == true)
{
connectWifi();
}
else
{
isconnected = false;
}
}
else{
isconnected = true;
}
return isconnected;
}
bool led_clock_time::isTimenSynced()
{
return timesynced;
}
bool led_clock_time::syncTime()
{
TimeChangeRule *tcr; // pointer to the time change rule, use to get the TZ abbrev
int httpCode = -1;
if((timelastsync == 0) || (((millis()/1000)- timelastsync) > NTP_SYNC_CYCLE_SECS))
{
if(true == isConnectedToWifi())
{
http->begin(TIMEURL);
// start connection and send HTTP header
httpCode = http->GET();
// httpCode will be negative on error
if (httpCode == HTTP_CODE_OK) {
String epoch_str = http->getString();
epoch = epoch_str.toInt();
epoch = CE.toLocal(epoch, &tcr);
if(epoch > 0)
{
struct tm * timeinfo = localtime(&epoch);
char timestr[9] = "";
char datestr[12] = "";
sprintf(timestr, "%02d:%02d:%02d",timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
sprintf(datestr, "%s %d %d", MONTH_STR[timeinfo->tm_mon].c_str(), timeinfo->tm_mday, 1900+timeinfo->tm_year);
RtcDateTime rtctime = RtcDateTime(datestr, timestr);
if(rtc_settime(rtctime) == true)
{
timelastsync = millis()/1000;
//Serial.printf("Synced time: %s %s\n", datestr, timestr );
timesynced = true;
}
}
}
}
}
if( HTTP_CODE_OK != httpCode )
{
if(((millis()/1000)- timelastsync) > (NTP_SYNC_MAX_TRIES * NTP_SYNC_CYCLE_SECS))
timesynced = false;
}
return(timesynced);
}

View File

@ -1,6 +1,6 @@
#include "led_clockelements.hpp"
void elements::init(CRGB *pixels, unsigned int first_led, unsigned int number_leds, hue_color huecolor, bool outside2inside)
void elements::init(CRGB *pixels, unsigned int first_led, unsigned int number_leds, hue_color huecolor, bool outside2inside)
{
element_pixels = pixels;
element_first_pixel = first_led;
@ -54,6 +54,53 @@ void elements::test(uint8_t huecolor, uint8_t saturation, uint8_t brightness, bo
show();
}
void elements::run_init(){
element_current_pixel = -1;
}
void elements::run(hue_color huecolor, bool to_outside){
if(element_outside2inside == true)
{
if(to_outside == true)
{
if(element_current_pixel == -1)
{
element_current_pixel = element_first_pixel;
}
element_current_pixel = element_current_pixel == element_first_pixel?element_last_pixel:element_current_pixel-1;
}
else
{
if(element_current_pixel == -1)
{
element_current_pixel = element_last_pixel;
}
element_current_pixel = element_current_pixel == element_last_pixel?element_first_pixel:element_current_pixel+1;
}
}
else
{
if(to_outside == false)
{
if(element_current_pixel == -1)
{
element_current_pixel = element_first_pixel;
}
element_current_pixel = element_current_pixel == element_first_pixel?element_last_pixel:element_current_pixel-1;
}
else
{
if(element_current_pixel == -1)
{
element_current_pixel = element_last_pixel;
}
element_current_pixel = element_current_pixel == element_last_pixel?element_first_pixel:element_current_pixel+1;
}
}
element_pixels[element_current_pixel] = CHSV(huecolor.hue,huecolor.sat, huecolor.bright);
}
void elements::fill(void)
{
fill(elements_huecolor.hue, elements_huecolor.sat, elements_huecolor.bright);
@ -87,7 +134,9 @@ void elements::ffill(unsigned int fraction, unsigned int fullvalue, uint8_t huec
unsigned int value_of_pixel = fullvalue / element_number_pixels; //this is what part one pixel of the element represents of the full value
unsigned int fullpixels = fraction / value_of_pixel; //the number of pixels that represents the fraction (part of the fullvalue)
unsigned int partialpixel = fraction % value_of_pixel; //the left over of the division of fraction and value of one pixel
uint8_t partial_brightness = (uint8_t)((brightness/element_number_pixels)*partialpixel);
uint32_t temp_brightness = brightness * partialpixel;
temp_brightness = temp_brightness / value_of_pixel;
uint8_t partial_brightness = (uint8_t)temp_brightness;
unsigned int current_pixel = 0;
for(unsigned int num = 0; num < fullpixels; num++)

View File

@ -1,152 +1,34 @@
#define TIMEDBG false
//#include <Arduino.h>
//#include <SoftwareWire.h> // must be included here so that Arduino library object file references work
//#include <RtcDS3231.h>
#include "led_clock.hpp"
#include "led_clock_time.hpp"
led_clock ledclock;
//SoftwareWire myWire(A4, A5);
//RtcDS3231<SoftwareWire> Rtc(myWire);
const unsigned int PIN_BUZZER = 9;
const int TICK_FREQ = 40;
const int TICK_DLY = 13;
const int TOCK_FREQ = 15;
const int TOCK_DLY = 35;
bool tick_not_tock = true;
const hue_color COLOR_SECS = {HUE_GREEN,255,128}; // green
const hue_color COLOR_HOURS = {HUE_RED,255,128}; // red
const hue_color COLOR_MINS = {HUE_BLUE,255,128}; // blue
const hue_color COLOR_NUMS = {0,0,255}; // white
/*
void init_rtc()
{
Rtc.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Serial.println();
if (!Rtc.IsDateTimeValid())
{
if (Rtc.LastError() != 0)
{
Serial.print("RTC communications error = ");
Serial.println(Rtc.LastError());
}
else
{
Serial.println("RTC lost confidence in the DateTime!");
Rtc.SetDateTime(compiled);
}
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
RtcDateTime now = Rtc.GetDateTime();
if (now < compiled)
{
Serial.println("RTC is older than compile time! (Updating DateTime)");
Rtc.SetDateTime(compiled);
}
else if (now > compiled)
{
Serial.println("RTC is newer than compile time. (this is expected)");
}
else if (now == compiled)
{
Serial.println("RTC is the same as compile time! (not expected but all is fine)");
}
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
}
*/
/*
void tick_tock()
{
if(tick_not_tock == true)
{tone(PIN_BUZZER, TICK_FREQ, TICK_DLY);}
else
{ tone(PIN_BUZZER, TOCK_FREQ, TOCK_DLY);}
tick_not_tock = !tick_not_tock;
}
*/
led_clock_time ledclocktime;
void setup() {
ESP.wdtEnable(5000);
Serial.begin(115200);
Serial.println("Lets tick ... tock ... tick ... tock ... ");
ledclock.init( ledclock.TEST_NONE );
ledclock.init_show_ring_wifi();
ledclock.show_ring_wifi(false);
ledclocktime.init(TIMEDBG);
ledclock.init_show_ring_wifi();
ledclock.show_ring_wifi(ledclocktime.isConnectedToWifi());
ledclock.init(COLOR_SECS, COLOR_MINS, COLOR_HOURS, COLOR_NUMS, ledclock.TEST_NONE );
//init_rtc();
}
unsigned int hour = 0;
unsigned int minute = 0;
unsigned int second = 0;
uint32_t inf_hour = 0;
uint32_t inf_minute = 0;
uint32_t inf_second = 0;
void loop() {
/*
RtcDateTime now = Rtc.GetDateTime();
if(now.Second() != second)
{
pixels.clear();
//tick_tock();
hour = now.Hour();
minute = now.Minute();
second = now.Second();
pointer[hour].fill(color_pointers_hour);
//pointer[hour].ffill(color_pointers_hour, minute/(60/NUM_POINTER_PIXELS));
pixels.show();
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
}
*/
while (0 == 0)
{
second = second + 1;
if(second > 59)
{
second = 0;
minute++;
if(minute > 59)
{
minute = 0;
hour++;
if(hour > 11)
{
hour = 0;
}
}
}
ledclock.showtime(hour,minute,second);
//Serial.printf("%02d : %02d : %02d \n" , hour, minute, second);
}
ledclocktime.gettime(&inf_hour,&inf_minute,&inf_second);
ledclock.showtime(inf_hour,inf_minute,inf_second, ledclocktime.isTimenSynced(), ledclocktime.isConnectedToWifi());
}