Word Clock

About the project

This is an LED word clock. It light up letters in a grid to spell out the time.

Project info

Difficulty: Moderate

Platforms: Espruino

Estimated time: 1 day

License: GNU General Public License, version 3 or later (GPL3+)

Items used in this project

Hardware components

USB power supply USB power supply x 1
AB26T-32.768KHZ-6 Crystals 32.768KHz 6pF 32.768KHZ AB26T-32.768KHZ-6 Crystals 32.768KHz 6pF 32.768KHZ x 1
114990308  ARM Espruino Pico unpinned 114990308 ARM Espruino Pico unpinned x 1
Thick card and tools to cut it Thick card and tools to cut it x 1
88 WS2811 LED lights - for an 8 x 11 grid 88 WS2811 LED lights - for an 8 x 11 grid http://www.espruino.com/WS2811 x 1
Deep picture frame Deep picture frame x 1

Software apps and online services

Espruino Web IDE Espruino Web IDE

Hand tools and fabrication machines

Soldiering iron Soldiering iron x 1

Story

Assembly


Measure and cut the card into 10 x 7 strips as above (measure them to fit the picture frame that you have), and assemble them.

We've left gaps for the WS2811 LEDs and their wires- however we used a string of LEDs. If you buy your LEDs in flat strip you won't need to cut out any large gaps.

Fit in the LEDs in an 'S' shape, and glue them securely with hot glue. Make sure know which end of the LED chain is the input and which is the output! Consult the WS2811 page if you're not sure.

Print out a pattern of letters that matches your grid. We did this on plan paper and mirrored it, so that the white paper faces the viewer. However you could do it the other way, or could use acetate and a diffuser.

If you print out the text as we've done, try and do it on a laser printer or photocopier. Printing lots of black on thin paper with a normal inkjet printer will cause it to warp slightly and look ugly.

Now assemble everything, and wire up to the Espruino board as follows:

And you're done! On to the software...


Software

Load the code below into Espruino, type save(), and you're sorted!

To set the time, you'll have to modify the 'h', 'm' and 's' variables (hour, minute, and second).

  1. // The indices of each word
  2. var words = {
  3. "its":[76,77,54],
  4. "_five":[80,51,58,29],
  5. "_ten":[75,74,73],
  6. "_quarter":[79,52,57,30,35,8,13],
  7. "_twenty":[75,78,53,56,31,34],
  8. "_half":[32,33,10,11],
  9.  
  10. "past":[72,81,50,59],
  11. "to":[36,7],
  12.  
  13. "one":[71,82,49],
  14. "two":[70,83,48],
  15. "three":[60,27,38,5,16],
  16. "four":[69,68,67,66],
  17. "five":[84,85,86,87],
  18. "six":[28,37,6],
  19. "seven":[61,26,39,4,17],
  20. "eight":[47,62,25,40,3],
  21. "nine":[17,18,19,20],
  22. "ten":[15,16,17],
  23. "eleven":[46,63,24,41,2,19],
  24. "twelve":[45,64,23,42,1,20],
  25. "oclock":[44,65,22,43,0,21],
  26.  
  27. "pico" : [55,9,12,14]
  28. };
  29. // set up SPI
  30. SPI2.setup({baud:3200000, mosi:B15});
  31. var arr = new Uint8Array(8*11*3);
  32. var pos = 0;
  33.  
  34. // Hue to RGB - we use this to work out what colour to set each word
  35. function HSVtoRGB(h, s, v) {
  36. var r, g, b, i, f, p, q, t;
  37. if (h && s === undefined && v === undefined) {
  38. s = h.s, v = h.v, h = h.h;
  39. }
  40. i = Math.floor(h * 6);
  41. f = h * 6 - i;
  42. p = v * (1 - s);
  43. q = v * (1 - f * s);
  44. t = v * (1 - (1 - f) * s);
  45. switch (i % 6) {
  46. case 0: r = v, g = t, b = p; break;
  47. case 1: r = q, g = v, b = p; break;
  48. case 2: r = p, g = v, b = t; break;
  49. case 3: r = p, g = q, b = v; break;
  50. case 4: r = t, g = p, b = v; break;
  51. case 5: r = v, g = p, b = q; break;
  52. }
  53. return [Math.floor(r * 255),Math.floor(g * 255),Math.floor(b * 255)];
  54. }
  55.  
  56. // Given an array of words, set the relevant LEDs to light up
  57. // in rainbow colours
  58. function getPattern(wordList) {
  59. arr.fill(0);
  60. var i = 0;
  61. pos+=0.05;
  62. wordList.forEach(function(word) {
  63. words[word].forEach(function(led) {
  64. arr.set(HSVtoRGB(i+pos,1,1,1),led*3);
  65. });
  66. i+=0.2;
  67. });
  68. }
  69.  
  70.  
  71. // Convert hours and minutes (seconds are ignored) into a string such as '_five minutes past six'
  72. // We prefix the first part with an underscore so we don't accidentally light the wrong 'five' up
  73. function timeToWords(h,m,s) {
  74. var mins = ["","_five","_ten","_quarter","_twenty","_twenty _five","_half"];
  75. var hours = ["", "one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];
  76.  
  77. var str = "its ";
  78. // the nearest 5 minutes
  79. var midx = Math.round(m/5);
  80. var hidx = h;
  81. // work out if we're 'past' or 'to' and adjust hour accordingly
  82. if (midx>6) {
  83. if (midx==12) midx=0;
  84. hidx++;
  85. if (hidx>12) hidx -= 12;
  86. }
  87. // finally output minutes and hours
  88. if (midx!=0) {
  89. if (midx<=6)
  90. str += mins[midx]+" past ";
  91. else {
  92. str += mins[12-midx]+" to ";
  93. }
  94. str += hours[hidx];
  95. } else {
  96. str += hours[hidx];
  97. str += " oclock";
  98. }
  99. // print it out for debugging
  100. console.log(h+":"+m+":"+s+" "+str);
  101. return str;
  102. }
  103.  
  104. // Very simplistic timekeeping...
  105. var h=5,m=59,s=0;
  106. setInterval(function() {
  107. // increment seconds
  108. s++;
  109. if (s>=60) {
  110. // if seconds goes to 60, inc minutes, and so on...
  111. s=0;
  112. m+=1;
  113. if (m>=60) {
  114. m=0;
  115. h++;
  116. if (h>12)
  117. h=1;
  118. }
  119. }
  120. // Get the time as a string
  121. var timeWords = timeToWords(h,m,s);
  122. // convert it to an array of words and light up the LEDs
  123. getPattern(timeWords.split(" "));
  124. SPI2.send4bit(arr, 0b0001, 0b0011);
  125. }, 1000);

You could also add a way to use buttons to set the time, or you could even use some Internet connectivity to get the time off the net, or GPS to get it from the Global Positioning System.

Code

Source code

Credits

Photo of Espruino

Espruino

Espruino, Espruino Pico and Puck.js are low-power Microcontrollers that run JavaScript. Espruino is a JavaScript Interpreter for Microcontrollers that is designed to make development quick and easy. The Espruino interpreter is firmware that runs on a variety of different microcontrollers, but we also make Espruino Boards that come with the interpreter pre-installed and are the easiest devices to get started with. However Espruino itself isn't just the interpreter firmware or hardware - there's also the Web IDE, command-line tools, documentation, tutorials, and modules that form a complete solution for embedded software development.

   

Leave your feedback...