# AVR C 74hc595 rgb matrix multiplexing and brightness

I have built a test matrix 2*2 rgb LED's, common Anode. Connected the anodes into columns, and the Cathodes trough 220R resistors into R,G,B rows. Both go to two different 74hc595 shift registers. I am then using this code to light up two LED's diagonally from an atmega48 connected to the registers (bottom left and top right).

/*
* RGBMatrix.c
*
* Created: 15.12.2017 23:35:52
* Author : Rando Hinn
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include "util/delay.h"
#define data_out PB2
#define shift_clock PB1
#define store_clock PB0

#define rgb_out PC5
#define rgbshift_clock PC4
#define rgbstore_clock PC3

#define SetBit(BIT, PORT) (PORT |= (1<<BIT))
#define ClearBit(BIT, PORT) (PORT &= ~(1<<BIT))

void shiftOut(uint8_t data) {
for(uint8_t i=0;i<8;i++) {
if(data & 0b10000000) {
SetBit(data_out, PORTB);
} else {
ClearBit(data_out, PORTB);
}
SetBit(shift_clock, PORTB);
ClearBit(shift_clock, PORTB);
data=data<<1;
}
SetBit(store_clock, PORTB);
ClearBit(store_clock, PORTB);
return;
}

void shiftOutRGB(uint8_t data) {
for(uint8_t i=0;i<8;i++) {
if(data & 0b10000000) {
SetBit(rgb_out, PORTC);
} else {
ClearBit(rgb_out, PORTC);
}
SetBit(rgbshift_clock, PORTC);
ClearBit(rgbshift_clock, PORTC);
data=data<<1;
}
SetBit(rgbstore_clock, PORTC);
ClearBit(rgbstore_clock, PORTC);
return;
}

int main(void)
{
DDRB|=((1<<shift_clock)|(1<<store_clock)|(1<<data_out));
DDRC|=((1<<rgbshift_clock)|(1<<rgbstore_clock)|(1<<rgb_out));
/*RCOL/LCOL*/
//shiftOut(0b10111111);

//shiftOutRGB(0b11010100);
/*BOT_R/BOT_G/BOT_B/TOP_R/TOP_G/TOP_B/NA/NA active low*/
while(1) {
shiftOutRGB(0b01111111);
shiftOut(0b01000000);
_delay_us(60);
shiftOutRGB(0b11111011);
shiftOut(0b10000000);
_delay_us(60);

}
}


The problem here is, that while I do get the LED's to light up, they are incredibly dim. Switching delays to ms, makes them brighter but causes visible flickering. What could I do to properly light the LED's?

Your program appears to have a problem with ghosting- I don't see you shutting down the anode drive before changing the cathode drive.

As far as brightness goes- it looks to me from a cursory look at the code that you have LEDs powered all the time so the duty cycle is about 50% for 'on' LEDs. Do verify this somehow, preferably with an oscilloscope.

In that case, you would have to increase the current (or use much better LEDs). The 74HC595 is not great at sourcing current and you are asking it to source current for (right now) 7 LEDs so the loading is like an LED with 31 ohms in series. If you only turn on a single LED you will probably see much more brightness.

You can add anode drivers (for example, use the 74HC595s to switch P-channel MOSFETs). You will then be limited by the abs max 70mA GND current of the 595. If you go 60mA that's 1.8mA per LED in a 2 of 4 matrix. Maybe enough with good LEDs, otherwise you have to add cathode drivers too.

As you've discovered, the brightness does not change significantly with timing until you fall below the flicker fusion frequency, it's basically the average LED current. No free lunches.

• I have now removed the delays alltogether. Brighter, solid LED's, but not bright enough still. What MOSFETs would you reccommend that can work this fast? – Rando Hinn Dec 17 '17 at 10:57
• Any transistor ideas then? – Rando Hinn Dec 20 '17 at 19:50
• Start with high-side drivers for the anodes- eg. 2N4403 with base resistors of maybe 1K (inverted drive). Emitter to +5, base through 1K to the HC595, collector the display common anode. – Spehro Pefhany Dec 20 '17 at 20:15
• Done and added, now the code needs adjusting. I have the same dim LED's with this code. And you were right - there is ghosting. What's next? – Rando Hinn Dec 23 '17 at 20:11
• Do you have a scope? What is the duty cycle of the drive? Visual brightness of a given LED is basically current * duty cycle. One or the other is inadequate. – Spehro Pefhany Dec 23 '17 at 20:15