I'm looking to drive a relay on a 5V rail from an Arduino 3.3V pin. Obviously the Arduino I'm using doesn't have the voltage to drive the 5V relay, so that's where the 2N2222 comes in. To test out the circuit, I figured I'd substitute an LED for the time being. My circuit looks like this.


simulate this circuit – Schematic created using CircuitLab

Using a standard, run of the mill, red LED, we say the voltage drop is 2V, and requires 20mA. Using Ohm's law, that gives us a resistor of 150 ohms, correct so far?

For the sake of easy math, we'll say hfe is 100. My understanding is that Ic is Ib x hfe. So we have 20mA = Ib * 100. Giving us Ib of 0.2mA. Using Ohm's law again, and factoring in the 0.7v drop from Vb to Ve we have 12k Ohms. Is that math all good so far?

Right, so plug in the Arduino into where 3.3V is, and set the pin to HIGH, and LED is on. Set it to LOW, and LED is still on. That makes no sense.

Remove the Arduino and make the circuit really simple.

I have a breadboard power supply that outputs 5V and 3.3V, so I take a lead and touch 3.3V to the Rb and LED comes on. Remove the lead, LED goes off.

So success right?

I go back to the Arduino and check, when the pin is set to LOW, my multi-meter sees no voltage. When it's set to HIGH, I see ~3.3V as expected.

Why would this not work?

I also noticed simply touching the resistor Rb also triggers the LED, albeit quite dim.

What am I missing? Or doing wrong?

Edit: I should add, I did stumble across this post, and even copied the resistor values from that, and came up with the same issues. Arduino driven LED stays on, touching resistor makes LED come on, and 3.3V line comes on as expected.

This handy YouTube video also helped me understand some of the logic or what I think is the logic.

  • 7
    \$\begingroup\$ Do you have a common ground between the 3.3V and 5V supplies? Also, what happens in your simple scenario when you connect the input to 0V rather than leaving it open? \$\endgroup\$ Mar 27, 2020 at 4:21
  • \$\begingroup\$ @SpehroPefhany suggests a very-likely item you're missing. You must connect Arduino's GND to the transistor emitter. Touching the base resistor impresses 60 Hz (or 50 Hz) into the transistor, turning it on/off too quickly to see with your eye. It is dim because the transistor only conducts for a small part of the 60 Hz cycle. \$\endgroup\$
    – glen_geek
    Mar 27, 2020 at 14:50
  • 1
    \$\begingroup\$ @SpehroPefhany comment looks to have been where I was going wrong. I'd been driving the power for the Arduino from USB while debugging/testing and had forgotten to connect the grounds. Once changing the power source and grounds for the Arduino, it was behaving as expected. LED comes on when pin is high. Thanks! \$\endgroup\$ Mar 27, 2020 at 16:32
  • \$\begingroup\$ hFE is not used when a transistor is a saturated switch. The datasheet says to use a base current that is 1/10th the collector current when the transistor is a saturated switch. The curves on a datasheet are for a "typical" transistor that you cannot buy. You need to use spec's for a transistor that has minimum specs. \$\endgroup\$
    – Audioguru
    Jan 8, 2022 at 19:51

3 Answers 3


When using a BJT as an ON|OFF switch, you want to drive the transistor into hard saturation for the ON state. You do not want to operate the transistor in its forward active mode (small signal amplification). Therefore, you need to use the transistor's saturation beta \$\beta_{sat}\$, not its DC forward active current gain \$\beta, h_{FE}\$, nor its AC forward active current gain \$\beta_{ac}, h_{fe}\$. (Additional information can be found here.)

For a small-signal transistor, \$\beta_{sat}=10\$ is a commonly-used value. Therefore, to drive the transistor into hard saturation the required base current is

$$ I_{B(sat)} = I_{C(sat)} / \beta_{sat} = 20\,\mathrm{mA}/10 = 2\,\mathrm{mA} $$

:: CHECK :: Ensure your microcontroller's general purpose I/O (GPIO) pin can safely source a current of \$I_{B(sat)}\$.

