[Solved]LED Matrix, can't make it bright enought

Hi,

I am editing the first post of this thread to summarize the things learned during the investigation and the solution. I've come across some contradictory information while working on this and that made things very difficult when you don't exactly know what you are doing.

The problem:
I was working on a 5x5 matrix, direct drive, not using any ICs.
The brightness of the LEDs was much lower when being Multiplexed than when plugging them to DC directly.
For this application i really need the LEDs to provide their maximum brightness.
LEDs can usually be fed with higher current when being Multiplexed to compensate for this (check datasheet of your LED).

These are the specs for the LEDs:
Forward voltage: 2.2v
Forward current: 20mA
Forward peak current: 50mA (at 10% duty cycle)

Approach:
I was planning to multiplex both Rows and Columns, so only 1 LED would be on at a time. I've done this in the past and it has worked fine, I managed to get consistent brightness on all LEDs and i was able to control the brightness of each LED individually refreshing it at 60Hz. The LEDs were not displaying their full brightness but that wasn't a problem for that application, they were bright enough.

The first problem I was facing was that Arduino can just provide or sink 40mA on each Pin. I needed 50mA to get the full brightness on the LEDs so I needed an extrenal power supply.
The way to switch bigger currents with Arduino on and off is obviously using transistors as switches and in this case I chose to use an NPN transistor, the 2N3904.

The way an NPN transistor works is current flows from the collector to the emitter when a small current is applied to the base.

Transistors can be used as amplifiers or as switches, in this case as i mentioned before, we want to use them as switches.Nowwhat we want to do is to calculate how much current we need to apply to the base, without damaging the transistor, to have it saturated, or fully ON so that the current of the power supply can flow.

There are a few things that you need to take into account when choosing a transistor:
1 - What's the current that you need, to switch the load ON?
In my case, 50mA
2N3904 supports 200mA of collector continuous current
2 - What's the voltage of the power supply that you are intending to use
In my case 9v, 2N3940 supports 40V Collector-Emitter voltage
3 - What's the gain(hFE) of the transistor?
This is basically a factor of the current that needs to be applied to the base in order to let the current pass from collector to emitter. In my case 100.
So if you take the current that you need to switch the LED ON (50mA) and divide it by hFE, 50mA / 100 = 0.5mA is the current that will need to be applied to the base to let 50mA pass through the collector-emitter.
Can the arduino provide that much current (0.5mA)? Yes! not a problem.

So the 2N3904 is a good choice.

Now how do i feed 0.5mA to the transistor from Arduino. Easy, we know the voltage that Arduino provides, we know the current that we need we are just missing the Resistance to apply Ohms Law.
However, the transistors lose 0.7 volts so we need to account for that. And we also want to make sure that the transistor is saturated so instead of 0.5mA we add a 30% to it.

Ib = 0.5 * 1.3 = 0.65

Rb = (5v - 0.7v) / 0.00065 = 6615 ohms (or the closest one available)

If we have done it right, the voltage across the collector and the emitter of the transistor should be < 0.7v, that means that the transistor is in saturation.

Next issue I was facing... Multiplexing.
The LEDs can be fed with 50mA if a duty cycle of 10%. What does this mean?
The duty cycle is the percentage of time that the LED will be ON in a pulse.
If we are using a pulse of 1ms, the LED can be on for 100 microseconds and has to be off for 900 microseconds. A 10% of the pulse.
This presents a problem, if i am planning to light just one LED at a time and i have a 5x5 matrix, this means that each LED can just be ON for 1/25 of the time, so they will be very dim, i need them to be on by 1/10 of the time.
One easy way to do this (I will work on a better solution later) is to split the matrix in sub-matrices of 10 LEDs.
In my case I did 3 groups,(A=Row1, Row2) (B=Row3, Row4) (C=Row5, DummyRow). I added a dummy row to group C just to keep the code consistent and easier.
Now if I want to refresh my matrix 100 times in 1 second
1/100 = 0.01 seconds = 10 miliseconds is the total time of the pulse
So now to achieve a 10% duty cycle, each LED will be ON for 1ms, then we will switch it off and do the same with the rest of the LEDs.
We will do this on the 3 groups at the same time.

