Suddenly cannot flash NodeMCU ESP8266

Suddenly, I cannot flash my NodeMCU ESP8266 boards anymore. Whatever I try, esptool simply says

Connecting........_____....._____....._____....._____....._____....._____....._____

A fatal error occurred: Failed to connect to ESP8266: Timed out waiting for packet header

In the past, I could flash these without any issue (even without having to press a button), but suddenly I just can’t seem to get it to work. I have tried everything:

  • Removing all connections, so all pins are unused
  • Pressing the FLASH and/or RST buttons (and many combinations of holding down one of both), like many people suggest online, even though that was never necessary with these boards in the past
  • Different upload_speeds
  • Different PCs (both running Arch Linux, though)
  • Different USB ports
  • Different USB cables
  • Different boards, even a brand-new sealed one

The boards work, and so does the serial communication: I can connect over serial and see the output of the previous program. I just can’t get it in flash mode, all of a sudden.

The LED also flashes, when it’s trying to connect.

I’m out of ideas. Hoping you have some!

The only valid combination of that is: Hold FLASH, press and release RST (while FLASH is still being held), release FLASH.

Try opening a serial monitor (miniterm.py /dev/ttyUSB0 74880), then do the procedure above. What does it output?

1 Like

Yes, I tried that.

When I monitor the serial port (using screen /dev/ttyUSB0 74880) and do that, I get a few question marks after pressing RST a few times, like this:

������

The output should have been

 ets Jan  8 2013,rst cause:2, boot mode:(1,6)

Either there is a hardware fault or a fault in the serial driver. If you are seeing garbled output it is usually an indication of listening at the wrong baud rate, but it could also be a bug in the driver setting up the USB-serial converter chip up in a wrong way. There have been bugs like this in the past. I also remember a fault in the Linux kernel stopping someone running Manjaro from connecting to USB-serial devices properly (BluePill stm32f103c8t6 USBSerial issues - #15 by thk), so the kernel should not be off of the list of suspects per-sé .

Can you boot into a live Linux OS (say, standard Ubuntu), install screen or miniterm.py there and check again if the output is still garbled when executing the reset-into-bootloader procedure?

I tried with linux-lts (5.10.61-1-lts), but no cigar. I will try it with another distro next.

With Debian 11 (linux 5.10.0-8), I also get garbled output…

I’m really perplexed…

Hm, given that you tested new boards it’s unlikely that those have a hardware fault, so it points more to the software side.

What is the USB-serial converter chip on those boards for reference? A CH340, CP2102, or different one?

In the off-chance that Debian 11 also has the same bug, can you test something older like Ubuntu 18.04?

One of the boards is new. The other one isn’t, but I have personally used (and flashed) it before without issues back then.

This is the specific board: 1.21€ |Wireless Modul CH340/CP2102/CH9102X NodeMcu V3 V2 Lua WIFI Internet der Dinge Entwicklung Board Basierend ESP8266 ESP 12E|nodemcu v3|lua wifiwireless module - AliExpress
(V3 Nodemcu-CH340)

I just tried with Ubuntu 20.04.3 LTS (that should be more than old enough) (linux 5.4.0-81), and still the same results.

Is it possible that I just got the wrong baud rate? I tried a couple of others (9600, 115200), but haven’t been able to get anything other than garbled output from it.

74880 is the bootloader baud rate of all ESP8266 modules (source). The bootloader is burned into the mask-ROM of the chip and thus unchangable and the same among all ESP8266’s.

The CH340 chips are known for very poor reliability (I read someone write ‘looking at them the wrong way even seems to breaks them’), but then again if you tried this on brand-new and multiple boards it seems unlikely that they’re broken. The only way to verify that would be to break out a logic analyzer and get a trace on what’s on the RX line.

But something has to be at fault here, either hardware or software.

Do you happen to have other boards with also a CH340 on them? E.g., an Arduino Uno clone or whatever. If the same problems manifest there, that would be interesting.

Right, so I tested this on a friends PC (with Windows), and there the diagnostic message appears.

So I did some searching, and apparently it is completely normal to get garbled output on Linux because the non-standard baud rate of 74880 is not supported. So that was a red herring.

However, my problem is not solved since I can still not flash the ESP8266s…

The initial baud rate of the bootloader is 74880, there is no getting around that. If it were true that it is not supported on Linux, then no Linux system could ever flash an ESP8266, which I’ve done hundreds of times. Something else must be at play here.

I’m not sure about the details, but from what I gathered it’s either just the debug messages that get printed at 74880 baud, or that it’s not a limitation of Linux itself, but rather of most serial utilities.

Apparently, using some hacking, it is possible to get a baud rate of 74880 working on Linux, but it’s not trivial. See:

http://sensornodeinfo.rockingdlabs.com/blog/2016/01/19/baud74880/
http://cholla.mmto.org/esp8266/weird_baud/

It seems that screen just fails silently and falls back to a default baud rate (which is stupid, of course), but in for example minicom it is clear that it doesn’t switch to 74880 baud when you ask it to. Similarly, in the Arduino IDE’s serial monitor, it fails (with the error message Error while setting serial port parameters: 74,880 N 8 1) when you try to select 74880 baud.

Nevertheless, I think I’ve found the root of the flashing issue. I found this issue on esptool’s GitHub: Automatic reset not working. Only able to connect with --before no_reset (ESPTOOL-300) · Issue #656 · espressif/esptool · GitHub

And indeed, when passing --before no_reset to esptool.py, it works! Well, after resetting the board manually by holding FLASH and pressing RST, that is.

Now, is there a way to set this option in platformio.ini so it passes it to esptool when I do a pio run?

Alright nice that a workaround is found. The rest should either be handled in esptool.py or in the kernel / driver, I aggree with this here.