How to get your Arduino to tell you its Serial baud rate

I’ve got several Nanos, some work at 115K for Serial; others only 38K4. I’ve also got a few other MCUs that run at various lower speeds.

So I connect a random one to Serial Monitor and … a bunch of Klingon algebra appears on the screen. What speed do I need to connect at?

So I created a standard chunk of code to tell me …

#if defined(HardwareSerial_h) //  // HardwareSerial defined in .arduino15/packages/arduino/hardware/avr/1.8.6/cores/arduino/HardwareSerial.h
void printSwitchBaudrateMessage(HardwareSerial* pSerial, long bps){ // print automated message to switch BAUDRATE
 if(pSerial){
  pSerial->end();
  pSerial->begin(bps);
  while(!(pSerial)){} // for Leonardo, Micro etc.
  while(pSerial->available()){ pSerial->read(); } // empty any spurious input chars
  pSerial->flush(); // wait for any spurious out chars to be transmitted
  pSerial->print(F("\n(@"));
  pSerial->print(bps, DEC);pSerial->print(F(") Switch to BAUDRATE "));
  pSerial->println(BAUDRATE, DEC);
  pSerial->flush(); // wait for any spurious out chars to be transmitted
  delay(100);
  pSerial->end();
 }
}
void printAutomatedSwitchBaudrateMessage(HardwareSerial pSerial){
 printSwitchBaudrateMessage(pSerial, 9600);
 printSwitchBaudrateMessage(pSerial, 19200);
 printSwitchBaudrateMessage(pSerial, 38400);
 printSwitchBaudrateMessage(pSerial, 115200);
}
#else
void printAutomatedSwitchBaudrateMessage(Print* pPrt){
 pPrt->print(F("Looks like BAUDRATE would be ")); pPrt->println(BAUDRATE, DEC);
}
#endif

void setup(){
 delay(500); // wait for stability on some boards to prevent garbage Serial. 100mS too short
 printAutomatedSwitchBaudrateMessage(&Serial);
 Serial.begin(BAUDRATE); // Serial defined in .../cores/arduino/HardwareSerial.h
 ...

This has saved me a lot of time over the years.

1 Like

??? I have yet to come across an arduino that does not work on hardware serial at any classical value between 9600 and 115200 bauds (even further).

If you see garbage it’s because the receiving serial monitor is not set at the same baud rate.

Am I missing something there?

Reducing the mix of different baudrates in your sketches or a sticker with the baudrate on each device would have done the same ;-)

1 Like

I guess you didn’t buy a batch of Chinese Nano clones with an old bootloader that drop Serial bits even at 57K6 baud.

I’ve also got an old alarm system with firmware that used to have a version sticker on it. The supplier asked what version it was on the sticker. I told him that the sticker had fallen off. If only there was some way for the firmware itself to tell me …

I really like self-documenting programmes, so when my Arduino powers up, it tells me things like …

�⸮⸮⸮⸮⸮⸮⸮⸮⸮�⸮�⸮⸮⸮�⸮����⸮�⸮�⸮�⸮⸮⸮⸮⸮⸮⸮⸮�
(@115200) Switch to BAUDRATE 115200

2026-01-10@18:20:17.896, BAUDRATE=115200, ARDUINO=10815 RAMEND=0x8FF FLASHEND=0x7FFF
Prjct: OptoCouplerTransferTester.ino
Fldrs:git/XXXX/TestEquipment_Folder/OptoCouplerTransferTester
GIT: 2026-01-10 17:46:09 +1300, bf1f44f-dirty
sizeof(size_t)=2
gSerAv4Wrt_AtStrt=63

