8x8 led grid

On the memory issue, defining the letters isn't costing us, it is the three-dimensional patterns array which eats up 64 bytes per letter displayed. "HELLO" would be the same memory usage as "LLLLL". I figure I'd max out at about ten letters.

Still pretty dang cool. Maybe someone will tackle it bit-wise.

Excellent, I'm glad you got it working.

Andrew

OK, so I tackled the bit-wise approach. This is my first serious C project, so go easy on the critiques. I started with Andrews pinout scheme, and wrote it out the best I could (not nearly as elegant as Andrew, but it works). I'm using 5x7 letters, so each character cost you 5 bytes instead of 64. You should be able to run a 100 char message easy. I was too lazy to tackle an 8x8 font, but that would only be 8 bytes per character.

(also my first Youtube video!)

As for the wiring, I cut an IDE cable header in half and used that to connect the matrix. Again, not elegant, but it works.

Remember, I'm using a cathode-row matrix, so you'll have to monkey with it to get an anode-row matrix to work.

/*
 * Show messages on an 8x8 led matrix (cathode rows),
 * scrolling from right to left.
 *
 * Pinouts & code by Andrew
 * see http://arduino.pastebin.com/f35fdf323
 * see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203747843/13#13
 */

// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[17]= {-1, 5, 4, 3, 2, 14, 15, 16, 17, 8, 9, 10, 11, 12, 13, 6, 7};
// (for some reason I ended up with different pinouts that Andrew's)

// col[xx] of leds = pin yy on led matrix
int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[06], pins[11], pins[15], pins[16]};

// row[xx] of leds = pin yy on led matrix
int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};

// Letter definitions based on 5 bit-wise columns (5 x 7 font)
#define SP {0, 0, 0, 0, 0}
#define EX {0, 125, 0, 0, 0}  // !

#define A {31, 36, 68, 36, 31}
#define B {127, 73, 73, 73, 54}
#define C {62, 65, 65, 65, 34}
#define D {127, 65, 65, 34, 28}
#define E {127, 73, 73, 65, 65}
#define F {127, 72, 72, 72, 64}
#define G {62, 65, 65, 69, 38}
#define H {127, 8, 8, 8, 127}
#define I {0, 65, 127, 65, 0}
#define J {2, 1, 1, 1, 126}
#define K {127, 8, 20, 34, 65}
#define L {127, 1, 1, 1, 1}
#define M {127, 32, 16, 32, 127}
#define N {127, 32, 16, 8, 127}
#define O {62, 65, 65, 65, 62}
#define P {127, 72, 72, 72, 48}
#define Q {62, 65, 69, 66, 61}
#define R {127, 72, 76, 74, 49}
#define S {50, 73, 73, 73, 38}
#define T {64, 64, 127, 64, 64}
#define U {126, 1, 1, 1, 126}
#define V {124, 2, 1, 2, 124}
#define W {126, 1, 6, 1, 126}
#define X {99, 20, 8, 20, 99}
#define Y {96, 16, 15, 16, 96}
#define Z {67, 69, 73, 81, 97}

int dispSpeed = 8;                               // Constrols scroll speed (1 minimum, way too fast)
byte bit[8] = {128, 64, 32, 16, 8, 4, 2, 1};      // Used for bit comparisons
byte colVals[8] = {0, 0, 0, 0, 0, 0, 0, 0};       // Hold display columns (initaly blank)

// Define display string here
const int charNum = 16;                            // Number of letters in display string
byte string[charNum][5] = {A,R,D,U,I,N,O,SP,R,O,C,K,S,EX,SP,SP};

void setup() {
  Serial.begin(9600);                    // for troubleshooting
  for (int i = 1; i <= 16; i++) {        // sets the pins as output
    pinMode(pins[i], OUTPUT); }
  for (int col = 0; col < 8; col++) {    // set up cols and rows
    digitalWrite(cols[col], HIGH);  }
  for (int row = 1; row < 8; row++) {
    digitalWrite(rows[row], HIGH);
  }
  Serial.println(availableMemory());     // 670 bytes for charNum = 15
}

void loop() {
  
  for (int ltr = 0; ltr < charNum; ltr++){// For each letter in string array
    for (int y = 0; y < 6; y++){          // For each columin in letter + one space
      shiftLeft();                        // shifts display columns left
      if (y < 5){
        colVals[7] = string[ltr][y]; }    // add new letter column on right
      else {colVals[7] = 0; }             // or empty space between
      for (int x = 0; x < dispSpeed; x++){// loop to refresh display x times ton control scrolling
        display();  
      }
    }
  }
}


