Go Down

Topic: LED Matrix Font (Read 1 time) previous topic - next topic

BetaDelta

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
"C++ : Where friends have access to your private members." - Gavin Russell Baker

Ben Combee

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.

BetaDelta

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
"C++ : Where friends have access to your private members." - Gavin Russell Baker

BetaDelta

Here is the updated and complete font file:

http://pastebin.com/f16e00890

Cheers! /me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

florinc

#4
Apr 15, 2009, 03:00 am Last 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 am Last Edit: Apr 15, 2009, 03:59 am by halley Reason: 1
EEPROM - 1KB, need to use a completely separate sketch to load it up

PROGMEM - 32KB minus your program size, loaded up every time you upload the sketch

AlphaBeta

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:
|| BetaDelta
|| Alexander Brevig
*/

//#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

BetaDelta

Wow that's great! Didn't fully understand that implementation but...

Cheers, /me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

AlphaBeta

If there is anything in particular I'll gladly try to explain :)

A nice font BTW.

BetaDelta

Um yeah kinda, all of it. Just don't really understand how it all stitches together.; probably due to my lack of knowledge:(

/me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

AlphaBeta

#10
Apr 15, 2009, 08:30 pm Last 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. :)

BetaDelta

Ah that makes more sense to me. Cheers for all the effort!

/me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

BetaDelta

It's nice to see people using the Arduino Pastebin. Just don't forget to C++ syntax colouring.

/me
"C++ : Where friends have access to your private members." - Gavin Russell Baker

Go Up