Pages: [1]   Go Down
Author Topic: LED Matrix Font  (Read 1140 times)
0 Members and 1 Guest are viewing this topic.
Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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
Logged

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

Brooklyn, NY
Offline Offline
Jr. Member
**
Karma: 0
Posts: 92
Webduino / RGB LED Shield
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the updated and complete font file:

http://pastebin.com/f16e00890

Cheers! /me
Logged

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

0
Offline Offline
Edison Member
*
Karma: 7
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why not use the internal eeprom to store the fonts?

« Last Edit: April 14, 2009, 08:01:02 pm by florinc » Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: April 14, 2009, 08:59:01 pm by halley » Logged

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

 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
Logged

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Cheers, /me
Logged

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

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

A nice font BTW.
Logged

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

/me
Logged

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

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well then, basically I made a container called FontChar that holds 6*7 bytes constrained to use 4 bits.

Code:
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:
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. smiley
« Last Edit: April 15, 2009, 01:31:53 pm by AlphaBeta » Logged

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

/me
Logged

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

Keynsham, UK
Offline Offline
Full Member
***
Karma: 0
Posts: 224
I like for loops and walks on the beach,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

/me
Logged

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

Pages: [1]   Go Up
Jump to: