diff --git a/README.md b/README.md
index 23f9232..0668086 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,14 @@ The code compiles only with one file named *wordclockfunctions.ino*. So please r
Thank you to everyone who provided feedback on adding new languages and testing their accuracy — your efforts have been invaluable in making this project truly inclusive and reliable!
+**Special Branches**
+
+We've got some interesting branches in this repo inspired by user feedback. These branches explore unique features and experimental ideas. Some will stay updated with the main branch's features.
+
+- [**hour_animation**](https://github.com/techniccontroller/wordclock_esp8266/tree/hour_animation): This branch replaces the spiral animation with some custom pattern animation defined as x/y coordinate pattern including custom color for each letter. Also, this animation is show ones per hour.
+- [**mode_seconds**](https://github.com/techniccontroller/wordclock_esp8266/tree/mode_seconds): This branch adds one additional mode to show the seconds as numbers on the clock. Thanks to [@Bram](https://github.com/BramWerbrouck)
+- [**rgbw_leds**](https://github.com/techniccontroller/wordclock_esp8266/tree/rgbw_leds): This branch uses RGBW LEDs instead of RGB LEDs.
+- [**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.
## Features
- 6 modes (Clock, Digital Clock, SPIRAL animation, TETRIS, SNAKE, PONG)
diff --git a/data/index.html b/data/index.html
index 9fda0be..4bce60d 100644
--- a/data/index.html
+++ b/data/index.html
@@ -243,7 +243,7 @@
}
.show{
- height: 230px;
+ height: 280px;
transition: height 1s;
}
@@ -288,6 +288,12 @@
Reset Wifi
@@ -311,9 +317,9 @@
WORDCLOCK 2.0
@@ -456,20 +462,38 @@
WORDCLOCK 2.0
modebuttons[state].classList.add("active");
// set checkbox states
- var ckb_nightmode = document.querySelector('input[id="Nightmode"]');
- if(myVar.nightMode == "1") {
- console.log("nightMode == 1");
- ckb_nightmode.checked = true;
+ var ckb_nightmodeactivated = document.querySelector('input[id="NightMode"]');
+ if(myVar.nightModeActivated == "1") {
+ console.log("nightmodeactivated == 1");
+ ckb_nightmodeactivated.checked = true;
+ }
+ else {
+ console.log("nightmodeactivated == 0");
+ ckb_nightmodeactivated.checked = false;
+ }
+ ckb_nightmodeactivated.addEventListener('change', () => {
+ if(ckb_nightmodeactivated.checked) {
+ sendCommand("./cmd?nightmodeactivated=1");
+ } else {
+ sendCommand("./cmd?nightmodeactivated=0");
+ }
+ });
+
+ // set checkbox states
+ var ckb_ledoff = document.querySelector('input[id="LED_Off"]');
+ if(myVar.ledoff == "1") {
+ console.log("ledoff == 1");
+ ckb_ledoff.checked = true;
}
else {
- console.log("nightMode == 0");
- ckb_nightmode.checked = false;
+ console.log("ledoff == 0");
+ ckb_ledoff.checked = false;
}
- ckb_nightmode.addEventListener('change', () => {
- if(ckb_nightmode.checked) {
- sendCommand("./cmd?nightmode=1");
+ ckb_ledoff.addEventListener('change', () => {
+ if(ckb_ledoff.checked) {
+ sendCommand("./cmd?ledoff=1");
} else {
- sendCommand("./cmd?nightmode=0");
+ sendCommand("./cmd?ledoff=0");
}
});
@@ -501,8 +525,10 @@ WORDCLOCK 2.0
}
ckb_colorshift.addEventListener('change', () => {
if(ckb_colorshift.checked) {
+ document.getElementById("colorcontainer").classList.add("hidden");
sendCommand("./cmd?colorshift=1");
} else {
+ document.getElementById("colorcontainer").classList.remove("hidden");
sendCommand("./cmd?colorshift=0");
}
});
@@ -539,7 +565,10 @@ WORDCLOCK 2.0
if(myVar != null && myVar.stateAutoChange == "0"){
switch(modeid){
case 0: // clock
- document.getElementById("colorcontainer").classList.remove("hidden");
+ var ckb_colorshift = document.querySelector('input[id="ColorShift"]');
+ if(!ckb_colorshift.checked) {
+ document.getElementById("colorcontainer").classList.remove("hidden");
+ }
document.getElementById("colorshiftcontainer").classList.remove("hidden");
break;
case 1: // diclock
diff --git a/wordclock_esp8266.ino b/wordclock_esp8266.ino
index e563f2b..b28faea 100644
--- a/wordclock_esp8266.ino
+++ b/wordclock_esp8266.ino
@@ -58,12 +58,12 @@
#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 NEOPIXELPIN 5 // pin to which the NeoPixels are attached
-#define NUMPIXELS 125 // number of pixels attached to Attiny85
#define BUTTONPIN 14 // pin to which the button is attached
#define LEFT 1
#define RIGHT 2
@@ -184,10 +184,12 @@ float filterFactor = DEFAULT_SMOOTHING_FACTOR;// stores smoothing factor for led
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 = true; // stores if dynamic color shift 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
@@ -414,11 +416,17 @@ void loop() {
}
// handle state behaviours (trigger loopCycles of different states depending on current state)
- if(!nightMode && (millis() - lastStep > behaviorUpdatePeriod) && (millis() - lastLEDdirect > TIMEOUT_LEDDIRECT)){
+ if(!nightMode && !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){
+ ledmatrix.gridFlush();
+ ledmatrix.drawOnMatrixInstant();
+ }
+
// periodically write colors to matrix
if(millis() - lastAnimationStep > PERIOD_MATRIXUPDATE && !waitForTimeAfterReboot){
ledmatrix.drawOnMatrixSmooth(filterFactor);
@@ -429,7 +437,7 @@ void loop() {
handleButton();
// handle state changes
- if(stateAutoChange && (millis() - lastStateChange > PERIOD_STATECHANGE) && !nightMode){
+ if(stateAutoChange && (millis() - lastStateChange > PERIOD_STATECHANGE) && !nightMode && !ledOff){
// increment state variable and trigger state change
stateChange((currentState + 1) % NUM_STATES, false);
@@ -610,18 +618,17 @@ void checkNightmode(){
int startInMinutes = nightModeStartHour * 60 + nightModeStartMin;
int endInMinutes = nightModeEndHour * 60 + nightModeEndMin;
- if (startInMinutes < endInMinutes) { // Same day scenario
+ if (startInMinutes < endInMinutes && nightModeActivated) { // Same day scenario
if (startInMinutes < currentTimeInMinutes && currentTimeInMinutes < endInMinutes) {
nightMode = true;
- logger.logString("Nightmode activated");
+ logger.logString("Nightmode active");
}
- } else if (startInMinutes > endInMinutes) { // Overnight scenario
+ } else if (startInMinutes > endInMinutes && nightModeActivated) { // Overnight scenario
if (currentTimeInMinutes >= startInMinutes || currentTimeInMinutes < endInMinutes) {
nightMode = true;
- logger.logString("Nightmode activated");
+ logger.logString("Nightmode active");
}
}
- setNightmode(nightMode);
}
/**
@@ -691,9 +698,8 @@ void entryAction(uint8_t state){
* @param persistant if true, the state will be saved to EEPROM
*/
void stateChange(uint8_t newState, bool persistant){
- if(nightMode){
- // deactivate Nightmode
- setNightmode(false);
+ if(ledOff){
+ ledOff = false;
}
// first clear matrix
ledmatrix.gridFlush();
@@ -782,14 +788,14 @@ void handleButton(){
// longpress -> nightmode
logger.logString("Button press ended - longpress");
- setNightmode(true);
+ ledOff = true;
}
else if((millis() - buttonPressStart) > SHORTPRESS){
// shortpress -> state change
logger.logString("Button press ended - shortpress");
- if(nightMode){
- setNightmode(false);
+ if(ledOff){
+ ledOff = false;
}else{
stateChange((currentState + 1) % NUM_STATES, true);
}
@@ -848,10 +854,12 @@ void loadNightmodeSettingsFromEEPROM()
nightModeStartMin = EEPROM.read(ADR_NM_START_M);
nightModeEndHour = EEPROM.read(ADR_NM_END_H);
nightModeEndMin = EEPROM.read(ADR_NM_END_M);
+ nightModeActivated = EEPROM.read(ADR_NM_ACTIVATED);
if(nightModeStartHour < 0 || nightModeStartHour > 23) nightModeStartHour = 22;
if(nightModeStartMin < 0 || nightModeStartMin > 59) nightModeStartMin = 0;
if(nightModeEndHour < 0 || nightModeEndHour > 23) nightModeEndHour = 7;
if(nightModeEndMin < 0 || nightModeEndMin > 59) nightModeEndMin = 0;
+ logger.logString("Nightmode activated: " + String(nightModeActivated));
logger.logString("Nightmode starts at: " + String(nightModeStartHour) + ":" + String(nightModeStartMin));
logger.logString("Nightmode ends at: " + String(nightModeEndHour) + ":" + String(nightModeEndMin));
}
@@ -930,11 +938,20 @@ void handleCommand() {
stateChange(st_pingpong, true);
}
}
- else if(server.argName(0) == "nightmode"){
+ else if(server.argName(0) == "ledoff"){
String modestr = server.arg(0);
- logger.logString("Nightmode change via Webserver to: " + modestr);
- if(modestr == "1") setNightmode(true);
- else setNightmode(false);
+ logger.logString("LED off change via Webserver to: " + modestr);
+ if(modestr == "1") ledOff = true;
+ else ledOff = false;
+ }
+ else if(server.argName(0) == "nightmodeactivated"){
+ String modestr = server.arg(0);
+ logger.logString("nightModeActivated change via Webserver to: " + modestr);
+ if(modestr == "1") nightModeActivated = true;
+ else nightModeActivated = false;
+ EEPROM.write(ADR_NM_ACTIVATED, nightModeActivated);
+ EEPROM.commit();
+ checkNightmode();
}
else if(server.argName(0) == "setting"){
String timestr = server.arg(0) + "-";
@@ -1105,7 +1122,9 @@ void handleDataRequest() {
message += ",";
message += "\"stateAutoChange\":\"" + String(stateAutoChange) + "\"";
message += ",";
- message += "\"nightMode\":\"" + String(nightMode) + "\"";
+ message += "\"ledoff\":\"" + String(ledOff) + "\"";
+ message += ",";
+ message += "\"nightModeActivated\":\"" + String(nightModeActivated) + "\"";
message += ",";
message += "\"nightModeStart\":\"" + leadingZero2Digit(nightModeStartHour) + "-" + leadingZero2Digit(nightModeStartMin) + "\"";
message += ",";
@@ -1122,18 +1141,6 @@ void handleDataRequest() {
}
}
-/**
- * @brief Set the nightmode state
- *
- * @param on true -> nightmode on
- */
-void setNightmode(bool on){
- if(on){
- ledmatrix.gridFlush();
- }
- nightMode = on;
-}
-
/**
* @brief Convert Integer to String with leading zero
*