:: CHECK :: Current that exits a GPIO pin (source current) comes from the microcontroller's VCC power pin, and current that enters a GPIO pin (sink current) exits the microcontroller via its GROUND power pin. Ensure the microcontroller's quiescent/operating current plus the combined source/sink currents at all GPIO pins does not exceed the maximum current specification for the microcontroller's VCC and GROUND pins.

Resistor R2's value can now be calculated as follows:

  1. Use the microcontroller's datasheet to determine the minimum voltage for a logic HIGH output signal (\$V_{OH}\$). (Reference1, Reference2)

  2. Use the parametric data plots in the 2N2222A datasheet (Fig. 1) to get an estimate of the base-emitter voltage drop when the transistor is operating in saturation mode \$V_{BE(sat)}\$ with (in your case) 20 mA of collector current.

enter image description here

Figure 1. Edited screen capture of "Figure 11. 'ON' Voltages" taken from ON Semiconductor publication number P2N2222A/D, Jan. 2013, Rev. 7, pg. 5 [Online]. Available: https://www.onsemi.com/pub/Collateral/P2N2222A-D.PDF

  1. Use Ohm's Law to calculate R2's resistance value:

$$ R2_{calc} = \frac{V_{R2}}{I_{R2}} = \frac{V_{OH}-V_{BE(sat)}}{I_{B(sat)}} $$

  1. Use R2's calculated value \$R2_{calc}\$ to choose R2's actual value \$R2\$ from a table of standard resistor values.

  2. Using R2's actual (chosen) resistance value, calculate the power dissipation in resistor R2: \$P_{R2} = I_{B(sat)}^2 R2\$. Select a resistor for R2 whose power dissipation rating is \$\ge (2 \times P_{R2})\$. For example, if the calculated power dissipation is 100 mW, choose a resistor whose power rating is ≥ 200 mW.

  3. When power is first applied to a microcontroller its I/O pins are (typically) configured as inputs by default; the I/O pins are not configured as outputs and do not actively drive a logic LOW or HIGH voltage signal. In Fig. 2, imagine that resistor R3 is not present. When the microcontroller's I/O pin is configured as an input, the input impedance between the I/O pin and the microcontroller's power supply pins (+VCC or GROUND) is extremely high. Consequently, the circuit path from Q1's base and through resistor R2 ends in what is essentially an open circuit; it is as if you completely removed microcontroller U1 and the left side of resistor R2 is disconnected from everything. Under these conditions—i.e., with the I/O pin configured as an input, and without resistor R3—the voltage at the BJT's base is indeterminate (note 1), and in some cases the base voltage is high enough that the BJT turns itself ON, if only partially, which could be very bad.

    To prevent this situation where Q1 self biases and turns itself on, a 10 kΩ "pull-down" resistor R3 is added to provide a path to ground, which "pulls down" Q1's base voltage to ≈0 V when no other signal source actively drives a voltage onto Q1's base, thereby ensuring that Q1 remains in cutoff (turned OFF). Figure 3 shows the 10 kΩ pull-down resistor connected between ground and the LEFT side of resistor R2; however, connecting resistor R3 to the RIGHT side of resistor R2 should also work, providing R3's resistance value is not too small. R3's resistance value is chosen so that its resistance (a) does not introduce a significant current load to the microcontroller's I/O pin when the pin is configured as an output pin, and (b) is sufficiently small (when positioned on the left side of resistor R2) to ensure Q1 is held in cutoff when the microcontroller's I/O pin is configured as an input.

