loading

This clock uses five MAX7219 8x8 LED matrices to display a clock.

The two left units display the hour, the right two the minutes, and the middle matrix counts off the seconds. This is accomplished by illuminating one LED per second, counting across each row. The 8th LEDs in alternate rows are skipped, thus two rows count 15 seconds; the full 8 rows tick off one minute.

I am running an Arduino Mega 2560, but this should on most models.

I've learned from many Arduino projects posted to this site, and appreciate members' expertise. I've tried, especially in the sketch listing itself, to explain points I think might be unclear to a newer user.

Any feedback is welcome.

Step 1: Assemble and Wire Your Matrices

Rather than duplicating effort, you are referred to the excellent Multiple LED Matrices with Arduino. In this case, however, wire a fifth matrix in series with the others. You will, of course, need one more matrix and another set of jumpers.

Step 2: Realtime Clock Notes

My realtime clock (RTC) turned out to be a dud and the new one has not yet arrived from HK. The time is therefore set manually; time is kept using the internal clock.

Step 3: Displaying Digits

As this is my first nontrivial project and I am learning as I go, I started with the Makepeace Madrid's LED matrix library LedControlMS.h used in their 4-LED scrolling text example.

The function displayChar takes two integer arguments: the matrix number addressed--starting with zero--and the character to display. Simply pass this function the numbers 0-9 to display those digits.

Since one LED matrix will not display two characters, each digit of the hour and minute must be isolated to a single variable. These are isolated from the hour and minute in the following way:

  • 1st digit: integer division by 10. This throws away the remainder (e.g., 43 so divided results in 4.3 with the 3 thrown away, therefore 4 (the first digit) is returned.
  • 2nd digit: modulo division by 10, returning the remainder (e.g., 43 so divided results in 3.)

I think a blanked first digit looks better than a leading zero, and thus fed displayChar a non-displayable character.

Note that the numbers are displayed left-justified on each LED matrix. I have not investigated correcting this.

Step 4: Seconds

Since I have 5 matrices, I decided to stick the 5th one between the hours and minutes, marking off seconds by illuminating a single LED across each row in turn, using the setLed function. Its arguments are: LED number (again, counting from 0), row, column, and a Boolean (true= on). For some reason, row and column are interchanged on my matrices, so I reversed them.

I used nested loops, testing for the 8th LED on even rows in order to skip. I'm sure there are more elegant ways to write this, but I'm just getting started in C and have not programmed in years.

Step 5: The LED Clock Sketch

/*This sketch runs a clock with five LED matrices based on MAX72xx chipset.
An example that shows writing and scrolls text across 4 LED matrices is shown at
https://www.instructables.com/id/Multiple-LED-Matrixes-with-Arduino
This sketch uses the LedControlMS.h (from Makerspace) from the page above, a modificarion of the LEDControl.h library.
This sketch uses the Arduino time & wire libraries, and the DS3131RTC (DS3232RCTC Library)
Sketch assumes the following wiring for the MAX72xx LED matrices--
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
Dataout (middle output pin) is daisy-chained to the DataIn of the next LED for each matrix except the last.
Wiring for the DS3231RTC
VCC and ground are connected to +5VDC and Gnd, respectively
Clock SDA --> Analog 4
SCL --> Analog 5
*/

#include <DS3232RTC.h> // DS3232RTC Clock library that also handles DS3231RTC
#include <Time.h> //Used for clock
#include <Wire.h> //Used for clock
#include "LedControlMS.h" // Note that this is not library LEDControl
int h1, h2, m1, m2; //Each LED matrix will display one number: hour 1&2, minute 1&2. These variables hold the single digits
int s1=2; // LED that counts off the seconds
int hr12; //Used for 12 hour time
int noMatrix=5; //Number of matrices. The library addresses up to 8.
boolean am=true; //To mark am or pm. Initialize as am
LedControl lc=LedControl(12,11,10,noMatrix); //Pin assignments and number of matrices (5)

void setup() {
//First, set the system time to a hard-coded date and time, and then sets the RTC from the system time.
//The setTime() function is part of the Time library.
// Hr Min Sec dd mm yyyy
setTime(18, 18, 30, 25, 11, 2014); //Manually set Arduino clock
//RTC.set(now()); //set the RTC from the system time

//Initialize the MAX72XXs (in power-saving mode on startup--wakeup call.
for (int i=0; i< noMatrix; i++){ //For each of the matrices...
lc.shutdown(i,false);
lc.setIntensity(i,1); // Set brightness to a low value
lc.clearDisplay(i); // Clear the display
}
delay(100); // Wait between updates of the display
lc.clearAll();
}

void loop() {
// Set am or pm Boolean (am was initialized as true)
if (hour() > 12)
{am=false;
hr12=hour()-12;
}

/* Isolate hours and minutes, one digit to each LED matrix.
I think a single-digit hour looks better with a blank first digit.
*/
//Place each digit of the hour in its own variable, h1 and h2
if (hr12 < 10)
{
/*
Blank 1st LED matrix if <10 hrs. (62 is a blank character.)
Could also insert a zero, as with minutes.
*/
h1=151;
h2=hr12; //2nd LED displays single digit of hour
}
else
{
//Othewise, just use the two digits of the hour on h1 and h2.
h1=hr12/10; //Integer division by 10 returns the first digit of the hour.
h2=hr12 % 10; //Modulo division by 10 returns the 2nd digit.
}

//Minutes are displayed by m1 and m2
if (minute() < 10)
{
m1=0; //First minute LED d1splays zero
m2=minute(); //2nd digit of minutes
}
else
{
m1=minute()/10;
m2=minute() % 10;
}

/*
Display hours and minutes using the displayChar function. This uses two integer arguments:
the LED matrix number (0-7) and the character to be displayed. Numbers are displayed simply
by passing the number itself as the 2nd argument: that is, lc.displayChar(0,h1)
*/
lc.displayChar(0,h1); //Hours 1 digit to left-most (#0) LED.
lc.displayChar(1,h2); //Hours 2 digit to LED #1
lc.displayChar(3,m1); //Minutes 1 digit to LED #3. (Recall that #2 is used to mark off the seconds.)
lc.displayChar(4,m2); //Minutes 1 digit to #4

/* This routine determines which single LED to light to count off the seconds.
The middle LED counts off the seconds by illuminating a single LED at a time
across each of the 8 rows. Count 8 LEDs across odd rows, and 7 across even rows.
Thus, two rows count 15 seconds.
*/
for (int r=7; r > -1; r--){ //For each of 8 rows, starting from the top (#7)...
for (int c=0; c < 8; c++){ //For each of the 8 leds in a row (0 on left)...

/*
Illuminate dot on current column and row. These seem to be interchanged on my hardware.
I therefore swapped the arguments to the setLed() function below.
Properly, it is addressed as setLed(int led#, int row, int col, boolean).
Variable s1 holds the LED number (counting from 0) of the LED matrix used for this.
*/

if (r%2 == 0 && c==7) //Even row AND col 7
{}
else
lc.setLed(s1,c,r,true); //Turn addressed LED on for 3/4 sec
delay(750);
lc.setLed(s1,c,r,false); //Turn off for 1/4 sec
delay(250);
}
}
}
}

