Two issues with Serial0 (UART 0) on Nano ESP32

I've got two issues with the Serial0 (pins D0/RX0 and D1/TX1), not necessarily related, but kinda...

#1 - Panic Dump

It seems that when the CPU panics, it sends the details to this port. In my project, I happen to have a small thermal printer, so when the CPU panics the printer spits out a long ribbon of crap.

I discovered that the Arduino API provides a setDebugOutput() method for serial ports, so I tried this:

// Set the USB serial port to send the panics
Serial.setDebugOutput( true );

// Disable panic dumps on the printer port
Serial0.setDebugOutput( false );

...but this seems to have no effect.

If I understand correctly, any digital pin on the ESP32 can host the hardware serial, so it's just a matter of using:

#define UART_ID 0
#define RX_PIN D12
#define TX_PIN D11

HardwareSerial mySerialPort( UART_ID );
mySerialPort.setPins( RX_PIN, TX_PIN );

But since that specifies UART 0, I'm betting the problem will just move with it.

I know I could also use SoftwareSerial, but I'd like to learn more about this situation and see if there's a real solution that stops panic dumps from being sent to UART 0.

#2 - Data sent to UART 0 at boot-up

As I mentioned above, I have a small thermal printer connected to Serial0. Every time the ESP32 boots, a small amount of data is being sent to that port (I can't tell what, as the printer is set to 9600 baud, and whatever is sending the data is set to a different speed, so the printer just spits out a few characters of garbage).

Somewhere, I can't remember where (maybe a GitHub issue), I found out that the boot ROM has something hard-coded in it that sends some little chunk of data at boot-up. They said that if you bring GPIO15 low, the bootloader will see this and not send any output to UART 0. Well, Arduino's implementation of the ESP32 seems to not have GPIO15 exposed anywhere, so this is not an option.

There's nothing I can really do in software to stop this, since it's in the bootloader. Unless I compile and load a custom bootloader?

Oh, I stumbled across this discussion.

One of the maintainers says:

By default, right after booting, Logging is set to output using UART0 (console serial port).

So this confirms what I'm experiencing. However, he goes on to say that Serial.setDebugOutput(false); will stop that (except it needs to be Serial0 for the Nano ESP32, in this case), which doesn't work.

Or maybe panic dumps happen from a different facility? Need to find whatever that is and disable that.

Hello @maffooclock, sorry to hear your printer is busy printing gibberish all the time! :sweat_smile: Wish I could help... but unfortunately, outputs from both the second stage bootloader (#2) and the panic handler (#1) are hardcoded in the source, and can be configured only at build time. What's even worse, these binaries are shared by all boards with similar Espressif CPUs, so it's not a simple change to make.

There are many other status/information messages in the ESP32 core, so regardless of the above, a setDebugOutput(false) is useful to prevent more messages from coming through.

The output is on the Serial0 hardware port, so routing on other pins via Serial0.setPins() has no effect on muting the messages. Still, this could improve #2, since the very first message would be printed on the default pins D0/D1; if you move the printer to 2 other GPIOs, that first message may not be received by the printer. Note however that this remapping may survive a software reset, so it might show on later resets if you don't do a full power cycle (or physically push the RESET button).

You shouldn't have to worry about #1 though. Why do you encounter the backtrace so often?

Thanks for confirming. Yeah, I dug deeeep into the Arduino API and Espressif SDK for this, trying to find hints about how some of this (excluding the ROM-based behaviors, of course) might be implemented. I didn't get very far.

But in the meantime, instead of changing the pins for the HardwareSerial, I implemented SoftwareSerial, so that solved worked-around the problem entirely.

Yes, speaking of this... I noticed that I never actually get any debug/info/error/etc messages on the USB serial console. I would expect this to be the magic sauce to get that:

Serial.setDebugOutput( true );
esp_log_level_set( "*", ESP_LOG_INFO );

...but this doesn't seem to make any difference. The only output I see is my own Serial.print stuff (which, I should re-factor all that to actually use the ESP_LOGx macros).

Well... not sure. I mean, obviously I've got bugs in my code, heh, but I was too focused on getting the darn thing to quit barfing into the printer and I wasn't too concerned with the crashing yet.

But now that the project is closer to being production-ready, I'd like to actually get a useful details -- when the printer was connected to Serial0, all I got was a "Guru Meditation" error with a bunch of register values.

I just need to learn more about debugging ESP32 -- this is my first time using one, and and I'm finding that although it can be just as easy to use as the original AVR-based units (thanks to Arduino and the community for the API), it has its own world that can be far more powerful.