In each iteration of the loop what you do is:
Switch on A-Row1 B-Row1 C-Row1
Switch on Column1
Delay 1 milisecond
Switch off Column1
Switch on Column2
Delay 1 milisecond
Switch off Column2
...
until Column5
Then:
Switch off A-Row1 B-Row1 C-Row1
Switch on A-Row2 B-Row2 C-Row2
Switch on Column1
Delay 1 milisecond
Switch off Column1
Switch on Column2
Delay 1 milisecond
Switch off Column2
...

The code would look something like this:

byte Rows[] = {3,4,5,6,7,-1};
byte Rows1[] = {Rows[0],Rows[1]};
byte Rows2[] = {Rows[2],Rows[3]};
byte Rows2[] = {Rows[4],Rows[5]};
byte Cols[] = {8,9,10,11,12};

void setup()
{
  for(byte i = 0; i < sizeof(Rows); i++)
  {
    pinMode(Rows[i], OUTPUT);
    digitalWrite(Rows[i], LOW);
  }
  for(byte i = 0; i < sizeof(Cols); i++)
  {
    pinMode(Cols[i], OUTPUT);
    digitalWrite(Cols[i], LOW);
  }
}
void loop()
{
  for(byte r = 0; r < 2; r++)
  {
    byte prevRow = !r;
    digitalWrite(Rows1[prevRow], LOW);
    digitalWrite(Rows1[r], HIGH);
    for(byte c = 0; c < sizeof(Cols); c++)
    {
      byte prevCol = c;
      if(prevCol == 0)
        prevCol = sizeOf(Cols) - 1;
      digitalWrite(Cols[prevCol], LOW);
      digitalWrite(Cols[c], HIGH);
      delayMicroseconds(1000);
    }
  }
}

Bear in mind that this code is assuming that we are using transistors for both rows and columns. So when the pins are set HIGH, the transistors are ON.
Also 3 LEDs (maximum) will be ON at the same time so we need will need to modify the formulas to calculate the resistors based on the current needed to feed the LEDs (150mA)

In my test i just had 1 LED and 1 transistor controlling the Row.

Plug everything in, upload the code, and boom! It works.

Thanks, any questions do not hesitate to ask.

Ok I have modified the circuit adding 2 NPN transistors this time, which should be more correct.
1 for the Row and 1 for the Column. I am getting the exact same results.

NPN1 has it's base connected to Pin4 (Row) through a 1k resistor. The collector is connected to +9v and the emitter is connected to the LED Anode.
NPN2 the base is connected to Pin13(Column) through a 1k resistor. The collector is connected to the cathode of the LED through a 100ohm resistor and the emitter is connected to 9v ground.

If i don't connect any of the arduino ground pins to the 9v ground, the LED doesn't light up. I don't really get that.

I have also modified the code so it makes the rows and columns LOW to switch them off and HIGH to switch them on.

void loop() {
  unsigned int time = millis(); 
  for(byte r = 0; r < sizeof(rows); r++)
  {
    //switch all rows off
    SwitchRows(LOW);
    //switch on current row
    digitalWrite(rows[r], HIGH);
    for(byte c = 0; c < sizeof(cols); c++)
    {
      //Switch all columns off
      SwitchCols(LOW);
      delayMicroseconds(360); //90% at 100hz
      //switch on current column
      digitalWrite(cols[c],  HIGH);
      delayMicroseconds(40); //10% at 100hz
    }
  }
  Serial.println(millis()-time);
}

You've got the 100 ohm resistor and the LED connected between the emitter and ground. That's not the way to use an NPN transistor as a switch. The load goes between the collector and the positive supply, and the emitter is grounded directly. As it's wired, the transistor is operating in its linear region, and it's limiting the current that flows through the LED. The transistor should be in saturation, with the 100 ohm resistor limiting the current. Recalculate the series resistor before you change it, though - if 50 mA is an absolute maximum rating for your LED, you might exceed it with 100 ohms and 9V.

It looks like you don't fully understand the notion of a duty cycle. A 10% duty cycle means that the LED is on 10% of the time; you seem to be thinking something else. It also applies to each LED individually; you seem to think it applies to the whole array. Check the Wikipedia article here: Duty cycle - Wikipedia, and, if that's not clear, googlit.

