I am using an ESP8266-01 to control a 3.3v relay via a 2N2222A NPN transistor. The ESP8266 GPIOs use a 3.3v logic level.

enter image description here

The idea is that by setting GPIO2 to hi/lo I can saturate/cut off the transistor and control the relay. This works fine - so long as I connect GPIO2 to the transistor after startup, because GPIO2 needs to be held hi during power up in order to boot normally from flash (http://robertoostenveld.nl/esp-12-bootloader-modes/). I have some concept that I probably need to have a pull-up on the pin, but I am confused with how GPIO2 can be held hi without always having the transistor in the saturated state (ie how can I then make GPIO2 low...). What is the best approach here?

Also - on an unrelated note - I've noticed that in many diagrams of relay driver circuits using transistors, there is a resistor between GPIO and transistor. Any good reason for this? Everything is working as is but maybe there's something I'm missing.

EDIT: To clarify, the problem is that the circuit does work as intended if I let the ESP boot and then connect GPIO2 to Q1. The problem occurs if I try to boot while GPIO2 is connected (ie, as shown in the diagram I provided) in which case the GPIO2 is presumably being pulled low, which results in the wrong boot mode.

  • 1
    \$\begingroup\$ GPIO2 is probably pulled high somewhere on that module (for normal operations.) So you will have to live with that fact. If you want to use that pin to drive a BJT, you will have to plan on the fact that it is "inactive high" and "active low." So you need to arrange things so that going LOW activates the relay. You can use a PNP to achieve that. It would help to know what kind of pull-up they use. But you can add a resistor to ground and measure the current in it (or voltage across it) to work out the details there. \$\endgroup\$ – jonk Apr 18 '17 at 0:05
  • \$\begingroup\$ Well, the simplest solution is to use the other pole on the relay. OP has shown SPDT relay, so just use it "backwards". \$\endgroup\$ – glen_geek Apr 18 '17 at 0:27
  • \$\begingroup\$ Please see my edit, the first issue is wrt boot mode. \$\endgroup\$ – arcologies Apr 18 '17 at 0:45
  • 2
    \$\begingroup\$ simple+effective way: replace the wire with a diode \$\endgroup\$ – dandavis Apr 19 '17 at 3:21

You must add a resistor between the GPIO output and the transistor’s base. If the transistor’s base was driven at 3.3V, it would drain a few amperes and either the transistor or the MCU would blow. If it did not blow, it probably means that something is limiting the current on the GPIO output, but I would not recommend depending on this.

If your MCU needs it, you certainly can add a pull-up resistor to GPIO2. As long as its value is high enough (10k is standard for me), the MCU can easily drive the pin low when requested so.

The schematic would be something like this:


simulate this circuit – Schematic created using CircuitLab

Edit: R2 should be much lower than R1, but still high, so I fixed the values and replaces the single transistor with a darlington-like structure to have a high-enough gain to properly drive the relay.


simulate this circuit

  • \$\begingroup\$ I suspect that his problem is that the relay fires for just a moment while the CPU boots. It is a module that allows different modes of operation if an external circuit controls a few lines during the power-up sequence. So I think the module includes an external resistor to Vcc in order to ensure that GPIO2 is pulled high in normal operations. (GPIO2 is power-on as an input and monitored by the CPU to determine modes.) He can turn it around in software. That's not his problem, though, as I read it. It's before he can get control that he is having trouble. \$\endgroup\$ – jonk Apr 18 '17 at 0:15
  • \$\begingroup\$ @jonk You may be right, but that’s not how I read the OP’s question. Let’s see how he reacts to your comment and my answer… \$\endgroup\$ – user2233709 Apr 18 '17 at 0:19
  • \$\begingroup\$ I went to his links and looked. I suspect I'm right, re-reading the OP's words more carefully now. But yes, I could be projecting. \$\endgroup\$ – jonk Apr 18 '17 at 0:21
  • \$\begingroup\$ Hey so with the circuit configured per your example, I still get the wrong boot mode. So somehow GPIO2 is pulled low in this circuit I guess? I also note that connecting GPIO2 directly to Vcc (3.3v) results in a correct boot as well so for sure it is supposed to be hi. \$\endgroup\$ – arcologies Apr 18 '17 at 0:41
  • \$\begingroup\$ Actually... with R1 present, I am unable to trigger the relay. If I connect the GPIO2 directly to base, I can do so. Current from GPIOs is ~12mA I believe. This is again when I put R1 in after boot so that the correct boot mode is entered. \$\endgroup\$ – arcologies Apr 18 '17 at 0:44

What you want to do is to connect your GPIO2 to the relay with this circuit. This will allow GPIO2 to pull up to near 3.3V at the power-on time but not click the relay. Then when the software in the MCU is ready to activate the relay have it output a '0' to the GPIO2 pin. The R1/R2 resistor pair have to be sized in ratio as shown so that the GPIO2 can actually be pulled high. (The circuit in the other answer has these backwards and does not allow GPIO2 to get to anywhere near to a valid high).

enter image description here

  • \$\begingroup\$ I will try this soon. So the double transistors basically 'invert' the GPIO signal? In the sense that GPIO going low causes Q1 to cut off which means Q2 saturates? Or am I misunderstanding? \$\endgroup\$ – arcologies Apr 18 '17 at 1:09
  • \$\begingroup\$ You are understanding exactly. The extra transistor inverts the signal from the GPIO so that the power-on condition with the pullup acts as the inactive relay state. \$\endgroup\$ – Michael Karas Apr 18 '17 at 6:08
  • \$\begingroup\$ I breadboarded the circuit. Boot works fine, but I can't get the relay to switch - does the fact that Vcc on the relay = +3.3v make Q2 not work properly...? \$\endgroup\$ – arcologies Apr 18 '17 at 6:15
  • 1
    \$\begingroup\$ I cannot guess what is wrong. Appears that you will have to roll up your sleeves and debug the circuit. There is the slight possibility that the GPIO2 output of the MCU or the original 2N2222 that you used in the original circuit have been compromised or burned due to your not having a base resistor to limit the current. Also the relay part number in your schematic appears to indicate a 9V relay coil which is unlikely to work correctly if you try to operate it on 3.3V. \$\endgroup\$ – Michael Karas Apr 18 '17 at 10:42
  • 1
    \$\begingroup\$ @alve89 - Q1 inverts because when the GPIO is high it turns on Q1 and the collector of Q1 will go to a low near GND. In the opposite state when the GPIO is low the Q1 turns off and the collector is pulled up to via R3. Since the base of Q2 is directly connected to the collector of Q1 the voltage at bottom of R3 will not achieve what is normally considered to be a "high" voltage level; ie the Q2 base-emitter junction clamps the voltage to somewhere around 0.7V to 0.8V. (continued) \$\endgroup\$ – Michael Karas Jan 4 at 4:42

Clearly the Base-Emitter {read diode} junction of the NPN is pulling GPOI2 to ground. AND if the GPIO output is high there is no proper current limit for that output.

Even with 10k pullup the 1k series resistor would only have approx 0.3v across it {assuming it is grounded} however there will be around 0.5v Base-Emitter voltage as well so the end result will still be around 0.8v on the IO pin. Will that still create the boot up problem? It certainly is not what I'd call pulled up.

The suggestion of using a PNP transistor might be a good one if you have more voltage to play with, but you still want to include a series resistor for current limiting which will mean less voltage to drive the relay though.

In the end you would be better off using a FET as there will be no gate current and no need of a series resistor. You just need to decide whether to use high-side or low-side switching and therefore P or N channel type FET.

Since you want the GPIO pin High at first but the relay not activated then you should use a P-channel FET in High side switching configuration and pull the gate low to drive the relay. Don't forget the pullup resistor

  • \$\begingroup\$ Ok. I haven't used an FET before - can you link to an appropriate example, or a resource where I can learn how to use on as a switch? Thanks! \$\endgroup\$ – arcologies Apr 18 '17 at 6:16
  • \$\begingroup\$ Well, electronics.stackexchange.com/questions/67343/… looks like it addresses this. \$\endgroup\$ – arcologies Apr 18 '17 at 6:16
  • \$\begingroup\$ Would this: cdn.sparkfun.com/datasheets/Components/General%20IC/… be an appropriate part to use? Please see the circuit: imgur.com/TGPP0Te. Is a series resistor necessary between GPIO2 and gate? And is the flyback diode still necessary? \$\endgroup\$ – arcologies Apr 18 '17 at 20:28
  • \$\begingroup\$ (Obviously assuming I reverse my programming of the MCU st GPIO2 remains hi until I want to switch on the relay) \$\endgroup\$ – arcologies Apr 18 '17 at 20:31
  • 1
    \$\begingroup\$ Series gate resistors on MOSFETs can be needed for big power FETs that have huge gate capacitance to limit the current surges that happen when trying to swing the gate between different voltage levels in fast manner. Small signal MOSFETs can often be used without series gate resistors. You do still need the flyback diode to prevent the fast inductive spikes that can kill transistors. \$\endgroup\$ – Michael Karas Apr 19 '17 at 4:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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