Homemade DIY word clock – Part 3

Introduction

Obsolete information! Please view this article for a complete and easier guide!

In this part I’ll discuss the code, needed to set and read the current time from the RTC and to control the individual LEDs on the LED matrix:

LED matrix addressing

With this IC, and the method we built the LED matrix, you can individually turn on and off each LED on each of the three boards. This is done by telling the MAX7219 IC the row and the column you want to turn on. The LED that sits at the intersection between row and column is going to be illuminated.

The three boards are controlled by individual ICs, so if you want to turn on an LED on the third board, you have to send the row and column information to the third chip, which is luckily possible by daisy-chaining the DIN and DOUT pins together as well as the CLK signal.

If you remember part 2 of the series, you might also remember the circuit diagram of the LED matrix, which I didn’t include a picture of in the article. However it looks like this:

wordlcock-matrix-schematic
Figure 1: The LED matrix schematic

As you can see, the right corner is missing 16 LEDs. Why? The explanation is easy: I wanted my clock to have 12 rows and 12 columns of characters, so 144 LEDs in total. Each IC can control an 8×8 matrix, so 64 LEDs per chip. However if you divide 144 by 3, you’ll end up with 48 LEDs per IC. You could simply control 128 LEDs with the first two chips and 16 with the last one, but that makes addressing them more complicated. My method is also easier to design and manufacture, because you only have to create one design. However with this design I had to be creative with the placement of the LEDs.

So the LEDs on my PCB are addressed the following way:

led-matrix-addressing
Figure 2: LED matrix addressing

That’s why the LEDs in the video above don’t light up from left to right in one sequence, because the test program simply writes to each address one after another.

It’s not a big deal though. You just have to remember this while coding. Note that if you try to address the LED G0 for example, which would be on the bottom right corner, nothing will happen. This is also the reason why the last LEDs in the video above have a slightly longer delay after each row, because the test program addresses the LEDs that are not on the board.

The test program

You can get the test sketch here.

I recommend, you test the matrix boards individually before proceeding with the build, just to make sure, that all your LEDs are working and the wiring is correct.

The code

Now we finally get to the code. I won’t write a lot about it here, the comments in the code should explain everything just fine. If you have questions regarding the code or this build in general don’t hesitate to leave a comment or contact me directly, if you want to.

Also, I won’t include the entire code, because it’s just way too long. So if you’re interested in viewing it, you can download it. The download link is under the code.

Just one more thing: before you can compile and upload the code, you’ll have to download the LedControl library and the Sodaq DS3231 library and put them in your Arduino IDE’s library folder. Oh yeah, almost forgot to mention: This is an Arduino sketch.

#include "LedControl.h"

// Struct used to hold the information needed to display a word
// by lighting up several LEDs. For example the word 'four' is
// composed by lighting up 4 individual LEDs that are placed on
// one ore more rows on one board. So the struct holds the
// informations about the board and the rows and which LEDs to
// turn on in that row.
struct LEDData
{
   unsigned short device;
   unsigned short rows[8]; // DP-G ! Indizes start with 1 !
   byte rowData[8];
};

unsigned const short dataLength = 8;
bool tested = false;

// DIN, CLK, CS, number of connected Displays
LedControl lc = LedControl(12, 11, 10, 3);

// Some LEDDate definitions
// See the watchface from part one for reference
LEDData itIs = {0, {1}, {B11011100}};

LEDData past = {0, {4}, {B11110000}};
LEDData to = {0, {3, 6}, {B11111110, B11000000}};

LEDData quarter = {0, {2}, {B01111111}};
LEDData half = {0, {6}, {B11110000}};

LEDData oclock = {2, {8}, {B01110000}};

LEDData numbers[] =
{
   {0, {4, 8}, {B00000111, B10000000}}, // One
   // (...) see full code
   {2, {4}, {B11111100}} // Twelve
};

LEDData welcome = {1, {3, 7}, {B00011111, B11000000}};

Basically these informations are then used to illuminate LEDs. A sentence is composed by several words which are connected together with a logical OR to form a sentence. The following code displays one word:

void displayData(LEDData data)
{
    // All LEDs of one board, 64 in total
    byte b[] = { B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000 };

    for (int i = 0; i < dataLength; i++)
    {
        if (data.rows[i] == 0)
            break;
        else
        {
            b[data.rows[i]-1] = data.rowData[i];
        }
    }

    // Send the data to the display driver
    for (int u = 0; u < 8; u++)
    {
        lc.setRow(data.device, u, b[u]);
    }
}

So 1 Matrix element is set at a time.

The rest of the code is just needed to read/set the time of the RTC and to form words out of the LED Data mentioned above. These parts are not very interesting, so I didn’t include them here. If you are interested in the whole code, you can download it here.

Download the code here: (Not uploaded yet, needs some bug fixes)

In the next part…

… I’ll put together everything you need to build this at home in one zip package, so you don’t have to collect the necessary files in the individual parts of this series. I’ll also show you how I put the clock together.

Table of contents

Part 1 – First steps 
Part 2 – The Electronics
Part 2.1 – Quick update and Board Rev. B
Part 3 – The Software (You are here)
Part 3.1 – Updated Revision
Part 4 – Completing the build (Not released yet)

Addendum:

Part 5 – Low cost variant

comment-banner

5 thoughts on “Homemade DIY word clock – Part 3

Leave your two cents, comment here!

This site uses Akismet to reduce spam. Learn how your comment data is processed.