Arduino: figuring out transistors and associated resistors

Published by paul at 8:36 PM under Arduino | Example Code | LED Projects

My aim while building all these cool circuits is to re-learn all the electronics theory I knew when I got my electronics degree, but have forgotten in the intervening 15 years!

The kinds of circuits I'm most interested in right now are those that drive large arrays of LEDs from an Arduino. To do that, I'm going to have to create multiplexer circuits using transistors and shift registers, as the Arduino doesn't have enough IO pins to drive, say, 64 LEDs. The trouble is, I've forgotten how to do things like calculate the value of a base resistor and the algorithm for loading bits into a shift register.

First things first - refresh memory on Ohm's Law - Voltage = Current x Resistance. Now I can properly calculate the resistor required to put in series with an LED. The 10-bar red LED arrays I'm playing with have a 2.0V drop across the LED at 20mA current - so I need a resistor to take up the other 3.0V of my 5.0V supply and give me 20mA. R = V/I = 3V / 0.02A = 150ohms. This resistor is said to be limiting the current through the LED - without it the LED would burn out.

Now on to selecting a transistor that can switch the current. My electronics textbooks explain what to do, and I found various web pages that explained things in different ways, some of them contradictory! Kind of hard to find the right thing though - Googling for 'Arduino transistor LED' or 'transistor LED driver' and the like didn't turn up anything simple and useful - hence this post.

I want to switch on the current through the LED when the Arduino's output pin is high, so I'm going to use an NPN transistor in common-emitter mode. If I wanted to switch it on when the output from the Arduino is low, I'd use a PNP transistor.

I need a transistor that has:

1) a maximum collector current (IC) greater than my desired load current of 20mA

2) a minimum current gain (hFE) that allows me to comfortably source a base current IB from the Arduino pin that will give me the collector current I need. When the Arduino pin goes high, current flows into the transistor base, turning it on and allowing current to flow through the collector to the emitter - lighting up the LED. I don't want too much current flowing into the transistor base otherwise it will damage it.

I want an IC of 20mA, and the maximum output current from the Arduino pin is 40mA. The hFE should be at least IC/IB * a safety factor (e.g. 10). In this case, that works out to be (20mA/40mA)*10 = 5. This isn't really a concern here. If I was trying to drive 600mA from an IC that could only source 5mA through a transistor with a gain of 100, that would be a problem.

On hand I have some BC337 transistors with a minimum current gain of 100 @ 150mA - perfect!

Now I need to calculate the right base resistor value so the transistor will be fully on (saturated) and act as a switch rather than acting as an amplifier (where collector current is proportional to base current). The required base current  IB = IC/hFE = 20mA/100 = 0.2mA. This is way lower than I need to be careful of. If I go for a 4.7K resistor, this will give me IB = (5V-0.7V)/4.7K = ~1mA - plenty to make sure I get the load current I want. The 0.7V is the voltage drop across the base-emitter junction when the transistor is on.

Amazing how all the theory comes flooding back - now I don't feel like I'm groping in the dark picking resistor values!

Now I've figured out the circuit to use, I'm going to draw a circuit diagram. I found a freeware tool from ExpressPCB that allows you to draw circuit diagrams really simply (and if I ever want to get PCBs made, I won't need to learn another tool). I'd like to start making a habit of this so it's easier for others to understand my circuit, and for my future reference. The circuit is below, with a photo (click for larger image):


The Arduino code to test the circuit is very simple, using pin 5 to drive the transistor switch:

  Driving a simple transistor-LED circuit

const int driverPin = 5;

void setup()
    pinMode (driverPin, OUTPUT);

void loop()
    digitalWrite (driverPin, HIGH);
    delay (1000);
    digitalWrite (driverPin, LOW);
    delay (1000);

And there we have it. Now I have the basis for switching currents through multiple LEDs - which will be very useful for driving LED arrays.

Next up - using a shift register.

[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Currently rated 3.4 by 31 people

  • Currently 3.387097/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

E-mail | Permalink | Trackback | Post RSSRSS comment feed 7 Responses


Comments are closed