Rainbow Word Clock With a Full Rainbow Effect and More




Introduction: Rainbow Word Clock With a Full Rainbow Effect and More


1) Simple

2) Not expensive

3) As energy efficient as possible

Rainbow Word Clock with a full rainbow effect.

A Smiley on the Word Clock.

Simple IR remote control

Update 03-nov-18 LDR for the Brightness Control of the Neopixels

Update 01-jan-19 Reducing WS2812B power consumption.

Update 15-jan-19 Smiley.

Update 23-jan-19 Code 1.6

Update 10-mar-19 Libraries links

Update 14-apr-19 version 1.7 Choice smiley on/off collor rainbow/fix enz.

Last update 01-jun-19 version 2.0 IR remote control and code redesign

Step 1: The Case for the Clock

With some simple tools and a bit of skill, it's not hard to make a letter clock
I used the materials availible to me.

For the case I used a rough pine bar in which I sawed a few frames. These would make the four sides of the case, which were glued together and reinforced with a small piece of wood in the corners. Then the wood needs sanding and painting.

The letters are cut out of foil by a printer in mirror writing. The foil is at the back of the glass plate and is covered with a double layer pattern paper for better light distribution. The glass is fixated by silicone sealant.

Step 2: Neopixels

The Neopixels LEDs are arranged on a wooden plate.
In this you first drill 3 mm holes. At the front they are enlarged to letter size to 3/4 depth. After that the 3 mm at the back is increased to 10 mm, this is the size of a Neopixel. For some characters among others the W, the hole should be slightly adjusted.

I used plywood which quickly splintered, MDF may be better.

With individual LEDs you are not bound to a fixed distance, which is the case with LED strips.
The LEDs must be connected to each other. You can do this with all short pieces of wire. But the two min (-) connections are just like the two plus (+) connections internally connected, so the same connection.

You can save yourself a lot of work by soldering a piece of wire to the left LED and then to the right LED. Then solder the intermediate ones.

The data connection must of course with short pieces because the data-out goes to data-in.

Step 3: Adjusting Front Text

The front plate is now in Dutch, but simply to convert in any language.

The NeoPixels leds are switched in succession here from 0-167. The numbering goes from the first row at the top left to the right and then to the second row right-to-left etc. Adjusting can be done according to your own needs. The number of NeoPixels is determined by the amount of characters. Less or more Neopixels can be adjusted in the following line

#define NUMPIXELS 168 // How many NeoPixels are attached to the Arduino?

168 is than another number. Numbering starts at 0. You can make any text. If you change the text then you will also have to adjust the corresponding words. The numbering remains the same.

As an example, DRIE of the minutes, is determined in the code

