Row Column Scanning (LED Matrix) with 74HC595

I am trying to use a 74HC595 shift register to create an LED Matrix.

If it has 16 outputs, does that mean, using row column scanning, that I can have a matrix of 64 LEDs?

You can run a 8x8 single color matrix with 64 LEDs with two of those shift registers.

I had no problem running a two color matrix with three and have wired other configs with RGBs .. all work well too.

Is your matrix common anode or common cathode?

Here is some code that may help.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1258679906/1#1

By the way, Marklar, it could be great if you show how you wired the bi-color matrix by threeof those 74HC595!! ::)

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

and an example code?

Thanks!!

I have two .. one is common anode and the other common cathode and the pinout / code is a bit different on the two. But once you know the pin-outs on the matrix .. know which is R/G and common pins 1-8 .. then you can wire it up based on the below details.

The summary is (for a two color matrix) .. I was using 1 SR set for green .. the other for red and the other for multiplexing.

So the wiring is directly from pin 1 of SR1 to red 1 .. then pin 1 of SR2 to green 1 and pin1 of SR3 to column1 and so on.

Here is some code to help get the idea. My code has custom classes patterns and other stuff making it too big to post here.

I included

This runs in an interrupt …

void iProcess(){

  ticker++;
  if( ticker > TICKER_MAX ) 
    ticker = 0;
  int myPos = ticker * TICKER_STEP;

  groundAt++;
  if( groundAt > groundMax - 1 )
    groundAt = 0;


  //IMPORTANT: This but be swapped for common cathod
  byte srTS = B11111111;
  byte mySR1  = B11111111;
  byte mySR2  = B11111111;
  srCommon = 0;

  /* for Common Cathode
   byte mySR1  = 0;
   byte mySR2  = 0;
   srCommon = B11111111;
   
   */
  for (int i = 0 ; i < 8; i++ ){
    int iLED = i;
    int myLev = 0;

    myLev = 1;
    if (srPins[i+(groundAt*16)] > myPos)
      myLev = 0;
    bitWrite(mySR1,i,myLev );

    myLev = 1;
    if (srPins[(i+8)+(groundAt*16)] > myPos)
      myLev = 0;
    bitWrite(mySR2,i,myLev );

  }


  bitWrite(srCommon,groundAt,1 );

  /* for Common Cathode - use this instead
   for (int i = 0 ; i < 8; i++ ){
   int iLED = i;
   int myLev = 0;
   
   myLev = 1;
   if (srPins[i+(groundAt*16)] > myPos)
   myLev = 1;
   bitWrite(mySR1,i,myLev );
   
   myLev = 0;
   if (srPins[(i+8)+(groundAt*16)] > myPos)
   myLev = 1;
   bitWrite(mySR2,i,myLev );
   
   }
   
   
   bitWrite(srCommon,groundAt,0);
   
   */
  latchOff();
  //SR's are daisy chained.  The 3rd SR is the common (anode or cathode)
  //Update order if needed so the common is correct for your arrangement
  //srTS = B10101010;
  //   spi_transfer(srTS);

  spi_transfer(srCommon);
  spi_transfer(mySR2);
  spi_transfer(mySR1);

  latchOn();

}

Other code parts including setup routine.

void latchOn(){
  bitSet(PORTB,latchPinPORTB);
}

void latchOff(){
  bitClear(PORTB,latchPinPORTB);
}

void setupSPI(){
  byte clr;
  SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
  //SPCR |= ( (1<<SPR1) | (1<<SPR0) ); // set prescaler bits
  SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
  clr=SPSR; // clear SPI status reg
  clr=SPDR; // clear SPI data reg
  SPSR |= (1<<SPI2X); // set prescaler bits
  //SPSR &= ~(1<<SPI2X); // clear prescaler bits

  delay(10); 
}


byte spi_transfer(byte data)
{
  SPDR = data;                    // Start the transmission
  loop_until_bit_is_set(SPSR, SPIF); 
  return SPDR;                    // return the received byte, we don't need that
}

