Signals & Parameters
theoryThe Four UART Pins
A UART interface has four pins. Understanding each one β what it carries, its electrical behavior, and whether it is required β is the difference between a working connection and a destroyed target.
TX β Transmit
TX is a digital output. The device drives this line high or low to send bits. From the device's perspective, TX is where data leaves. From your adapter's perspective, TX is where data arrives β which is why you connect it to the adapter's RX pin.
Idle state on TX is logic HIGH (the supply voltage β either 3.3V or 5V). When the device has nothing to send, TX sits at this high voltage. A low pulse on TX signals the start of a new byte. This is called the start bit, and it is always the first thing UART sends.
TX is a required pin. Without it you receive nothing.
RX β Receive
RX is a digital input. The device listens on this line for incoming bits. When you send commands to the device (interacting with a shell or bootloader), your adapter's TX drives this pin.
RX is optional for passive observation. If your goal is only to read boot logs and you do not need to type commands, you can leave your adapter's TX disconnected. Nothing breaks β you simply cannot send data to the device. For interactive access (shell, U-Boot commands), RX is required.
GND β Ground
Ground is the voltage reference. It defines what "0V" means for both sides. Without a shared ground, the voltage levels on TX and RX are meaningless β the adapter might read a 3.3V signal as floating noise because it has no reference to compare against.
GND is always required. This is the most commonly overlooked pin by beginners. Symptoms of a missing ground connection: garbage output, no output at all, or erratic behavior even at the correct baud rate.
VCC β Voltage Supply
VCC provides power to the device. On a standalone embedded system that is already powered by its own supply (a router with a power brick, a camera with a 12V adapter), you do not connect VCC from your adapter. The device is already powered.
VCC on a UART interface is relevant in two scenarios: (1) powering a small standalone module like a GPS receiver or Bluetooth module that draws little current, or (2) as a reference to identify the logic voltage level (you can probe VCC with a multimeter without connecting it, just to read the voltage).
Never power a device through the VCC pin of a USB-to-UART adapter unless that device is specifically designed to be powered this way. Most adapters source 3.3V or 5V at 100-500mA maximum β far too little for a router or camera.
Connection Diagram: Device to Adapter
The cross-connection rule is fundamental. TX on one side always goes to RX on the other.
Target Device USB-to-UART Adapter
+-----------+ +------------------+
| TX |------------>| RX |
| RX |<-----------| TX |
| GND |<---------->| GND |
| VCC | (do not | |
| | connect | |
| | unless | |
| | powering | |
+-----------+ module) +------------------+
Think of it from the data's journey: a bit leaves the device on TX, travels the wire, and arrives at the adapter on RX. A bit leaves the adapter on TX, travels the wire, and arrives at the device on RX. The data always flows from TX to RX.
A common mistake: connecting TX to TX because "they're both transmit." This shorts two outputs together. No data flows, and depending on voltage levels, you may damage one or both devices.
Voltage Levels: 3.3V vs 5V
CRITICAL β READ THIS BEFORE CONNECTING ANYTHING
Connecting a 5V signal to a 3.3V device input can permanently destroy the device. The damage is instantaneous and irreversible. There is no warning, no smell, no reset β the GPIO input protection diode on the SoC's RX pin absorbs the overvoltage and may fail, latching the pin HIGH or shorting it internally. You will not know until the device fails to boot.
Modern IoT devices β produced after roughly 2010 β almost universally operate at 3.3V logic. This includes virtually all devices built on:
- Qualcomm IPQ series (routers)
- MediaTek MT7620/MT7621/MT7981 (routers, APs)
- Realtek RTL8xxx series (switches, cameras)
- Broadcom BCM63xx/BCM47xx (cable modems, routers)
- Espressif ESP8266/ESP32 (smart home devices)
- NXP i.MX series (industrial, smart speakers)
- Allwinner H-series (set-top boxes, single-board computers)
Older hardware β devices from the mid-2000s or earlier, Arduino-based designs, some industrial equipment β may use 5V logic.
How to Identify the Logic Voltage Before Connecting
Use a multimeter in DC voltage mode:
- Power on the target device normally.
- Identify the GND pad (a continuity test to the metal shield or chassis usually confirms this).
- Probe the TX pin with the red lead, GND with the black lead.
- Read the idle voltage. TX idles HIGH. A reading of ~3.3V means 3.3V logic. A reading of ~5V means 5V logic.
Do not use a logic analyzer or your UART adapter to make this determination. Use a multimeter first. The 30 seconds this takes will save you from destroying a target device.
Using a Level Shifter
If your USB-to-UART adapter outputs 5V (common with CP2102 and CH340 modules in their default configuration) and your target is 3.3V, you must insert a level shifter in the TX path from your adapter to the device's RX pin.
Two commonly used level shifter ICs:
- BSS138: A single N-channel MOSFET used in simple bidirectional level shifter modules. Cheap (~$0.30/channel), available in breakout boards with 4 or 8 channels. Suitable for UART speeds up to ~1Mbaud.
- TXS0108E: Texas Instruments 8-channel bidirectional voltage translator. Handles higher speeds, has active output-enable, appropriate for SPI-speed applications too. More expensive but more robust.
Many USB-to-UART adapters (CP2102N, FT232RL, CH343) can be configured or purchased in 3.3V-only output mode. If you are buying new hardware, get a 3.3V adapter to begin with. The simplest solution is a 3.3V adapter that also has a 3.3V VCC output β connect nothing to VCC and you are done.
Baud Rate
Baud rate (named after Γmile Baudot) is the number of symbol changes per second on the communication line. For UART, where each symbol is one bit, baud rate equals bits per second.
Both sides must use exactly the same baud rate. There is no negotiation, no auto-detection in hardware. If the rates differ even slightly, the receiver will sample bits at the wrong moment and decode garbage.
Common baud rates in embedded systems:
| Baud Rate | Typical Use |
|---|---|
| 9600 | Legacy industrial equipment, GPS NMEA output, slow sensors |
| 19200 | Some older embedded systems, industrial PLCs |
| 38400 | Less common, occasionally found in modem-era devices |
| 57600 | Some consumer routers (older Broadcom chipsets) |
| 115200 | Most common in modern IoT Linux devices |
| 230400 | High-speed logging, some Qualcomm platforms |
| 460800 | Some Espressif ESP32 bootloader output |
| 921600 | High-throughput applications, fast bootloaders |
115200 is the default to try first. When 115200 produces garbage, try 57600, then 9600. When none produce readable output, the baud rate is non-standard and must be identified through oscilloscope measurement or automated tools (covered in L5).
The 8N1 Frame Format
UART transmits data in frames. Each frame carries one byte of data, wrapped in control bits that mark its boundaries. The most common configuration is 8N1:
- 8 β 8 data bits per frame
- N β No parity bit
- 1 β 1 stop bit
This gives a total of 10 bits per frame: 1 start bit + 8 data bits + 1 stop bit.
Bit-Level Diagram: 8N1 Frame Transmitting 0x41 ('A')
The ASCII value of 'A' is 0x41 = 0b01000001. UART transmits LSB first.
Idle Start D0 D1 D2 D3 D4 D5 D6 D7 Stop Idle
HIGH LOW 1 0 0 0 0 0 1 0 HIGH HIGH
| | | | | | | | | | |
|_____| |_____|_____|_____|_____|_____| |_____| |_____|
| |_____| | |_____|
| | |
| <1 bit > | <------------- 8 bits ----------> | <1b>|
Bit timing = 1 / baud_rate
At 115200 baud: 1 bit = ~8.68 microseconds
Full frame (10 bits) = ~86.8 microseconds
The Start Bit
The idle state of TX is HIGH. A frame always begins with a start bit, which pulls TX LOW for exactly one bit period. The receiver detects this HIGH-to-LOW transition and knows a frame is arriving. It then samples the incoming line at the center of each subsequent bit period.
The start bit has no data content β it is purely a synchronization signal.
Data Bits
After the start bit, 8 data bits follow. UART sends LSB first (least significant bit first). This is a common source of confusion: if you are manually decoding a capture, remember to reverse the bit order.
At 115200 baud, each bit lasts approximately 8.68 microseconds. The receiver samples each bit near its center to maximize noise immunity.
The Stop Bit
After the 8 data bits, TX returns HIGH for one bit period (the stop bit). This marks the end of the frame and ensures the line returns to idle state before the next start bit can be sent. Some configurations use 1.5 or 2 stop bits, but on modern IoT hardware you will almost exclusively see 1 stop bit.
Parity Bit
Parity is an error-detection mechanism inserted between the data bits and the stop bit. The transmitter counts the number of 1-bits in the data byte and sets the parity bit so the total number of 1s is either always even (even parity) or always odd (odd parity). The receiver performs the same count and flags a parity error if the result doesn't match.
Embedded devices almost never use parity. It adds overhead, only detects single-bit errors, and cannot correct errors. On a short PCB trace between the SoC and a USB adapter, the signal integrity is good enough that parity errors are essentially nonexistent. The 'N' in 8N1 means parity is disabled β this is the correct setting for nearly every IoT device you will encounter.
Full-Duplex Operation
UART is full-duplex: both TX and RX operate simultaneously and independently. The device can stream boot logs on TX while you type commands on RX at the same time. There is no collision, no turn-taking, no half-duplex protocol overhead.
This is possible because TX and RX are separate physical wires. Each wire carries data in one direction only. The transmitter does not monitor its own wire for collisions (unlike Ethernet CSMA/CD).
Practical Configuration Cheat Sheet
+---------------------------+---------------------+
| Parameter | Value to Try First |
+---------------------------+---------------------+
| Baud rate | 115200 |
| Data bits | 8 |
| Parity | None (N) |
| Stop bits | 1 |
| Flow control | None |
| Logic voltage (modern IoT)| 3.3V |
| Logic voltage (legacy/AVR)| 5V |
+---------------------------+---------------------+
| minicom command | minicom -D /dev/ttyUSB0 -b 115200 |
| screen command | screen /dev/ttyUSB0 115200 |
| picocom command | picocom -b 115200 /dev/ttyUSB0 |
+---------------------------+---------------------+
| Cross-connection rule | Adapter TX -> Device RX |
| | Adapter RX <- Device TX |
| | GND <-> GND (always) |
| | VCC: only connect if powering module|
+---------------------------+---------------------+
Before connecting your adapter to any target: measure the TX idle voltage with a multimeter. Three seconds of verification prevents permanent hardware damage.