Introduction: A Simple Introduction to Transistors and PWM (Pulse-Width Modulation)

About: I finally graduated from Missouri University of Science and Technology (Missouri S&T, formerly University of Missouri Rolla) with a computer engineering degree. Originally from Belleville, IL (St. Louis area)…

The silicon transistor was invented in 1954 and has been considered one of the greatest inventions in the history of technology. Its invention practically spawned the field of electronics and contributed to all of our modern computers, iPods, phones, etc. If you've ever asked what a transistor is or does, you probably were told that it is like a switch. However, it is a bit more complicated than that.

This Instructable will detail a basic transistor and what it can be used for. I am making this because I have had a box of assorted transistors for a while and never really knew how to use them in circuits. After reading some tutorials online I combined some ideas together and figured out how to use transistors in basic circuits.

I will demonstrate the use of transistors by controlling PC fans from a computer's LPT (parallel) port. Then I will implement a simple form of PWM (pulse-width modulation) to control the fan's speed. This demonstrates the ability of transistors to use low-voltage, low-current signal lines (such as a parallel port or microcontroller IO line) to control higher voltage, higher current devices like motors (in this case, PC fans).

Step 1: How a Transistor Works

In this instructable I will be focusing on NPN transistors. A transistor has three terminals: Base, Emitter, and Collector. The base terminal is connected to the signal voltage, the collector is connected to the load, and the emitter is connected to negative (ground). Whenever the base voltage is zero, the collector voltage is also zero. Applying a small current to the base causes a proportionately larger current to flow through the collector. By doing this, a tiny amount of current from a signal can be used to drive larger currents to power heavier loads such as relays and motors.

Note that the load and the signaling devices must share a common ground. In the case of a fan (running from an external power supply) and a computer's LPT port, you can connect the ground terminal of the power supply to the ground pin on the LPT port to achieve this. For a microcontroller you can use the same ground for the chip and the load.

For my examples I soldered three NPN transistors to a small PCB and wired all of the emitters together to form a common ground. I did this to make connecting things easier. In the following examples I am only using one of the transistors. The other two are not affecting anything and can be disregarded entirely. The transistors are "MPS A06" labeled. According to the datasheet they can control up to 300mA and have a voltage limit at 80V. On my PCB, the brown wires are common ground, blue is collector (load), and white is base (signal).

Step 2: Programming for the Parallel Port

To generate the signal current for this experiment, I used the easiest thing that I already had access to. Since I don't have any microcontrollers or other cool devices, I resorted to my old laptop's LPT port. If you're using Windows you can try programs that are designed to flash LED's connected to the LPT port. However, I wanted to have a little more control so I wrote a little program in C++. I'm running Ubuntu Linux 9.04 on my laptop. Windows has an annoying restriction that prevents programs from directly using the legacy ports (LPT and serial) and having to use drivers to get around it is confusing and annoying, so I just used Linux, where it is easy to access the LPT port if you have root access.

The input and output functions are in a header called sys/io.h (some sites say asm/io.h, this is outdated and doesn't work in 9.04). The function ioperm() gives you access to the LPT port and the function outb() outputs binary to the port. The base address for the port is 0x378 and we are going to control all the outputs together, so writing a 255 to the port turns on all 8 output pins, writing a 0 turns them all off. Other combinations involve converting the number to binary which isn't going to be described in this Instructable.

Here is a sample program that will turn on the signal lines for 10 seconds and then turn them off. Compile it with g++ in the form "g++ lptfan.cpp -o lptfan.o" replacing lptfan with whatever you save it as.

//lpt controlled fan

#include
#include

#define base 0x378

using namespace std;

int main()
{
ioperm(base,1,1);
outb(255,base);
sleep(10);
outb(0,base);
return 0;
}

Step 3: Connecting the Transistor, Fan, and Computer

Be careful! Drawing too much current from the LPT port or connecting higher voltage to the LPT port will destroy it. Only connect signal pins!

For this step, I'm using a PC fan (12V), a 9V transformer, and my transistor board to connect the fan to the PC. I have the base (white wire) connected to pin 2 on the LPT port, the collector (blue wire) connected to the fan's negative wire, the fan's positive wire connected to the power supply's positive wire, the brown wire to one of the LPT port's ground pins, and the other brown wire to the power supply's negative wire.

Step 4: Turn on the Power!

After double checking your connections to make sure that the LPT port is connected ONLY to the base of the transistor and ground, you can plug in the transformer or turn on the power supply to the circuit. The fan may or may not start spinning because some PC's or operating systems may leave the data pins on after booting. The fan should stop if you remove the white signal wire from the LPT port.

With everything connected, run the program you wrote in step 2. You'll have to use sudo and enter your password because port access is restricted. Start it by typing "sudo ./lptfan.o" (again typing whatever you called your program instead of lptfan) and hitting enter.

The fan should start spinning at full speed, run for 10 seconds, and then turn off.

Step 5: Write a Program for PWM

If you've gotten this far and the fan starts and stops correctly using the simple on-off program, you are now free to play with the code to make it do other things. Probably the most useful thing you can do at this point is write a PWM generator so that you can change the fan's speed. For this example, I am going to use a percentage to change the speed. For instance, inputting 10 percent makes the fan run at 10 percent speed and (if done right) approximately 10 percent of the input voltage. In this code I used a function to make it a little cleaner, you don't have to use functions.

As this is a quick program I threw together, there is no good way to exit it, just do CTRL+C to kill it.

//LPT-controlled fan

#include <iostream>
#include <sys/io.h>

#define base 0x378
using namespace std;

void runFan(int powerLevel)
{
ioperm(base,1,1);

//Turn the fan to 100% for 1 second to get it spinning
outb(255,base);
sleep(1);
outb(0,base);

//Loop to generate PWM at a given percentage
while(1)
{
outb(0,base);
usleep(10000-powerLevel*100);
outb(255,base);
usleep(powerLevel*100);
}
}

int main()
{
int powerLevel = 0;
cout << "Power level %: ";
cin >> powerLevel;
runFan(powerLevel);
}

Step 6:

After you compile the PWM example, you can run it like you did the first, using sudo. Type in any value from 1 to 100 to vary the fan's speed. You can experiment with low values to find the slowest speed that the fan can run at without stopping. This depends on the fan itself as well as the power supply. You will probably notice that the fan makes a buzzing sound even if it is stopped. This is because PWM uses high frequency pulses to create lower voltages and these pulses cause the coils in the motor to vibrate (similar to how speakers work) and produce sound. Adding a small capacitor across the fan's positive and negative wires will reduce this buzzing sound because the capacitor absorbs and smooths the pulses.