How to use shift registers and transistors in an led matrix

Hello arduino community im 16 and im trying to build a 5x5 led matrix for a school project. from what ive read you need to use shift registers and transistors where the transistors are to draw the current. i understand what multiplexing is and all that but im not sure if i use a shift register for the columns and then a shift register with thransistors for the rows or vice versa. and i have no idea how to understand the code. if anyone could explain the code and how it works better than the existing shift register threads and where specifically to place the shift registers and transistors i would really appreciate it.

Pleas help!!

Maybe try to be a bit more specific about what you don't understand? There are so many threads, tutorials, instructables, .... all explaining it in varying levels of details.

What have you read, and what don't you understand about it?. Ask some concrete questions (and show that you've done some effort in trying to understand it)
we won't be making your school assignments for you :p.

But maybe some first answers: if you plan to make a 5x5 matrix: you don't need shift registers. You only need 10 pins to control it using multiplexing, so no shift registers are needed, your arduino has more than 10 pins.
And the transistors: you'll split up your matrix in lines, and of a single line when multiplexing all leds can be lit. A normal led draws 20mA of current. The arduino can handle at very most 40mA. But turning all the leds on at the same time would draw 100mA, and thus risk damaging your arduino.
To resolve this, you put a transistor between it. A transistor is like an electrically driven switch. Provide it a small current, and it can allow a larger current to flow. So the arduino may only have to provide 1mA, and by that open the transistor so 100mA can flow toward the line of leds being lit.

thanks for the suggestions. I know i dont have to use the shift registers but i think its a really neat thing to learn and might as well do it now. for the transistors can i make the columns going up the positve side and the rows going across negative and put the transistors on the negative rows or does it need to go on the positive columns? and on the code what does this mean specifically if you could be very in depth i would appreciate it. its the first line of code after void setup on the arduino shift register tutorial page code examples for using an array

for (int j = 0; j < 10; j++)

I agree shift registers is cool to use (i just started with arduino myself, and while waiting for more shift registers, i've currently got a 4x4 led matrix driven completely by a single shift register and 4 transistors). So 4 of the pins of the shift register control the rows, the other 4 pins control the columns (and have a transistor so i won't overload the shift register).

And it doesn't really matter if you make the rows or columns positive or negative, every setup is possible, and neither is more difficult than the other.

I would however suggest you start without shift registers. When you completely understand how to build it without a shift register, you can try adding one. But starting out understanding nothing, and immediatly wanting to use all the fancy stuff, is just too much to learn all at once :).

Now for your concrete question:
what does "for (int j = 0; j < 10; j++)" mean?
don't forget this site has a great reference for all the programming statements you need as a beginner:

for the for loop:
http://arduino.cc/en/Reference/For

The explanation there might be a bit technical, in short:
for : you indicate you'll start a for loop (programming uses a lot of loop statements to control program flow. A for loop is a loop that happens for a certain amount of times. It allows you to at the start of it set a value, set a condition (that will be evaluated before each loop), and for every time you loop trough it to modify a value).
(int j = 0; : in this for loop, we create a value with the name of j , and set it to 0
j < 10; : we want to stay in this loop as long as j is smaller than 10
j++) : and after every time we've gone trough this loop, j is increased by 1 (++ increases a value by 1).
after this statement you'll notice curly braces:
{

}
everything between those curly braces will be repeated. In this case it will be repeated 10 times (since after the 10th loop j will be increased to 10, and then is no longer smaller than 10, and the loop will stop looping.

I see you never programmed before, and have never had any experience with programming languages?
I think a very good starting point for you might be this: Java tutorial for beginners | freejavaguide.com
it's a java programming tutorial. java is very very close to C(++) (which the arduino uses), and this guide with a lot of examples explains all the basics you need. It might be worthwhile to download the java jdk, and spend some time following parts 1-4 (the fifth part you won't be needing). It'll teach you all about the basics of how to create a program, how programs are structured, how the loops work, how variables work, ...
i've looked trough it, and it looks like a very good tutorial, and without gaining the knowledge in there, you won't learn how to make your project... And i think for beginning, java and the jdk are a lot more userfriendly than the arduino and having to work trough the serial monitor.

