Dim LEDs with multiplexing

After much cautious soldering, I've got my first decent project finished. The set-up is my arduino (pins: digital 10, 11, 12, 13 & analog 5v and GND). This is hooked up to a 4051 (as a demux) which then runs out 8 outputs to leds (common cathode) with appropriate resistors (on the anode of course).

A number of questions come to mind:

  1. The LEDs are slightly dim. Because I'm rapidly flipping through them, I assume they aren't getting enough current. Are there formulas to calculate a lower resistor value that takes into account the switching frequency?

  2. Are there advantages or disadvantages to which end of the LEDs are common? (anode vs cathode)

  3. I've seen people mention TLC5940s. Would these be something to look into for large groups of LEDs like this one?

For the curious my sketch looks like this:

/* muxProg v1.0
 * Author: Johnny Ferguson
 *
 * Uses a 4051 to make a simple programmable LED Array
 */
 
#define PROG_LENGTH 98

// Global Vars
/// Pinout
int ledOut = 13;    // led output
int selA = 12;      // select A
int selB = 11;      // select B
int selC = 10;      // select C

/// Select
int bin [] = {000, 1, 10, 11, 100, 101, 110, 111};    // binary values for mux select
int selValue = 0;    // holds the value for select bit bitshifting
int sa, sb, sc = 0;

int ledVal = 0;
int portBOut = 0; // pins 8-13

unsigned int pattern [PROG_LENGTH] = {
B00000001,
B00000011,
B00000111,
B00001111,
B00011111,
B00111111,
B01111111,
B11111111,
B11111110,
B11111100,
B11111000,
B11110000,
B11100000,
B11000000,
B10000000,
B00000000,
B10000000,
B11000000,
B11100000,
B11110000,
B11111000,
B11111100,
B11111110,
B11111111,
B01111111,
B00111111,
B00011111,
B00001111,
B00000111,
B00000011,
B00000001,
B00000000,
B00000001,
B00000011,
B00000111,
B00001111,
B00011111,
B00111111,
B01111111,
B11111111,
B11111110,
B11111100,
B11111000,
B11110000,
B11100000,
B11000000,
B10000000,
B00000000,
B10000000,
B11000000,
B11100000,
B11110000,
B11111000,
B11111100,
B11111110,
B11111111,
B01111111,
B00111111,
B00011111,
B00001111,
B00000111,
B00000011,
B00000001,
B00000000,
B00000000,
B00000000,
B11111111,
B11111111,
B00000000,
B00000000,
B11111111,
B11111111,
B00000000,
B00000000,
B11111111,
B11111111,
B11111111,
B11111111,
B00000000,
B00000000,
B00000000,
B00000000,
B11111111,
B11111111,
B00000000,
B00000000,
B11111111,
B11111111,
B00000000,
B00000000,
B11111111,
B11111111,
B11111111,
B11111111,
B00000000,
B00000000,
B00000000,
B00000000,
};

// setup
void setup(){
  // Set pins 10-13 for output
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
}

// main loop
void loop(){
  for(int j = 0; j < PROG_LENGTH; j++){
    for(int i = 0; i < 8; i++){
      // load selValue from binary array
      selValue = bin[i];
      // bitshift and mask to get appropriate values
      sa = selValue & 0x01;
      sb = (selValue >> 1) & 0x01;
      sc = (selValue >> 2) & 0x01;
      // get the on/off bit for this part of the pattern, then use port manipulation to write select values (faster than digitalwrite)
      ledVal = ((pattern[j] >> i) & 0x01) ? 1 : 0;
      portBOut = B00111100 & ((ledVal << 5) | (sa << 4) | (sb << 3) | (sc << 2));
      PORTB = portBOut;
      // to stop the animation from playing way too fast
      delay(1);  
    }
    // stops the last LED in the chain from staying on bright between animation frames
    PORTB = B00000000;
    delay(1);
  }
}

I'm thinking for the next sketch I do with this board, I'll write the program so my array can specify a time in milliseconds for each frame to display. I'd also like to avoid the use of delay as it's just sloppy in general (but was a great way to get this thing tested).

