How to Use a Transistor as a Switch: Arduino Circuit Design Guide
If you have ever needed to control a motor, a solenoid, or a high-power LED strip with an Arduino, you have probably realized that the 5V GPIO pins on your board cannot deliver enough current or voltage. The solution is to use a transistor as a switch. When configured properly, a small low-current signal from an Arduino pin controls a much larger load. This guide explains exactly how to do that with both NPN and PNP transistors, including schematics, code, and component selection.
Why You Need a Transistor as a Switch
An Arduino’s GPIO pins can safely source or sink about 20–40 mA of current at 5V (or 3.3V on some boards). That is fine for a single LED or a logic-level sensor, but it will not drive a DC motor drawing 500 mA, a relay coil, or a 12V LED strip.
- Current limitation: The load draws more current than the Arduino can supply.
- Voltage mismatch: The load requires a higher voltage (e.g., 12V) than the Arduino’s 5V.
- Inductive loads: Motors and solenoids generate voltage spikes that can damage the microcontroller.
A transistor eliminates all three problems. The Arduino switches the transistor on or off with a tiny current, and the transistor handles the high-current, high-voltage path.
NPN vs. PNP: Which One to Use
The choice between NPN and PNP depends on how you want to connect the load and the power supply.
- NPN (low-side switch): The load sits between the positive supply and the transistor’s collector. The emitter connects to ground. When the Arduino outputs a HIGH signal to the base, the transistor turns on and current flows through the load to ground. This is the most common configuration for Arduino projects.
- PNP (high-side switch): The load sits between the transistor’s collector and ground. The emitter connects to the positive supply. The Arduino turns the transistor on by pulling the base LOW. This is useful when you need to keep the load connected to ground (e.g., common-cathode LED displays).
| Feature | NPN (Low-Side) | PNP (High-Side) |
|---|---|---|
| Arduino signal to turn ON | HIGH (5V/3.3V) | LOW (0V) |
| Load connection | Between VCC and collector | Between collector and GND |
| When to use | Simple on/off; most common | When load must share ground |
| Resistor R1 | Base to GPIO | Base to GPIO |
| Additional resistor | None needed | Base to VCC (pull-up) |
Part Selection: Choosing the Right Transistor
Select a transistor with adequate current and voltage ratings. For typical Arduino projects, these are the most common through-hole options:
- 2N2222 (NPN): Good for loads up to 800 mA, max 40V. Widely available. Not ideal for motors above 500 mA without a heat sink.
- BC547 (NPN): Similar to 2N2222 but lower current (100 mA). Fragile — avoid for motors.
- TIP120 (NPN Darlington): Handles up to 5A, 60V. The Darlington structure gives very high gain. The downside: ~1V voltage drop when on, so it heats up under high current.
- IRLZ44N (N-channel MOSFET): Not a BJT, but acts as a voltage-controlled switch. Zero base current, very low on-resistance. Perfect for high-current loads. Requires a gate resistor (100–220Ω) to limit inrush current.
- 2N3906 (PNP): Moderate PNP for small loads (<200 mA). Use 2N3904 (NPN) similarly.
For this tutorial, I will use the 2N2222 for NPN examples and the 2N3906 for PNP. If you plan to drive motors, swap out to a TIP120 or IRLZ44N.
Circuit #1: NPN Transistor as a Switch (Low-Side) — Driving a DC Fan
This is the most common scenario: control a 12V fan (or LED strip) with an Arduino pin.
Parts List
- Arduino Uno (or any 5V logic board)
- 2N2222 NPN transistor
- 1 kΩ resistor (R1)
- 1N4007 diode (flyback protection for inductive loads)
- 12V fan (or any load up to 800 mA)
- 12V power supply
- Breadboard and jumper wires
How It Works
The Arduino pin goes HIGH. Current flows through R1 into the base of the 2N2222. The transistor saturates (fully turns on), allowing current from collector to emitter. The fan spins. When the pin goes LOW, base current stops, the transistor cuts off, and the fan stops.
The 1N4007 diode across the fan, with the cathode (banded end) toward +12V, protects the transistor from the voltage spike produced when the fan turns off.
Wiring Diagram
Arduino 5V --> fan (+) --> fan (-) --> collector (2N2222)
emitter (2N2222) --> GND
Arduino GPIO --> R1 (1k) --> base (2N2222)
12V supply (+) --> fan (+)
12V supply GND --> Arduino GND
Place the 1N4007 diode in parallel with the fan: cathode to fan (+), anode to fan (–).
Arduino Code
const int fanPin = 9; // Use PWM-capable pin if you want speed control
void setup() {
pinMode(fanPin, OUTPUT);
}
void loop() {
digitalWrite(fanPin, HIGH); // Turn on
delay(5000);
digitalWrite(fanPin, LOW); // Turn off
delay(5000);
}
For speed control, use analogWrite(fanPin, value) where value is 0–255. Note: not all fans respond to PWM — you may need a MOSFET for clean switching.
Circuit #2: PNP Transistor as a Switch (High-Side) — Driving a Common-Anode RGB LED
High-side switching is less common but indispensable when the load needs a common ground. A common-anode RGB LED has one shared positive pin. To control each color with a PNP transistor, you connect the emitter to 5V, the collector to the LED’s cathode pin, and pull the base LOW to light that color.
Parts List
- Arduino Uno
- 2N3906 PNP transistor (x3, one per color)
- 3 × 220Ω resistors (current-limiting for LED)
- 3 × 1 kΩ resistors (base resistors)
- Common-anode RGB LED
- Breadboard and jumper wires
How It Works
Each PNP transistor’s emitter connects to 5V, collector to the LED cathode through a 220Ω resistor, and base to an Arduino pin through a 1 kΩ resistor. A 10 kΩ pull-up resistor from base to 5V keeps the transistor off when the Arduino pin is HIGH or floating. When digitalWrite(pin, LOW), the base pulls below 5V, the transistor turns on, and current flows through that LED channel.
Wiring Diagram (One Channel)
Arduino GPIO --> R1 (1k) --> base (2N3906)
10k pull-up resistor: base to 5V
emitter (2N3906) --> 5V
collector (2N3906) --> R_LED (220Ω) --> cathode (LED)
anode (LED) --> 5V
Arduino Code
const int redPin = 10;
const int greenPin = 11;
const int bluePin = 12;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
// Initialize all off
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
}
void loop() {
setColor(1, 0, 0); // Red
delay(1000);
setColor(0, 1, 0); // Green
delay(1000);
setColor(0, 0, 1); // Blue
delay(1000);
setColor(1, 1, 1); // White
delay(1000);
}
void setColor(bool r, bool g, bool b) {
digitalWrite(redPin, r ? LOW : HIGH);
digitalWrite(greenPin, g ? LOW : HIGH);
digitalWrite(bluePin, b ? LOW : HIGH);
}
Important Design Considerations
Base Resistor Calculation
Without a base resistor, the transistor will draw unlimited current from the Arduino pin and destroy both the pin and the transistor. Calculate the base resistor like this:
- Find the load current ( I_C ) (e.g., 500 mA for a fan).
- Look up the transistor’s DC current gain ( h_{FE} ) (e.g., 100 for 2N2222 at 500 mA).
- Calculate needed base current: ( I_B = I_C / h_{FE} ).
- For hard saturation, multiply ( I_B ) by 5 (safety factor): ( I_B' = I_B \times 5 ).
- Choose resistor: ( R = (V_{GPIO} - V_{BE}) / I_B' ). For Arduino (5V) and 2N2222 (( V_{BE} \approx 0.7V )), with ( I_C = 500 , \text{mA}, h_{FE}=100 ):
- ( I_B = 5 , \text{mA} )
- ( I_B' = 25 , \text{mA} ) (too high for Arduino — max 40 mA per pin).
- Solution: use a Darlington (TIP120) with ( h_{FE} = 1000 ) → ( I_B' = 2.5 , \text{mA} ), and ( R = (5 - 1.4) / 0.0025 = 1440 , \Omega ) (use 1.5 kΩ).
Flyback Diode — Non-Negotiable for Inductive Loads
Motors, solenoids, and relays are inductive. When you turn them off, the collapsing magnetic field generates a negative voltage spike that can exceed 100V — instantly destroying the transistor. Always place a 1N4007 (or Schottky for faster switching) in parallel with the load, cathode toward the positive supply.
Thermal Management
If you drive more than 500 mA, or if the transistor operates with a significant voltage drop across it (( V_{CE(sat)} )), it will heat up. For the 2N2222, ( V_{CE(sat)} ) is about 0.3V at 500 mA. Power dissipation = 0.3V × 0.5A = 150 mW — safe without a heat sink. The TIP120 drops ~1V, so at 2A you dissipate 2W — you will need a small heat sink.
Common Mistakes and How to Avoid Them
- Connecting the transistor backwards: For NPN, emitter goes to ground. For PNP, emitter goes to positive supply. Check the pinout datasheet.
- Forgetting the base resistor: The most common cause of immediate failure. Always add one.
- Using NPN for high-side switching: You can do it, but the emitter voltage will track the base voltage and the load will never get the full supply voltage. Use PNP or a complementary pair.
- Not using a flyback diode with inductive loads: Transistors die silently. Add the diode.
- Driving a logic-level MOSFET incorrectly: If you use an IRLZ44N, you can drive the gate directly from 5V. For non-logic-level MOSFETs (e.g., IRF540), you need at least 10V at the gate — use a gate driver.
Related Arduino Projects
If you enjoyed this, check out these guides for more practical circuit-building:
- How Capacitors Work: A Beginner's Guide with Practical Arduino Circuits — important for stabilizing power to your transistor circuits.
- How to Use a Bluetooth Module with Arduino — add wireless control to your switching projects.
- Top 10 555 Timer Projects for Beginners (with Arduino Integration) — learn timing circuits that often drive transistors.
For high-power switching with relays, my post I Turned My Old Fan Into a Remote Control Fan (ESP8266 + Relay) shows another approach.
Conclusion
Using a transistor as a switch is a fundamental skill every maker needs. With an NPN transistor and a single resistor, you can control virtually any DC load from an Arduino pin. The PNP configuration gives you flexibility for high-side switching. Remember the base resistor, the flyback diode for inductive loads, and choose a transistor with enough current and voltage headroom. Once you master this, you have unlocked the ability to power motors, pumps, solenoids, LED strips, and entire robots from a tiny microcontroller.
All code examples in this guide are available on GitHub. If you get stuck, join the Discord community — we help each other debug circuits live.