void setup() {
  randomSeed(analogRead(0));
  Serial.begin(9600);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

  digitalWrite(latchPin,LOW);
  digitalWrite(dataPin,LOW);
  digitalWrite(clockPin,LOW);

  setupSPI();
  Timer1.initialize(timerDelay); // Timer for updating pwm pins
  Timer1.attachInterrupt(iProcess);


}

Vars and PWM Write Function

#include <TimerOne.h>

#define TICKER_MAX 16
#define TICKER_STEP 16
#define YIELD_DELAY 10
int timerDelay = 165;
byte srCommon = B11111111;

//--- Pin connected to ST_CP of 74HC595
int latchPin = 10;
//--- Pin connected to SH_CP of 74HC595
int clockPin = 13;
//--- Pin connected to DS of 74HC595
int dataPin = 11;

//--- Used for faster latching
int latchPinPORTB = latchPin - 8;

//======================

int groundMax = 8;  //number of multiplex

int ticker = 0;

int groundAt = 255;

byte srPins[128] = {
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0
};

void pwmWrite(int port, byte val){
  srPins[port] = val;  
}

You can then use pwmWrite to write to any of the ports you want … value from 0 to 255 and iProcess does the rest.

Good luck.

What do you mean by common cathode or annode?

Two colour LEDs (two LEDs in one package) come in three different types:- 1) Common anode - the anode of both LEDs is brought out to the same pin 2) Common cathode (guess fro above) 3) Independent - you have four pins and separate access to each LED

Marklar you said:-

You can run a 8x8 single color matrix with 64 LEDs with two of those shift registers.

As shift registers only pull down (sink current) what else do you add to get the second shift register to source current? Have you a schematic?

There's been a few posts about the 74HC595 lately (I just cant seem to find the one I'm thinking about just now), so (some of) you probably know this by now. But the 74HC595 can both sink and source current.

So if you are happy with somewhat dim LED's, it'll be okay as long as you don't go above specs. A max of +/- 30 mA according to datasheets pr. pin (and max 70mA total for the IC, and 500mW for the DIP version).

...which btw is just what I did (went above specs) in a little project I'm doing now. I've made some 4 by 4 RGB LED matrices driven directly from two 74HC595's, and it works pretty well, sans a little issue regarding brightness and color even-ness. Not entirely sure if that is due to a somewhat rather conservative current, and / or normal LED diversity (I'm thinking it would even out a bit more, but not completely, by having a bit more current through than I did. A few blue ones are very different, I guess I should swap those anyway).

In my case I settled for 390 ohms for the green (~5.82 mA), and 1 k ohm for the red (~3.22 mA) and blue (~2.15 mA) LED's, totalling a worst-case current draw of about 11.2 mA pr. LED at 5 volt. Values were experimentally found, for a white as possible color and also keeping the current as low as possible (I think).

