TLC5940 LED Matrix

Hi, I’ve built a 5x16 LED matrix, using a TLC5940 to drive the columns and Arduino pins 8 to 4 to drive the rows. I would like to be able to write text on this etc, and I made the character tables (3x5 characters), but my computer force restarted and lost it all, so I have to retype it :frowning:

So I’m wondering, what do I need to do to get test etc working on my matrix? I only know very basic coding, this seems a bit out of my reach :-X

Cheers,
Dan

This may help you with the font situation. Since you have a 5x16 matrix .. you may consider a 5x5 font like this person was nice enough to post .. along with a video.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234005825/all

Also see this post.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1257022922

Do you already have the code to turn on/off any led using a x/y position?

but my computer force restarted and lost it all, so I have to retype it

Rule #1: Save Often! ... It's free!!!

As of now, I don't really have any code. I have arrays typed up for 5x3 fonts, but thats about it. A coordinate system would be very handy of you have it/know how to code it :slight_smile:

Cheers,
Dan

OK, I have managed to rewrite all the code from the screenshots. It uploads, but it simply does not do anything …

#include <Tlc5940.h>

int A[] = {1,1,1, 1,0,1, 1,0,1, 1,1,1, 1,0,1};
int B[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,1,1};
int C[] = {1,1,1, 1,0,0, 1,0,0, 1,0,0, 1,1,1};
int D[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int E[] = {1,1,1, 1,0,0, 1,1,1, 1,0,0, 1,1,1};
int F[] = {1,1,1, 1,0,0, 1,1,0, 1,0,0, 1,0,0};
int G[] = {1,1,1, 1,0,0, 1,0,1, 1,0,1, 1,1,1};
int H[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,0,1};
int I[] = {1,1,1, 0,1,0, 0,1,0, 0,1,0, 1,1,1};
int J[] = {0,0,1, 0,0,1, 1,0,1, 1,0,1, 1,1,1};
int K[] = {1,0,1, 1,1,0, 1,0,0, 1,1,0, 1,0,1};
int L[] = {1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,1,1};
int M[] = {1,0,1, 1,1,1, 1,1,1, 1,0,1, 1,0,1};
int N[] = {1,0,1, 1,0,1, 1,1,1, 1,0,1, 1,0,1};
int O[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int P[] = {1,1,1, 1,0,1, 1,1,1, 1,0,0, 1,0,0};
int Q[] = {1,1,1, 1,0,1, 1,0,1, 1,1,0, 1,1,1};
int R[] = {1,1,1, 1,0,1, 1,1,1, 1,1,0, 1,0,1};
int S[] = {1,1,1, 1,0,0, 1,1,1, 0,0,1, 1,1,1};
int T[] = {1,1,1, 0,1,0, 0,1,0, 0,1,0, 0,1,0};
int U[] = {1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int V[] = {1,0,1, 1,0,1, 1,0,1, 1,0,1, 0,1,0};
int W[] = {1,0,1, 1,0,1, 1,1,1, 1,1,1, 1,0,1};
int X[] = {1,0,1, 1,0,1, 0,1,0, 1,0,1, 1,0,1};
int Y[] = {1,0,1, 1,0,1, 0,1,0, 0,1,0, 0,1,0};
int Z[] = {1,1,1, 0,0,1, 1,1,1, 1,0,0, 1,1,1};
int ZERO[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int ONE[] = {0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0};
int TWO[] = {1,1,1, 0,0,1, 1,1,1, 1,0,0, 1,1,1};
int THREE[] = {1,1,1, 0,0,1, 1,1,1, 0,0,1, 1,1,1};
int FOUR[] = {1,0,1, 1,0,1, 1,1,1, 0,0,1, 0,0,1};
int FIVE[] = {1,1,1, 1,0,0, 1,1,1, 0,0,1, 1,1,1};
int SIX[] = {1,1,1, 1,0,0, 1,1,1, 1,0,1, 1,1,1};
int SEVEN[] = {1,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1};
int EIGHT[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,1,1};
int NINE[] = {1,1,1, 1,0,1, 1,1,1, 0,0,1, 0,0,1};
int sp[] = {0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0};

//Just a little variable declaration
  int delayms = 50;          // Delay in milliseconds before doing the next row
  int indexoffset = 0;       // The column index + the row offset (used within the output iteration
  
// End variable declaration

void setup() {
  Tlc.init();
  //Setup the row pins
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
  digitalWrite(5, LOW);
  digitalWrite(4, LOW);
}

void row(int rownum, char state){
  // Makes a more linear way to keep track of row numbers. It will also make the iteration work.
  // Turns numbers 0-4 into digitalWrites for pins 8-4
  switch(rownum){
    case 0:
    digitalWrite(4, state);
    break;
    case 1:
    digitalWrite(5, state);
    break;
    case 2:
    digitalWrite(6, state);
    break;
    case 3:
    digitalWrite(7, state);
    break;
    case 4:
    digitalWrite(8, state);
    break;
    default:
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
}

void loop() {
  
  // We have 3 groups of LED's either on or off. We'll read them 3 at a time, display that row, then display the next row.
  //First row:
  
  for (int offset = 0; offset <5; offset++){   // Offset here means the row offset, in the char array. Ie, which 3 LED's we are working on
    row(offset, HIGH);                         // Enables the row we are working on
    for (int index = 0; index<3; index++){     //Do this 3 times, for the 3 LED's
      offset = offset * 3;                     // Multiply the row offset by 3, to obtain the index offset in the char array.
                                               //Example: If we're writing the first row, we will obtain an  offset of 0. For the second
                                               //an offset of 3. Third - six. This means that we wil read the correct 3 values from the
                                               //the char array, instead of using the first 3 over and over.
    indexoffset = index + offset;              // This obtains the absolute index of the array that we are reading...
    switch(A[indexoffset]){                    // so that we can use it here to read the value (either 0 or 1) with this switch 
      case 1:
        Tlc.set(index, 4095);                  // Set 1's HIGH on the columns
        break;
      case 0:
        Tlc.set(index, 0);                     // And 0's LOW..
        break;
    }                                          // Now we are done checking the LED and writing it
    
}                                              // end FOR loop setting up the TLC outputs for this row
  
    Tlc.update();                              // Send this rows data to the TLC
    delay(delayms);                            // Wait so we can actually see the LED's
    row(offset, LOW);                          // Turn off the row so we can move onto the next
    Tlc.clear();                               // Clear all the columns
    Tlc.update();                              // Send the CLEAR
  }                                            // End the FOR loop writing the whole character
  
}

Cheers,
Dan

and Arduino pins 8 to 4 to drive the rows

I assume these are not just coming from the arduino but going through a transistor or FET. There is not enough current drive to power 16 LEDs from one arduino pin.

Yes, they are running through transistors.

  1. Can you make the matrix do anything .. even if you just turn on a single row and turn on some of the LED using the TLC (Tlc.set and update)?

  2. Your alphabet is quite a large number of integers. It appears you are using 1/2 your 2K RAM. (37 letters * 15 entries * 2bytes per int) .. that is 1110 bytes. If you have a chip with only 1K ram .. you have already over run it. If you are going to use this character set .. then you will want to restructure it to be more efficient (i.e. a single unsigned in with each bit being one of the letters), which would reduce your footprint to 37 chars * 2 bytes = 75bytes

Before you worry about any letters .. you have to be able to first control the matrix. I would start with a blank project and then attempt to simply turn on a single row and control the pins .. can you try that and report back .. or let us know if you got that far already? if so, post that code please.

I can control the matrix, I know it works. For example, I can set row 1 high, and Tlc.set(0, 4095) and it lights the top left LED.

I am using a duemilanove here.

It's just the code I am having problems with. I haven't gone outside the basics really and these loops, reading arrays etc is confusing to me.

So work building up the code slowly instead of trying to do it all in one big go.

I can set row 1 high, and Tlc.set(0, 4095) and it lights the top left LED.

So keep the Tlc.set(0, 4095) but put it through your rows routine via the main loop so that all the LEDs down the left come on.
Then extend that so a few rows come on.
When that is working extend it to your arrays.

Alright, got it working :slight_smile:

Thought I’d share it here just incase anyone else wants to do similar.

Now I need to figure out how to have it print a couple letters at once …

#include <Tlc5940.h>

int A[] = {1,1,1, 1,0,1, 1,0,1, 1,1,1, 1,0,1};
int B[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,1,1};
int C[] = {1,1,1, 1,0,0, 1,0,0, 1,0,0, 1,1,1};
int D[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int E[] = {1,1,1, 1,0,0, 1,1,1, 1,0,0, 1,1,1};
int F[] = {1,1,1, 1,0,0, 1,1,0, 1,0,0, 1,0,0};
int G[] = {1,1,1, 1,0,0, 1,0,1, 1,0,1, 1,1,1};
int H[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,0,1};
int I[] = {1,1,1, 0,1,0, 0,1,0, 0,1,0, 1,1,1};
int J[] = {0,0,1, 0,0,1, 1,0,1, 1,0,1, 1,1,1};
int K[] = {1,0,1, 1,1,0, 1,0,0, 1,1,0, 1,0,1};
int L[] = {1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,1,1};
int M[] = {1,0,1, 1,1,1, 1,1,1, 1,0,1, 1,0,1};
int N[] = {1,0,0, 1,1,1, 1,0,1, 1,0,1, 1,0,1};
int O[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int P[] = {1,1,1, 1,0,1, 1,1,1, 1,0,0, 1,0,0};
int Q[] = {1,1,1, 1,0,1, 1,0,1, 1,1,0, 1,1,1};
int R[] = {1,1,1, 1,0,1, 1,1,1, 1,1,0, 1,0,1};
int S[] = {1,1,1, 1,0,0, 1,1,1, 0,0,1, 1,1,1};
int T[] = {1,1,1, 0,1,0, 0,1,0, 0,1,0, 0,1,0};
int U[] = {1,0,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int V[] = {1,0,1, 1,0,1, 1,0,1, 1,0,1, 0,1,0};
int W[] = {1,0,1, 1,0,1, 1,1,1, 1,1,1, 1,0,1};
int X[] = {1,0,1, 1,0,1, 0,1,0, 1,0,1, 1,0,1};
int Y[] = {1,0,1, 1,0,1, 0,1,0, 0,1,0, 0,1,0};
int Z[] = {1,1,1, 0,0,1, 0,1,0, 1,0,0, 1,1,1};
int DASH[] = {0, 0,0,0, 1,1,1, 0,0,0, 0,0,0};
int ZERO[] = {1,1,1, 1,0,1, 1,0,1, 1,0,1, 1,1,1};
int ONE[] = {0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0};
int TWO[] = {1,1,1, 0,0,1, 1,1,1, 1,0,0, 1,1,1};
int THREE[] = {1,1,1, 0,0,1, 1,1,1, 0,0,1, 1,1,1};
int FOUR[] = {1,0,1, 1,0,1, 1,1,1, 0,0,1, 0,0,1};
int FIVE[] = {1,1,1, 1,0,0, 1,1,1, 0,0,1, 1,1,1};
int SIX[] = {1,1,1, 1,0,0, 1,1,1, 1,0,1, 1,1,1};
int SEVEN[] = {1,1,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1};
int EIGHT[] = {1,1,1, 1,0,1, 1,1,1, 1,0,1, 1,1,1};
int NINE[] = {1,1,1, 1,0,1, 1,1,1, 0,0,1, 0,0,1};
int sp[] = {0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0};

// Let's declare our X-Y pixel array
int pixel[15][4];


//Just a little variable declaration
  int delayms = 200;         // Delay in microseconds before doing the next row (.2ms)
  int delaywait = 100;            // Delay in microseconds while we wait for the TLC to get set up (.1ms)
  int indexoffset = 0;       // The column index + the row offset (used within the output iteration
  int tripleoffset = 0;           // triple the row offset to obtain the absolute index in the character array
  
// End variable declaration

void clearPixelArray(){
        // Let's make the pixel array all zeroes... much less painful than doing these manually in declaration
        for (int x = 0; x < 16; x++){
            for (int y = 0; y < 5; y++){
                  pixel[x][y] = 0;
            }
        }
}


void setup() {
  Tlc.init();
  delay(10);
  // Let the TLC get set up
  //Setup the row pins
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  
//  Serial.begin(115200);
  
  digitalWrite(8, LOW);
  digitalWrite(7, LOW);
  digitalWrite(6, LOW);
  digitalWrite(5, LOW);
  digitalWrite(4, LOW);
  
clearPixelArray();
  randomSeed(analogRead(1));
  /*
  pixel[0][0] = 1;
  pixel[1][1] = 1;
  pixel[2][2] = 1;
  pixel[3][3] = 1;
  pixel[4][4] = 1;
  pixel[5][0] = 1;
  pixel[6][1] = 1;
  pixel[7][2] = 1;
  pixel[8][3] = 1;
  pixel[9][4] = 1;
  pixel[10][0] = 1;
  pixel[11][1] = 1;
  pixel[12][2] = 1;
  pixel[13][3] = 1;
  pixel[14][4] = 1;
  pixel[15][0] = 1;
  */
}

void rowswitch(int rownum, char state){
  // Makes a more linear way to keep track of row numbers. It will also make the iteration work.
  // Turns numbers 0-4 into digitalWrites for pins 8-4
  switch(rownum){
    case 0:
    digitalWrite(4, state);
    break;
    case 1:
    digitalWrite(5, state);
    break;
    case 2:
    digitalWrite(6, state);
    break;
    case 3:
    digitalWrite(7, state);
    break;
    case 4:
    digitalWrite(8, state);
    break;
    default:
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(8, LOW);
  }
}

void test() {
  //Do a little test - scan through each of the LEDs
  
  digitalWrite(4, HIGH);
  for (int i=0;i<16;i++){
    Tlc.set(i, 4095);
  //  Serial.print("Setting TLC output ");
  //  Serial.print(i);
  //  Serial.println(" on row 4 to ON");
    Tlc.update();
    delay(50);
    Tlc.set(i, 0);
  //  Serial.print("Setting TLC output ");
  //  Serial.print(i);
  //  Serial.println(" on row 4 to OFF");
    Tlc.update();
    delay(5); // Let's try giving the TLC some time to set this all up
  }
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);
  for (int i=0;i<16;i++){
    Tlc.set(i, 4095);
    Tlc.update();
    delay(50);
    Tlc.set(i, 0);
    Tlc.update();
    delay(5);
  }
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
    for (int i=0;i<16;i++){
    Tlc.set(i, 4095);
    Tlc.update();
    delay(50);
    Tlc.set(i, 0);
    Tlc.update();
    delay(5);
  }
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
    for (int i=0;i<16;i++){
    Tlc.set(i, 4095);
    Tlc.update();
    delay(50);
    Tlc.set(i, 0);
    Tlc.update();
    delay(5);
  }
  digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
    for (int i=0;i<16;i++){
    Tlc.set(i, 4095);
    Tlc.update();
    delay(50);
    Tlc.set(i, 0);
    Tlc.update();
    delay(5);
  }
  digitalWrite (8, LOW);
}

void loop() {
//  test();

// This code writes an A (or whatever letter you choose. It works now :D

  

  
  for (int offset = 0; offset <5; offset++){    // Offset here means the row offset, in the char array. Ie, which 3 LED's we are working on
    rowswitch(offset, HIGH);                          // Enables the row we are working on
    for (int index = 0; index<3; index++){      //Do this 3 times, for the 3 LED's
      tripleoffset = offset * 3;                      // Multiply the row offset by 3, to obtain the index offset in the char array.
                                                //Example: If we're writing the first row, we will obtain an  offset of 0. For the second
                                                //an offset of 3. Third - six. This means that we wil read the correct 3 values from the
                                                //the char array, instead of using the first 3 over and over.
    indexoffset = index + tripleoffset;               // This obtains the absolute index of the array that we are reading...
    switch(A[indexoffset]){                     // so that we can use it here to read the value (either 0 or 1) with this switch 
      case 1:
        Tlc.set(index, 4095);                   // Set 1's HIGH on the columns
        break;
      case 0:
        Tlc.set(index, 0);                      // And 0's LOW..
        break;
    }                                           // Now we are done checking the LED and writing it
    
  }                                             // end FOR loop setting up the TLC outputs for this row
  
    Tlc.update();                               // Send this rows data to the TLC
    delayMicroseconds(delayms);                 // Wait so we can actually see the LED's
    rowswitch(offset, LOW);                           // Turn off the row so we can move onto the next
    Tlc.clear();                                // Clear all the columns
    Tlc.update();                        // Send the CLEAR
    delayMicroseconds(delaywait);              // Let's wait for the TLC to update this before continuing
  }                                             // End the FOR loop writing the whole character
}
/*
  
  clearPixelArray();
  int rand = random(5,15);
  for (int count = 0; count<rand; count++){
        pixel[random(0,16)][random(0,5)] = random(0,2);
  }
  
  // Begin X-Y code
  
  for (int row = 0; row <5; row++){               // Which row we're working on
    rowswitch(row, HIGH);                             // Enables the row we are working on
    for (int column = 0; column<16; column++){  // Do this 16 times, for the 16 LEDs in the row
     
    switch(pixel[row][column]){                 // Read the value of the LED we're working on (either 0 or 1) with this switch 
      case 1:
        Tlc.set(column, 4095);                   // Set 1's to ON
        break;
      case 0:
        Tlc.set(column, 0);                      // And 0's OFF
        break;
    }                                           // Now we are done checking the LED and writing it
    
  }                                             // end FOR loop setting up the TLC outputs for this row
  
    Tlc.update();                               // Send this rows data to the TLC
    delayMicroseconds(delayms);                 // Wait so we can actually see the LED's
    rowswitch(row, LOW);                           // Turn off the row so we can move onto the next
    Tlc.clear();                                // Clear all the columns
    Tlc.update();                        // Send the CLEAR
    delayMicroseconds(delaywait);              // Let's wait for the TLC to update this before continuing
  }                                             // End the FOR loop writing the whole character
  
}                                    // End void loop
*/

Cheers,
Dan

Great, glad to see you got the matrix working.

If your pixel array is working then you can load the letters into the pixel array and then just right out the pixels. This allows you to load up letters into the pixel list, which redraws. This will also allow you to slide the letters for scrolling text fairly easily by manipulating the pixel array directly (move all the columns to the left add the next row of the buffered letter).

You may consider using Timer1 to write the pixel array to the matrix. Then in your loop you can just set the pixels as you want them.