void shiftLeft(){
 for (int x = 0; x < 7; x++){
   colVals[x] = colVals[x + 1];
 }
}


void display() {

   for (int col = 0; col < 8; col++){
    for (int row = 0; row < 8; row++){
      if (colVals[col] & bit[row]){
        digitalWrite(rows[row], HIGH);}
      }
    digitalWrite(cols[col], LOW);  // Turn on column
    delay(1);  // Delay for POV
    for (int row = 0; row < 8; row++){
      digitalWrite(rows[row], LOW);
    }
    digitalWrite(cols[col], HIGH);  // And off
  }
}

// this function will return the number of bytes currently free in RAM
// written by David A. Mellis
// based on code by Rob Faludi http://www.faludi.com
int availableMemory() {
  int size = 1024;
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL);
  free(buf);
  return size;
}

Now, of course, all I need for for my Max7221 chips to arrive so I can try a different tack.

OK, so I tackled the bit-wise approach. This is my first serious C project, so go easy on the critiques. I started with Andrews pinout scheme, and wrote it out the best I could (not nearly as elegant as Andrew, but it works). I'm using 5x7 letters, so each character cost you 5 bytes instead of 64. You should be able to run a 100 char message easy. I was too lazy to tackle an 8x8 font, but that would only be 8 bytes per character.

http://www.youtube.com/watch?v=vEATaGx28_8
(also my first Youtube video!)
...

Brilliant, someone's done the hard work for all the rest of us! :slight_smile: :slight_smile: Thanks!

Neat idea on the IDE cable too.

Andrew

I've been playing with this too, In addition to storing bytes to save space I was thinking about using the internal eeprom space to define the characters. 512 bytes seems like a whole lot of space.

If each char is 8 bytes, thats 208 bytes for the whole alphabet, leaving more than half the eeprom for special characters etc.

I jut have to learn a little about the flash now. I'm hoping it is not reset when I upload a sketch.

So I'll have 1 program for uploading the characters, and once the eeprom is loaded, I'll load the program that runs my scrolling text.

Of course I want to use shift registers to reduce pins as well, but one thing at a time.

I'll post my progress up here for you guys.

Thanks again Andrew for s great starting point.

I'm hoping it is not reset when I upload a sketch.

It's configurable, but I think by default EEPROM is preserved through a chip erase (which is what happens when a sketch is uploaded).

--Phil.

Hi Guys,

I used Eric Latrop's code (found on http://ericlathrop.com/electronics/LedGrid.php) as a starting point to write a program that can scroll 5x7 or 8x8 characters on a 8x8 led grid using the direct drive method.
The only thing you have to do is change the constants NUM_COLS and NUM_ROWS and define either 5x7 characters or 8x8 characters or anything in between in pattern.h.

You can find the code at: public-art-international.com.

Enjoy!

How did you get on with uploading the font array to teh eeprom and then reading it? I have been trying to do the same thign without success. How do you write a 2 dimensional array to the eeprom and then read it back in the order needed?

How do you write a 2 dimensional array to the eeprom and then read it back in the order needed?

I haven't done this with the Arduino EEPROM but it's a common programming task, or at least it was back in the good old days before automagic memory management and array objects. Basically you turn a two dimensional array of width COLS and height ROWS into a one dimensional array (linear list of numbers) of length (COLS x ROWS). Then the number which was stored at 2d array position (i, j) can be found at position ((i x COLS) + j) in the 1d list where i is the row number from 0 to (ROWS - 1) and j is the column number from 0 to (COLS - 1).

So we have a 2d array like this:

cols
0 1 2 3 4 5
r 0 A B C D E F
o 1 G H I J K L
w 2 M N O P Q R
s 3 S T U V W X

turns into a 1d list like this:

Position
1 1 1 1 1 1 1 1 1 1 2 2 2 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
A B C D E F G H I J K L M N O P Q R S T U V W X

and the letter 'Q' which was at (2, 4) (row 2, col 4) can now be found at position (2 x COLS + 4) which is 2 x 6 + 4 = 16.

So to write your whole 2d array to the EEPROM you loop through each element and translate its (row, column) position into its position in the linear list, and write the array value to the EEPROM at that address. To reverse the process you again loop through each array position, but this time you read from the EEPROM at the 1d address and write the value back into the array.

Obviously if you only want values from some of the positions in the array you only loop over that subset.

After all that I hope that's what you were having trouble with. If it was the actual mechanics of writing to and reading from the EEPROM then someone else will have to answer...

Andrew

hi.
can you please tell me how to compile frequency time2 with duemilanove?? atmega 328.
the cpp. file has a problem and i don't know much of programming.
thanks