diff --git a/60LED_WS2812B_NTP_Clock.ino b/60LED_WS2812B_NTP_Clock.ino
index 374e9db..4cc70bf 100644
--- a/60LED_WS2812B_NTP_Clock.ino
+++ b/60LED_WS2812B_NTP_Clock.ino
@@ -61,6 +61,12 @@ RgbwColor darkred(HtmlColor(0x800000));
RgbwColor darkgreen(HtmlColor(0x006400));
RgbwColor lightgreen(HtmlColor(0x90ee90));
RgbwColor temp;
+RgbwColor secondsColor = white;
+RgbwColor minuteColor = darkred;
+RgbwColor hourColor = gold;
+RgbwColor highnoonColor = white12;
+RgbwColor backlightColor = white;
+RgbwColor hourMarkingColor = whiter;
#else
#define MINIMAL_BRIGHTNESS 20
#define LDR_SCALE 16
@@ -82,6 +88,12 @@ RgbColor darkred(HtmlColor(0x800000));
RgbColor darkgreen(HtmlColor(0x006400));
RgbColor lightgreen(HtmlColor(0x90ee90));
RgbColor temp;
+RgbColor secondsColor = white;
+RgbColor minuteColor = darkred;
+RgbColor hourColor = gold;
+RgbColor highnoonColor = white12;
+RgbColor backlightColor = white;
+RgbColor hourMarkingColor = whiter;
#endif
//NTP handler
@@ -100,45 +112,66 @@ volatile int MAX_BRIGHTNESS = 200;
// WebPortal
const char thingName[] = "NTP-Clock-RGBLED";
const char wifiInitialApPassword[] = "12345678";
-//ToDo add internal LED and check visibility
#define STRING_LEN 63
#define NUMBER_LEN 4
+// -- Maximal length the input-range attributes can have.
+#define COLOR_ATTR_LENGTH 60
// -- Configuration specific key. The value should be modified if config structure was changed.
-#define CONFIG_VERSION "V1.0.0"
+#define CONFIG_VERSION "V1.1.2"
-// -- Javascript block will be added to the header. 🔒 🔓
const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\n\
-document.addEventListener('DOMContentLoaded', function(event) {\n\
- let elements = document.querySelectorAll('input[type=\"password\"]');\n\
- for (let p of elements) {\n\
- let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '83%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\
- btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\
- };\n\
-});\n";
-//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " ";
-DNSServer dnsServer;
-WebServer server(80);
-#ifdef ESP8266
-ESP8266HTTPUpdateServer httpUpdater;
-#elif defined(ESP32)
-HTTPUpdateServer httpUpdater;
-#endif
+ function colorCh(id)\n\
+ {\n\
+ var x=document.getElementById(id);\n\
+ var s=document.getElementById(id + 'Val');\n\
+ s.innerHTML = x.value;\n\
+ }\n\n\
+ document.addEventListener('DOMContentLoaded', function(event) {\n\
+ let elements = document.querySelectorAll('input[type=\"password\"]');\n\
+ for (let p of elements) {\n\
+ let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '80%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\
+ btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\
+ };\n\
+ });\n";
+const char IOTWEBCONF_HTML_FORM_COLOR_PARAM[] PROGMEM =
+ "
\n";
-char ntpServerParamValue[STRING_LEN];
-char maxBrightnessParamValue[NUMBER_LEN];
-char singleSecondParamValue[STRING_LEN];
-char allDotsOnParamValue[STRING_LEN];
-char followingHourParamValue[STRING_LEN];
+// -- Our custom class declaration. You should move it to a .h fine in your project.
+class ColorWithValueParameter : public iotwebconf::NumberParameter
+{
+ public:
+ ColorWithValueParameter(
+ const char* label, const char* id, char* valueBuffer, int length,
+ const char* defaultValue
+ ) : iotwebconf::NumberParameter(
+ label, id, valueBuffer, length, defaultValue)
+ {
+ snprintf(
+ this->_colorAttr, COLOR_ATTR_LENGTH,
+ "oninput='colorCh(this.id)'");
-IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
-IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings");
-IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org");
-IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings");
-IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'");
-IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true);
-IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true);
-IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true);
+ this->customHtml = this->_colorAttr;
+ };
+ protected:
+ // Overrides
+ virtual String renderHtml(
+ bool dataArrived, bool hasValueFromPost, String valueFromPost) override
+ {
+ return TextParameter::renderHtml("color", hasValueFromPost, valueFromPost);
+ };
+ virtual String getHtmlTemplate()
+ {
+ return FPSTR(IOTWEBCONF_HTML_FORM_COLOR_PARAM);
+ };
+ private:
+ char _colorAttr[COLOR_ATTR_LENGTH];
+};
+
+// -- We need to create our custom HtmlFormatProvider to add some javasripts.
class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider
{
protected:
@@ -157,12 +190,57 @@ class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider
}
*/
};
+// -- Javascript block will be added to the header.
+/*
+ const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\n\
+ document.addEventListener('DOMContentLoaded', function(event) {\n\
+ let elements = document.querySelectorAll('input[type=\"password\"]');\n\
+ for (let p of elements) {\n\
+ let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '83%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\
+ btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\
+ };\n\
+ });\n";
+*/
+//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " ";
+DNSServer dnsServer;
+WebServer server(80);
+#ifdef ESP8266
+ESP8266HTTPUpdateServer httpUpdater;
+#elif defined(ESP32)
+HTTPUpdateServer httpUpdater;
+#endif
+
+char ntpServerParamValue[STRING_LEN];
+char maxBrightnessParamValue[NUMBER_LEN];
+char singleSecondParamValue[STRING_LEN];
+char allDotsOnParamValue[STRING_LEN];
+char followingHourParamValue[STRING_LEN];
+char hourColorParamValue[COLOR_ATTR_LENGTH];
+char minuteColorParamValue[COLOR_ATTR_LENGTH];
+char secondsColorParamValue[COLOR_ATTR_LENGTH];
+char highnoonColorParamValue[COLOR_ATTR_LENGTH];
+char backlightColorParamValue[COLOR_ATTR_LENGTH];
+char hourMarkingColorParamValue[COLOR_ATTR_LENGTH];
+
+IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
+IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings");
+IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org");
+IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings");
+IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'");
+IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true);
+IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true);
+IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true);
+ColorWithValueParameter hourColorParam = ColorWithValueParameter("Stundenfarbe", "hourColorParam", hourColorParamValue, COLOR_ATTR_LENGTH, "#FFD700");
+ColorWithValueParameter minuteColorParam = ColorWithValueParameter("Minutenfarbe", "minuteColorParam", minuteColorParamValue, COLOR_ATTR_LENGTH, "#800000");
+ColorWithValueParameter secondsColorParam = ColorWithValueParameter("Sekundenfarbe", "secondsColorParam", secondsColorParamValue, COLOR_ATTR_LENGTH, "#ffffff");
+ColorWithValueParameter highnoonColorParam = ColorWithValueParameter("12Uhr Farbe", "highnoonColorParam", highnoonColorParamValue, COLOR_ATTR_LENGTH, "#1E2823");
+ColorWithValueParameter backlightColorParam = ColorWithValueParameter("Hintergrundfarbe", "backlightColorParam", backlightColorParamValue, COLOR_ATTR_LENGTH, "#1E2823");
+ColorWithValueParameter hourMarkingColorParam = ColorWithValueParameter("Stundenmarkierung", "hourMarkingColorParam", hourMarkingColorParamValue, COLOR_ATTR_LENGTH, "#787878");
+
+
// -- An instance must be created from the class defined above.
CustomHtmlFormatProvider customHtmlFormatProvider;
-//ToDo color Picker Second, 12Clock, Minute, Hour
-
-
Task bootAnim(200, TASK_FOREVER, &bootAnimCallback);
Task clockTick(1000, TASK_FOREVER, &clockTickCallback);
Task ledRefresh(200, TASK_FOREVER, &ledRefreshCallback);
@@ -194,7 +272,7 @@ void iotWebConfHandleRoot() {
// -- Captive portal request were already served.
return;
}
-
+ char sTemp[12];
String s = "";
s += "";
//s += CUSTOMHTML_BODY_INNER;
@@ -204,7 +282,7 @@ void iotWebConfHandleRoot() {
s += "";
s += "Current Time: | ";
s += printLocalTime();
- s += " |
|
NTP Server: | ";
+ s += " |
|
NTP Server: | ";
s += ntpServerParamValue;
s += " |
|
Current Brightness value: | ";
s += String(strip.GetBrightness());
@@ -216,7 +294,37 @@ void iotWebConfHandleRoot() {
s += (allDotsOn ? "Yes" : "No");
s += " |
Following Hour: | ";
s += (followingHour ? "Yes" : "No");
- s += " | |
";
+ s += "";
+ s += " |
High noon: | | |
";
+ s += "Hour color: | | |
";
+ s += "Minute color: | | |
";
+ s += "Seconds Color: | | |
";
+ s += "Backlight: | | |
";
+ s += "Hour Marking: | | |
";
s += "";
s += "Go to configure page to change values.";
s += "\n";
@@ -234,30 +342,23 @@ void iotWebConfConfigSaved()
//Serial.println(allDotsOnParam.isChecked() ? "true" : "false");
followingHour = followingHourParam.isChecked() ? true : false;
//Serial.println(followingHourParam.isChecked() ? "true" : "false");
+ HtmlColor htmlTemp;
+ htmlTemp.Parse( highnoonColorParamValue );
+ highnoonColor = htmlTemp ;
+ htmlTemp.Parse( hourColorParamValue );
+ hourColor = htmlTemp;
+ htmlTemp.Parse( minuteColorParamValue );
+ minuteColor = htmlTemp;
+ htmlTemp.Parse( secondsColorParamValue );
+ secondsColor = htmlTemp;
+ htmlTemp.Parse( backlightColorParamValue );
+ backlightColor = htmlTemp;
+ htmlTemp.Parse( hourMarkingColorParamValue);
+ hourMarkingColor = htmlTemp;
+
Serial.println("Configuration was updated.");
}
-/*
-bool iotWebConfFormValidator(iotwebconf::WebRequestWrapper* webRequestWrapper)
-{
-
- Serial.println("Validating form.");
- boolean valid = true;
-
- int l = server.arg(ntpServerParam.getId()).length();
- if (l < 3)
- {
- ntpServerParam.errorMessage = "Please provide at least 3 characters for this test!";
- valid = false;
- }
- int b = atoi(maxBrightnessParamValue);
- if (b < MINIMAL_BRIGHTNESS || b > 254)
- {
- valid = false;
- }
- return valid;
-}
-*/
void iotWebConf_Setup() {
@@ -267,6 +368,12 @@ void iotWebConf_Setup() {
ledGroup.addItem(&singleSecondParam);
ledGroup.addItem(&allDotsOnParam);
ledGroup.addItem(&followingHourParam);
+ ledGroup.addItem(&hourColorParam);
+ ledGroup.addItem(&minuteColorParam);
+ ledGroup.addItem(&secondsColorParam);
+ ledGroup.addItem(&highnoonColorParam);
+ ledGroup.addItem(&backlightColorParam);
+ ledGroup.addItem(&hourMarkingColorParam);
iotWebConf.addParameterGroup(&timeGroup);
iotWebConf.addParameterGroup(&ledGroup);
@@ -332,6 +439,7 @@ void setup() {
Serial.printf("Lighten up all LEDs: \t%s\n", allDotsOn ? "yes" : "no");
Serial.printf("Following Hour: \t%s\n\n", followingHour ? "yes" : "no");
+
strip.Begin();
strip.SetBrightness( MINIMAL_BRIGHTNESS );
strip.ClearTo(white);
@@ -359,25 +467,25 @@ void loop()
}
void ledRefreshCallback() {
- temp = allDotsOn ? white : black;
+ temp = allDotsOn ? backlightColor : black;
strip.ClearTo(temp);
//1 dot hour marking
for (int dot = 0; dot < NUM_LEDS; dot++) {
if (MOD(dot, 5) == 0) {
- strip.SetPixelColor(dot, whiter);
+ strip.SetPixelColor(dot, hourMarkingColor);
}
}
//3 dots hour
- strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), gold);
- strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), gold);
- strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), gold);
+ strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), hourColor);
+ strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), hourColor);
+ strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), hourColor);
- strip.SetPixelColor(0, white12); //define high noon
+ strip.SetPixelColor(0, highnoonColor); //define high noon
if (singleSecond) {
- strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : white));
+ strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : secondsColor));
}
- strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), darkred);
+ strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), minuteColor);
strip.Show();
}
diff --git a/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin b/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin
new file mode 100644
index 0000000..755e453
Binary files /dev/null and b/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin differ
diff --git a/README.md b/README.md
index 6570b99..9402053 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,12 @@ Ab sofort ist die Uhr unter einer neuen IP erreichbar, sodass dort weitere Einst
- Anzeige der einzelnen Sekunden
- Aufleuchten aller LEDs
- Folgende Stunde (wie auf einer analogen Uhr)
+ - Farbwahl der 12Uhr Markierung
+ - Farbwahl der aktuelle Stunde (3LED)
+ - Farbwahl der aktuellen Minute (1LED)
+ - Farbwahl der aktuellen Sekunde (1LED)
+ - Farbwahl der übrigen LEDs
+ - Farbwahl der restlichen Stunden (10 LEDs)
Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Möglichkeit für den Upload einer neuen Firmware sowie die aktuelle Firmwareversion wird angezeigt.
@@ -44,13 +50,15 @@ Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Mögl
- Show Seconds
- all Dots lighten up
- following Hour
+ - hourColor
+ - fminuteColor
+ - fsecondsColor
+ - fhighnoonColor
+ - fbacklightColor
+ - fhourMarkingColor
- firmware update link
- Firmware config version 'xxxx'
## ausstehende Verbesserungen
- - [ ] RGB Auswahl Sekunden
- - [ ] RGB Auswahl Minuten
- - [ ] RGB Auswahl Stunden
- - [ ] RGB Auswahl 12 Uhr
- [ ] flüssige Helligkeitsadaptierung