LED_BUILTIN=13
NUM_DIGITAL_PINS/NUM_ANALOG_INPUTS =20/8
F_CPU=16000000 (16.00MHz)
AVR H/W=<avr/iom328p.h>
PROGMEM='attribute((progmem))'
SIG  0/1/2=0x1E/0x95/0x0F
FUSE L/H/E=0xFF/0xDA/0xFD
(default=0x62/0xD9/0xFF

Some of that info comes from Arduino #defines, other bits from a pre-compiler script that the IDE runs automatically.

1 Like

Agree 100%

I recall that in the past on the forum one or two sensors had an obscure baud rate of 70000-80000 something. However the Serial was not used simultaneously for user interaction. And yes , MIDI uses 31250 baud.

Yes, I could use a consistent baudrate - but that would slow things down.

My baudrate calculation takes a bunch of factors into account. The code is:

#if F_CPU >= 12000000UL
// NANO_OLD_BOOTLOADER needs .arduino15/packages/arduino/hardware/avr/1.8.6/boards.txt + nano.menu.cpu.atmega328old.build.extra_flags=-DNANO_OLD_BOOTLOADER
// as well as atmega328old
// add to atmega328old128
// add to atmega328oldRTTI
// was // NANO_OLD_BOOTLOADER needs .arduino15/packages/arduino/hardware/avr/1.8.3/boards.txt + nano.menu.cpu.atmega328old.build.extra_flags=-DNANO_OLD_BOOTLOADER
#ifdef NANO_OLD_BOOTLOADER
#define BAUDRATE 38400 // old boot loader drops @ 57K6
#pragma message("\n#BTW Nano Old Bootloader Speed USB: " NUM2STR(BAUDRATE))
#else
#define BAUDRATE 115200 // ESP8266 default of 74880 not supported on Linux
#pragma message("\n#BTW Full Speed USB: " NUM2STR(BAUDRATE))
#endif
#elif F_CPU >= 1000000UL
#define BAUDRATE 19200
#pragma message("\n#BTW Medium Speed USB: " NUM2STR(BAUDRATE))
#else
#define BAUDRATE 9600
#pragma message("\n#BTW Slow Speed USB: " NUM2STR(BAUDRATE))
#endif

I have lots of good and crappy stuff in my deawers :slight_smile:

The UART is hardware - bootloader you can change…

Also with your code printing at various baud rates - how do you handle that in the terminal ? You set a baud rate, it will just read correctly what is sent at that baud rate…

@J-M-L i think its up to you to process the message:

I would be interested in seeing a complete sketch that uses your

But if as you say it does not work and / or you have the wrong baud rate - you never see that message …

It tries a few baudrates to tell you. I think you must be unlucky when you are not on one of these.

You could, in a loop, emit the same message at a series of baud rates, perhaps a table in memory, or in EEPROM; then, sit waiting at the desired rate for the user to type a specific message, like "Hello"; once that is received, proceed with your program.
But I think it's a poor approach. I work at one of two bauds - 115200, or 9600 IFF there is a solid reason for the slower baud rate.
YMMV, works for me.

1 Like

Why would that be? Or maybe better to ask "what would it slow down"?

I guess I don’t understand the use case…

2 Likes

I have a lot of NANO clones, all my sketches use either 9600 or 115200, and my monitor is set to the same. Everything works. Do I sometimes get garbage at startup, as does every board I own? When I upload, I see it is finished, click the monitor start and/or press the reset button and voila, all is good. It's been that way forever.

1 Like

obviously a chicken & egg problem -- how can the Arduino report the speed on the Serial port without the port set to that speed.

i think you like the code to always come up at some speed (e.g. 300) and report the new speed specified in Serial.begin() before changing to that speed, similar to how modems use to handshake to determine a common speed

if you're deperate, use an o-scope to measure the bit period

1 Like

The threshold on F_CPU is arbitrary and does not reflect the real USART baud rate error, which depends on the UBRR divider and the resulting timing error.

The claim that the old Nano bootloader “drops at 57.6 k” is misleading; 57600 is the bootloader speed, but user serial at 115200 generally works within acceptable error margins.

Choosing 38400 for the old bootloader has no clear mathematical or datasheet justification.

As long as you are happy with you voodoo approach - that’s OK - but really this makes no sense at all to me.

The offered code publishes the message about the correct baud rate at a number of baud rates. Very clever. One will print correctly, directing the choice the use must make at the serial monitor.

But noobs aren't going to be any better off, they won't find and include this code in their sketches.

It's for them just something to learn by having it happen once or twice, or for some of us a few dozen times, like any stupid error = v. ==, integer overflow, stray semicolons &c.

And ppl who know what they are doing, well, know what to do.

This is useful I suppose if you use a large number of baud rates in your sketches, can't be bothered to flip through them to find the correct one when you see garbage (or nothing) on the serial monitor and don't have a pencil to write down what each of all that vast number of variously fast projects you've strewn about runs at.

Which seems odd for someone who could come up with this self-identifying trick.

Here technique beats custom tool.

a7

something likely to be done after the horses leave the barn and the lesson learned to be more consistent.

1 Like

I built a Nano oscilloscope using IDE Serial Plotter for its display. That needs top speed to keep refreshing the display at a useful rate. (I also run the ADC pretty fast, too; maybe 6 bit resolution which is ‘good enough’)

I have an atmega328p chip on battery power using the 128KHz oscillator; that has to communicate at a tiny fraction of the oscilloscope speed.

1 Like