In this post, I will build a super cool word clock with Arduino and Neopixel LEDs. Such word clocks cost several hundred euros in the trade, but with a little skill, they are also fast self-built. I show you how it works. The electronic base is similar to that of my LED-Matrix.

UPDATE 2022: I built version 2.0 of the Word clock. This time with WiFi and some games to play on it (Pong, Tetris, Snake). Find my blog post about it here.

Material for the word clock

You need the following material for the word clock. Overall they cost less than 100 EURO.

  • deep wooden picture frame 24x30cm (or similar size, amazon.de*)
  • black adhesive foil (amazon.de*)
  • NeoPixel LED Strip with 114x WS2812b LEDs (60LEDs/m) (amazon.de*)
  • Arduino Nano V3.0 (amazon.de*)
  • Real-Time-Clock Modul DS3231 (amazon.de*)
  • power supply 5V/3A (amazon.de*)
  • DC power jack 5.5×2.1 (amazon.de*)
  • two sheets of black cardboard
  • one sheet of white paper
  • some cables, one 470 Ohm resistor, one 1000uF capacitor, one small switch

Optionally you can upgrade the Word Clock with these components:

* The links are affiliate links. The offers do not come from me, however, I receive a commission through the reference, if then a purchase takes place, but without you incurring additional costs.


Step-by-Step instructions

  1. The first step is to stick the adhesive foils onto the glass pane of the picture frame. Tip: Here it helps to spray the glass pane with detergent water first so that the bubbles can be easily pushed out of the foil afterward.
  2. The most complex task is cutting out the individual letters from the black adhesive foil. The best way to do this is to print out a template with the letters and fix it on the glass pane with adhesive tape. Now the letters can be cut out with a sharp cutter knife.
Cut out letters from the adhesive foil
  1. To avoid reflections, it is recommended to paint the back panel with spray paint.
Painted backboard
  1. Now you divide the LED strip into 10 strips of 11 LEDs each and glue them in a zigzag pattern on the back of the picture frame. It helps to mark the desired position on the back panel.
LED strip on the backboard
  1. To reduce stray light from the individual LEDs, we now create a grid structure from the black cardboard. To do this, we cut 2 cm wide strips from the cardboard and cut them 11 or 12 times up to the middle. Afterward, the strips can be put together as grids as shown in the picture below.
The black cardboard grid structure
  1. Now it goes to the electronics. We solder the Arduino with the LED strips and the real-time clock (RTC) module. It doesn’t matter if you use a hole board or solder the cables directly. As an add-on, you can add the radio clock receiver module DCF77 and/or the light sensor module for automatic brightness control, but this is not absolutely necessary. The RTC module with its battery always keeps the current time. But without using the radio receiver you have to flash the Arduino again when changing the battery of the RTC module.
Schematic of the word clock
Back panel with electronics
techniccontroller / think_wordclock

Arduino source code for the Wordclock on GitHub

  1. The next step is to flash the software to the Arduino. The complete source code can be found here on GitHub. It also describes which additional libraries need to be installed in the Arduino IDE. While connecting to a computer via USB, the small switch must be turned off (to prevent damage to the Arduino due to the high current drawn by the LEDs).
  2. So that the letters shine as a whole and not the individual LEDs are visible, we now stick a simple sheet of white paper on the back of the glass plate. Then we fix the grid with hot glue on the glass plate.
Grid structure inside the picture frame
  1. The last step is to insert the glass plate and back panel into the picture frame. You can also add an on/off switch in the picture frame.
The word clock at day
The word clock at night

You can extend the project as desired: As some of you might have noticed in the pictures above, a built-in light sensor allows automatic adjustment of the brightness of the LEDs to the environment. I placed the light sensor inside the first “K” and connect it to an analogue input (A6) of the Arduino.

Have fun rebuilding it.

Share this post

95 Comments

Fabio · 20/02/2024 at 14:16

