# Explain why the NodeMCU auto-program circuit would be useful

I'm looking at the NodeMCU "auto-program" circuit but could not understand why it is there at all.

From my point of view, this circuit enables open-collector outputs, but makes programming dependent on the time between switching the DTR and RTS pins being smaller than the ESP goes from reset to sampling the GPIO0 level.

Another reason I could imagine was to avoid invalid startup/connection resets, but I can't see why proper pulling couldn't fix this.

Is there any reasoning I couldn't see from my analysis? Why isn't DTR/CTS connected directly with one transistor on each line? Why controlling each line directly (and thus allowing to switch GPIO0 low before resetting without glitches) wouldn't be better?

EDIT: while the question is about the same structure shown in Is this a flip-flop?, I understand it's function and know it's not a flip-flop (no need to redraw it). What I'd like to do is know why was it chosen instead of a much simpler open collector configuration like the one below, specially since this one doesn't generate a glitch in the transition between the two programming states (from reset to/from GPIO0=0).

Again, yet another cute way of drawing the schematic. (See: Is this a flip-flop? for another cute way.) And once again, a less-cute drawing would look like:

simulate this circuit – Schematic created using CircuitLab

The RTS line needs to pull down (be LO) on its emitter in order to have an impact on nRST. The DTR line needs to pull down (be LO) on its emitter in order to have an impact on GPIO0. Either way, the nRST and GPIO0 results are open-collector outputs, so they actively pull down (if active at all) but will need some kind of passive pull-up (often found inside the MCU) in order to have a definite output voltage in all cases.

If both DTR and RTS are pulled LO (or HI) then neither GPIO0 or nRST are actively pulled down. So DTR and RTS must be oppositely engaged in order for either (one or the other, but not both) output to be actively pulled down.

An advantage here is that the external controlling device can choose to set both DTR and RTS to LO in order to decouple itself from the target device's I/O lines. (Setting them both to HI could lead to a problem where there is conduction via the base-collector diode.) This frees up the I/O lines on the target device for other circuitry to be added for target device purposes not related to being reset.

Note added on 8/14/2020: The above was entirely written before the OP's EDIT was added. None of it applies to that addition. (Now that I'm looking, today, I've no idea why the OP thinks that the "simpler" circuit is a good design or even safe to use.)

• I've edited the question to make it clear I want to know the difference from that circuit to a simpler open collector configuration. Please do not mark it as duplicate, since the subject is different from the mentioned question. Jan 18, 2018 at 1:07
• @RonanPaixão I see your newly added schematic. Perhaps this is a lesson in spending the time needed to write a better question at the outset. Regardless, the difference should be quite obvious. Your newly added schematic approach would interfere with the available options for a designer. Your pull-up resistors, for example, cannot be disabled and would very much limit other possible uses of the I/O pins. More could be said, but that should be enough and quite obvious. The first circuit (not your added one) is much better for the purposes at hand.
– jonk
Jan 18, 2018 at 1:36
• I really don't get the difference, since the first circuit also needs pull-ups (they just don't show up in this image because they are farther on the NodeMCU schematic). But from the circuit one can guess (or actually read the NodeMCU schematics) that NRST and GPIO0 won't ever be high except for added pull-ups or other external circuitry. Also, if the designer chooses disableable pulls, the same can be done for the second circuit. The only difference in interference is that the first circuit won't allow interference in both pins at once, but it will allow interference one at a time. Jan 18, 2018 at 2:14
• I have edited again just to make it clear in the second picture that the external pull-ups are external to the core of the circuit, even if the NodeMCU schematic includes them, Perhaps this is a lesson in understanding that people will pick a detail and take your question out of context, even if the context was provided (in this case the NodeMCU board, which also has external resistors). Jan 18, 2018 at 15:16
• @D.Patrick The answer itself was made prior to OP modification and wasn't at all dismissive (only I can tell you what was in my mind at the time.) But I'll take the hit on the comments, since that's what I think you are focused on. It's fine. Thanks for taking the time to make your point.
– jonk
Dec 11, 2018 at 20:43

This question doesn't seem to be fully answered, so I'll take a stab at it.

I can't say what was on WeMos's mind when they designed it, but the difference between their circuit and your redrawn alternative is that the original one only asserts NRST or BOOT0 (or EN/GPIO2) when both RTS and DTR are being controlled in opposite of each other.

Some cursory searching seems to imply that there is no standard "default" state for DTR/RTS to be set. Or at the very least, it's not consistently adhered to by manufacturers. With the existing WeMos circuit, one has to be active and intentionally controlling those lines to have an effect, so your device won't just reset when you plug into a host that is allowing RTS/DTR to reset at an improper state.

I would like to answer this part of the question:

What I'd like to do is know why was it chosen instead of a much simpler open collector configuration like the one below, specially since this one doesn't generate a glitch in the transition between the two programming states (from reset to/from GPIO0=0).

NodeMCU was designed to be compatible with the Arduino IDE. The Arduino IDE has a built-in programmer. That programmer was originally made for Arduino MCUs, and they have a specific wiring that requires both DTR and RTS lines pulled high/low at the same time to put the device into flashing/programming mode. ESP8266 and ESP32 chips are a bit different. You can read more about that here: https://cdn.sparkfun.com/datasheets/IoT/esp32_datasheet_en.pdf in section 2.4 "strapping pins". Most importantly, if you want to flash the device, then you cannot keep both lines high at the same time for a long time.

Some programming tools that are specific to ESP chips work out of the box, without the "cross bjt" circuit. For example, look at the reset code of esptool:

https://github.com/espressif/esptool/blob/master/esptool.py#L463

There you can see various line state changes and delays that are used to properly reset the chip. If you use such tools, then you can connect GPIO0 to DTR and RST to RTS (well, only if you have a 3.3V USB to serial converter!)

NodeMCU however, was created with compatibility in mind. You can use the Arduino IDE and Arduino (basically, the C language) the write programs, and flash them to the device from within the Arduino IDE, and you can also program it with esptool. It works either way.

If you are designing a custom PCB then you can save some costs by leaving out this "cross bjt" schematic - but then you must use the right tools to do the flashing.

• "Arduino MCUs, and they have a specific wiring that requires both DTR and RTS lines pulled high/low at the same time" INCORRECT The Arduino tools for ATmega targets drive both merely because there are some boards and bench lash-ups that use one and some that use the other and this saves figuring out which the user has. An ATmega only has one reset pin and no hardware or bootloader mode strapping, so only one signal is usable on any given board. Jul 1, 2020 at 15:30
• Okay, so maybe it is not required for all of them, and maybe the reason behind changing both DTR and RTS at the same time is different. But one thing is sure: the purpose of the "cross bjt" circuit is to correctly reset the ESP chip when both DTR and RTS are high. Jul 1, 2020 at 17:24
• How could a microcontroller be restarted in bootloader mode using such a circuit when for activating the bootloader reset has to occur while IO0 is LOW? May 7, 2021 at 21:45