[NOTE 1: This assumes the microcontroller's I/O pin does not have an internal pull-up or pull-down resistor that is enabled/functional at the moment when power is turned ON. — end note]

enter image description here

Figure 2.

  • 1
    \$\begingroup\$ So if I'm understanding correctly, the calculations I did above, and reading the charts correct. R1 is 150 Ohms (R = 3V / 20mA). Using the chart on that datasheet, and drawing a line straight up from 20mA, it looks like Vbe(sat) should be ~0.75. So 3.3v / 2mA = 1650 Ohms. Conveniently, there is a 1.6k Ohm resistor for R2. Does that seem correct? Or round up to 1.8K. \$\endgroup\$ Mar 27, 2020 at 17:25
  • 2
    \$\begingroup\$ R1's value is okay. When selecting R2, I usually round down--so, 1650 down to 1.6 kohm. If R2's value goes up from the calculated value, chances are it's not a problem but it does reduce the base current into Q1, and you want to avoid a design that does not drive Q1 into hard saturation. \$\endgroup\$ Mar 27, 2020 at 20:00
  • 2
    \$\begingroup\$ That's the curve for V_BE(on) @ V_CE = 1.0 V \$\endgroup\$ Jan 19, 2021 at 8:46
  • \$\begingroup\$ Nice post Jim. I wonder what the arrow pointing to the curve with the '1V' label means in that manufacturer data sheet Fig. 11. And I don't think they defined VBE(on). ----- Thanks Jim (above) for mentioning the details from my question about that curve with the 1V label. \$\endgroup\$
    – Kenny
    Jan 19, 2021 at 19:56
  • 1
    \$\begingroup\$ @drudru, transistor Q1's saturated collector current I_C(sat) is the starting point for this solution, so that current must be known. If a circuit parameter cannot be determined from a data sheet, what I do is devise/build a test circuit and use electronic test equipment to measure the unknown parameter. And in some cases a simple SPICE simulation is possible and sufficient. Also, you might consider using a MOSFET as the ON|OFF switch instead of a BJT. (NB: The instructions I provided in my answer are not applicable to FET-based ON|OFF switch circuits.) \$\endgroup\$ Sep 15, 2022 at 15:48

Assuming the 2N2222 is good, and the MCU gnd === the emitter voltage, and assuming the MCU output goes to 0.0 volts, that circuit should work.

Lets diagnose a bit.

Make the base resistor about 1,000 ohms. That puts a (good) transistor well into saturation when MCU output is near 3.3v. And when MCU output Is nominally 0.0v, any leakage current from collector-base junction will be shunted to gnd.

By the way, your base voltage will increase about 0.06 volts for each 10x increase in current.


You need a pull-down resistor on the Arduino side of the transistor. Otherwise, even if the Arduino is driving 'low', the voltage can't get to a low enough level to switch off the transistor. Put like a 100k resistor that stretches between your 12k and ground.


simulate this circuit – Schematic created using CircuitLab

  • 2
    \$\begingroup\$ I am curious about this pull-down resistor being here. Based on my reading of the Arduino docs, when setting the pin to LOW, voltage is 0v, though switching to mV on multimeter it looks to actually be about 1.1mV. Even with the pull down resistor in place, this would behave like a voltage divider, the transistor would still see about 1mV. \$\endgroup\$ Mar 27, 2020 at 16:18
  • \$\begingroup\$ Oops, you are correct - I think I misspoke. That will act as a voltage divider. You can avoid that by putting the pull down on the other side of the 12k. I've fixed it \$\endgroup\$
    – epiolba
    Mar 28, 2020 at 22:10
  • 1
    \$\begingroup\$ This isn't correct, @epiolba. The Arduino MCU GPIOs can easily pull low enough (below 0.6 V) to turn the transistor off. R1 is not required. See Jim Fisher's answer. \$\endgroup\$
    – Transistor
    Mar 28, 2020 at 22:14
  • \$\begingroup\$ @Transistor Oh interesting! Looks like Jim still has the pull-down, but for a different reason! I didn't know the Arduino was capable, thanks \$\endgroup\$
    – epiolba
    Mar 28, 2020 at 22:43
  • \$\begingroup\$ @epiolba - a pull-down resistor is not required for normal operation, when the Arduino is emitting an active low it can drive the voltage to zero. One case where a pull-down (or in other circumstances a pull-up) is useful is for defining the state just after rest before the software has activated the port as an output. \$\endgroup\$ Jun 29, 2021 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.