Hi thank you for all the advice and the explanation of the code. i understannd that i should probably not use shift registers right away but i've already soldered everything together lol so theres no turning back. And your right i have next to no coding experience so that link will be very helpful. When i finish the code ill post it here and see if you would recommend any revisions

So you have something like this with the anodes coming from a shift register, or from Arduino pins, and the NPN bases driven from a shift register, or from Arduino pins?

yea that's exactly how it is. It seems to work fine so i'm just assuming the currents coming from the transistors and not overloading the arduino. I used one shift register to drive both the transistors and the anodes

One? There's 10 lines needed, most shift registers only have 8 outputs.

my bad i meant to say 2

Hello everyone i just made a simple code that displays the letter A on my matrix but its really inconvenient cause if i wanted to spell out a word it would take a long time to make the code. Is there a way to make an integer called A and i can just say shiftout A in the code or type a in the serial command box?

Basically what im asking is can i put everything thats in the loop of this code and make it an integer and then just say shiftout A and it will work or is there a way to make like a 1's and 0's box to tell what to put on the registers like this

11111
10001
11111
10001 this on the left would be the A. is there a way to do this in the code?
10001

heres the code

/*
Led matrix using two 595 shift registers
one for columns and one for rows
comluns are positive and rows are negative
but have transistors on them

im modifying an example code found on arduino website

By:Chris Yambo
*/

const int CPR = 2;
// clock pin row
const int LPR = 3;
// latch pin row
const int DPR = 4;
// data pin row
const int CPC = 8;
// clock pin cloumn
const int LPC = 9;
// latch pin column
const int DPC = 10;
// data pin column
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(CPR, OUTPUT);
pinMode(LPR, OUTPUT);
pinMode(DPR, OUTPUT);
pinMode(CPC, OUTPUT);
pinMode(LPC, OUTPUT);
pinMode(DPC, OUTPUT);
}

void loop() {

// turn off the output so the pins don't light up
// while you're shifting bits:
digitalWrite(LPR, LOW);
digitalWrite(LPC, LOW);

shiftOut(DPR, CPR, LSBFIRST, 128);
shiftOut(DPC, CPC, LSBFIRST, 136);
// turn on the output so the LEDs can light up:
digitalWrite(LPR, HIGH);
digitalWrite(LPC, HIGH);

digitalWrite(LPR, LOW);
digitalWrite(LPC, LOW);

shiftOut(DPR, CPR, LSBFIRST, 64);
shiftOut(DPC, CPC, LSBFIRST, 136);
// turn on the output so the LEDs can light up:
digitalWrite(LPR, HIGH);
digitalWrite(LPC, HIGH);

digitalWrite(LPR, LOW);
digitalWrite(LPC, LOW);

shiftOut(DPR, CPR, LSBFIRST, 32);
shiftOut(DPC, CPC, LSBFIRST, 255);
// turn on the output so the LEDs can light up:
digitalWrite(LPR, HIGH);
digitalWrite(LPC, HIGH);

digitalWrite(LPR, LOW);
digitalWrite(LPC, LOW);

shiftOut(DPR, CPR, LSBFIRST, 16);
shiftOut(DPC, CPC, LSBFIRST, 136);
// turn on the output so the LEDs can light up:
digitalWrite(LPR, HIGH);
digitalWrite(LPC, HIGH);

digitalWrite(LPR, LOW);
digitalWrite(LPC, LOW);

shiftOut(DPR, CPR, LSBFIRST, 8); // this is an 8 not a smiley face idk why its doing that
shiftOut(DPC, CPC, LSBFIRST, 255);
// turn on the output so the LEDs can light up:
digitalWrite(LPR, HIGH);
digitalWrite(LPC, HIGH);

}

Yes, you put all the font definitions in an array, then call the letters from the array.
Each 5 bytes of the array can be 1 letter.
Then call up the letters by their position in the array.
Say 0-4 was H,
5-9 was E,
10-14 was L, and
15-19 was P.
Then your code could have another array with the order of the letters to be displayed
messageArray[] = {1,2,3,4,};
Then loop could simple call out the messageArray value, muliitply by 5 for the starting location and take the next four from there.

