This LED Matrix Clock is a feasability study for a much larger project I built for my employer. The intention was to prove to myself (and my employer!) that I was able to drive an LED matrix from a PC. This is the first project I have made which is driven by a PC. The clock uses 3 B64CDM8/B48CDM8 8x8 5mm LED Matrix modules from Nexus Machines, each having an onboard MAX7219 display driver chip. These require an SPI serial interface, which I by toggling pins of the host PC's parallel port (printer port). The small software application which drives the displays is written in Delphi 5 and runs on Windows NT 4.
LED Matrix Modules
The Nexus Machines modules used are an assembly having 64 LED's (8x8 matrix) set in moulded plastic, with a PCB mounted on the back containing a MaximMAX7219 display driver chip. For evaluation purposes we purchased 2 of the large modules (B64CDM8-R, 60mm square) with Red LED's, and one of the medium-sized modules (B48CDM8-G, 38mm square) with Green LED's. I could have made an LED display matrix using discrete LED's, however for the size of the future project the assembly and connection of so many discrete LED's, not to mention electronics for driving them, would be formiddable. The modules have 5 connection pins on either side and the moulded cases have slots to enable stacking. In this way it is easy to cascade several modules to create a much larger matrix. The modules are available from RS components (stock number 321-0991), or more cheaply from Farnell (stock number 301-4058), or EVEN more cheaply (in large quantities) direct from Nexus Machines themselves.
Circuit Diagram
Because all the hard work is taken care of my the MAX7219 on the PCB of the modules, the amount of wiring required is minimal! This diagram shows the connections between modules, and the pin numbers on the standard 25-pin PC parallel port connector. I am using a packaged power supply, which is capable of supplying +5V at the required 1A current (maximum current per module with all LED's on at maximum brightness is specified as 330mA). This diagram also shows the configuration of the jumpers on the modules, which determine which direction the data flows between cascaded modules. This configuration is the reverse of the default factory setting.
Construction
The three modules are glued to a small piece of pine wood left over from my Nixie Clock. The front panel is a neutral display filter from RS components (stock number 588-746). A red display filter would have given higher brightness for the red modules but blocked the green modules completely. The display filter is sawn to size using a hacksaw and there is plenty left over from the 220mm x 130mm sheet to cut triangular side-pieces to bracket the front panel rigidly to the base. For this simple demonstration project no proper enclosure is used. Connections to the computer parallel port are via a 5-way ribbon cable, glued to the wooden base to prevent strain on the solder connections. The modules are wired together in series, in the opposite direction to the default configuration of the modules, which means the blue direction jumpers must be reversed.
Software
Controlling the PC parallel port on Windows NT isn't easy because they have protected the parallel port. Fortunately I found a shareware library TVicHW32 which takes care of all the Windows NT unpleasantness and allows direct access to the PC hardware under Windows 95/98/Me/NT/2000/XP. My demo application drives one data pin of the parallel port, and two of the control pins, to behave like a serial SPI interface.
A 24x8 array isn't very much to display 6 digits of a clock on (including seconds). To demonstrate different fonts I prepared three different sets of numbers (pictured right), of different widths. They are on 8x8, 5x8 and 4x8 grids respectively. For 6 digits of a clock the 4x8 font is needed. However if you make it a 12-hour clock rather than 24-hour, then you can take advantage of the fact that the leftermost digit is only ever blank or a 1, and a 1 can be made very narrow. So I set up a mode having 5x8 digits for the hours and minutes, and 4x8 for the seconds. I also created a 3-digit counter mode to show off the large 8x8 grid font. A Reuters quote mode (in the smallest font) shows a real time stock quote from Reuters (this is a feasability study for a financial application, after all!). A bar mode uses a scroll bar on the screen to light up a horizontal bar. Finally there is a "Scroll" mode, which displays each of the 5 display modes for 3 seconds, then smoothly scrolls off in the vertical direction and scrolls in the next demo mode.
The screenshot to the right shows what the application's window looks like. The mode of operation is selected by clicking one of the option boxes on the left side. In the lower part of the control window are some facilities to put the MAX7219 through its paces. Each of the modules can be switched to "Test" by clicking a check box, or all three can be set to "Test" by clicking the "All" checkbox. In module are ON. Similarly "Shutdown" mode can be set, which switches all the LED's in the module OFF. "Test" mode has priority over "Shutdown" mode. The display brightness can be set in 16 levels, corresponding to display modulation of 1/32 peak current to 31/32 peak current. The "Speed" button when clicked, switches to the 3-digit "Counter" mode, and counts from 0 to 999. At the end it displays a "Test" mode, all of the LED's in the message (shown left) about how many modules were written per second. This is a very important part of the feasibility study, since it will determine how many times I can refresh the much larger array in the project to come. I needed to be sure that I would be able to write the modules fast enough for the size of the array.
Since I cannot host .pas or .dfm files on my website, I have included the ufmMain.pas source code file as a text file. The form code was generated in Delphi by clicking "View as text" on the design-time form. A few notes about the files specified in the uses clause of the code. TVicLib and HW_Types belong to the shareware TVicHW32 library for controlling the parallel port. uEdit is a control called TuEdit which is a customisation of the standard Delphi TEdit control, providing various enhanced functionality that I use in my Delphi applications. In this case I am using a text entry box for the Reuters quote code, and the additional functionality is the provision of the ChangeValue event that occurs when the user changes the text value and hits "Return" or clicks or tabs away from the edit box. SSLRecordEvents and SSLRecord_TLB are heavily modified units obtained years ago in an alpha release, and used ever since for getting a real time data feed from Reuters. WITH NO APOLOGIES FOR BAD CODE - this code was written in an extreme hurry so it isn't well commented and might not be well structured, but it does work.
12-hour clock
Here's the 12-hour clock. At 10, 11 and 12 o'clock, the leftermost column of LED's is lit for the 10-hours digit. Betweeen the hours and minutes, the bottom LED is flashed at 0.5 Hz with the seconds. In this picture that LED happened to be ON.
24-hour clock
The 24-hour clock. Though narrow, the digits are perfectly readable. In fact, some argue that they are more readable, but personally I prefer the 12-hour mode. Once again there's a flashing seconds indicator betweeen the hours and minutes, but it happened to be OFF here.
Counter
A 3-digit counter. The scroll bar deterines the speed of the count. Incidentally, the font used for these digits (8x8 grid) is exactly that used in the Sinclair ZX Spectrum home computer, first sold in 1982. Of the three styles, these digits are most readable at a distance.
Reuters Quote
The Reuters Quote. The code for the quote is entered in the "Ric" box. The display shows the UK's FTSE100 index some time in the afternoon on Friday 26-Apr-02 at 5168.2. Note that the Reuters functionality requires the installation of special software and subscription to Reuters data services.
Bar
A plain bar, just to illustrate what the block-lit matrix will look like. The size of the bar is set by a scroll bar in the control window; in this case I am lighting 19 of the available 24 LED columns.