If i don't connect any of the arduino ground pins to the 9v ground, the LED doesn't light up. I don't really get that.

To turn on the transistor, current has to flow from the base to the emitter. That means that current has to flow from the Arduino's output pin into the base, out the emitter, through the LED and resistor, and then back to the ground of the Arduino. The 9V battery circuit is completely isolated from the Arduino's power supply unless you connect them. Without that connection, there isn't a complete circuit for the base current to flow through. No current flows, the transistor stays off, and the LED stays dark.

See how you like the performance with the LED and resistor between the collector and 9V, and the emitter grounded. There may be some other things you can do, but we won't know until you fix the circuit.

Thanks a lot for the reply tmd3!

The load goes between the collector and the positive supply, and the emitter is grounded directly

I have updated the circuit accordingly but i see no difference. I have placed the load between the +9v and the collector of NPN1.

9v+ ----- 100ohm ---- LED Anode
LED Cathode ------------ NPN1 Collector
Pin4 ---- 1k -------------------------------------- NPN1 Base
NPN1 Emitter -------- NPN2 Collector
Pin13---- 1k ---------- NPN2 Base
-9v & -Arduino ------- NPN2 Emitter

It doesn't let me upload the picture from the office, i will submit it later.

Recalculate the series resistor before you change it, though - if 50 mA is an absolute maximum rating for your LED, you might exceed it with 100 ohms and 9V.

As for the resistor value: (9 - 2.2 = 6.8) R=6.8/0.05 R=136ohms

A 10% duty cycle means that the LED is on 10% of the time; you seem to be thinking something else. It also applies to each LED individually; you seem to think it applies to the whole array.

I understand that and I though I was applying the concept correctly but I might be wrong! Let me explain to you again what i'm doing to see if i'm doing it right.

  1. The entire matrix has to refresh 100 times per second (100hz), which means that it has to refresh every 10ms.
  2. There are 25 LEDs in the matrix and I am going to have only 1 on at a time. Which means that each LED has to refresh in 10ms/25 = 0.4ms
  3. The LED can be on at 50ma a maximum of 10% duty cycle. 10% of 0.4ms = 40 micro seconds
  4. Each LED has to be ON for 40 micro seconds, and off for 360 micro seconds, to have equal cycles in all LEDs therefore consistent brightness.

Is that right?

I was thinking about the duty cycle issue that you mentioned tmd3 and yeah it seems like i am mixing concepts here.
I did a graphic representation of the logic and the way i am doing it now, it would look like the image attached.
The LEDs are not OFF for 360 micro seconds, basically they are off until the loop reaches them again and switches them on. That means they remain off for 9960 micro seconds, and on for 40 micro seconds.
I guess the duration of the pulse is 10ms, a duty cycle of 10% should be 1ms.

Does that sound right?

Hi,

I have tried modifying the software to fix the duty cycle issue. The way I've done it is by grouping the LEDs in groups of 2x5. This way i have a total of 10 LEDs in each group. I multiplex then the 3 groups at the same time. I have a delay of 1 millisecond after I switch on each column making the pulse 10ms long and the duty cycle is 10%.
It looks brighter but still not at 100% brightness.

I have tried modifying the circuit also both by having the load from the +9v to the NPN1 collector, and also by having the load between the NPN1 emitter and NPN2 collector with the same results.

I hope that someone can bring some light in here, I have been googling and reading many articles and I found some issues while reading that i fixed but this is still not working correctly.

I have attached a picture of a version of the circuit with the load from +9v to NPN1 collector and the updated code.

byte rows1[] = {4,5};
byte rows2[] = {6,7};
byte rows3[] = {8,-1}; //-1 dummy just to keep the arrays consistent
byte cols[] = {9,10,11,12,13};

void SwitchRows(boolean pOn)
{
  for(byte r = 0; r < sizeof(rows1); r++) 
  {
    digitalWrite(rows1[r], pOn);
    digitalWrite(rows2[r], pOn);
    digitalWrite(rows3[r], pOn);
  }
}

