Multiplexing RGB LED's with TLC5940 and 7HC595

Hi there,
Currently I am trying to MUX an 8x8 one color LED array to demo the code to be used for a 10x16 array of RGB LED's. With the demo circuit I get a lot of flicker happening in my LED matrix. What i've noticed is that if i DISCONNECT more cathodes from the TLC leaving 1 or 2 the flicker disappears, with the exact same code uploaded! But if I have over 2 connections to my TLC, complex code like this, causes flicker.
The flicker also does not appear if there is some delay between row switching in the code.

My thinking is that either:

  1. Circuit setup causes some kind of weird drain issue that is coupling between rows
  2. Software setup is causing latching to not synchronize properly, causing flickering unless no other rows have been hooked up (which would allow for current leakage).
    I have located other code such as:
    Google Code Archive - Long-term storage for Google Code Project Hosting.
    but I can't make sense of any of the code.

Can anyone point me in the right direction onto how to solve this issue??

The final circuit will look as follows:


This doesn't include the coupling capacitor connected between the TLC ground and VCC pins. They are a .1pF and a 10pF capacitor in parallel configuration.

I have the shift register hooked up to an Uno and the TLC in my DEMO circuit hooked up according to the tlc5940_config.h file.

Here is a guess of my code, as the actual code is at home and I am at school:

#include "tlc_config.h"
#include "Tlc5940.h"

int dataPin = 7;
int latchPin = 5;
int clockPin = 6;
byte leds = 0;
int shiftSelect[8] = {1,2,4,8,16,32,64,128};

void setup() {
  // set the shift register pins to output
  pinMode(dataPin,OUTPUT);
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  Tlc.init();
}

void loop() {
  // 1.  Start of display cycle
  // 2.  Switch anode to next row
  next_row();

  // 3.  Calculate/load data for the next next row (not the one we just switched to, but the next one)
  // let's display two circles
  // I'm assuming that outputs 0-7 are red, 8-15 are green
  Tlc.clear();
    Tlc.set(2, 4095);
    Tlc.set(3, 4095);
    Tlc.set(4, 4095);
    Tlc.set(5, 4095);

  // 4.  Send the data to the tlc's
  Tlc.update();

  leds = shiftSelect[count];
  updateShiftRegister();
  // 5.  Wait till the end of display cycle
  while (tlc_needXLAT);
  count++;
  if(count > 7) {
     count = 0;
  }
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}

EDIT:

I should have previously stated, the final project will be using a teensy, so it needs to be a teensy compatible solution.
Regards,
-Mat

Those transistors don't look correct. Did you intend to have PNPs there, that turn on when their base is pulled low?

Hi mHo2,

You need to post the real code for us to be reliable help. Where is next_row() for example?

My best guess at this point would be one of the most common mistakes made when multiplexing. You need to switch off all the anodes (i.e. shift register outputs) before updating your cathodes (i.e. the tlc outputs), then set the required shift reg output to switch on the required anode.

Hope this helps.

Paul

CrossRoads:
Those transistors don't look correct. Did you intend to have PNPs there, that turn on when their base is pulled low?

Sorry about the diagram, they are NPN.

Hi mHo2,

You need to post the real code for us to be reliable help. Where is next_row() for example?

My best guess at this point would be one of the most common mistakes made when multiplexing. You need to switch off all the anodes (i.e. shift register outputs) before updating your cathodes (i.e. the tlc outputs), then set the required shift reg output to switch on the required anode.

Hope this helps.

Paul

I'll give that a shot and report back with the actual code!

PaulRB:
Hi mHo2,

You need to post the real code for us to be reliable help. Where is next_row() for example?

My best guess at this point would be one of the most common mistakes made when multiplexing. You need to switch off all the anodes (i.e. shift register outputs) before updating your cathodes (i.e. the tlc outputs), then set the required shift reg output to switch on the required anode.

Hope this helps.

Paul

Sorry for the double post.
That seemed to work! I'm getting a slight bit of column bleed though, d'you know how that could be fixed?
Regards,
-Mat

Here's the updated code:

#include "tlc_config.h"
#include "Tlc5940.h"

int dataPin = 7;
int latchPin = 6;
int clockPin = 8;
byte leds = 0;
int count = 0;
int shiftSelect[8] = {1,2,4,8,16,32,64,128};
int num = 4095;
void setup() {
  // set the shift register pins to output
  pinMode(dataPin,OUTPUT);
  pinMode(latchPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  Tlc.init();
}

void loop() {
  // 1.  Start of display cycle
  // 2.  Switch anode to next row
  leds = 0;
  updateShiftRegister();
  // 3.  Calculate/load data for the next next row (not the one we just switched to, but the next one)
  // let's display two circles
  // I'm assuming that outputs 0-7 are red, 8-15 are green
  Tlc.clear();
  num = 4095;
  if(count == 3) {
   num = 0; 
  }
    Tlc.set(1, num);
    Tlc.set(2, num);
    Tlc.set(3, num);
    Tlc.set(4, num);
    Tlc.set(5, num);
    Tlc.set(6, num);
    Tlc.set(7, num);
    Tlc.set(8,num);
  // 4.  Send the data to the tlc's
  Tlc.update();

  leds = shiftSelect[count];
  updateShiftRegister();
  // 5.  Wait till the end of display cycle
  while (tlc_needXLAT);
  count++;
  if(count > 7) {
     count = 0;
  }
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}

Hard to say. What does this bleed through look like? Can you post a pic?

Also post your corrected schematic. Label the base, collector and emitter of one of your npn transistors. You might have collectors and emitters reversed.