UART Baud Rates Explained: From Garbage Characters to Reliable Serial Links
A practical guide to UART baud rates — why 9600 and 115200 exist, how clock error causes framing failures, worked examples with real MCUs, and the 2% rule every embedded engineer needs to know.
Contents
- The Moment Everyone Has Had
- What Baud Rate Actually Is
- The Standard Baud Rates (And Why Those Weird Numbers)
- Why 9600 Is The Universal Default
- Worked Example: GPS Module Mismatch
- Worked Example: High-Speed Sensor Data Logging
- The 2% Rule — Clock Tolerance
- Why 2%?
- What 2% Looks Like In Practice
- MCU Clock Sources and Baud Rate Error
- Crystal Oscillator (HSE)
- Internal RC Oscillator (HSI)
- The BRR Divisor Problem
- Common Mistakes
- 1. Wrong Baud Rate In Code
- 2. Software UART (Bit-Banging) Limitations
- 3. Voltage Level Mismatch (Looks Like Baud Rate Problem)
- 4. Forgetting UART Overhead
- 5. Not Accounting for Temperature Drift
- When To Use Which Baud Rate
- Using the Calculator
- Quick Reference: UART Baud Rate Formulas
The Moment Everyone Has Had
You wire up two boards. TX to RX, RX to TX, ground to ground. You flash your firmware, open the serial monitor, and... garbage. ÿÿÿÿ or ⸮⸮⸮⸮ or maybe nothing at all. You double-check the wiring. You swap TX and RX (everyone does this at least once). Still garbage.
Then someone asks: "what baud rate are you set to?"
And there it is. One side is talking at 9600, the other is listening at 115200. The electrical signals are perfect — voltage levels, wiring, everything checks out — but the two devices are speaking at completely different speeds. It's like trying to read a book while someone flips the pages at triple speed. The characters are all there; you just can't make sense of them.
This is the most common serial communication failure in embedded systems, and it's entirely preventable once you understand what baud rate actually means and why it matters so much for UART.
What Baud Rate Actually Is
Baud rate is the number of signal transitions — symbols — per second on the wire. For UART specifically, each symbol is one bit, so baud rate equals bit rate. When you set 115200 baud, you're telling the transmitter to change the line voltage every 1/115200 seconds, which works out to about 8.68 microseconds per bit.
Here's the critical thing: UART has no clock wire. Unlike SPI or I2C, there's no separate signal telling the receiver when to sample. Both sides independently generate their own timing from their own clocks. They just have to agree on the speed beforehand.
Think of it like two people reading a shared ticker tape. There's no bell that rings for each letter — they both just agreed to look at the next character every 8.68 microseconds. If one person's watch runs 5% fast, they'll eventually start reading the wrong characters. That's exactly what happens with UART when clocks don't match.
The receiver detects the start of a byte by watching for the start bit — a transition from high (idle) to low. Once it sees that falling edge, it starts its internal timer and samples the data bits at the expected intervals. If the baud rate is even slightly off, by the time it gets to bit 7 or the stop bit, it's sampling at the wrong moment.
The Standard Baud Rates (And Why Those Weird Numbers)
If you've worked with serial at all, you've seen the usual suspects:
| Baud Rate | Bit Period | Origin |
|---|---|---|
| 75 | 13.3 ms | Telegraph (Baudot code) |
| 110 | 9.1 ms | Teletype ASR-33 |
| 300 | 3.33 ms | Early acoustic modems |
| 1200 | 833 µs | 1200-baud modem era |
| 2400 | 417 µs | V.22 standard |
| 9600 | 104 µs | De facto "safe default" |
| 19200 | 52.1 µs | 2× 9600 |
| 38400 | 26.0 µs | 4× 9600 |
| 57600 | 17.4 µs | Oddball (not 6× 9600) |
| 115200 | 8.68 µs | Standard "fast" UART |
| 230400 | 4.34 µs | 2× 115200 |
| 460800 | 2.17 µs | Pushing it for many MCUs |
| 921600 | 1.09 µs | Near the limit |
So why is 57600 in the standard set instead of 56400 (which would be a cleaner multiple)? It's 115200 / 2, and 115200 itself comes from the 8250 UART chip used in IBM PCs. The 8250 had a 1.8432 MHz oscillator, and with a divisor of 1, you got 115200 baud (1843200 / 16 = 115200). The divisor-of-16 oversampling is baked into the hardware.
The result: we're all still using baud rates dictated by a crystal frequency chosen in 1981.
Why 9600 Is The Universal Default
9600 baud is slow enough to work with almost any clock source, any wire length under a few meters, and any UART peripheral — even the most basic ones. It's the speed that "just works." GPS modules default to it. Bootloaders use it. When you don't know what speed a device speaks, try 9600 first.
But 9600 is also painfully slow for anything beyond short text messages. At 10 bits per frame (8N1 format), you get 960 bytes per second. Printing a 1 KB debug log takes over a second. That's why most development work uses 115200 — it's 12× faster and still reliable with any modern MCU crystal.
Worked Example: GPS Module Mismatch
Let's say you have a u-blox NEO-6M GPS module. It outputs NMEA sentences at 9600 baud by default. Your STM32 firmware accidentally configures USART2 at 115200. What happens?
The GPS sends a $ character (ASCII 0x24, binary 00100100). On the wire at 9600 baud, each bit is 104.17 µs wide. The full 10-bit frame (start + 8 data + stop) takes 1.042 ms.
But your STM32 is sampling at 115200 — expecting bits that are 8.68 µs wide. When it sees the start bit's falling edge, it starts sampling every 8.68 µs. In the time it takes the GPS to send ONE bit (104.17 µs), the STM32 samples 12 times. It reads 12 "bits" from what's actually a single bit.
The result: you see random-looking characters in your terminal. Not just wrong characters — completely unpredictable garbage, because the receiver is slicing the waveform into 12× more pieces than intended.
The fix: Match the baud rate. Set your STM32 to9600 or reconfigure the GPS (via UBX protocol commands) to 115200. There's no negotiation, no auto-detect (in most cases) — both sides must be explicitly configured to the same speed.
Worked Example: High-Speed Sensor Data Logging
You're building a data logger that reads an accelerometer at 1 kHz (1000 samples per second). Each sample has X, Y, Z axes as 16-bit integers, plus a timestamp. You want to stream this over UART to an FTDI USB-serial adapter for PC capture.
Let's figure out what baud rate you need:
Step 1: Calculate the data payload.- 3 axes × 2 bytes each = 6 bytes per sample
- 4 bytes for timestamp = 4 bytes
- 2 bytes overhead (header + checksum) = 2 bytes
- Total: 12 bytes per sample
12 bytes × 1000 samples/s = 12,000 bytes/second
Step 3: Convert to bits per second (accounting for UART overhead).With standard 8N1 framing, each byte costs 10 bits on the wire (1 start + 8 data + 1 stop):
12,000 bytes × 10 bits/byte = 120,000 bits/second
Step 4: Choose a baud rate with margin.You need at least 120,000 bps. The next standard rate up is 230400. But wait — can you use 115200? That gives you 115,200 bps on the wire, which is less than your 120,000 requirement. You'll lose data.
So 230400 it is — giving you 230,400 / 120,000 = 92% headroom. That's plenty of margin for interrupt latency, buffer management, and occasional burst traffic.
Alternatively, you could use 115200 if you reduce your sample rate to 960 Hz (115,200 / 12 / 10 = 960). In practice, I'd recommend 230400 with the full 1 kHz rate — the headroom lets your firmware breathe.
Use the UART Baud Rate calculator to verify the actual achievable rate and error for your specific MCU clock.
The 2% Rule — Clock Tolerance
Here's where UART gets tricky. Since there's no shared clock, both transmitter and receiver generate their baud rate from their own oscillators. If those oscillators drift apart, bits get misread.
The standard tolerance for reliable UART communication is ±2% cumulative error between both ends. In practice, most references recommend keeping each side under ±1%, so the worst-case total mismatch stays under 2%.
Why 2%?
UART receivers use 16× oversampling — they sample the line 16 times per bit period and use the middle samples (typically samples 7, 8, 9 out of 16) to determine the bit value. This gives some tolerance to timing drift.
For an 8N1 frame (10 bits total), the last bit sampled is bit #10 (the stop bit). The accumulated error by that point is:
If the total timing error causes the sampling point to drift by more than half a bit period by the end of the frame, you'll sample the wrong bit. Working backwards:
But that's theoretical maximum with perfect start-bit detection. In practice, the start bit detection itself has ±0.5 sample uncertainty (out of 16 samples), eating into your margin. The real-world safe limit is about 3.75% total, and engineers use 2% as a conservative design rule.
What 2% Looks Like In Practice
At 115200 baud, a 2% error means the actual baud rate is somewhere between 112,896 and 117,504. The bit period is off by ±0.17 µs. Over a 10-bit frame, that accumulates to ±1.7 µs of drift — about 20% of a bit period. Still safe, but you're using up your margin.
At 9600 baud, 2% error is much less critical in absolute terms (±2.08 µs per bit, ±20.8 µs per frame) because the bit periods are so wide. This is another reason 9600 is the "safe" default — even terrible oscillators can hit it.
MCU Clock Sources and Baud Rate Error
Not all clocks are created equal for UART:
Crystal Oscillator (HSE)
Accuracy: typically ±20 ppm (0.002%). Essentially perfect for UART. Any standard baud rate will work with negligible error. This is what the ESP32, most STM32 dev boards, and Arduino Uno (16 MHz crystal) use.
Internal RC Oscillator (HSI)
Accuracy: ±1% to ±5% depending on temperature and voltage. The STM32's internal 8 MHz HSI is factory-trimmed to ±1% at 25°C, but can drift to ±2% over the full temperature range. The ATmega328P's internal 8 MHz RC oscillator is ±10% uncalibrated (!) but ±2% after factory calibration.
This is where things get dangerous. If both your transmitter AND receiver are using RC oscillators, you could have up to 4% total mismatch. UART will fail intermittently — working fine on the bench at room temperature, then dropping characters in the field when it's hot or cold.
Rule of thumb: If you're running UART above9600 baud without a crystal, calculate your worst-case baud rate error using the UART calculator and verify it stays under 2%.
The BRR Divisor Problem
Even with a perfect crystal, you might not get an exact baud rate. The UART peripheral divides the clock by an integer (the BRR register) to generate the baud rate:
If the division doesn't come out even, you get quantization error. For example, a 16 MHz clock trying to generate 115200 baud:
You can't load 8.68 into a register — it rounds to 9. The actual baud rate becomes:
Error: . That exceeds 2%. This specific combination of clock and baud rate won't work reliably without fractional divider support.
Some MCUs (STM32, SAM, nRF) have fractional BRR dividers that solve this. Others (ATmega) don't — you need to choose your crystal frequency carefully. The classic 7.3728 MHz and 11.0592 MHz crystals exist specifically because they divide evenly into standard baud rates.
| Crystal | BRR for 115200 | Actual Baud | Error |
|---|---|---|---|
| 7.3728 MHz | 4 | 115200 | 0.00% |
| 8 MHz | 4.34 → 4 | 125000 | 8.51% |
| 11.0592 MHz | 6 | 115200 | 0.00% |
| 16 MHz | 8.68 → 9 | 111111 | 3.55% |
| 18.432 MHz | 10 | 115200 | 0.00% |
| 48 MHz | 26.04 → 26 | 115385 | 0.16% |
| 72 MHz | 39.06 → 39 | 115385 | 0.16% |
Modern STM32 and ESP32 chips use fractional dividers with 4–8 fractional bits, effectively eliminating this problem. But if you're working with an ATmega328P (Arduino Uno) at 16 MHz, that 3.55% error on 115200 is real. The Arduino bootloader actually uses 115200 and gets away with it because the FTDI chip on the other end is crystal-accurate and tolerant — but it's right at the edge.
Common Mistakes
1. Wrong Baud Rate In Code
The number one cause of serial garbage. Triple-check that both sides match. Common traps:
- GPS modules default to
9600, not115200 - ESP32 boot ROM outputs at
74880baud (a weird one) - Some Bluetooth modules (HC-05) use
38400for AT commands but9600for data mode - Many sensors default to
9600regardless of what the marketing says about "high-speed"
2. Software UART (Bit-Banging) Limitations
Software UART (Arduino's SoftwareSerial, for example) generates timing in software using delay loops. This means:
- Interrupts can stretch bit timing unpredictably
- Maximum reliable speed is typically
19200–38400baud - CPU load scales linearly with baud rate
- Receiving while transmitting is often impossible
115200 or higher, use a hardware UART peripheral. Always.
3. Voltage Level Mismatch (Looks Like Baud Rate Problem)
A 3.3V UART talking to a 5V UART (or vice versa) can produce garbled output that looks exactly like a baud rate mismatch. The receiver's threshold voltage isn't being crossed cleanly, causing false start bits and corrupted data. Always check voltage compatibility before blaming the baud rate.
4. Forgetting UART Overhead
New engineers often calculate required bandwidth as data_rate / 8 and set that as the baud rate. But each byte costs 10 bits (8N1) or 11 bits (8E1) on the wire. The actual useful throughput of 115200 baud with 8N1 is:
Not 14.4 KB/s (which would be 115200/8). That 20% overhead from start/stop bits matters.
5. Not Accounting for Temperature Drift
Your UART link works perfectly on the bench at 22°C. Then it goes into a product that operates at -20°C to +85°C. The internal RC oscillator drifts 3%, and suddenly you're dropping bytes on cold mornings. Always check oscillator specs over your full operating temperature range.
When To Use Which Baud Rate
Some practical guidelines:
9600— Default for unknown devices, GPS modules, sensor modules with infrequent data, bootloader fallback. Works with any clock source.115200— Standard for development/debugging, moderate data streams, most MCU-to-PC communication. Requires crystal or calibrated HSI.230400–460800— High-throughput sensor logging, firmware update over UART, FTDI-based tools. Requires crystal and short wires (<30 cm).921600–3000000— Specialized high-speed applications (ESP32 logging, FTDI at max speed). Requires matched crystals, short traces, good PCB layout. Signal integrity starts to matter.
1 Mbaud, you're pushing UART beyond where it's comfortable. At that point, consider switching to SPI (synchronous, much faster) or USB (differential, noise-immune).
Using the Calculator
The UART Baud Rate & Frame Timing calculator on rftools.io computes everything we've discussed:
- Enter your target baud rate —
9600,115200, or whatever your peripheral needs. - Set your frame format — data bits (usually 8), stop bits (usually 1), parity (usually none).
- Enter your MCU clock frequency — the APB/peripheral clock, not necessarily the core clock. Check your datasheet.
- Bit period — how long each bit is on the wire (useful for scope measurements)
- Frame period — total time for one character
- Effective throughput — actual data rate after subtracting UART overhead
- BRR divisor — the exact register value you need (for 16× oversampling)
- Actual baud rate — what you really get after integer rounding
- Baud rate error — green (<0.5%), yellow (0.5–2%), red (>2%)
Quick Reference: UART Baud Rate Formulas
For anyone who wants the math in one place:
Keep the error under 2%. Use a crystal when speed matters. Match your baud rates. Your serial links will thank you.
Related Articles
Thermocouple Voltage to Temperature Conversion
Learn how to accurately calculate thermocouple voltages, handle cold junction compensation, and avoid common measurement pitfalls.
May 2, 2026
Motor ControlBLDC Motor Winding Design for Peak Performance
Master BLDC motor winding design with our comprehensive calculator. Learn wire selection, turns calculation, and performance optimization techniques.
May 1, 2026
Audio EngineeringClass D Amplifier Design for Power Efficiency
Uncover the secrets of Class D amplifier efficiency, from MOSFET selection to power loss calculation with practical engineering insights.
Apr 30, 2026