void SwitchCols(boolean pOn)
{
  for(byte c = 0; c < sizeof(cols); c++)
  {
     digitalWrite(cols[c], pOn);
  } 
}

void setup() {
  Serial.begin(9600);
  for(byte i = 0; i < sizeof(rows1); i++)
  {
     pinMode(rows1[i], OUTPUT); 
     pinMode(rows2[i], OUTPUT);      
     pinMode(rows3[i], OUTPUT);      
  }
  for(byte i = 0; i < sizeof(cols); i++)
  {
     pinMode(cols[i], OUTPUT);    
  }
  SwitchRows(LOW); //Switch all off
  SwitchCols(LOW); //Switch all off
}



void loop() {
  unsigned int time = millis(); 
  for(byte r = 0; r < sizeof(rows1); r++)
  {
    //switch all rows off
    SwitchRows(LOW);
    //switch on current row
    digitalWrite(rows1[r], HIGH);
    digitalWrite(rows2[r], HIGH);
    digitalWrite(rows3[r], HIGH);
    for(byte c = 0; c < sizeof(cols); c++)
    {
       //byte pass = (sizeof(cols) * r) + c;
       //Serial.print("Pass:");
       //Serial.println(pass);
      //Switch all columns off
      SwitchCols(LOW);
      //switch on current column
      digitalWrite(cols[c],  HIGH);
      delayMicroseconds(1000); //10% at 100hz
    }
  }
  Serial.println(millis()-time);
}

Pretty good, dude, you found your way through the duty cycle.

Let's ask some questions:

  • When you say, "100% brightness," what does that mean? Are you comparing it to the same LED with 20mA DC running through it?
  • Does the LED data say that it'll deliver the same effective brightness at 50mA, 10% duty cycle, as it will with its rated continuous DC current? Intuition tells me that it won't, but my intuition is wrong often enough to keep me from trusting it.

The problem you're trying to solve is to get the LED brighter. I think it's a good idea to get other uncertainties out of the picture, and focus on the LED. I'd recommend that you simplify the whole thing for an experiment: Put your multiplexing code aside for now, and take your circuit apart. Write some test code to drive a digital output at a 10% duty cycle, at about 1kHz - that'd be delayMicroseconds(100), delayMicroseconds(900). Use one NPN transistor, with the emitter grounded, and the resistor/LED combination between the collector and 9V. Drive the base the same way you do now, with a 1k. I'd recommend that you try it first with about 350 ohms in series with the LED, to keep the current at about 20mA. Observe that the LED glows much more dimly that it does at 20mA DC, to verify that your switching works, and then switch to the resistor that gives you 50 mA. The LEDs brightness is the what you can expect at 50 mA, 10% duty.

Is it bright enough for you? If not, then you're not going to get the brightness you want this way, with this LED. If it is, then you can keep this one, and we'll keep going.

Hi,

Thanks a lot for getting back to me.

When you say, "100% brightness," what does that mean? Are you comparing it to the same LED with 20mA DC running through it?

Yes, that's what i mean. The specs of the LED don't say anything about the luminosity when driving it with PWM, but I was assuming that feeding it with 50mA with a 10% duty cycle should produce the same results as 20mA DC.
Based on this article: Pulsing LEDs for effeciency, brighter appearance and multiplexed display

"LED's pulsed for say 200% of their 'normal' current at a 50% duty cycle appear brighter than 100% current for 100% duty cycle even though the maths says that it's all the same average current"
"The magic numbers here seem to be run the LED at 60Hz, with a duty cycle of 5% and it'll appear twice as bright to humans. Works better on Blue & Green than it does on Red"

Does the LED data say that it'll deliver the same effective brightness at 50mA, 10% duty cycle, as it will with its rated continuous DC current? Intuition tells me that it won't, but my intuition is wrong often enough to keep me from trusting it.

These are the specs for the LED:
Product Name
LED
Emitted Color
Orange
Size (mm)
5mm
Lens Color
Water Clear
Peak Wave Length (nm)
600 - 605
Static Sense
Yes
Forward Voltage (V)
2.0 - 2.2
View Angle
25 - 30°
Luminous Intensity (mcd)
4000
Maximum Current
20mA Continuous, 50mA peak for 10% Pulse Width
Item Net Weight
95g / 3.4oz