void zetmDrie () {

Led_Aan[56]=1, Led_Aan[57]=1, Led_Aan[58]=1, Led_Aan[59]=1 ; // min-drie


If you want to make the word Arduino then it goes like this:

void zetArduino () {

Led_Aan [38] = 1, Led_Aan [50] = 1, Led_Aan [56] = 1, Led_Aan [93] = 1;

Led_Aan [120] = 1, Led_Aan [135] = 1, Led_Aan [147] = 1; //Word-arduino


So you can make words between.

For clock words it is useful if they form a contiguous word but it is not absolutely necessary. The unused letters do not need Neonpixels. I have them all filled for the use of future possibilities other than time being displayed.

If you change the starting point or change the succession sequence the numbering should change accordingly.

Step 4: Full Rainbow Effect

The clock is now so programmed that there number of times per second is counted how many neopixsels there are switched on.

The total spectrum is about the number of divided and then slightly shifted. As a result, each Neopixel a different color which changes continuously. Neopixel nr 1 and nr 167 follow each other on some color involves.

If you prefer less different colors at the same time, this is easy to adjust. The color shifts still over the entire spectrum but with a smaller part of it. Neopixel nr 1 and nr 167 no longer follow on each other some color involves.

The brightness can be set in the following line,


A smaller number is less and a larger number more brightness.

Step 5: The Various Components

The following components I used

Arduino Pro Mini ATMEGA328 5V/16MHz

Clock Module DS3231

168 pieces Neopixels led's WS2812 LED Chip & Heatsink 5V 5050 RGB WS2811 IC Built-in

Foil letter stencil

DCF77 receiver

Step 6: Code for the Clock

Here is the code.
Added a brightness control and power off when no one is present and at night.

Added RCWL-0516 Radar Microwave Motion Sensor ( search for RADAR )

After 10 minutes of no movement, the NeoPixels go out.

About version 2.0

The memory usage was too much, with runs out of memory warnings in the compiler. That is why I have completely changed the code, but the operation has remained the same and an IR receiver has been added.

There is a piece of code to provide the EEPROM with data.
Run this once by temporarily removing the / * and * /. Search for => run this once to provide the EEPROM with data

At the beginning of the void loop is code to read the code from your own remote control.
You can run this by temporarily removing the / * and * /, don't forget to put them back afterwards. You can also define your own buttons. The code read must be entered in => Define your own buttons here

The Samsung remote control works better than the (very cheap) simple.

Step 7: The Hardware Description

There are different versions of the Arduino Pro Mini. Please note, the connections may differ.

Added a RCWL-0516 Microwave Motion Sensor.

As long as there is movement in the vicinity of the clock, the NeoPixel remain on

and as soon as there is no more movement the NeoPixel go off after a few minutes.

In version 2.0 the DCF77 receiver is supplied with power via pin 13. This pin is defined as output and set high when the DCF77 routine is addressed. The DCF77 receiver uses 0.28 mA and is only needed for a few minutes per day.

Switching off saves

5 Volts * 0.28 mA / 1000 * 24 hours * 365 days * 1 / 0.85 efficiency power supply = 14.4 watts a year.

This doesn't seem like much, but every bit helps.

Step 8: LDR for the Brightness Control of the Neopixels

Added an LDR for the brightness control of the neopixels.

I have glued the LDR into the space of neopixel 103. This one is not used in the time display and therefore does not influence the regulation. The paper damps the incident light, but that is no problem.

The voltage divider of LDR and 20 kohm resistor goes to A0 of the Arduino Pro Mini. The voltage is an indicator of the light intensity and therefore also an indicator of the amount of light that the neopixels have to give.

The formula that I use gives me good light control, it can be adjusted depending on the circumstances. Depending on the light quantity, the voltage can vary between 0 and 5 volts which is converted to 0 to 1024 counts which are in "LDRValue".

If the new measured value is greater than the last calculated value, the intensity is increased by 1, if it is lower than decremented by 1 and if it is equal nothing is done. In order to make the value proceed slowly, so that there is no blinking effect, only 1 is increased or decreased and because the calculation is in the loop it is only recalculated after traversing the loop 25 times.

The intensity is theoretically a minimum of 20 and a maximum of 1024/7 + 45 = 191. The maximum value that I measured was 902, which amounts to an intensity of 173. This fits well with the 150 that I have set as default value. ( see pixels.setBrightness(150) )

In version 2.0 you can set the control via the remote control.
The following parameters have been added: Brightness_min as minimum and Brightness_max as maximum setting and Brightness_Offset as setting parameter. Brightness_min and _max are the values that can depend on your own situation. Brightness_Offset is a value that can be set with the remote control and with which more or less brightness can be set.

There is also a dead band of 3 between measured LDRValue and calculated BerLDRValue values.

Use the print statements in the void BrightnessControl to check the brightness setting.

Step 9: Reducing WS2812B Power Consumption.

The drivers on WS2812B addressable neopixels are drawing current even when the neopixels are off, set to color 0 (no neopixels elements lit).

When all 169 neopixels are out, I measure 69 mA to the neopixels. Assuming that the clock is off 12 hours a day, total shutdown then saves: 5 (Volt power supply) * 69/1000 (Miliampere / 1000 = Ampere) * 12 (Number of hours per day) * 365 (Number of days in a year) = 1511 Watt hours. So on an annual basis 1.5 Kwh. I agree, it's not much in itself, but many small ones make a big one.

The circuit is simple.
The plus of the power supply is switched by a P-channel MosFet. The radar sensor determines whether the neopixels are on or off. I have put two MosFet parrelel to keep the ON resistance as low as possible due to loss of the MosFets. In normal use I measure 4,5 mili volts over the MosFets. The gate is controlled by output 4 from the Arduino via a 470 Kohm resistor. If the output goes to low (0) digitally, the neopixels are on and at a high (1) they are off.

Step 10: Smiley on the Word Clock

A Smiley on the Word Clock.

There appears occasionally a Smiley on the clock.
That makes you happy, however.

The Smiley is triggered by the radar sensor.
The number of times movement (adjustable) is a measure of the appearance of the Smiley. The % signs indicate that motion has been detected. With every tenth (adjustable) movement, the Smiley comes up with a Winky Face and after three times a Winky Face comes the fourth time a Smiley Face sticking tongue out.

The Smiley is a small change in the code.

Step 11: Which Libraries Are Used.

Which Libraries are used.

I use them in Windows 7 with Arduino IDE 1.6 and they have also been tested in Windows 10 with Adruino IDE 1.8.8

RTClib-master https://github.com/adafruit/RTClib/archive/master....

Arduino-DS3231-master https://github.com/jarzebski/Arduino-DS3231

Adafruit_NeoPixel-master https://github.com/adafruit/Adafruit_NeoPixel

Arduino-DCF77-master https://github.com/thijse/Arduino-DCF77

Ken Shirriff's IRremote Library https://github.com/z3t0/Arduino-IRremote/archive/...

Because there is always confusion about the library used, I add the one I use.

The IRremote library uses a lot of memory.
In the IRremote.h it is indicated that you can disable any unused protocol

// Each protocol you include costs memory and, during decode, costs time
// Disable (set to 0) all the protocols you do not need/want!

I have everything disabled except the NEC and Samsung protocol. This gives a memory saving of 10%. At the moment there is no longer a problem with the amount of memory, so for the time being the disableling is not necessary.

Step 12: Simple IR Remote Control

The assembly.

As you can see in the photos, the hole for LED 132 has turned out to be a little too large. I made good use of this and added the IR receiver to it. Connect the data pin of the IR receiver VS1838 to pin 7 of the Arduino. Furthermore connect the plus and minus power supply. The IR receiver uses 0.21 mA and could also be connected to the plus power supply after the FET switch. This results in a saving, if the clock is on 50% of the time, of 5 Volts * 0.21 mA / 1000 * 12 hours * 365 days * 1 / 0.85 efficiency power supply = 5.4 watts per year. This doesn't seem like much, but every bit helps.

Operation is as follows.

Press any key on the IR remote control and then the OK key. The first time you press, you will end up in the IR processing and the second time you will detect whether it was a justified request. The second time OK must follow quickly the first key press because otherwise it goes back again. I made this construction so that I hardly got the first code correctly decoded and therefore did not end up in the IR handling.

Once in the IR handling then a number of LEDs go on for info, for explanation read further and view the first image.

The description is for the simple remote control but you can use any remote control and define your own keys. I also used a Samsung remote control.

The first four keys correspond to the top four rows of LEDs.
Four LEDs turn left or right depending on the setting. When the keys 1 to 4 are pressed, the state is reversed and stored in the memory.

1 fixed color or rainbow effect

2 second flash off or second flash on

3 smiley off smiley on

4 DCF77 off or DCF77 on

The number of the key is displayed on the following keys

5 smiley counter

6 rainbow spectrum width

7 fix red setting

8 fix green setting

9 fix blue setting

Row 6, 7 and 8 of the LEDs now correspond to the set value, row 6 indicates the units, row 7 the tens and row 8 the hundred. Each row starts with the value zero. So the first led in the row is 0 the second is 1 etc.

0 time setting

/\ brightness setting

When the 0 button is pressed, the "ten" LEDs light up to indicate that you want to set the time and when you press 0 a second time, the set time appears on the display.

The time can now be set and is shown in the display.

Set the correct time and then if the minute is the same on a reference clock, press the OK button.

The time is adjusted.

If you do not operate the minutes or hours button, no time change will be made. If you do press them, the time will be set immediately.

The value for keys 5 to 9 can be changed with the keys

right is plus 1

left is minus 1

forward is plus 10

reverse is minus 10.

and for the time setting

right is plus 1 minute

left is minus 1 minute

forward is plus 1 hour

reverse is minus 1 hour

It sometimes happens that the keypress is not recognized or is carried out twice. So pay attention if the setting goes well otherwise try or correct again. The Samsung remote control which I also tested worked many times better than the (very cheap) simple remote control.

When setting the color you see the change directly on the entire display.
For a site with an overview of colors see http://www.helderester.nl/kleurentabel.html. You can of course set any value.

If rainbow spectrum width has a value of 0 the spectrum is very narrow and the display has one color that changes constantly.

The disadvantage of setting the time in this way is that you cannot calculate a summer / winter transition because we have the date incorrect. It doesn't matter for the clock itself because we don't use it now.

Step 13: What Nexts ?

What follows, sound, if the free memory is still sufficient.

I already have the loudspeaker boxes. They are from an old laptop.

LED Contest 2017

Participated in the
LED Contest 2017

2 People Made This Project!


  • "Can't Touch This" Family Contest

    "Can't Touch This" Family Contest
  • CNC Contest 2020

    CNC Contest 2020
  • Robots Contest

    Robots Contest

55 Discussions


1 year ago

Hallo Jan,Nee nog niet alles is nieuw dus steile leercurve.

In de bijlage wat foto's waar ik mee bezig ben. Moet nog 3 rijen ledjes solderen. Zoals je kunt zien heb ik bijna jou voorplaat gebruikt, ik heb het alleen laten lasersnijden.

Bedankt voor de backup,


Reply 4 months ago

En dit is hem dan, auto sync wordclock met Wemos D1 en NTP time server sync....


Reply 4 months ago

Mooie klok geworden. Bij heel Holland bakt zou men zeggen
smaakt naar meer, dus op naar het volgende project.
Mvg Jan.


Reply 1 year ago


Dat ziet er prima uit, wordt beslist een mooie klok.

Mvg Jan.


Reply 1 year ago

Ha die Jan,

Heb je toevallig de code zonder de smiley nog? En kun je me richting geven hoe ik de kleuren wit krijg i.p.v. rainbow?




Reply 1 year ago


Ik heb de code aangepast zodat je een en ander zelf kunt instellen.
I have adjusted the code so that you can set things up yourself.

Mvg Jan


Reply 1 year ago

Hey Jan,

Ik ben er mee aan het experimenteren geweest, een aantal dingen zijn geslaagd. Smiley is uit, ik heb de code aangepast voor 1 kleur dus rainbow doet het niet meer. Het is echter zo dat ik geen andere kleur kan kiezen ook al verander ik de RGB codes.

Ook is het zo dat de ledjes meeknipperen met de seconde led, ik heb maar 1 led an de rest knippert dan mee.

Wanneer ik hem op een externe voeding aansluit heb ik heel veel storing en flikkeren de ledjes.

Wanneer ik een andere scene laad, met bv veel verschillende animaties dan werkt alles naar behoren.

Alvast dank voor je hulp,



Reply 1 year ago


Stuur me de code per mail dan kijk ik ernaar.
Mvg, Jan


Reply 1 year ago

Heb je de kleuren aan het werken?

De lichtvariatie met de seconde knipper zie ik inderdaad ook en zeker bij lage helderheid.
Bij rainbow effect valt het niet zo op omdat daar de kleur toch iedere seconde iets veranderd.
Wordt veroorzaakt doordat de helderheids regeling constant iets verspringt.
Opgelost door in de code + 3 en - 3 toe te voegen en xy < 25 waardoor er niet meer gereageerd wordt op een kleine variatie en iets minder snel.
De regeling wordt trager maar dat is geen probleem.
Je kunt het testen door in je code de regel BerLDRValue = 40; te zetten, zodat er altijd een vaste waarde 40 is.

Lichtflitsen bij aansluiten op externe voeding heeft te maken met hoe je de voedings draden van de UNO en de Neopixels aan elkaar knoopt en de condensator vandaar de vraag.

Mvg Jan.

// *** begin void BrightnessControl ***
void BrightnessControl() {
LDRValue = analogRead(LDRpin); // read the value from the LDR
// calculate the value for the light setting
LDRValue = (( LDRValue / 7 ) + 25 ) ;
if ( xy < 25 ) { xy = xy + 1;
else if ( LDRValue > BerLDRValue+3 ) { BerLDRValue = BerLDRValue + 1 ;
xy = 0;
else if ( LDRValue < BerLDRValue-3 ) { BerLDRValue = BerLDRValue - 1 ;
xy = 0;
else { // nothing to do
xy = 0;
Serial.print(LDRValue); // print the value to the serial port
Serial.print(" ");
Serial.print(" ");
Serial.print(BerLDRValue); // print the value to the serial port
Serial.print(" ");
// BerLDRValue = 40;
// *** einde void BrightnessControl ***


Reply 1 year ago

Hey Jan,

Wat een fantastische ondersteuning bied je, de aanpassing van de code heeft gewerkt, geen knipperende led's meer behalve de seconde LED.

Ben langzamerhand steeds verder richting het gewenste eind resultaat, op dit moment krijg ik de DCF77 module nog niet werkend. De mosfet en de radar moet ik nog installeren en de ldr moet ik nog testen.

Ik krijg wel in blauw funk te zien maar dan wordt ie rood en krijg dus geen signaal.

Bedankt voor de moeite hoor,



Reply 1 year ago


Versie 2.0 komt er spoedig aan. Deze is met geoptimaliseerde code en IR afstandsbediening zodat je alles extern kunt instellen.

Version 2.0 is coming soon. This is with optimized code and IR remote control so that you can set everything externally.

Mvg Jan


Reply 1 year ago

Hey Jan,

Wat is de waarde van jou pull up weerstand voor de DCF klok? Ik krijg hem nog niet aan de praat.




Reply 1 year ago


Ik weet niet welke DCF module je hebt maar de weerstand waarde lijk me niet direct het probleem. Ik heb aansluitingen gezien met 10K ohm maar ook wat ik heb
gedaan zonder weerstand.

Zelf heb ik een RPC module DCF77. Dat is een oude ontvanger voor een computer op de seriële poort welke hoogohmig is.

De oplossing moet je meer zoeken in de ontvangst,
wat zie je in de seriële monitor?

Probeer eens dichter bij een raam voor beter ontvangst en/of de module zelf verder van de klok af zetten door er één meter draad tussen te zetten.

Er zijn ook modules die een geïnverteerd signaal leveren, maar dat zou in de DCF77 library opgelost zijn. Hier heb ik geen ervaring mee.

Verder zou je eens op de site van Thijs http://thijs.elenbaas.net/2012/04/arduino-dcf77-radio-clock-receiver-library/
moeten kijken, hier staat het goed beschreven wat je moet zien in de seriële monitor.
Je kunt de test software downloaden naar je Arduino, hiervoor hoef je niets los te halen.

Verder een link met een inverter probleem oplossing https://ednieuw.home.xs4all.nl/Woordklok/DCF77/DCF77_Arduino.html
en een met een signaal aanpassing http://www.hjberndt.de/soft/rtctftdcf.html

Maar de ontvangst conditie lijkt me het grootste probleem.

Geef eens aan wat je klok moet doen buiten alleen de tijd aangeven, mogelijk kan ik je idee overnemen, sta open voor suggesties voor mijn
andere klok project.

Succes Jan


I do not know which DCF module you have but the resistance value does not seem to me to be the problem. I have seen connections with 10K ohm but also what I have done without resistance.

I myself have an RPC module DCF77. That is an old receiver for a computer on the serial port which is highly resistive.

You have to look for the solution more in the reception,
what do you see in the serial monitor?

Try closer to a window for better reception and / or to move the module itself further away from the clock by putting one meter of wire between them.

There are also modules that provide an inverted signal, but that would have been resolved in the DCF77 library. I have no experience with this.

Furthermore you should take a look at the site of Thijs http://thijs.elenbaas.net/2012/04/arduino-dcf77-radio-clock-receiver-library/
here it is well described what you should see in the serial monitor.
You can download the test software to your Arduino, you do not have to disconnect anything.

Furthermore, a link with an inverter problem solution https://ednieuw.home.xs4all.nl/Woordklok/DCF77/DCF77_Arduino.html
and one with a signal adjustment http://www.hjberndt.de/soft/rtctftdcf.html

But the reception condition seems to me to be the biggest problem.

Specify what you need to do outside of the clock, just indicate the time, possibly I can take over your idea, be open to suggestions for my other clock project

Good luck Jan


Reply 1 year ago

Goedemorgen Jan,

Bedankt voor al deze waardevolle tips, ik zal er eens mee aan de slag gaan en je laten weten wat de vorderingen zijn.




Reply 1 year ago

Hey Jan,

Klinkt goed kerel, ik heb de komende weken wat meer tijd en zal eerst de DCF in gebruik nemen en dan me op de rest concentreren. Maar het klinkt goed al die vernieuwingen, maak je het wel modulair dat het ook uitgeschakeld kan worden?




Question 6 months ago

Hi Jan,
if i use remote xinda need to modify your code or not?
if yes, how can i find xinda IR code?

// SAMSUNG code
#define button_r 0x898943BC // button > => + 1
#define button_fw 0x898941BE // button /\ => + 10
#define button_l 0x898944BB // button < => - 1

how to add function AM PM :) please advise

Thank you.


Answer 6 months ago

Hello WinnerW,
"void loop" begint met een aantal regel waarmee je de code van je afstandsbediening kunt uitlezen in de seriële monitor.
Deze moet je even uit commentariëren, zie “change this line to read the code”, run het programma en je weet de codes. Vervolgens vul je ze in bij “define button”.

"void loop" starts with a number of lines with which you can read the code of your remote control in the serial monitor.
You have to comment this out, see "change this line to read the code", run the program and you know the codes. Then enter them in the "define button".

void loop() {

// /* change this line to read the code
// *** use this piece of code to find out the IR codes ***
Led_Aan[53] = 1, Led_Aan[90] = 1, Led_Aan[122] = 1 ;
e = 13 ;
NeoPixelsOnOff(); // call NeoPixels On Off
Serial.println(" read IR codes ");
while(1) {
if (irrecv.decode(&results)) {
Serial.print(" ");
Serial.println(results.value, HEX);
Serial.println(" ");
// *** end of code to find out the IR codes ***
// */ change this line to read the code

AM of PM.
Je kunt bij het bepalen van 12 uur een bool toevoegen om AM of PM te onthouden en vervolgens een led aanzetten.
Code zou iets kunnen worden als onderstaand, zelf niet getest en kan mogelijk nog slimmer.
Ik heb geen rekening gehouden met AM en PM en dus ook geen letter AM of PM ter beschikking. Je moet er zelf dus maar iets van maken b.v. door % tekens te gebruiken, de linker dan wel rechter kolom aan te zetten, of extra leds toe te voegen.

AM or PM.
When determining 12 hours, you can add a bool to remember AM or PM and then turn on an LED.
Code could become something like the one below, not tested itself and could possibly be smarter.
I have not taken AM and PM into account and therefore no letter AM or PM available. So you have to make something of it yourself, e.g. by using % characters, turning on the left or right column, or adding extra LEDs.

bool AMPM = true; // AM = true and PM = false

AMPM = true; // AM
uren = dt.hour ;
if (uren >= 12) {
uren -= 12;
AMPM = false; // PM

add to "void ledaanzeten ()"
if (AMPM == true) {
Led_Aan[xx] = 1, Led_Aan[xx] = 1 ; // AM on
Led_Aan[yy] = 0, Led_Aan[yy] = 0 ; // PM off
else {
Led_Aan[xx] = 0, Led_Aan[xx] = 0 ; // AM off
Led_Aan[yy] = 1, Led_Aan[yy] = 1 ; // PM on

Success, Jan


Reply 6 months ago

Thank you for your feedback :)


Question 1 year ago

Hi Jan,
Can you add button for setting Fix color, rainbow, Hours,minutes, Thanks.


Answer 1 year ago

Hello WisonC,

Do you have the clock working?

I'm working on a simple IR remote control.
This is almost finished. So buttons are not necessary.

As long as you still have to adjust it in the code.

I have a DCF module so the time is adjusted automatically.
What do you want for what concerned the time actually set,
correction with sec, minutes, summer / winter transition or total date and time.
I have the same kind of question from someone else.
Let me know and I will look at it if I have the time.