8x8 bicolor matrix - concerns about current

I know there's a bunch of topics on this already and I've read a few of them but I'm new to electronics and would like to have some knowledgeable people confirm my assumptions and give me some advice with regards to how to best drive the matrix.

The scenario is as follows: I have a common anode matrix. Let's say I have the anodes hooked up to one 74HC595 and the cathodes to two TPIC6B595 - one for red and one for green. If I turn on the red LED at position 0, 0 on the matrix I'll have 20mA flowing through 1 pin on the red TPIC6B595 as well as 1 pin on the 74HC595. If I also turn on the green LED at the same position I'll have 20mA flowing through 1 pin on the red TPIC, 20mA flowing through 1 pin on the green TPIC and 40mA flowing through 1 pin on the 74HC. Is this correct?

Only one column will be active a time on the matrix so there will be a max of 16 LEDs that can be on at any given time. From what I understand, a 74HC595 can handle up to 20mA on a pin but only 70mA through VCC so if I were to use something like 750 Ohm resistors I'd have only 4mA per LED and 64mA if all 16 are on which would be safe for the chip. Between the high resistor value and multiplexing though the matrix would be too dim which won't work.

So the question becomes what's a good combination of chips to use to drive it? I've tried the MAX7219 with the LedControl library and found it to be a major headache so I'd rather stick with dumb shift registers and do my own multiplexing. The main concerns are cost and space. For example, from what I understand I could use a 74HC595 with a ULN2003. However, I want to have 4 matrices arranged in a square configuration for a 16x16 "display" so having 4 chips (74HC595, ULN2003 and two TPIC6B595) per matrix would probably take up too much space.

Are my assumptions correct and can anybody give me some ideas as to how to proceed?

Use a different shift register to source current - cd74AC164.
Keep TCIP6B595 to sink current from the cathodes.
With common anode, do your multiplexing so that only 1 column of red or green is on at a time.
Otherwise the LEDs will just look yellow/amber whenever turned on because both columns will show the same color.

Other option is to use 2 MAX7219s, and alternate between them using shutdown mode - each one controls 8 columns - 4 pairs, or all 8 of one color. Each will drive the anodes thru diodes so that when shutdown one 7219 is isolated from the other (they pull the anodes to Gnd in shutdown mode).

Have to experiment & see how long each can be shutdown and still maintain persistence of vision/nonflickering. Probably 2-3 mS each.

cd74ac164, 20mA high output shift register.pdf (597 KB)

I’ve tried driving the matrix with 2 MAX7219 as described in this tutorial. This worked well for a single matrix but caused headaches when daisy chaining more MAX7219 together to drive additional matrices so I gave up on the idea and would rather use simple shift registers.

Regarding your suggestions on multiplexing (and I don’t know if what I’m doing is proper multiplexing) but this is how I currently have it set up using 4 matrices to end up with a 16x16 display area:

Only one column of LEDs is on at a time. While the column is on, I have individual control of all 32 LEDs in it (which are spread across two matrices). So each row in that column can be either red, green or orange. A single refresh cycle starts at column 0 and ends at column 15.

Is this a sound approach? One drawback to doing it this way is that the interval between columns turning on and off has to be around .4ms for a person to not notice the LEDs flickering. Using the same method on a single matrix where you only have to cycle through 8 columns rather than 16, 1.5ms is good enough. .4ms makes the matrices appear dim.

I was reading some things last night and know that I can optimize my code - for example, I’m using shiftOut where a faster way would be to use SPI.transfer. Perhaps this will help with the refresh rate.

I used 4 8x8 matrices with 4 MAX7219s. I found it easier to code to give each MAX7219 its own chip select. You could also look into parola here in the forum, library written to daisy can max7219s for way more than 4 displays. SPI definitely the way to go.

With dual color, you must multiplex between the 2 columns, or both red & green will both be on. You have this kind of part, yes? http://www.futurlec.com/LED/LEDM88RGCA.shtml You can have the anodes going all the way across, driven by two cd74ac164 shift registers. Then you will have 4 TCIP6B595 to sink current from the columns. Drive the anodes, turn on a cathode to sink current from a column. Drive the anodes, sink the next column.

Use of the DS pins on the 164 as an active high chip select:

digitalWrite (164CS, HIGH);
SPI.transfer (anodeHigh[x]);
SPI.transfer (anodeLow[x]);
digitalWrite (164CS, LOW);

digitalWrite (6B595CS, LOW);
SPI.transfer (cathode[x]);
SPI.transfer (cathode[x+1]);
SPI.transfer (cathode[x+2]);
SPI.transfer (cathode[x+3]);
digitalWrite (6B595CS, HIGH);

where anodeHIGH[0 to 31] and anodeLow[0-31] are the 32 columns of your data. cathode[x] is the 4 bytes that determines which cathode CS is on:

0x80, 0x00, 0x00, 0x00 0x40, 0x00, 0x00, 0x00 0x20, 0x00, 0x00, 0x00 0x20, 0x00, 0x00, 0x00 0x08, 0x00, 0x00, 0x00 0x04, 0x00, 0x00, 0x00 0x02, 0x00, 0x00, 0x00 0x01, 0x00, 0x00, 0x00

0x00, 0x80, 0x00, 0x00 etc. Manipulate during the time while a column is lit up. If you get ghosting you can use MasterClear/ on the 164s to clear all outputs before shifting new data in and turning on the next cathode. You can go even faster if you use direct port manipulation instead of digitalWrite - the 6 bytes can be sent out in mere 8-12 microseconds or so then, allowing for longer on times.

OK I see what I was doing wrong now. I had each matrix be its own little self-contained unit whereas, per your suggestion, I should have tied the anodes together and then only need to use two (rather than four) shift registers to drive the anodes on all 4 matrices.

I'll go back and rework it as well as read up on optimizing the code piece of the puzzle.

The last question I have is regarding the current pumped through a single CD74AC164 in this scenario - just want to make sure I understand the math correctly. Let's say I want to light up the entire 16x16 matrix in orange color. Let's say each green LED is 10mA and each red one 10mA as well. Wouldn't this mean that current going through a single AC164 would be 160mA (keeping into account that only one column is on at a time)? (10mA from green + 10mA from red) * 8? If I'm reading the datasheet correctly, max current through VCC should be 100mA so I would need each LED to be about 6mA instead which would give a safe total of 96mA. Make sense? Sorry for my noobishness.

Thanks a bunch for the help and ideas!

Have a look at the circuit for the 504-LED sign I hacked.


They used transistors for the common rows to handle the amount of current needed to be sourced.

Each '164 output will be driving 20mA into 1 LED. If you want orange the multiplexing will turn on Red in one column for say 1mS, then Green in he next column for 1mS, persistence of vision will trick your brain into seeing both as on together look like orange. So in 32mS all LEDs will have been on 1mS, the refresh rate will be 31.25Hz, and your eye will see the display as orange.