Go Down

### Topic: LED Matrix Font (Read 2870 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

#### Ben Combee

#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  3333  3333333333  3333  333331  33 33 33 33 33 33 3331  33 33 33 33 33311 33 13133  3333  3333  3333 13133311 33 33 33 33 33 33 33 33 33 33 33 33 13331 3333   33   33   33   33   33   3333  31  33331 3333313333 33333  3333  3333  3311331113  3133  3333  3333  3313  31113311`

#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

#12
##### Apr 22, 2009, 05:18 pm
It's nice to see people using the Arduino Pastebin. Just don't forget to C++ syntax colouring.

/me

Go Up

Please enter a valid email to subscribe