Step 6:

<p>Thanks for the well documented instructable and the commented code.</p><p>After some modification of your code, I made it for 4 screens and 22-h time.</p><p>Only problem is that it doesnt read the DS1307RTC (after a lot of effort) and the characters are rotated 90degrees so the clock is vertical!</p><p>If I achieve to adress those issues I think it will be a great clock.</p><p>I m thinking of adding two dots in the middle for seconds too.</p><p>Regards and thank you again</p><p>P.S I attach a minor correction of your code</p>
My apology for the delayed reply: been occupied. <br><br>I do not have a DSC 1307 RTC, but I understand that the newer unit is addressable in the same way. In any case, you got it going: congratulations!<br><br>Now that you made one, I do think I prefer the vertical format: it would go well on a wall, I think. <br><br>Some LEDs seem to display 90 degrees rotated from the orientation I'd expect. My LED modules are discrete (separate), so I just turn each one whichever way I want, and attach them to a base or stick them on a breadboard. Possibly, yours are mounted in a line on some sort of board? If so, you'd need to rewrite the library, I believe, swapping the row/column definition of each digit.<br><br>What is that device to the bottom right of your matrices? Looks to be an IR detector--did you incorporate one into your circuit? (Light up the matrices only when it detects a warm body?)<br><br>Well done!
<p>Thank you for the comment! The little device at the bottom right is the DS1307RTC! A lot has happened since Satyrday! I rewrote the code a few times, and redesigned the 0123456789 numbers in the LedControlMS.h so that they would be rotated 90 degrees (unfortunately to do this the numbers had to be 2 pixels shorter).But thankfully now I have a horizontal watch!</p><p>Oh and now I m working on the casing....As I woodworker I will enclose it between two oak planks! I think it ll look nice. </p><p>I also made a few attempts to incorporate two button, a slide switch and an alarm buzzer in order to turn this into an alarm clock, but my code didnt work unfortunately. Havent found the courage to continue coding, so I'll call this a finished project for the time beeing!</p><p>Thanks for the instructable again!</p><p>P.S</p><p>I might make an instructable as well if I achieve to add an alarm!</p><p>Regards</p>
<p>any chance of a copy of your code?</p>
<p>Certainly: just copy &amp; paste it from step 5. Have fun!</p>
<p>Oh and I forgot to add that I solved the issue with the DS1307RTC.</p><p>The clock can be unplugged without losing the time now.</p>
<p>I don't have a RTC so I was trying to program the time manually. However, I don't have the 'Time' library so none of those functions are working.. Any idea where I could download it?</p>
<p>info: <a href="http://www.pjrc.com/teensy/td_libs_Time.html" rel="nofollow"> http://www.pjrc.com/teensy/td_libs_Time.html</a></p><p>info: <a href="https://github.com/PaulStoffregen/Time" rel="nofollow"> https://github.com/PaulStoffregen/Time</a></p><p>download library (&quot;zip&quot; file)</p><p><a href="https://github.com/PaulStoffregen/Time/archive/master.zip" rel="nofollow">https://github.com/PaulStoffregen/Time/archive/mas...</a></p>
<p>Allow me to congratulate you on one of the finest instructables on led arduino clocks.</p><p>May I ask if the DS3221RTC code will work if I use the DS1307RTC instead (I ve already bought some of those since I hadnt seen you instructable) ? I m asking this because the DS1307RTC also has the same exits (SDA SCL GND and VCC). Otherwise I ll search for the specific code of course in the Arduino playground.</p>
I have built this clock on a breadboard but I am struggling to get the sketch to work. At first all I could get on the first display was a mishmash of leds to light up. I have now reworked the code to get a zero to display on the first LED matrix (I prefer it this way) but now I cannot get the hour to increment when minutes goes to zero (after 59 mins). Anyone have any ideas?
Misbehaving LED matrices meant that I had connected something incorrectly or called out the incorrect pin number. I also found that my off-brand devices occasionally needed to be power-cycled a couple of times.<br><br>The leading zero is a matter of taste. Congratulations for modifying the provided sketch!<br><br>Did you get the hours to display, but do you mean, for instance, that it shows<br>...09 58<br>...09 59<br>...09 00 <br>?<br><br>Check that the hour digits increment properly with the Serial.print() function: that will verify that you have the correct values written to the variables. Double-check that the correct digit is being written to each LED matrix.<br><br>One of my favorite FSMs (forehead-slapping moments) is discovering that I have, for instance, set a variable to a particular value rather than reading it during the loop.<br><br>Please post an update, thanks.<br>
Thanks for the reply. Yes I do mean<br>9:58<br>9:59<br>9:00<br>The hour is not incrementing. I copied/pasted the sketch from the Instructables web page as I couldn't find a link to the sketch. I have checked and rechecked the wiring and have rebuilt the circuit a couple of times but still end up with the same result. I have checked the sketch and there is no serial print command. Have I got the right sketch or is there a link to another sketch somewhere. You will have to forgive &quot;stupid&quot; questions as I am trying to learn this new fangled wizardry and I am 60 years old.
<p>No such thing as a stupid question: that's the way one learns. I turned 60 a few days ago, and am relatively new at this new-fangled wizardry as well.</p><p>I did not link the sketch to the Instructables page; you copied the one I had posted. I did not include the Serial.Print() function in that sketch: you will need to add it yourself.</p><p>--&gt;In the void setup() section, add the line</p><p>Serial.begin(9600);</p><p>--&gt;In the void loop() section, add these 4 lines</p><p>Serial.print(&quot;Hours=&quot;);</p><p>Serial.print(hr1); // Print hour, digit 1, to the computer screen</p><p>Serial.println(hr2); // Print hour, digit 2, to the screen and skip to next line</p><p>delay(1000); // Wait 1 sec (adjust to your taste... 2000=2 seconds, etc.)</p><p>Save the modified sketch over the old one (or use Save As to create a new one if you wish.) With the computer connected to your Auduino, upload the sketch as usual. </p><p>With the devices still connected, press the magnifying glass at the top right of the Arduino IDE. Ensure the number at the top is set to 9600 in the drop-down.</p><p>This will print the contents of h1 and h2 (the hour digits) to your computer screen at each loop, and wait 1000ms (1 sec) so the results do not disappear off the screen in an instant.</p><p>The variables h1 and h2 contain the digits the Arduino is telling your LED matrices to display. Let's see what they say.</p><p>My email is pgmanney (at) yahoo.com, if you'd like to shoot me a message directly--to send me your sketch, for instance.</p>
<p>Excellent project and tutorial. Keep on experimenting and learning:-)</p>
Smart idea! Thanks for shearing :)
<p>Very nicely done! I'm building up the nerve to take on my first microcontroller project, so I really enjoy seeing stuff from other arduino-newbies.</p>
​Thanks! What will your first project involve? My next is a garage car-distance sensor (several on this site, but I like to write my own code.)<br><br>If you wish to spend the extra money, my best suggestion for a newer user is to buy components from a vendor that offers examples or tutorials featuring their specific offerings. I bought my LED matrices from an eBay vendor for $15. All well and good, but as far as making them work, I was completely lost until I ran across this site and could study working code.<br>
<p>Cool. I'm not sure what I'd like to make, but it will surely include several other disciplines to make it interesting. Maybe a little woodwork, some carving, and perhaps a bit of sewing. No concrete plans yet though!</p><p>Thanks for the tips!</p>

About This Instructable

34,447views

45favorites

License:

More by PM4:Basement Flood Alarm - Arduino Arduino Binary clock using LED Matrix Arduino LED Matrix Clock 
Add instructable to: