So I was lucky enough to get a couple of LED Matrix modules (GHI) which contain 8 x 8 red LEDs and they are great fun. The obvious thing to make is a display scroller, like the ones you get in trains, but as I am limited to just 2 modules, perhaps a clock is a good starting point.

LedMatrix

2 x Led Matrix and .NET Gadgeteer mainboard (http://www.mountaineer.org/)

 

The LED matrix is very easy to use, each row (or column if you rotate it) can be turned on/off by sending a hex value. You can send an integer if you want and in fact one of the easiest ways to get a result is to display an integer counter. You will end up with a binary counter displayed on the matrix. I have used hex as it is more logical to me…

Here is a simple example, asking the matrix to display 3 columns. The first has the values 0 and 2 (hex) so the first 4 LEDs will not be turned on as the value is 0 and the next set of 4 will only have one LED visible. The one which corresponds with the binary value 2 will be lit. The example below displays the number 1 using only 3 columns. (I had to put my digits on a diet as I only have 2 displays.)

private byte[] displayArray = new byte[]{};

I started generating the hex values for my numbers by hand, in my head and just coding it. Most were correct but there were a few odd ones, then I discovered a much easier way. (I know there are many others) Roznerd has a nice Excel workbook that lets you ‘draw’ the character and then gives you the hex. (http://roznerd.blogspot.co.uk/2010/02/led-dot-matrix-pov-font-generator.html).Number1 Most characters on LED matrix are 5×7 or there about but since my display is only 16 LEDs wide, I have opted to create all my digits using only 3 columns. After experimenting a bit I gave up on trying to round the corners and there is just not enough space, opting instead to keep the ‘font’ square and retro. .NetMF does not have all the juicy collections that the full .NET framework supports so I used a HashTable to store all the digits, ensuring it is nice and extensible for the future. 

AsciiLookup.Add((int)'1',  new byte[] { 0x02, 0xFE, 0x42 });
AsciiLookup.Add((int)'2', new byte[] { 0xF2, 0x92, 0x9E }); 
AsciiLookup.Add((int)'3', new byte[] { 0xFE, 0x92, 0x92 });
AsciiLookup.Add((int)'4', new byte[] { 0xFE, 0x10, 0xF0 });
AsciiLookup.Add((int)'5', new byte[] { 0x9E, 0x92, 0xF2 });
AsciiLookup.Add((int)'6', new byte[] { 0x9E, 0x92, 0xFE });
AsciiLookup.Add((int)'7', new byte[] { 0xFE, 0x80, 0x80 });
AsciiLookup.Add((int)'8', new byte[] { 0xFE, 0x92, 0xFE });
AsciiLookup.Add((int)'9', new byte[] { 0xFE, 0x90, 0xF0 });
AsciiLookup.Add((int)'0', new byte[] { 0xFE, 0x82, 0xFE });
AsciiLookup.Add((int)' ', new byte[] { 0x00 });
AsciiLookup.Add((int)':', new byte[] { 0x28 });
AsciiLookup.Add((int) '!', new byte[] {0x20, 0x10, 0xD7, 0xF8, 0xD7, 0x10, 0x20});
AsciiLookup.Add((int) 'o', new byte[] {0x06, 0x63, 0x63, 0x0B, 0x63, 0x63, 0x06});

Each digit is 3 columns wide, with space being a single column, there are a few extra characters at the end to show how to cope with wider characters. Writing the time to the display is a simple case of getting the current time (repeatedly), and formatting a string such as “1 2 4 6” (for 12:46) using the separation of the displays as the colon. Each character is 3 columns, and a space, so 4 columns requires 15 columns,Clock not leaving enough room for the colon, however if we chop a bit off the 1 it looks pretty good.  (Note the blur is my great phone camera, in reality the LED matrix is very readable)

Once you have the hex sorted for each character it gets painful to reread it, so I write a method that takes a string, looks up each the character in the hex table and appends it to an output array. The output array is then displayed to the LED matrix. Be advised to take care of the situation where the character has not been translated into an LED matrix character.

public void DrawString(string str) { char[] characterArray = str.ToCharArray(); foreach (char c in characterArray) {  this.AddCharacter((byte[]) this.AsciiLookup[(int)c]); } this.Draw();

}

private void AddCharacter(byte[] characterBytes) { displayArray = Utility.CombineArrays(

characterBytes, displayArray); }

The advantage of having an array to store all the characters and then displaying it, is that the array can be larger than the display. In this case you can just keep adding characters, but only the last 16 columns will be shown. This leads me on to the next little tweak, by chopping the head off the array and adding it to the tail, then rendering the display you can generate a scrolling effect very easily.

private void Draw() { //pad array to display size - minimum if (displayArray.Length < displays.Length*8) { displayArray = Utility.CombineArrays(

displayArray,

new byte[(displays.Length*8)

- displayArray.Length]);

//For each matrix. for (int ctr = 0; ctr < displays.Length; ctr++) { byte[] currentDisplayData = new byte[] {}; if ((displayArray.Length >= (ctr + 1)*8)) { currentDisplayData = Utility.ExtractRangeFromArray(

displayArray, ctr*8, 8); } else { currentDisplayData = Utility.ExtractRangeFromArray(

displayArray, ctr*8,

displayArray.Length - (ctr*8));

 

currentDisplayData = Utility.CombineArrays(

currentDisplayData, new byte[8 - currentDisplayData.Length]); } displays[ctr].DrawBitmap(currentDisplayData); } }

I am sure there are plenty of ways to improve on this, but the effect is good and the code is short. I have added a stick figure and a smiley at the end to show how variable width characters can be handled and the code is adaptable to a variable number of LED Matrix modules (only in a straight line) – apologies for the poor quality of the video.

.NET Gadgeteer LED Matrix scrolling text.