Hi Edgar, I saw your project and it’s truly amazing, I have a question for you. I would have liked to make a large format of the clock and to do so the simplest solution would be to skip an LED (I’ll try to make a diagram for you). Do you think it would be feasible?
The letter “Y” indicates that the LED is working and would light up for the corresponding letter, while the letter “n” indicates that the LED will always remain off and serves only as additional space between one LED and another to avoid cutting the led individually and solder them to the necessary length. Thank you and congratulations again.

I S K I S T
Y n Y n Y n Y n Y n Y

Fabio

    Techniccontroller · 20/02/2024 at 21:14

    Hello Fabio,

    thank you for your comment. That is an interesting idea 😉
    Due to my modular software design, this should be doable with three minor changes. I expect you will have 21 leds instead of 11 leds per row (10 leds off). The minute leds stay the same without turned-off leds in between.

    Then the required changes are:

    • wordclock_esp8266.ino, line 154: Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(WIDTH+10, HEIGHT+1, NEOPIXELPIN,
    • wordclock_esp8266.ino, line 346: for(int c = 0; c < WIDTH+10; c++){
    • ledmatrix.cpp, line 194: (*neomatrix).drawPixel(s*2, z, color24to16bit(filteredColor));

    The changes are also viewable in this special branch: https://github.com/techniccontroller/wordclock_esp8266/commit/54ae4f8a98c499e92ba0aab8055d088760768680

    If you have further questions, please feel free to ask.
    Best regards
    Edgar

      Fabio · 23/02/2024 at 18:29

      Hi Edgar, I’m glad it was an interesting question. The idea came because I saw that there are 90×90 cm versions on the market and thinking of soldering each LED in the right position would have been madness, but taking an RGB with a wider pitch and skipping one could have been a good compromise. As soon as I get to work I’ll give you the day. Thank you!

Marc · 28/11/2023 at 11:37

Grüezi Edgar,
ich habe ein Problemchen, eine Kettenreaktion an Fehlercodes.
Weißt du wie man die wegbekommt?

https://ibb.co/QFQR3rV
https://ibb.co/gDPL4CQ

    Techniccontroller · 28/11/2023 at 14:07

    Hallo Marc,
    danke für dein Kommentar.

    Aus deinen Screenshots sehe ich, dass du zwei .ino-Dateien in deinem Arduino Projektordner (“Wordclock Codinus”) hast. Die Datei “BUCHANZEIGE.ino” hat dort nichts zu suchen. Ich weiß nicht, was da drin steht, auch weiß ich nicht ob der Code in “Wordclock Codinus.ino” meinem Code entspricht. Ich vermute allerdings, dass die Fehlermeldungen daher kommen, dass in beiden Dateien die glichen Funktionen und Variablen definiert wurden.

    Ich würde empfehlen meinen Originalcode der Wortuhr von GitHub herunterzuladen und zu probieren ob dieser im Originalzustand kompilierbar ist. Dann kannst du deine Änderungen step-by-step implementieren und immer prüfen ob die Kompilierung nach wie vor klappt.

    Wenn du weiter auf Probleme stößt, kannst du dich gerne nochmal melden.

    Viele Grüße
    Edgar

      Marc · 01/12/2023 at 9:00

      Hallo,
      wir haben jetzt die Codes von deiner Website heruntergeladen. Leider gibt es immer noch Probleme, daher für uns die Codes nicht ausführlich genug Kommentiert sind, können wir es auch nicht eigenständig lösen.
      Hier ist die Fehlermeldung:
      C:\Users\2018WE~1\AppData\Local\Temp\ccZrrGS7.ltrans0.ltrans.o: In function `printDateTime’:
      C:\Users\2018WeidigBen\OneDrive – FSG Rüthen\Schule\Technik und Informatik\Arduino\Wordclock\wordclock_german/wordclock_german.ino:288: undefined reference to `DateTime::dayOfTheWeek() const’
      (…)

        Techniccontroller · 01/12/2023 at 19:57

        Hallo Marc,
        die Fehlermeldung sieht etwas seltsam aus. Ich vermute, dass etwas bei deinen importierten Bibliotheken nicht stimmt.

        Wie in der README.md geschrieben, würde ich dir empfehlen mal mit den Bibliotheken, welche ich im Repository bereitgestellt habe, die Kompilierung versuchen.
        (Einfach alle sieben Ordner in deinen libraries-Ordner kopieren und die IDE neustarten)
        Ich musste beispielsweise an der DCF77 Bibliotheken ein paar Änderungen vornehmen, damit es bei mir fehlerfrei funktioniert hat.

        Wenn mein originaler Code bei dir immer noch nicht kompiliert, ist vielleicht etwas mit deinem Computer/Installation fehlerhaft.
        Kannst du die normalen Beispiele der Adafruit_NeoMatrix kompilieren?

        EDIT: Noch zwei weitere Hinweise, welche helfen könnten:

        – verwende immer die aktuellste Version der IDE (aktuell 2.2.1), das schließt mögliche Fehlerquellen aus.

        – Versuche in deinem Datei-Pfad keine Umlaute zu verwenden. Ich sehe, dass du in deinem Pfad ein ‘ü’ hast. Das mag die IDE nicht, und hat früher zu Kompilierungsfehlern(hier) geführt. Ich weiß nicht ob das mittlerweile gefixt ist. Aber generell, würde ich nie Umlauten oder Leerzeichen in Ordernamen verwenden.

        Viele Grüße
        Edgar

Christian · 02/11/2023 at 21:58

Lieber Edgar,
da du anscheinend Fragen wirklich beantwortest wage ich es doch dich zu belästigen….
Aber zu allererst herzlichen Dank für deine Anleitung! Ich konnte alles bauen und um setzen – und da dein Code so extrem sauber geschrieben und kommentiert ist auch an meine Bedürfnisse anpassen (ich habe leider nur ganz rudimäntere Ahnung vom Programieren 🙁 )!
Nun habe ich aber noch einen Wunsch: Ich würde gerne die Farben bei der der Normalen Uhrzeit anzeige kontiunierlich verändern – so das die Farben langsam durch das Spektrum Cyclen. a) weil ich denke das es toll aus sieht aber auch auch b) um die LED’s gleichmässiger “abzunutzen”. Ich habe Versucht dein ColorWeehl code zu recyklen – leider nicht wirklich erfolgreich…
Hast Du mir eventl. einen Tipp?
Herzlichen Dank für all deine Benühungen und deine vielen Tipps!
Viele Grüsse
Christian
PS: Und wenn man sich irgendwo, irgendwie erkenntlichzeigen kann mache ich das _sehr_ gerne!

    Techniccontroller · 03/11/2023 at 1:02

    Hi Christian,
    danke für deinen Kommentar. Es freut mich, dass du die Uhr erfolgreich nachgebaut hast.

    Ich habe deinen dynamischen Farbwechsel in einem neuen Branch auf GitHub umgesetzt. Hier kannst du die paar wenigen Änderungen sehen:
    https://github.com/techniccontroller/think_wordclock/compare/main…dynamic_color_change

    Leider habe ich die Uhr gerade nicht zur Hand, daher kann ich den Code nicht testen, aber der dynamische Farbwechsel ist nun im Farbmodus 1 aktiv. Also wo ursprünglich die Uhr rot geleuchtet hat. So kannst du die anderen statischen Modi immer noch nutzen. Du kannst durch die verschiedenen Modi schalten, indem du die Uhr kurz hintereinander aus- und wieder einschaltest. Der dynamische Farbwechsel cyclet innerhalb etwa 60 min. einmal durch das ColorWheel.

    Viel Spaß beim Ausprobieren.
    Vielen Grüße
    Edgar

    PS: Ganz unten auf meiner Website ist ein Link zu PayPal 🙂

      Christian · 03/11/2023 at 19:49

      Thank you – it works like a charm 🙂 – And thank you for the PayPal link – worked too 🙂

      Christian · 14/11/2023 at 21:17

      Hallo Edgar,
      jetzt muss ich dich dochnochmals belästigen: Mein DCF77 Modul will nicht wirklich meistens erscheint no Signal. Eine normale DCF77 Funkuhr hat am gleichen Ort aber sehr guten Empfang. Hast Du erfahrung mit DCF Modulen – irgendwelche Tipps?

        Techniccontroller · 14/11/2023 at 21:39

        Hallo Christian,
        ja ich hatte auch einige Problem mit dem DCF77 Modul. Bei mir war die Orientierung der Antenne sehr entscheidend für den Empfang. Ich glaube ich musste die Antenne horizontal ausrichten. Also leider nicht so wie in den Bildern oben gezeigt.

        Ich hoffe das hilft dir, ich habe ja auch einen Signalstärkeanzeige in die Uhr integriert, damit man die Signalstärke beim starten der Uhr als Balken ablesen kann (1. Zeile).

        Viele Grüße
        Edgar

          Jonas · 25/11/2023 at 19:29

          Hallo Edgar,

          erstmal vielen Dank für das tolle Projekt. ich habe inzwischen 4 Uhren in Größe 60×60 gebaut, welche je Buchstabe eine LED haben. nun möchte ich mich steigern und gerne eine Uhr in 120×120 bauen. ich denke ich benötige wegen der Größe drei Led je Buchstabe. kann ich den Code einfach umschreiben, also in Bezug auf die Pixel oder müssen hierzu auch alle Datenbänke angepasst werden? evtl. gibt es hierzu auch einen einfacheren Weg?

          auch funktioniert mein dcf 77 leider nicht. habe das nun bei der Zeitumstellung festgestellt. ich denke jedoch, dass das ein Anschlussfehler ist.

          schonmal vielen Dank !!!

          Techniccontroller · 26/11/2023 at 1:28

          Hallo Jonas,
          dank für deinen Kommentar.

          Ich hatte das Thema mit mehreren LEDs für einen größere Wortuhr bereits mehrfach. Hierbei muss man darauf achten, dass der Speicher des Arduino begrenzt ist. Wenn man die Anzahl der LEDs im Code erhöht, erhöht sich auch der Speicherbedarf des Arduino. Bei Speicherüberlauf bricht das Programm ab (da es sich um Arbeitsspeicher handelt, sieht man das nicht beim Kompilieren). Wenn durch die zusätzliche Anzahl an LEDs kein Mehrwert im Code erzeugt wird, würde ich empfehlen, stattdessen zwei oder drei LED-Strips parallel anzuschließen und mit dem originalen Programm anzusteuern.

          Das funktioniert nicht wenn du 2×2 oder 3×3 LEDs für einen Buchstaben möchtest. für den Fall 2×2 hatte ich mal einen Branch auf GitHub erstellt: https://github.com/techniccontroller/think_wordclock/tree/width22leds
          Hier siehst du überschaubaren Anpassungen im Code. Auch hier werden dann zwei LED-Strips parallel angesteuert und zudem werden immer zwei LEDs hintereinander zusammen angesteuert. Da der Branch dem master-Branch etwas hinterherhängt würde ich dir in diesem Fall empfehlen nur die Änderungen in deinen aktuellen Code zu übernehmen.

          Ich hoffe das hilft dir weiter.

          Beim DCF77 hab ich ja hier in den Kommentaren bereits geschrieben, dass die Orientierung der Antenne sehr wichtig ist.

          Viele Grüße
          Edgar

