Go Down

### Topic: LED Matrix Font (Read 3565 times)previous topic - next topic

##### Apr 12, 2009, 09:46 pm
I have written a font for an RGB matrix that uses PWM [TLC5940] to get soft edges and stuff. It's actually a 5*7 for most characters. But some things are smaller, some bigger.

I adapted an actual font and arranged the data in separate multi-dimensional arrays like this:

Code: [Select]
// 0 (Zero)
int 0[][]= {0x3FF, 0x7FF, 0xFFF, 0xFFF 0x7FF, 0x3FF,
0x7FF, 0xFFF, 0x00, 0x00 0xFFF, 0x7FF,
0xFFF, 0xFFF, 0x00, 0xFFF, 0xFFF, 0xFFF,
0xFFF, 0xFFF, 0x00, 0x00, 0xFFF, 0xFFF,
0xFFF, 0xFFF, 0xFFF, 0x00, 0xFFF, 0xFFF,
0x7FF, 0xFFF, 0x00, 0x00 0xFFF, 0x7FF,
0x3FF, 0x7FF, 0xFFF, 0xFFF 0x7FF, 0x3FF};

[Contains hexadecimal data for 1/2, 3/4 and full brightness]

But I'm not sure the best way to display these on an LED matrix (using the TLC5940 Library btw) without filling the font in with 0x00 which would suck and be Noob!

/me

#### unwiredben

#1
##### Apr 14, 2009, 06:53 am
1) Make sure you store the font in PROGMEM.  You've got a lot more of that than RAM, and if it's in RAM, it's already eating away at PROGMEM as the program has to copy it from Flash to RAM during startup.

2) Since all characters are going to always be 7 dots high, just store them that way.  Use a table to point to the start of any character and the number of columns to read.  So, you'd use something like

const char chr0[4][7] PROGMEM = { ..... };

const char *chrs[] PROGMEM = { chr0, chr1... };

You can compute the size by looking at the address of the next character as the stop.  Have a dummy character at the end that you don't use to act as a sentinel.

#2
##### Apr 14, 2009, 05:10 pm
Ah thank you, that makes sense. I was planning to convert the font to PROGMEM, but would have done it sooner if I had understood it!

Cheers, /me

#3
##### Apr 14, 2009, 09:36 pm
Here is the updated and complete font file:

http://pastebin.com/f16e00890

Cheers! /me

#### florinc

#4
##### Apr 15, 2009, 03:00 amLast Edit: Apr 15, 2009, 03:01 am by florinc Reason: 1
Why not use the internal eeprom to store the fonts?

#### halley

#5
##### Apr 15, 2009, 03:58 amLast Edit: Apr 15, 2009, 03:59 am by halley Reason: 1
EEPROM - 1KB, need to use a completely separate sketch to load it up

#### AlphaBeta

#6
##### Apr 15, 2009, 05:17 am
I thought that using 8 bits for storing one of three possible states was a bit overkill, so I've played with your code and made something that stores a font character using 21 bytes, as opposed to 42.

It has a maximum of 16 states per 'dot'.

Pastebin code dump, upload and see what is the result of below sketch

[size=14]Arduino Client Sketch:[/size]
Quote

/*
|| LED Matrix Font Client
||
|| Contributed:

*/

//#include "FontData.h"

void printChar( const FontChar& printme );

void setup(){
Serial.begin(9600);

printChar(A);
printChar(R);
printChar(D);
printChar(U);
printChar(I);
printChar(N);
printChar(O);

}

void loop(){}

void printChar( const FontChar& printme ){
//Serial.println("\n\nSample on how to access values");
for (byte y=0; y<7; y++){
for (byte x=0; x<6; x++){
if (printme.get(x,y)){
Serial.print( printme.get(x,y) , DEC );
} else {
Serial.print(" ");
}
}
Serial.println();
}
Serial.println();
}

[size=14]Result:[/size]

Code: [Select]

1331
3333
33  33
33  33
333333
33  33
33  33

3331
33 33
33 33
33 33
3331
33 33
33 33

33311
33 131
33  33
33  33
33  33
33 131
33311

33 33
33 33
33 33
33 33
33 33
33 33
13331

3333
33
33
33
33
33
3333

31  33
331 33
333133
33 333
33  33
33  33
33  33

113311
13  31
33  33
33  33
33  33
13  31
113311

#7
##### Apr 15, 2009, 07:45 pm
Wow that's great! Didn't fully understand that implementation but...

Cheers, /me

#### AlphaBeta

#8
##### Apr 15, 2009, 08:14 pm
If there is anything in particular I'll gladly try to explain

A nice font BTW.

#9
##### Apr 15, 2009, 08:19 pm
Um yeah kinda, all of it. Just don't really understand how it all stitches together.; probably due to my lack of knowledge:(

/me

#### AlphaBeta

#10
##### Apr 15, 2009, 08:30 pmLast Edit: Apr 15, 2009, 08:31 pm by AlphaBeta Reason: 1
Well then, basically I made a container called FontChar that holds 6*7 bytes constrained to use 4 bits.

Code: [Select]

struct FontChar{
byte value : 4;
};

This is what caused the RAM usage to get halved.

Then I made a constructor of that struct to enable simple construction of characters. The usual way to use structs is:

Code: [Select]

FontChar char;

char.value = 3;

But since you set 42 values that would take a while with that syntax.

Bu using the constructor you get kind of a visual feedback as well.

I added a function called byte get(byte x,byte y); which returns the corresponding byte if this was a 2d matrix.

The constants
const byte V = 0; //Void
const byte QR = 1; //Quarter
const byte HAL = 2; //Half
const byte FULL = 3;
const byte NO_SUCH_INDEX = 0;

Was created to provide a gretaer visual feedback when initializing FontChars.

The rest is basically just initializing instances of the struct FontChar and the client only uses the get(x,y) function.

Wikipedia on clases and structs

PM me for a more in-depth examination / explanation if you want.

#11
##### Apr 15, 2009, 08:33 pm
Ah that makes more sense to me. Cheers for all the effort!

/me