From ddd4da1686898338f2a1161534fd16b401fbfd6e Mon Sep 17 00:00:00 2001 From: Edgar W <36072504+techniccontroller@users.noreply.github.com> Date: Sun, 23 Feb 2025 19:53:06 +0100 Subject: [PATCH 1/7] Update README.md --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5e0bb2c..f98983e 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,14 @@ Thank you to everyone who provided feedback on adding new languages and testing 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. +- [**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. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=hour_animation) - [**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. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=mode_seconds) +- [**rgbw_leds**](https://github.com/techniccontroller/wordclock_esp8266/tree/rgbw_leds): This branch uses RGBW LEDs instead of RGB LEDs. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=rgbw_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. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=static_background_pattern) From 8f543a5c1fe5a82b5103297b533a794b09c1f012 Mon Sep 17 00:00:00 2001 From: Edgar W Date: Sun, 30 Mar 2025 18:45:41 +0200 Subject: [PATCH 2/7] add swiss german language version --- README.md | 2 +- wordclockfunctions.ino_swiss | 225 +++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 wordclockfunctions.ino_swiss diff --git a/README.md b/README.md index f98983e..67e5e7b 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ More details on my website: https://techniccontroller.com/word-clock-with-wifi-a **Languages** -The Wordclock is available in **German**, **English**, **Italian**, **French** and **Javanese** language. By default the language is German. +The Wordclock is available in **German**, **English**, **Italian**, **French**, **Swiss German**, and **Javanese** language. By default the language is German. To use other languages like English or Italian please replace the file *wordclockfunctions.ino* with *wordclockfunctions.ino_english* or *wordclockfunctions.ino_italian*. The code compiles only with one file named *wordclockfunctions.ino*. So please rename the file you want to use to *wordclockfunctions.ino* and replace the existing file. diff --git a/wordclockfunctions.ino_swiss b/wordclockfunctions.ino_swiss new file mode 100644 index 0000000..7ec5f2c --- /dev/null +++ b/wordclockfunctions.ino_swiss @@ -0,0 +1,225 @@ +// Thanks to Sandro for providing this swiss german version +const String clockStringSwiss = "ESPESCHAFUFVIERTUBFZAAZWANZGSIVORABOHWORTUHRHAUBIANESSIEISZWOISDRUVIERIYFUFIOSACHSISEBNIACHTINUNIELZANIERBEUFIZWOUFINAGSI"; + +/** + * @brief control the four minute indicator LEDs + * + * @param minutes minutes to be displayed [0 ... 59] + * @param color 24bit color value + */ +void drawMinuteIndicator(uint8_t minutes, uint32_t color){ + //separate LEDs for minutes in an additional row + { + switch (minutes%5) + { + case 0: + break; + + case 1: + ledmatrix.setMinIndicator(0b1000, color); + break; + + case 2: + ledmatrix.setMinIndicator(0b1100, color); + break; + + case 3: + ledmatrix.setMinIndicator(0b1110, color); + break; + + case 4: + ledmatrix.setMinIndicator(0b1111, color); + break; + } + } +} + +/** + * @brief Draw the given sentence to the word clock + * + * @param message sentence to be displayed + * @param color 24bit color value + * @return int: 0 if successful, -1 if sentence not possible to display + */ +int showStringOnClock(String message, uint32_t color){ + String word = ""; + int lastLetterClock = 0; + int positionOfWord = 0; + int index = 0; + + // add space on the end of message for splitting + message = message + " "; + + // empty the targetgrid + ledmatrix.gridFlush(); + + while(true){ + // extract next word from message + word = split(message, ' ', index); + index++; + + if(word.length() > 0){ + // find word in clock string + positionOfWord = clockStringSwiss.indexOf(word, lastLetterClock); + + if(positionOfWord >= 0){ + // word found on clock -> enable leds in targetgrid + for(unsigned int i = 0; i < word.length(); i++){ + int x = (positionOfWord + i)%WIDTH; + int y = (positionOfWord + i)/WIDTH; + ledmatrix.gridAddPixel(x, y, color); + } + // remember end of the word on clock + lastLetterClock = positionOfWord + word.length(); + } + else{ + // word is not possible to show on clock + logger.logString("word is not possible to show on clock: " + String(word)); + return -1; + } + }else{ + // end - no more word in message + break; + } + } + // return success + return 0; +} + +/** + * @brief Converts the given time as sentence (String) + * + * @param hours hours of the time value + * @param minutes minutes of the time value + * @return String time as sentence + */ +String timeToString(uint8_t hours, uint8_t minutes, bool puristModeActive){ + + //ES IST + String message = ""; + + if(puristModeActive){ + message = ""; + if(minutes < 5 || (minutes >=30 && minutes < 35)){ + message = "ES ESCH "; + } + } + else{ + message = "ES ESCH "; + } + + //show minutes + if(minutes >= 5 && minutes < 10) + { + message += "FUF AB "; + } + else if(minutes >= 10 && minutes < 15) + { + message += "ZAA AB "; + } + else if(minutes >= 15 && minutes < 20) + { + message += "VIERTU AB "; + } + else if(minutes >= 20 && minutes < 25) + { + message += "ZWANZG AB "; //Sandro + } + else if(minutes >= 25 && minutes < 30) + { + message += "FUF VOR HAUBI "; + } + else if(minutes >= 30 && minutes < 35) + { + message += "HAUBI "; + } + else if(minutes >= 35 && minutes < 40) + { + message += "FUF AB HAUBI "; + } + else if(minutes >= 40 && minutes < 45) + { + message += "ZWANZG VOR "; //Sandro + } + else if(minutes >= 45 && minutes < 50) + { + message += "VIERTU VOR "; + } + else if(minutes >= 50 && minutes < 55) + { + message += "ZAA VOR "; + } + else if(minutes >= 55 && minutes < 60) + { + message += "FUF VOR "; + } + + //convert hours to 12h format + if(hours >= 12) + { + hours -= 12; + } + if(minutes >= 25) //Sandro 20 + { + hours++; + } + if(hours == 12) + { + hours = 0; + } + + // show hours + switch(hours) + { + case 0: + message += "ZWOUFI "; + break; + case 1: + message += "EIS "; + // //EIN(S) + // if(minutes > 4){ // Sandro + // message += "S"; + // } + // message += " "; + break; + case 2: + message += "ZWOI "; + break; + case 3: + message += "DRU "; + break; + case 4: + message += "VIERI "; + break; + case 5: + message += "FUFI "; + break; + case 6: + message += "SACHSI "; + break; + case 7: + message += "SEBNI "; + break; + case 8: + message += "ACHTI "; + break; + case 9: + message += "NUNI "; + break; + case 10: + message += "ZANI "; + break; + case 11: + message += "EUFI "; + break; + } + if(minutes < 5) + { + message += "GSI "; + } + + logger.logString("time as String: " + String(message)); + + return message; +} + From 44a6125f96bf0b281ba218b5b79ae20ed8ff269d Mon Sep 17 00:00:00 2001 From: Edgar W Date: Fri, 25 Apr 2025 22:30:25 +0200 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20correct=20italian=20version=20for=20?= =?UTF-8?q?times=20(11:35=E2=80=9311:55=20and=2023:35=E2=80=9323:55)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wordclockfunctions.ino_italian | 4 ---- 1 file changed, 4 deletions(-) diff --git a/wordclockfunctions.ino_italian b/wordclockfunctions.ino_italian index a1f0f47..56069ea 100644 --- a/wordclockfunctions.ino_italian +++ b/wordclockfunctions.ino_italian @@ -118,10 +118,6 @@ String timeToString(uint8_t hours,uint8_t minutes){ { message += "= # "; //E' L' -> = is for E' and # is for L' } - else if (hours == 0 && minutes >= 35) - { - message += "= # "; //E' L' -> = is for E' and # is for L' - } else { message += "SONO LE "; From b0124723abbb33ed970b6f30361341b812e1b493 Mon Sep 17 00:00:00 2001 From: Edgar W <36072504+techniccontroller@users.noreply.github.com> Date: Thu, 1 May 2025 18:18:00 +0200 Subject: [PATCH 4/7] fix "one minus..." issue --- wordclockfunctions.ino_italian | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wordclockfunctions.ino_italian b/wordclockfunctions.ino_italian index 56069ea..a960a82 100644 --- a/wordclockfunctions.ino_italian +++ b/wordclockfunctions.ino_italian @@ -114,7 +114,7 @@ String timeToString(uint8_t hours,uint8_t minutes){ } //SONO LE - if(hours == 1 && minutes < 35) + if(hours == 1) { message += "= # "; //E' L' -> = is for E' and # is for L' } From 43a3992b3335e301f4f3bc7257e20ad6b158edf8 Mon Sep 17 00:00:00 2001 From: Edgar W <36072504+techniccontroller@users.noreply.github.com> Date: Wed, 4 Jun 2025 12:37:20 +0200 Subject: [PATCH 5/7] Update README.md --- README.md | 94 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 67e5e7b..f7bc04c 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,60 @@ # Wordclock 2.0 ![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=main) -Wordclock 2.0 with ESP8266 and NTP time +A modern Wi-Fi Word Clock powered by the ESP8266 and synchronized via NTP (Network Time Protocol). +Displays time in words with support for multiple languages and colorful NeoPixel LED effects. +Additional gaming modes, such as PONG, SNAKE, and TETRIS, can be played via an interactive Web UI. -More details on my website: https://techniccontroller.com/word-clock-with-wifi-and-neopixel/ +**Project Details and Guide:** +Full tutorial and build instructions on https://techniccontroller.com/word-clock-with-wifi-and-neopixel/ -**Languages** - -The Wordclock is available in **German**, **English**, **Italian**, **French**, **Swiss German**, and **Javanese** language. By default the language is German. -To use other languages like English or Italian please replace the file *wordclockfunctions.ino* with *wordclockfunctions.ino_english* or *wordclockfunctions.ino_italian*. -The code compiles only with one file named *wordclockfunctions.ino*. So please rename the file you want to use to *wordclockfunctions.ino* and replace the existing file. +## Features +- 6 modes + - Word Clock + - Digital Clock + - SPIRAL animation + - TETRIS (playable via web interface) + - SNAKE (playable via web interface) + - PONG (playable via web interface) +- Interactive Web-Based Games: Control PONG, TETRIS, and SNAKE directly through the built-in web UI +- Real-time clock synchronized over Wi-Fi using NTP +- Automatic daylight saving time (summer/winter) switching +- Automatic timezone detection +- Easy Wi-Fi setup with WiFiManager +- Configurable color themes +- Customizable night mode (start/end time) +- Adjustable brightness settings +- Automatic mode rotation +- Web interface for configuration and control +- Physical button for quick mode change or night mode toggle +- Intelligent current limiting of LEDs +- Dynamic color shifting mode + +## Supported Languages + +The WordClock currently supports the following languages: +- **German (default)** +- **English** +- **Italian** +- **French** +- **Swiss German** +- **Javanese** + +**How to Change the Language** + +To switch to another language: +1. Go to the `wordclockfunctions.ino_` file (e.g., `wordclockfunctions.ino_english`) +2. Rename it to `wordclockfunctions.ino` +3. Replace the existing `wordclockfunctions.ino` file +4. Compile and upload the code to your ESP8266 + +Only one language file should be named wordclockfunctions.ino at any time for successful compilation. 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. -![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=hour_animation) -- [**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) -![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=mode_seconds) -- [**rgbw_leds**](https://github.com/techniccontroller/wordclock_esp8266/tree/rgbw_leds): This branch uses RGBW LEDs instead of RGB LEDs. -![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=rgbw_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. -![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=static_background_pattern) - -## Features -- 6 modes (Clock, Digital Clock, SPIRAL animation, TETRIS, SNAKE, PONG) -- time update via NTP server -- automatic summer/wintertime change -- automatic timezone selection -- easy WIFI setup with WifiManager -- configurable color -- configurable night mode (start and end time) -- configurable brightness -- automatic mode change -- webserver interface for configuration and control -- physical button to change mode or enable night mode without webserver -- automatic current limiting of LEDs -- dynamic color shift mode - ## Pictures of clock ![modes_images2](https://user-images.githubusercontent.com/36072504/156947689-dd90874d-a887-4254-bede-4947152d85c1.png) @@ -68,6 +79,19 @@ We've got some interesting branches in this repo inspired by user feedback. Thes +## 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. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=hour_animation) +- [**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) +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=mode_seconds) +- [**rgbw_leds**](https://github.com/techniccontroller/wordclock_esp8266/tree/rgbw_leds): This branch uses RGBW LEDs instead of RGB LEDs. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=rgbw_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. +![compile esp8266 workflow](https://github.com/techniccontroller/wordclock_esp8266/actions/workflows/compile_esp8266.yml/badge.svg?branch=static_background_pattern) + ## Install needed Libraries Please download all these libraries as ZIP from GitHub, and extract them in the *libraries* folder of your Sketchbook location (see **File -> Preferences**): From 75e6bd1926c3ba2e31924f6e77276124c34d12b6 Mon Sep 17 00:00:00 2001 From: Edgar W Date: Tue, 22 Jul 2025 20:59:20 +0200 Subject: [PATCH 6/7] fix: set config portal timeout to 10 minutes for better connection handling --- wordclock_esp8266.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wordclock_esp8266.ino b/wordclock_esp8266.ino index 5369da9..b8d9046 100644 --- a/wordclock_esp8266.ino +++ b/wordclock_esp8266.ino @@ -248,6 +248,10 @@ void setup() { // set a custom hostname wifiManager.setHostname(hostname); + + // set timeout of config portal to 10min, continue even if not connected, + // clock will show wrong time, but eventually restart after watchdog counter is 0 (after ~5min) + wifiManager.setConfigPortalTimeout(600); // fetches ssid and pass from eeprom and tries to connect // if it does not connect it starts an access point with the specified name From 80160cd89f49b95fd6b3edee038568c5325406d4 Mon Sep 17 00:00:00 2001 From: Edgar W Date: Sun, 27 Jul 2025 16:47:42 +0200 Subject: [PATCH 7/7] fix: remove incompatible code --- wordclockfunctions.ino_swiss | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/wordclockfunctions.ino_swiss b/wordclockfunctions.ino_swiss index 7ec5f2c..146e5cd 100644 --- a/wordclockfunctions.ino_swiss +++ b/wordclockfunctions.ino_swiss @@ -9,7 +9,6 @@ const String clockStringSwiss = "ESPESCHAFUFVIERTUBFZAAZWANZGSIVORABOHWORTUHRHA */ void drawMinuteIndicator(uint8_t minutes, uint32_t color){ //separate LEDs for minutes in an additional row - { switch (minutes%5) { case 0: @@ -31,7 +30,6 @@ void drawMinuteIndicator(uint8_t minutes, uint32_t color){ ledmatrix.setMinIndicator(0b1111, color); break; } - } } /** @@ -93,20 +91,10 @@ int showStringOnClock(String message, uint32_t color){ * @param minutes minutes of the time value * @return String time as sentence */ -String timeToString(uint8_t hours, uint8_t minutes, bool puristModeActive){ +String timeToString(uint8_t hours, uint8_t minutes){ //ES IST - String message = ""; - - if(puristModeActive){ - message = ""; - if(minutes < 5 || (minutes >=30 && minutes < 35)){ - message = "ES ESCH "; - } - } - else{ - message = "ES ESCH "; - } + String message = "ES ESCH "; //show minutes if(minutes >= 5 && minutes < 10)