Thanks for trying to help but i'm really new to coding and really don't understand what you said. Do you think you could give a small code example just displaying 1 letter to help me grasp what your saying?

No, I only have a completed sketch.
Take from this what you can.
If too complex, try the parola.h library.

single_eight_eight_display_a.ino (8.19 KB)

Ok thanks. If anyone Else has any more examples i would be really appreciative.

hi was trying to understand your code but its to advanced for me is there anyway you could try and explain it to me?

Take a look at the code examples here. I hope the code is not too complicated for you.

That code was for sending data to MAX7219.
Best way I can explain is in several parts:

  1. Use blink without delay to keep track of 2 sets of time passing.
    One set will occur every 2 mS to multiplex the display. Every 2mS you will send out anode data for 1 column of a letter and turn on the matching cathode.
    2nd set will update the data to be displayed once a second or however fast you want to change letters.
  2. Use a font array like I have in the code to define the LEDs to light for each letter.
  3. Use a message array to define the message to be displayed.
  4. Copy one letter at a time into a 5-byte buffer, and have the multiplexing code display that letter.

Take it a step at a time. I didn't write that code all in one shot, I worked out the pieces and found out how to make them all work together.
Once you have the multplexing working to display data from a 5-byte array, then mixing in the fonts and the letter list for the message is not too hard, especially where you only have 5 columns to work with.

Thanks very much everyone you've been more than helpful. I really appreciate it. I'll post my finished code when done.

I just made this small code and I made it to display the letter A but for some reason it only displays the bottom row. Any ideas?

/* In this matrix tha column register will
be updated and each row will turn on as needed.
It's basically cycling one row at a time from 
bottom to top

By:Chris Yambo
*/

const int CPR = 2;
// clock pin row
const int LPR = 3;
// latch pin row
const int DPR = 4;
// data pin row
const int CPC = 8;
// clock pin cloumn
const int LPC = 9;
// latch pin column
const int DPC = 10;
// data pin column



const int RA[5] = {B10000000, B01000000, B00100000, B00010000, B00001000, }; // Row activator. How I can adress each row individually

const int A[5] = {B01010000, B01010000, B01110000, B01010000, B00100000}; // capital A


int rows = 5;
int columns = 5;

int x, y, z;


void setup() {
  //set pins to output
  pinMode(CPR, OUTPUT);
  pinMode(LPR, OUTPUT);  
  pinMode(DPR, OUTPUT);
  pinMode(CPC, OUTPUT);
  pinMode(LPC, OUTPUT);
  pinMode(DPC, OUTPUT);
  
}


void loop() {
  digitalWrite(LPR, LOW);
  digitalWrite(LPC, LOW);
  
  for(x=0; x<5; x++){
  
    shiftOut(DPC, CPC, LSBFIRST, A[x]);
    shiftOut(DPR, CPR, LSBFIRST, RA[x]);
   
  
  digitalWrite(LPC, HIGH);
  digitalWrite(LPR, HIGH);

  }
}

(code tags added by moderator]

cabyambo:
hi was trying to understand your code but its to advanced for me is there anyway you could try and explain it to me?

The java guide i gave you also has a section on arrays. Read that first, so you understand what an array is , and how to use it.

The code you show is already pretty close to how it should be. but... how will the code know which item of the array to take? arrays aren't something magical that when you loop over them every time a different item will be returned. So as your code is right now, the first item will always be taken, since you're not indicating which item you'd like to take from the array :).
(together with the programming tutorial, you should be able to figure it out now)

And what your next question might be: how do i handle multiple characters? your first idea will probably be to make a second array named B, store the letter B in there, etc... It does make it annoying for the code however to always have to switch to a different array. You can also make one huge array containing all the letters, and when needing a letter, you just calculate the offset needed. A will start at position 0, and will need 5 bytes, so B will start at position 5, C at 10, etc... :slight_smile:

good luck :slight_smile: