diff --git a/README.md b/README.md
index f7bc04c..80599fd 100644
--- a/README.md
+++ b/README.md
@@ -91,6 +91,8 @@ We've got some interesting branches in this repo inspired by user feedback. Thes

- [**static_background_pattern**](https://github.com/techniccontroller/wordclock_esp8266/tree/static_background_pattern): This branch allows to light up specific letters always during clock mode. E.G., to display some special words in another color.

+- [**frame_light**](https://github.com/techniccontroller/wordclock_esp8266/tree/frame_light): This branch allows to add an additional LEDs around the clock, as background/frame light it has the same color as the clock. Thanks to Sandro for the idea.
+
## Install needed Libraries
diff --git a/data/index.html b/data/index.html
index 4bce60d..15700fd 100644
--- a/data/index.html
+++ b/data/index.html
@@ -243,7 +243,7 @@
}
.show{
- height: 280px;
+ height: 320px;
transition: height 1s;
}
@@ -280,6 +280,10 @@
var nmStart = document.getElementById("nm_start");
var nmEnd = document.getElementById("nm_end");
var sld_brightness = document.getElementById("brightness");
+ var sld_nm_brightness = document.getElementById("nm_brightness");
var sld_colorshiftspeed = document.getElementById("colorshiftspeed");
var ckb_resetWifi = document.querySelector('input[id="ResetWifi"]');
var cmdstr = "./cmd?setting=";
@@ -616,6 +622,8 @@
WORDCLOCK 2.0
cmdstr += sld_brightness.value;
cmdstr += "-";
cmdstr += sld_colorshiftspeed.value;
+ cmdstr += "-";
+ cmdstr += sld_nm_brightness.value;
console.log(cmdstr);
sendCommand(cmdstr);
if(ckb_resetWifi.checked) {
diff --git a/ntp_client_plus.cpp b/ntp_client_plus.cpp
index 451bde3..6892941 100644
--- a/ntp_client_plus.cpp
+++ b/ntp_client_plus.cpp
@@ -128,11 +128,12 @@ void NTPClientPlus::setPoolServerName(const char *poolServerName)
* @return unsigned long seconds since 1. Jan. 1900
*/
unsigned long NTPClientPlus::getSecsSince1900() const
-{
- return this->_utcx * this->secondperminute + // UTC offset
- this->_summertime * this->secondperhour + // Summer time offset
- this->_secsSince1900 + // seconds returned by the NTP server
- ((millis() - this->_lastUpdate) / 1000); // Time since last update
+{
+ int64_t secsSince1900WithDST = static_cast(this->_secsSince1900) + // seconds returned by the NTP server
+ static_cast((millis() - this->_lastUpdate) / 1000) + // Time since last update
+ this->_summertime * this->secondperhour + // Summer time offset
+ (static_cast(this->_utcx) * this->secondperminute); // UTC offset
+ return static_cast(secsSince1900WithDST);
}
/**
@@ -199,15 +200,14 @@ int NTPClientPlus::getSeconds() const
String NTPClientPlus::getFormattedTime() const {
unsigned long rawTime = this->getEpochTime();
unsigned long hours = (rawTime % 86400L) / 3600;
- String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);
-
unsigned long minutes = (rawTime % 3600) / 60;
- String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);
-
unsigned long seconds = rawTime % 60;
- String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);
- return hoursStr + ":" + minuteStr + ":" + secondStr;
+ // Fester Puffer statt mehrfacher String-Verkettung, um Heap-Fragmentierung zu vermeiden
+ // Format identisch zu vorher: hh:mm:ss (jeweils 2-stellig, mit fuehrender Null)
+ char buffer[9]; // "hh:mm:ss" + '\0'
+ snprintf(buffer, sizeof(buffer), "%02lu:%02lu:%02lu", hours, minutes, seconds);
+ return String(buffer);
}
/**
@@ -314,6 +314,26 @@ unsigned int NTPClientPlus::getDayOfWeek()
return this->_dayOfWeek;
}
+/**
+ * @brief Getter for day of the month
+ *
+ * @return unsigned int
+ */
+unsigned int NTPClientPlus::getDayOfMonth()
+{
+ return this->_dateDay;
+}
+
+/**
+ * @brief Getter for the month number
+ *
+ * @return unsigned int
+ */
+unsigned int NTPClientPlus::getMonthNumber()
+{
+ return this->_dateMonth;
+}
+
/**
* @brief Function to calc current year
*
@@ -565,6 +585,21 @@ bool NTPClientPlus::updateSWChange()
unsigned int dateDay = this->_dateDay;
unsigned int dateMonth = this->_dateMonth;
+ // Calculate local STANDARD time (without DST) for exact switch-hour handling.
+ // EU rule: DST starts on last Sunday in March at 02:00 (standard time),
+ // and ends on last Sunday in October at 03:00 local summer time
+ // (== 02:00 standard time).
+ int64_t currentUtcSeconds = static_cast(this->_secsSince1900) +
+ static_cast((millis() - this->_lastUpdate) / 1000);
+ int64_t secsSince1900NoDST = currentUtcSeconds +
+ (static_cast(this->_utcx) * this->secondperminute);
+ int64_t secondsIntoDay = secsSince1900NoDST % this->secondperday;
+ if (secondsIntoDay < 0)
+ {
+ secondsIntoDay += this->secondperday;
+ }
+ unsigned int hourNoDST = static_cast(secondsIntoDay / this->secondperhour);
+
bool summertimeActive = false;
if (this->_swChange)
@@ -587,10 +622,19 @@ bool NTPClientPlus::updateSWChange()
//Calculation: 31 - 30 = 1; 1 + 2 = 3;
//Result: Last day in March is a Wednesday. Changeover to summer time already done => set summer time
- // If today is Sunday (dayOfWeek == 7) then this is already the last sunday in march -> set summer time
+ // If today is Sunday (dayOfWeek == 7) then this is the last Sunday in March.
+ // Switch to summer time at 02:00 standard time (clock jumps to 03:00).
if(dayOfWeek == 7){
- this->setSummertime(1);
- summertimeActive = true;
+ if (hourNoDST >= 2)
+ {
+ this->setSummertime(1);
+ summertimeActive = true;
+ }
+ else
+ {
+ this->setSummertime(0);
+ summertimeActive = false;
+ }
}
//There follows within the last week in March one more Sunday => set winter time
@@ -632,10 +676,20 @@ bool NTPClientPlus::updateSWChange()
//Calculation: 31 - 26 = 5; 5 + 2 = 7;
//Result: Last day in October is a Sunday. There follows another Sunday in October => set summer time
- // If today is Sunday (dayOfWeek == 7) then this is already the last sunday in october -> winter time
+ // If today is Sunday (dayOfWeek == 7) then this is the last Sunday in October.
+ // Switch back to winter time at 02:00 standard time
+ // (which corresponds to 03:00 local summer time).
if(dayOfWeek == 7){
- this->setSummertime(0);
- summertimeActive = false;
+ if (hourNoDST >= 2)
+ {
+ this->setSummertime(0);
+ summertimeActive = false;
+ }
+ else
+ {
+ this->setSummertime(1);
+ summertimeActive = true;
+ }
}
// There follows within the last week in October one more Sunday => summer time
@@ -677,4 +731,4 @@ bool NTPClientPlus::updateSWChange()
}
return summertimeActive;
-}
\ No newline at end of file
+}
diff --git a/ntp_client_plus.h b/ntp_client_plus.h
index 847306c..7060f2c 100644
--- a/ntp_client_plus.h
+++ b/ntp_client_plus.h
@@ -33,6 +33,8 @@ class NTPClientPlus{
String getFormattedDate();
void calcDate();
unsigned int getDayOfWeek();
+ unsigned int getDayOfMonth();
+ unsigned int getMonthNumber();
unsigned int getYear();
bool isLeapYear(unsigned int year);
int getMonth(int dayOfYear);
diff --git a/udplogger.cpp b/udplogger.cpp
index 369af22..619afc7 100644
--- a/udplogger.cpp
+++ b/udplogger.cpp
@@ -10,21 +10,23 @@ UDPLogger::UDPLogger(IPAddress interfaceAddr, IPAddress multicastAddr, int port)
_interfaceAddr = interfaceAddr;
_name = "Log";
_Udp.beginMulticast(_interfaceAddr, _multicastAddr, _port);
+ _lastSend = 0;
}
void UDPLogger::setName(String name){
_name = name;
}
-void UDPLogger::logString(String logmessage){
+void UDPLogger::logString(const String& logmessage){
// wait 5 milliseconds if last send was less than 5 milliseconds before
if(millis() < (_lastSend + 5)){
delay(5);
}
- logmessage = _name + ": " + logmessage;
- Serial.println(logmessage);
+ // use fixed buffer instead of string concatenation to avoid heap fragmentation
+ // message will be truncated to fit into _packetBuffer (99 chars + NUL)
+ snprintf(_packetBuffer, sizeof(_packetBuffer), "%s: %s", _name.c_str(), logmessage.c_str());
+ Serial.println(_packetBuffer);
_Udp.beginPacketMulticast(_multicastAddr, _port, _interfaceAddr);
- logmessage.toCharArray(_packetBuffer, 100);
_Udp.print(_packetBuffer);
_Udp.endPacket();
_lastSend=millis();
@@ -35,4 +37,4 @@ void UDPLogger::logColor24bit(uint32_t color){
uint8_t resultGreen = color >> 8 & 0xff;
uint8_t resultBlue = color & 0xff;
logString(String(resultRed) + ", " + String(resultGreen) + ", " + String(resultBlue));
-}
\ No newline at end of file
+}
diff --git a/udplogger.h b/udplogger.h
index c26fa49..e4cac28 100644
--- a/udplogger.h
+++ b/udplogger.h
@@ -22,7 +22,7 @@ class UDPLogger{
UDPLogger();
UDPLogger(IPAddress interfaceAddr, IPAddress multicastAddr, int port);
void setName(String name);
- void logString(String logmessage);
+ void logString(const String& logmessage);
void logColor24bit(uint32_t color);
private:
String _name;
diff --git a/wordclock_esp8266.ino b/wordclock_esp8266.ino
index b8d9046..b3fe8c9 100644
--- a/wordclock_esp8266.ino
+++ b/wordclock_esp8266.ino
@@ -48,20 +48,38 @@
// CONSTANTS
// ----------------------------------------------------------------------------------
-#define EEPROM_SIZE 30 // size of EEPROM to save persistent variables
-#define ADR_NM_START_H 0
-#define ADR_NM_END_H 4
-#define ADR_NM_START_M 8
-#define ADR_NM_END_M 12
-#define ADR_BRIGHTNESS 16
-#define ADR_MC_RED 20
-#define ADR_MC_GREEN 22
-#define ADR_MC_BLUE 24
-#define ADR_STATE 26
-#define ADR_NM_ACTIVATED 27
-#define ADR_COLSHIFTSPEED 28
-#define ADR_COLSHIFTACTIVE 29
-
+#define EEPROM_VERSION_CODE 3 // Change this value when defaults settings change
+
+// EEPROM address map (all uint8_t, 1 byte each)
+#define EEPROM_SIZE 14 // size of EEPROM to save persistent variables
+#define ADR_EEPROM_VERSION 0 // uint8_t
+#define ADR_NM_START_H 1 // uint8_t
+#define ADR_NM_END_H 2 // uint8_t
+#define ADR_NM_START_M 3 // uint8_t
+#define ADR_NM_END_M 4 // uint8_t
+#define ADR_BRIGHTNESS 5 // uint8_t
+#define ADR_MC_RED 6 // uint8_t
+#define ADR_MC_GREEN 7 // uint8_t
+#define ADR_MC_BLUE 8 // uint8_t
+#define ADR_STATE 9 // uint8_t
+#define ADR_NM_ACTIVATED 10 // uint8_t
+#define ADR_COLSHIFTSPEED 11 // uint8_t
+#define ADR_COLSHIFTACTIVE 12 // uint8_t
+#define ADR_NM_BRIGHTNESS 13 // uint8_t
+
+// DEFAULT SETTINGS (if one changes this, also increment the EEPROM_VERSION_CODE, to ensure that the EEPROM is updated with the new defaults)
+#define DEFAULT_NM_START_HOUR 22 // default start hour of nightmode (0-23)
+#define DEFAULT_NM_START_MIN 5 // default start minute of nightmode (0-59)
+#define DEFAULT_NM_END_HOUR 7 // default end hour of nightmode (0-23)
+#define DEFAULT_NM_END_MIN 0 // default end minute of nightmode (0-59)
+#define DEFAULT_BRIGHTNESS 40 // default brightness of LEDs (10-255)
+#define DEFAULT_MC_RED 200 // default main color red value
+#define DEFAULT_MC_GREEN 200 // default main color green value
+#define DEFAULT_MC_BLUE 0 // default main color blue value
+#define DEFAULT_NM_ACTIVATED 1 // if function nightmode is activated (0 = deactivated, 1 = activated)
+#define DEFAULT_NM_BRIGHTNESS 0 // default brightness during night mode (0-255)
+#define DEFAULT_COLSHIFT_SPEED 1 // needs to be between larger than 0 (1 = slowest, 255 = fastest)
+#define DEFAULT_COLSHIFT_ACTIVE 0 // if dynamic color shift is active (0 = deactivated, 1 = activated)
#define NEOPIXELPIN 5 // pin to which the NeoPixels are attached
#define BUTTONPIN 14 // pin to which the button is attached
@@ -76,6 +94,7 @@
#define PERIOD_SNAKE 50
#define PERIOD_PONG 10
#define TIMEOUT_LEDDIRECT 5000
+#define TIMEOUT_WIFI_DISCONNECTED 30000
#define PERIOD_STATECHANGE 10000
#define PERIOD_NTPUPDATE 30000
#define PERIOD_TIMEVISUUPDATE 1000
@@ -159,7 +178,7 @@ const uint32_t colors24bit[NUM_COLORS] = {
LEDMatrix::Color24bit(0, 128, 0),
LEDMatrix::Color24bit(0, 0, 255) };
-uint8_t brightness = 40; // current brightness of leds
+uint8_t brightness = DEFAULT_BRIGHTNESS; // current brightness of leds
bool sprialDir = false;
// timestamp variables
@@ -171,6 +190,7 @@ long lastNTPUpdate = millis() - (PERIOD_NTPUPDATE-3000); // time of last NTP up
long lastAnimationStep = millis(); // time of last Matrix update
long lastNightmodeCheck = millis() - (PERIOD_NIGHTMODECHECK-3000); // time of last nightmode check
long buttonPressStart = 0; // time of push button press start
+long wifiDisconnectedSince = 0; // time since WiFi connection was lost (0 = connected)
uint16_t behaviorUpdatePeriod = PERIOD_TIMEVISUUPDATE; // holdes the period in which the behavior should be updated
// Create necessary global objects
@@ -182,24 +202,25 @@ Tetris mytetris = Tetris(&ledmatrix, &logger);
Snake mysnake = Snake(&ledmatrix, &logger);
Pong mypong = Pong(&ledmatrix, &logger);
-float filterFactor = DEFAULT_SMOOTHING_FACTOR;// stores smoothing factor for led transition
-uint8_t currentState = st_clock; // stores current state
-bool stateAutoChange = false; // stores state of automatic state change
-bool nightMode = false; // stores state of nightmode
-bool nightModeActivated = true; // stores if the function nightmode is activated (its not the state of nightmode)
-bool ledOff = false; // stores state of led off
-uint32_t maincolor_clock = colors24bit[2]; // color of the clock and digital clock
-uint32_t maincolor_snake = colors24bit[1]; // color of the random snake animation
-bool apmode = false; // stores if WiFi AP mode is active
-bool dynColorShiftActive = false; // stores if dynamic color shift is active
-uint8_t dynColorShiftPhase = 0; // stores the phase of the dynamic color shift
-uint8_t dynColorShiftSpeed = 1; // stores the speed of the dynamic color shift -> used to calc update period
+float filterFactor = DEFAULT_SMOOTHING_FACTOR; // stores smoothing factor for led transition
+uint8_t currentState = st_clock; // stores current state
+bool stateAutoChange = false; // stores state of automatic state change
+bool nightMode = false; // stores state of nightmode
+bool nightModeActivated = DEFAULT_NM_ACTIVATED; // stores if the function nightmode is activated (its not the state of nightmode)
+bool ledOff = false; // stores state of led off
+uint32_t maincolor_clock = colors24bit[2]; // color of the clock and digital clock
+uint32_t maincolor_snake = colors24bit[1]; // color of the random snake animation
+bool apmode = false; // stores if WiFi AP mode is active
+bool dynColorShiftActive = DEFAULT_COLSHIFT_ACTIVE; // stores if dynamic color shift is active
+uint8_t dynColorShiftPhase = 0; // stores the phase of the dynamic color shift
+uint8_t dynColorShiftSpeed = DEFAULT_COLSHIFT_SPEED; // stores the speed of the dynamic color shift -> used to calc update period
// nightmode settings
-uint8_t nightModeStartHour = 22;
-uint8_t nightModeStartMin = 0;
-uint8_t nightModeEndHour = 7;
-uint8_t nightModeEndMin = 0;
+uint8_t nightModeStartHour = DEFAULT_NM_START_HOUR;
+uint8_t nightModeStartMin = DEFAULT_NM_START_MIN;
+uint8_t nightModeEndHour = DEFAULT_NM_END_HOUR;
+uint8_t nightModeEndMin = DEFAULT_NM_END_MIN;
+uint8_t nightModeBrightness = DEFAULT_NM_BRIGHTNESS;
// Watchdog counter to trigger restart if NTP update was not possible 30 times in a row (5min)
int watchdogCounter = 30;
@@ -221,6 +242,25 @@ void setup() {
//Init EEPROM
EEPROM.begin(EEPROM_SIZE);
+ // Check EEPROM version code
+ uint8_t storedVersion = EEPROM.read(ADR_EEPROM_VERSION);
+ if (storedVersion != EEPROM_VERSION_CODE) {
+ // Set new defaults
+ EEPROM.write(ADR_EEPROM_VERSION, EEPROM_VERSION_CODE);
+ EEPROM.write(ADR_NM_START_H, DEFAULT_NM_START_HOUR);
+ EEPROM.write(ADR_NM_START_M, DEFAULT_NM_START_MIN);
+ EEPROM.write(ADR_NM_END_H, DEFAULT_NM_END_HOUR);
+ EEPROM.write(ADR_NM_END_M, DEFAULT_NM_END_MIN);
+ EEPROM.write(ADR_BRIGHTNESS, DEFAULT_BRIGHTNESS);
+ setMainColor(DEFAULT_MC_RED, DEFAULT_MC_GREEN, DEFAULT_MC_BLUE);
+ EEPROM.write(ADR_STATE, st_clock);
+ EEPROM.write(ADR_NM_ACTIVATED, DEFAULT_NM_ACTIVATED);
+ EEPROM.write(ADR_COLSHIFTSPEED, DEFAULT_COLSHIFT_SPEED);
+ EEPROM.write(ADR_COLSHIFTACTIVE, DEFAULT_COLSHIFT_ACTIVE);
+ EEPROM.write(ADR_NM_BRIGHTNESS, DEFAULT_NM_BRIGHTNESS);
+ EEPROM.commit();
+ }
+
// configure button pin as input
pinMode(BUTTONPIN, INPUT_PULLUP);
@@ -360,6 +400,7 @@ void setup() {
loadNightmodeSettingsFromEEPROM();
loadBrightnessSettingsFromEEPROM();
loadColorShiftStateFromEEPROM();
+ loadNightmodeBrightnessFromEEPROM();
if(ESP.getResetReason().equals("Power On") || ESP.getResetReason().equals("External System")){
// test quickly each LED
@@ -417,24 +458,43 @@ void loop() {
lastheartbeat = millis();
// Check wifi status (only if no apmode)
- if(!apmode && WiFi.status() != WL_CONNECTED){
- Serial.println("connection lost");
- ledmatrix.gridAddPixel(0, 5, colors24bit[1]);
- ledmatrix.drawOnMatrixInstant();
- delay(1000);
+ if(!apmode){
+ if(WiFi.status() != WL_CONNECTED){
+ if(wifiDisconnectedSince == 0){
+ wifiDisconnectedSince = millis();
+ Serial.println("connection lost");
+ }
+
+ if(millis() - wifiDisconnectedSince >= TIMEOUT_WIFI_DISCONNECTED){
+ ledmatrix.gridAddPixel(0, 5, colors24bit[1]);
+ ledmatrix.drawOnMatrixInstant();
+ delay(1000);
+ }
+ }
+ else {
+ wifiDisconnectedSince = 0;
+ }
}
}
// handle state behaviours (trigger loopCycles of different states depending on current state)
- if(!nightMode && !ledOff && (millis() - lastStep > behaviorUpdatePeriod) && (millis() - lastLEDdirect > TIMEOUT_LEDDIRECT)){
+ if(!ledOff && (millis() - lastStep > behaviorUpdatePeriod) && (millis() - lastLEDdirect > TIMEOUT_LEDDIRECT)){
updateStateBehavior(currentState);
lastStep = millis();
}
- // Turn off LEDs if ledOff is true or nightmode is active
- if((ledOff || nightMode) && !waitForTimeAfterReboot){
+ // Turn off LEDs if ledOff is true
+ if(ledOff && !waitForTimeAfterReboot){
ledmatrix.gridFlush();
}
+
+ // Apply night mode brightness
+ if(nightMode && !ledOff && !waitForTimeAfterReboot){
+ ledmatrix.setBrightness(nightModeBrightness);
+ }
+ else if(!nightMode && !ledOff && !waitForTimeAfterReboot){
+ ledmatrix.setBrightness(brightness);
+ }
// periodically write colors to matrix
if(millis() - lastAnimationStep > PERIOD_MATRIXUPDATE && !waitForTimeAfterReboot && (millis() - lastLEDdirect > TIMEOUT_LEDDIRECT)){
@@ -446,7 +506,7 @@ void loop() {
handleButton();
// handle state changes
- if(stateAutoChange && (millis() - lastStateChange > PERIOD_STATECHANGE) && !nightMode && !ledOff){
+ if(stateAutoChange && (millis() - lastStateChange > PERIOD_STATECHANGE) && !ledOff){
// increment state variable and trigger state change
stateChange((currentState + 1) % NUM_STATES, false);
@@ -897,6 +957,16 @@ void loadColorShiftStateFromEEPROM()
logger.logString("ColorShiftActive: " + String(dynColorShiftActive));
}
+/**
+ * @brief Load the night mode brightness from EEPROM
+ *
+ */
+void loadNightmodeBrightnessFromEEPROM()
+{
+ nightModeBrightness = EEPROM.read(ADR_NM_BRIGHTNESS);
+ logger.logString("Night mode brightness: " + String(nightModeBrightness));
+}
+
/**
* @brief Handler for handling commands sent to "/cmd" url
*
@@ -969,6 +1039,7 @@ void handleCommand() {
nightModeEndMin = split(timestr, '-', 3).toInt();
brightness = split(timestr, '-', 4).toInt();
dynColorShiftSpeed = split(timestr, '-', 5).toInt();
+ nightModeBrightness = split(timestr, '-', 6).toInt();
if(nightModeStartHour < 0 || nightModeStartHour > 23) nightModeStartHour = 22;
if(nightModeStartMin < 0 || nightModeStartMin > 59) nightModeStartMin = 0;
if(nightModeEndHour < 0 || nightModeEndHour > 23) nightModeEndHour = 7;
@@ -981,11 +1052,13 @@ void handleCommand() {
EEPROM.write(ADR_NM_END_M, nightModeEndMin);
EEPROM.write(ADR_BRIGHTNESS, brightness);
EEPROM.write(ADR_COLSHIFTSPEED, dynColorShiftSpeed);
+ EEPROM.write(ADR_NM_BRIGHTNESS, nightModeBrightness);
EEPROM.commit();
logger.logString("Nightmode starts at: " + String(nightModeStartHour) + ":" + String(nightModeStartMin));
logger.logString("Nightmode ends at: " + String(nightModeEndHour) + ":" + String(nightModeEndMin));
logger.logString("Brightness: " + String(brightness));
logger.logString("ColorShiftSpeed: " + String(dynColorShiftSpeed));
+ logger.logString("Night mode brightness: " + String(nightModeBrightness));
ledmatrix.setBrightness(brightness);
lastNightmodeCheck = millis() - PERIOD_NIGHTMODECHECK;
}
@@ -1139,6 +1212,8 @@ void handleDataRequest() {
message += ",";
message += "\"brightness\":\"" + String(brightness) + "\"";
message += ",";
+ message += "\"nightModeBrightness\":\"" + String(nightModeBrightness) + "\"";
+ message += ",";
message += "\"colorshift\":\"" + String(dynColorShiftActive) + "\"";
message += ",";
message += "\"colorshiftspeed\":\"" + String(dynColorShiftSpeed) + "\"";
diff --git a/wordclockfunctions.ino b/wordclockfunctions.ino
index ecbdc6e..5720b03 100644
--- a/wordclockfunctions.ino
+++ b/wordclockfunctions.ino
@@ -114,7 +114,7 @@ String timeToString(uint8_t hours,uint8_t minutes){
}
else if(minutes >= 20 && minutes < 25)
{
- message += "ZEHN VOR HALB ";
+ message += "ZWANZIG NACH ";
}
else if(minutes >= 25 && minutes < 30)
{
@@ -130,7 +130,7 @@ String timeToString(uint8_t hours,uint8_t minutes){
}
else if(minutes >= 40 && minutes < 45)
{
- message += "ZEHN NACH HALB ";
+ message += "ZWANZIG VOR ";
}
else if(minutes >= 45 && minutes < 50)
{
@@ -150,7 +150,7 @@ String timeToString(uint8_t hours,uint8_t minutes){
{
hours -= 12;
}
- if(minutes >= 20)
+ if(minutes >= 25)
{
hours++;
}