I have started a project to make a large digital clock (12cm height and 30cm wide) with LED matrix displays, 10 in total with the clock having two rows. I want to add a RTC and alarm option to it but before i can get to them I need some help in the best way of driving the displays to get the output I want. I indent to use the code from here.
The layout I want is shown in the attachment, the problem I have is with addressing the right displays with a specific number of the time, the first and last digit are on 1 matrix, so I see no problem here. The middle two digits overlap to the next matrix and here is where I am lost at the moment. The middle matrix need to display the outer row from its neigbours digit, and in the perfect world I would like the dots ( to blink.
I have been thinking on making patterns for every minute from 00:00 up to 23:59 but that seems like total overkill. Second option i have is making the basic patterns for digit 1 and 4 and and for digit 2 and 3 separate patterns and re-using the double one. Then I need a conversion table to use what patterns for what time to display.
All together it seems like a lot of overhead and I wonder if there could be some better way in doing this, basicly only needing the patterns for the digits itself and some code to light the right LEDs. Any help is appreciated !
If you rotate the matrices 90 degrees clockwise then the problem vanishes. You get 40 rows of 16 pixels and it's easy to draw a digit starting at any row (which is the real problem).
If you can't physically rotate the matrices then do the same thing in software:
Store an imaginary clock display as 80 bytes in RAM (two bytes per row, 40 rows) as if the matrix were rotated. This really simplifies the drawing code. Update your imaginary display in those 80 bytes of RAM.
Now you need a function to shuffle those bits around to match the hardware layout, then copy them to the physical matrix.
Think of the matrix as 40 columns by 16 rows (no rotation). Then, just write a function to display a number at an offset from the left most column (0) to the right most column (39).
So, to display the time, you would have something like:
void DrawCurrentTime()
{
// the first parameter is the column to draw in, the second parameter is the character to draw
DrawNum(0, '8'); // draw the number '8' on the very left
DrawNum(9, '8'); // draw the number '8' starting in the 9th column
DrawNum(19, ':'); // draw the ':'
DrawNum(23, '8');
DrawNum(32, '8');
}
Agree with Crossroads. unless you are going to do animations or other graphics type fancy stuff, then you really only need the matrices for digits 1, 2, 3, 4. The ':' between the digits can just be LEDs (two or more), driven directly from the microcontroller.
If you want to use the displays as you have them, you may also want to look at the hardware and code for the Parola displays (see the signature block below). You can define your own character set as the top and bottom half of each digit and then write the data using the offset technique, as stated in a previous post.
marco_c:
Agree with Crossroads. unless you are going to do animations or other graphics type fancy stuff, then you really only need the matrices for digits 1, 2, 3, 4. The ':' between the digits can just be LEDs (two or more), driven directly from the microcontroller.
It won't look as pretty. The extra column of pixels on the digits adds a lot.
arduinodlb:
Think of the matrix as 40 columns by 16 rows (no rotation). Then, just write a function to display a number at an offset from the left most column (0) to the right most column (39).
Writing code to do that isn't easy.
The whole point of rotating the matrices/data was to make that part of the code easy at the expense of having to transpose the data later on (not too difficult).
I agree with the data as columns idea.
Write the fonts as ints, upper byte goes to upper MAX7219, lower byte goes to lower MAX7219.
For example:
c 01234567
0 01111110
1 11111111
2 11000011
3 11000011
4 11000011
5 11000011
6 11000011
7 01111110
8 01111110
a 11000011
b 11000011
c 11000011
d 11000011
e 11111111
f 01111110
arduinodlb:
Think of the matrix as 40 columns by 16 rows (no rotation). Then, just write a function to display a number at an offset from the left most column (0) to the right most column (39).
Writing code to do that isn't easy.
Yes it is.
The whole point of rotating the matrices/data was to make that part of the code easy at the expense of having to transpose the data later on (not too difficult).
I get that. I'm just providing an alternative. Conceptually, it's easier to think of the panel in the horizontal plane so if it were me, I would do it that way. The code is no harder, just different.
Rotating is an good option since I have not build anything, I will take this as a first choice at the moment and search for some good solutions from there. I have only got 2 matrices at the moment, orderd some more but will try to make some code soon for testing the rotated matrix with those two.
Keeping a 'gap' between the matrix is not an option, I want to be able to change the layout later on to display the alarm time when set on a side (90 degrees rotated or so) and then make the digits smaller.
I don't see how rotating an 8x8 matrix helps?
If they are common cathode, they really need to be arranged as 8 vertical columns, otherwise you have to mess around a lot in software to rotate things.
If you have an array of 40 ints holding your digits or pattern or whatever, then you only need to send the upper byte to one display and the byte to the display below, and work your way thru 40 bytes across the 5 pairs of MAX7219s.
Want to change a digit? Pull the 8 ints from progmem and put them in the array, then send the array to the MAX7219s.
Is there any chance we are saying the same thing but in different words?
arduinodlb:
Think of the matrix as 40 columns by 16 rows (no rotation). Then, just write a function to display a number at an offset from the left most column (0) to the right most column (39).
Writing code to do that isn't easy.
Yes it is.
No it isn't. Drawing text at an arbitrary horizontal position needs a lot of bit shifting and twiddling. It's basically a monochrome sprite routine.
arduinodlb:
Think of the matrix as 40 columns by 16 rows (no rotation). Then, just write a function to display a number at an offset from the left most column (0) to the right most column (39).
Writing code to do that isn't easy.
Yes it is.
No it isn't. Drawing text at an arbitrary horizontal position needs a lot of bit shifting and twiddling. It's basically a monochrome sprite routine.
At the risk of repeating myself, yes it is. I realize you're dead-set on your solution, but Engineering is rarely "this is 100% the way to go". There are always alternatives, and in this case, it depends on what the original poster feels most comfortable with. Either way is valid, and both are as easy as each other but in different ways.