I have done the test that you have suggested and I got some weird results.
1st test
No PWM
R=(9-2.2)/0.02 = 340 ohms
I've put a 220 and a 100 resistors in series with the LED. This is connected to +9v and to the collector.
The base connected to Pin4 (which is set as HIGH in the setup()) through a 1k.
The emitter and the arduino ground pin both connected to -9v.

The LED is at full brightness. When i measure the voltage across the led i get 2.4/2.5. However when i break the circuit and measure the current between the resistor and the anode of the LED, i get 14mA.

2nd test
PWM 10% duty cycle at 1kHz (1ms)
With the same configuration is way dimmer so i proceed to increase the current to 50mA
R=(9-2.2)/0.05 = 136 ohms (I am just using a 100 ohms resistor)
Same setup as above, the LED is still dimmer than the 1st test. When i measure the voltage across the LED it reads 0.5v. Breaking the circuit and measuring the current between the resistor and the anode reads 1mA.

This is the code for the PWM:

void setup() {
  // put your setup code here, to run once:
  pinMode(4, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly: 
  digitalWrite(4, HIGH);
  delayMicroseconds(100);
  digitalWrite(4, LOW);
  delayMicroseconds(900);
}

I have no freaking clue what's going on with the current. Does that make any sense? I know multimeters are not appropiate for measuring when using PWM but shouldn't the readings be more or less close? I mean, the LED is a lot dimmer so it could make sense that those readings are good.

Thanks a lot for the help in advance!

Retest the DC circuit. This time, instead of using the ammeter, measure the voltage at each junction relative to ground. Check the voltage at the base, collector, the junction between the LED and the resistor, and 9V. Measure the resistor with your ohmmeter. I'm wondering whether we're getting the transistor into saturation, although the math say that it should be there, and I'm wondering how accurate the current reading really is.

I'm not surprised that you got odd results measuring 1kHz with t he meter. I'm presuming that you were measuring in DC. The average voltage across a 2.5V LED with a 10% duty cycle is 0.25V. Given that the meter isn't intended for a 1kHz square wave, that doesn't sound so bad.

I know multimeters are not appropiate for measuring when using PWM but shouldn't the readings be more or less close?

No the readings will be nowhere like the true value. The only way to measure current like this is to measure the voltage across the series resistor on an oscilloscope and use ohms law to calculate the current.

Using a 50% duty cycle and having 40mA current should give you approximately the same brightness as a 100% duty cycle at 20mA. There is a very small difference but you will not notice it.

Have you read these pages:-
http://www.thebox.myzen.co.uk/Tutorial/LEDs.html
and
http://www.thebox.myzen.co.uk/Workshop/LED_Matrix.html

Grumpy_Mike:
Using a 50% duty cycle and having 40mA current should give you approximately the same brightness as a 100% duty cycle at 40mA. There is a very small difference but you will not notice it.

Pay no attention to the cantankerous Brit. You're a scientist now. You don't take the word of some guy on the Internet - you do experiments, and find the truth for yourself. After all, you found other information on the web that makes the opposite claim.

OK, the pages he references are, in fact, quite informative. Based on the pictures you've posted, it wouldn't hurt you to understand more about multiplexing.

But, for now, you're testing whether you can get adequate brightness by pulsing an LED at higher-than-rated current. Back to the breadboard.

100% duty cycle at 40mA

Sorry that should say 20mA. I will correct the original.

You don't take the word of some guy on the Internet - you do experiments, and find the truth for yourself.

I would advise both of you to do the experiments and see for your self.
Please publish both your results and your methods what ever the results.
Lets see if they agree with mine.

Pay no attention to the cantankerous Brit.

Or indeed a jumped up colonialist.

Hey thanks for the replies!

@Grumpy_Mike: I've read the link that you gave me, basically states the same as the previous link i posted and adds some good information.

"LED's pulsed for say 200% of their 'normal' current at a 50% duty cycle appear brighter than 100% current for 100% duty cycle even though the maths says that it's all the same average current"

"The magic numbers here seem to be run the LED at 60Hz, with a duty cycle of 5% and it'll appear twice as bright to humans. Works better on Blue & Green than it does on Red"

However I'm not there yet, I would like to make sure that the transistor setup is correct. I did some more research on setting up the transistors correctly based on tmd3 comment "Maybe the transistor is not getting into saturation".

This is what i came up with, let's see if this is correct:
I'm using a 2N3094, here is the datasheet:
http://www.fairchildsemi.com/ds/2N/2N3904.pdf

Voltage = 9v
Load Current = 50mA
hFE = 60 (Assuming I am reading the datasheet correctly it says if Ic=50mA then hFE min=60)

So to determine the base resistor:
R1 = Voltage / (Load current / hFE * 1.3) ---- 1.3 is just adding a 30% to the result to ensure that the transistor is in saturation state

RB = 9 / (0.05 / 60 * 1.3)
RB = 8333 ohms

However I was reading another website and it uses a different formula:
RB = (Voltage * hFE) / (Load Current * 5)
RB = (9 * 60) / (0.05 * 5)
RB = 2160 ohms

Which one is right?

Currently i am using a 1K resistor for the base. As far as i know, just from what i've read online, overloading the current at the base could cause the current across C-E to drop. Does that make sense?

I have taken the readings and the results are:
No PWM, relative to ground, RC = 320 ohms, RB = 1K

Vbase = 0.87v
Vcollector = 1.36v
Rc/LED Cathode = 3.65v
9v = 10.32v
Rc = 315 ohms
Rb = 983 ohms
Collector/Emmiter = 1.36v

As far as I understand, the voltage difference between the collector and the emitter should be close to 0 is the transistor is saturated. To achieve that, I should lower the value of Rb.
I have tried with 470ohms and the readings kind of make more sense:

Vbase = 0.98v
Vcollector = 0.1v
Rc/LED Cathode = 2.5v
9v = 10.5v
Rc = 315 ohms
Rb = 460 ohms
Collector/Emmiter = 0.07v

So I am not sure what to think... the formulas above indicate that Rb should be higher but actually it seems like it has to be lower.

Thanks!

By the way... I was checking the datasheet for the 2N3904 and it seems like i have them connected in reversed.
With the flat part facing you and the pins at the bottom : E -B -C Current flows from the collector to the emitter which means i have them connected wrongly!!

I flipped it and now this is starting to make more sense (what an idiot!):

Vcc:9v
Ice = 20mA
Hfe = 100
Ib = Ic / Hfe
Ib = 0.02 / 100
Ib = 0.0002

Rb = (Vb - 0.7) / 0.0002
Rb = 4.3 / 0.0002 = 21500 ohms

I have done the test and now Vce = 0.2, so the numbers make sense and the transistor is almost in saturation (i guess minor offsets here and there).

So I have moved onto the next step, multiplexing it. I have changed the resistors Rc and Rb to work on 50mA and i have multiplexed the LED with a 10% duty cycle at 1kHz... voila! same brightness (almost)!!!

I'm awaiting confirmation from you guys to make sure that i got everything right but it's looking good!

What i don't really understand is how the LED was ON with the transistor reversed, isn't it supposed to just let the current flow in 1 direction? from C to E?

Thanks!

I recall that 0.2V is a rule-of-thumb figure for VCE saturation voltage. Sounds right.

I don't know why you got any light at all, either. I don't know why the transistor still works.

Looks good to me. If you like it, I do too.

It's good then!
I'll do a recap of all I've learned along the investigation and post it. I came across some contradictory and wrong information while looking online for a solution.
Thanks a lot for the help man! It's very very appreciated. You definitely brought some light in here!! Hope
To be able to help you some day!

I don't know why you got any light at all, either. I don't know why the transistor still works

Because an NPN transistor with its collector and emitter swapped over is still an NPN junction and still works as a transistor but the gain is very much reduced.

Quote
"LED's pulsed for say 200% of their 'normal' current at a 50% duty cycle appear brighter than 100% current for 100% duty cycle even though the maths says that it's all the same average current"

That is wrong although it is a common myth. Do your own experiments.

Which one is right?

They both are, it is just they are calculating diffrent things. Having too much base current, even several hundred percent more has no effect on turning a transistor on, it has a slight effect on the time it takes to turn off however.