The RGB output pins are okay regarding current requirements, but worst case current sourcing (since my LED's are common anode) is about 44.8 mA for one row (and hence one pin). At least for 1/4 of the time in a 4 by 4 matrix. Actually I thought wrong in the beginning - I managed to multiply one LED by 3 instead of 4 at design-time... so I arrived at just above 30mA at first :-[ Yeah I know - still a bad decision.. Luckily it works, well, so far at least, after some hours.

But in practice it wont be exactly 5 volt, as the outputs of the IC is not exactly at the supply rails nor ground but off with a few tenths of a volt. Also, I sometimes run it off 3 AA batteries (4.5V), again lowering the current. I just havent measured that yet. So I might be in luck. Well with the exception of the colors since LED's are not linear. In particular, "white" isn't too white, but more like random shades of yellow-red-pink-purple-green-ish white-ish. A little camel I had to swallow, but I've worked too much with this now to not like it :P At least other colors seems okay (using PWM))

I didn't know about that other "high-current" version of the 74x595, mentioned in the post I couldn't find at the moment. I forgot the name. I will probably get some of those instead. Another thing I could (should) have done, is having some transistors at the 4 row multiplexing pins of the 595's, but I'm not going to make new PCB's now.

All in all it works (and pretty well imho), but don't expect very bright LED's. As in, not very visible directly under a desk lamp.

But the 74HC595 can both sink and source current.

Well yes but it is not a driver is it.

The point as you say is that you have to supply enough current for a whole row of LEDs on at the same time. With an 8 row matrix 30mA does not go very far.

I didn't know about that other "high-current" version of the 74x595, mentioned in the post I couldn't find at the moment.

It's a TPIC6B595 http://uk.farnell.com/texas-instruments/tpic6b595n/8bit-shift-register-pdip20/dp/1287675 But it is open drain so it sinks only up to 150mA per line or 500mA pulsed.

Im still pretty damn dumb when it comes to data sheets, its quite clear that the TPIC6B595 sinks 150ma, it is quite proud of that on the data sheet

BUT what about sourcing current? does it, can it? where the heck do I see that in the datasheet, if not can anyone recommend a high power 8 bit shift register that can source current matching what the tpic6b595 can source?

why not use a darlington transistor array in combination with shift register.. e.g uln2003 or ... uln2803

I think the ULN2803 can also only be used as a sink.

BUT what about sourcing current? does it, can it? where the heck do I see that in the datasheet,

No it doesn't source current at all. You can tell this because the data sheet says (and shows) the output as open drain. That means it can only pull down and there is no sourcing.

I think the ULN2803 can also only be used as a sink.

Yes but we are talking about the TPIC6B595 here.

Well yes but it is not a driver is it.

No I guess not.

It's a TPIC6B595 http://uk.farnell.com/texas-instruments/tpic6b595n/8bit-shift-register-pdip20/dp... But it is open drain so it sinks only up to 150mA per line or 500mA pulsed.

Thanks for answering! Seems I'm outta luck regarding a simple swap then.

Osgeld:

If you're thinking about something like an 8 by 8 matix thing, and if you use common cathode LED's, maybe you could use one TPIC6B595 and ordinary 74HC595's for the rest?

TPIC6B595 and ordinary 74HC595's for the rest?

You still have the problem with current source limitations. The way round this is to use a 74HC595 to drive some P-channel FETs for the rows. Then you have all the current you want. Just like this project:- http://www.thebox.myzen.co.uk/Hardware/Econo_Monome.html

just trying to avoid the whole transistor / fet thing as the matrix I am planning is 32x32, and board space is already tight

nothing? ah poop

Grumpy_Mike: Yes. But - it would still be much better than without the TPIC6B595 imho. Since I haven’t tried that combination I cant say for sure how much better. But as the TPIC6B595 could take 500mA pulses, I would think it could take 20-25mA (just to keep it below 30mA…) times 8 quite well for 1/8th the time in an 8 by 8 matrix. Maybe even in a matrix double that size.

As stated I have tried with only 74HC595’s, and that sorta works too, but I wouldn’t recommend it (besides it was only 4 by 4).

Osgeld: 32 by 32 with shiftregisters? Maybe you should think about modulizing (sorry, spelling?) it, like into 16 matrices of 8 by 8, or 4 with 16 by 16, or sometthing. Do you intend to use PWM and RGB colors too?

Osgeld: 32 by 32 with shiftregisters? Maybe you should think about modulizing (sorry, spelling?) it, like into 16 matrices of 8 by 8, or 4 with 16 by 16, or sometthing. Do you intend to use PWM and RGB colors too?

Treating each 8x8 matrix as a individual matrix would require 32 shift registers, and seems like a over complication and a waste of hardware, thats not really the question here tho (I have most of that worked out)

I am trying to find a shift register that can source enough current to get nice n bright led's while reducing hardware (ie tons of transistors and their resistors)

I am aware of led display driver chips, but at 6-9 us dollars each needing 8-16 of them (some drive dual displays / colors) is not really appealing

PS: no pwm no colors just red, and no I do not intend to turn on all the led's at once, this will be a pov scan trick