Matthias · 29/10/2023 at 12:27

Hi Edgar,

I have a PI PICO left. Can I use it to replace the arduino or would this lead to a lot of changes or other drawbacks?

BR

Matthias

    Techniccontroller · 29/10/2023 at 12:57

    Hi Matthias,
    A straightforward replacement of the Arduino with a PI PICO is not possible, especially because I use a few libraries (e.g., Adafruit_NeoMatrix, TimeLib, DCF77, RTClib, EEPROM) that are not compatible with the PI PICO.

    So, if you want to use the PI PICO, you must find alternatives to those libraries or adapt them to the PI PICO. The logic for displaying the time on the matrix you can take over from my code, but this is only 50% of the total effort. So it’s up to you if you want to do this 😉 If you have good experience programming the PI PICO, it should be doable within a few hours.

    Best regards
    Edgar

      Matthias · 23/02/2024 at 20:48

      Hi Edgar,

      Ich habe die Uhr jetzt fertig gebaut, wäre aber noch sehr froh um einen Hinweis zur Fehlversuche. Die LEDs bleiben aber permanent aus. Ich habe sie noch gar nicht leuchten sehen. Die Spannung liegt an, das habe ich geprüft. Was könnte ich denn machen, um die Fehlerursache einzugrenzen?
      Vielen Dank für den tollen Support hier im Kommentarbereich.

      Gruß
      Matthias

        Techniccontroller · 23/02/2024 at 21:34

        Hallo Matthias,

        ich gehen davon aus, du hast die Wortuhr mit einem Arduino Nano gebaut. Ich würde dir vorschlagen, die folgenden Punkte zu testen:

        1. Prüfe ob das Datenkabel vom Arduino (PIN D6) an den DI Pin des NeoPixel-Strip angeschlossen ist. Das Kabel darf nicht an den DO Pin des Strip angeschlossen sein, das wäre die falsche Seite!
        2. Teste die NeoPixel-Strip mit dem Beispielprogramm “strandtest” aus der Adafruit-Library (In der Arduino-IDE -> Datei-> Beispiele -> Adafruit NeoPixel -> strandtest).
        3. Prüfe ob der Arduino das Wortuhr-Programm erfolgreich ausführt. Dazu den Seriellen Monitor öffnen und prüfen ob die Logging-Nachrichten des Arduino ankommen. Falls du Änderungen am Code vorgenommen hast kann es sein, dass das Programm aufgrund von Speicherüberlauf abstürzt, darauf bitte beim Kompilieren achten.
        4. Falls alle oberen Punkte erfolgreich sind, dann kann es sein, dass der Nightmode aktiv ist. Dazu prüfen ob in den Logging-Nachrichten “Nightmode active -> LED OFF” zu sehen ist. Ist dies der Fall ist der Nightmode aktiv, diesen Einschaltzeiten kann über die Konstanten im Code angepasste werden.

        Ich hoffe ich konnte dir damit weiterhelfen.

        Viele Grüße
        Edgar

André · 14/08/2023 at 15:36

Hallo Edgar

von mir auch vielen lieben Dank für das Teilen des Projektes! Ich wollte die Uhr demnächst mal für meine Eltern nachbauen, alle Teile sind schon bestellt und im Zulauf. Finde es richtig toll, dass es hier mal keine webbasierte Version ist (Uhrzeit über Zeitsserver) und sogar mit einem Helligkeitssensor gearbeitet wird. So kommen meine Eltern dann ohne Handy noch besser mit der Uhr klar.
Ich würde mich nur gerne auf eine Vorder- und eine Hintergrundfarbe beschränken. Gibt es ne Möglichkeit, dass ich das “Durchwechseln” der Farben über 2 Hardwarebuttons über einen der Eingänge des Nanos selbst steuern kann?

Grüße
André

    Techniccontroller · 14/08/2023 at 22:30

    Hallo Andre,

    danke für deinen Kommentar. Freut mich, dass du die Uhr nachbauen willst.

    Ja klar, man kann auch durch einen separaten Hardware-Taster den Farbmodus wechseln lassen.
    Ich hab mal provisorisch eine Codeversion auf einem neuen Branch auf GitHub erstellt, um zu zeigen wie das dann aussehen kann (Änderungen zum Original siehst du wenn du den letzten Commit öffnest):

    https://github.com/techniccontroller/think_wordclock/tree/colorchange_via_hardkey

    Ist nicht getestet, weil ich die Uhr gerade nicht zur Hand habe.
    Ich nutze hier nur einen Taster an Pin 7 um den Farbmodus durchzuschalten.
    Du kannst auch noch mehr Farbmodie hinterlegen, allerdings habe ich keine seperate Hintergrundfarben. Nur im Farbmodus 0 wird im Hintergrund ein Regenbogenmuster abgespielt.

    Hoffe das hilft dir weiter. Bei weiteren Fragen gerne melden.

    Vielen Grüße
    Edgar

    Franz HoH · 22/02/2024 at 15:55

    Hallo Edgar,

    super Projekt, gut erklärt, einfach top!!! Vielen Dank!
    Die Buchstaben habe ich bereits aus einer Folie ausgeschnitten. (hat viel zeit und viele Nerven gekostet 🙂 )
    Ich würde die Clock gerne für meinen Bruder nachbauen (ohne dcf77 und lm393), habe mich desshalb ein wenig mit dem Code auseinandergesetzt und bin damit an meine Grenzen gestoßen
    Ich würde gerne wissen wofür der letzte teil im Code zuständig ist und was er überhaupt macht.

    Diesen Teil meine ich:

    uint8_t readGrid(uint8_t x, uint8_t y){
    uint16_t id = x*WIDTH + y;
    uint8_t byteId = id / 8;
    uint8_t bitId = id % 8;
    }

    void writeGrid(uint8_t x, uint8_t y, uint8_t val){
    uint16_t id = x*WIDTH + y;
    uint8_t byteId = id / 8;
    uint8_t bitId = id % 8;

    if(val > 0){
    grid[byteId] = (0x1 << bitId) | grid[byteId];
    } else {
    grid[byteId] = ! (0x1 << bitId) & grid[byteId];
    }
    }

    Vielen dank für deine Bemühungen und dieses tolle Projekt!

    Liebe Grüße
    Franz

      Techniccontroller · 22/02/2024 at 20:32

      Hallo Franz,
      danke für deinen Kommentar.

      Kurz vorweg, der Code läuft auch ohne angeschlossenem LM393 und DCF77, aber natürlich schadet ein angepasster Code nicht ;). Ohne DCF können folgende Zeilen gelöscht werden: 130-144, 159, 204 (+ die dort referenzierten Funktionen). Und Ohne LM393 kann Zeile 174 gelöscht werden.

      Nun zu deiner Frage mit den beiden Funktionen readGrid() und writeGrid():
      Diese Funktionen schreiben/lesen Werte aus der Variable grid[], welche eine Repräsentation der LED-Matrix der Uhr darstellt. Es ist ein Byte-Array, in welchem jedes Bit den Zustand einer LED darstellt. Wenn ein Bit 1 ist, dann soll die LED an sein, und wenn das Bit 0 ist, dann soll die LED aus sein. Im Anschluss muss ich diese Repräsentation nur noch mit der richtigen Farbe auf die Matrix kopieren (drawOnMatrix()).

      Ich habe mich für diese sehr speichereffiziente Art der Repräsentation entschieden weil der Arduino Nano bereits jetzt an seiner Grenze ist (dynamischer Speicher). Als ich gerade nochmal den Code angeschaut haben, habe ich festgestellt, dass in der Weise wie der Code aktuell geschrieben ist, es vermutlich keinen wirklichen Grund gibt das Uhrzeitmuster nochmal als Repräsentation zwischenzuspeichern, anstatt direkt auf die Matrix zu schreiben. Zwischenzeitlich hatte ich allerdings die Ermittlung des Uhrzeitsmusters (timeToString()) nur alle paar Sekunden gestartet und somit brauchte ich diese zwischengespeicherte Repräsentation um das animierte Farbrad im Hintergrund (activeColorID == 0) immer alle 500ms neu zeichnen zu können.

      Ich hoffe das war soweit verständlich für dich. Bei weiteren Fragen kannst du dich gerne nochmal melden.
      Ich wünsche dir weiter viel Spaß beim Bau der Wortuhr.

      Vielen Grüße
      Edgar

Add a Comment

Your email address will not be published. Required fields are marked *