The LEDs are slightly dim. Because I'm rapidly flipping through them, I assume they aren't getting enough current. Are there formulas to calculate a lower resistor value that takes into account the switching frequency?

In the LED datasheet there should be a constant current and a 'peak' current that can be used when multiplexing. Most LEDs will burn out after a period of time on higher current but if it is flashed then it will be fine. If you can find out what is the highest current that the LEDs can take then you can calculate a resistor from that.

Also, the pin13 already has a resistor (and LED) on board (on most arduino boards) so that may be your problem as it looks like you are using pin13 for at least 1 LED.

Mowcius

Ah yes, pin 13 does have an LED. This was good for diagnostics, but I'll try switching to another pin. I have pin 13 running to my mux as the input. Using pin 9 now, it seems I get a bit more juice.

This could be something to clarify. Is the LED on pin 13 in series with the pin?

I will go looking through my datasheets to see what I can find. I almost wonder what would be needed to create my own LED testing suite (find their breaking points to squeeze out as much as possible).

In my mind if you know how fast your mux is switching between leds, you should be able to calculate some kind of average power level (just like PWM can simulate different voltages out the digital pins). From there, you could probably make a decent calculation as to the limits you have to work with.

Thanks for the tips!

For a first approximation consider this:-
If you have an 8 by 8 matrix then any one LED is only on one eight of the time. This is the equivalent of an LED that is on all the time but with only one eight of the current. So in a multiplexed LED display the peak power should be 8 times the static power.

For a 20mA LED there is little perceived difference between running it at 10mA and 20mA so running at 60 to 80mA would give you the same sort of brightness.

I almost wonder what would be needed to create my own LED testing suite

This is more difficult than you might think because it is not just a matter of when an LED burns out and stops working you must also consider the LED lifetime. This is normally defined as the time when the LED light output has dropped by a half. The peak current will affect this lifetime so you have to measure things for a long time and balance extra peak current with shorter lifetime. This lifetime is typically 3 to 5 years so you have to use accelerating techniques in your test set up. The chief of these is temperature. So you need high level stabilised climatic chambers.

Is the LED on pin 13 in series with the pin?

Only on some early arduinos, not the majority have the pin coming straight out.

This could be something to clarify. Is the LED on pin 13 in series with the pin?

I am pretty sure that the resistor is before the pin so the LED is in parallel but the power to that pin has a resistor on. It means that you can connect most LEDs to the pin without the need for a resistor.

Mowcius

I am pretty sure that you are wrong take a look at the schematic of the board you are interested in.

The ones I have seen:- Diecimila, Duemilanove, mega, pro, all have the output connection straight to the pin.

The mini does have the resistor in line with the pin.

I have a dumillanove. Basically what I am getting at is that I want to know if the little orange LED is pulling power from the output of the pin. It would be better to know this than to simply switch my output to pin 9 and guess that it "looks brighter".

It may be splitting hairs, but I'm curious.

I'll try looking up a schematic (they look like mazes to me). I'll need a microscope if I'm going to be looking at the board itself.

EDIT: I can just use a multi-meter... sometimes the best solutions are the simplest ;D

I am pretty sure that you are wrong take a look at the schematic of the board you are interested in.

The ones I have seen:- Diecimila, Duemilanove, mega, pro, all have the output connection straight to the pin.

The mini does have the resistor in line with the pin.

Okey dokey, Well if you have an LED on pin13 then it is a lot dimmer than on any other pin but that should not happen if the LED and resistor is in parallel to the pin, two LEDs would not draw that much current.

Mowcius

I believe the last Arduino to have a resistor in line with Pin 13 was the NG way back in the mists of time (2007 ?). It didn't have a Pin 13 LED built in so you could stick one directly in the sockets. They are wired direct now with the built in one in parallel with its own resistor.

Ok but that doesn't explain why LEDs are dimmer when using pin13 as an output rather than another pin

Mowcius