Mastering Linux serial port communication gives you direct, low-level control over microcontrollers, network switches, and embedded hardware. Even though modern systems rely heavily on Ethernet and USB, the standard serial interface remains indispensable for headless debugging, console management, and hardware prototyping.
To set up a serial connection on Linux, you first identify your device node using utilities like dmesg or ls /dev/tty*, grant your user account access via the dialout group, and configure transmission parameters such as baud rate with stty. Terminal emulators like Minicom or Screen then let you interact directly with the hardware data stream.
This guide covers hardware discovery, permission management, configuration parameters, and terminal emulation without fluff.
Identifying Serial Ports on Linux
Before you can communicate with any external hardware, your Linux kernel must recognize the device and assign it a device file in the /dev directory. Native serial ports typically show up as ttyS*, while USB-to-serial adapters appear as ttyUSB* or ttyACM*.
Run the kernel ring buffer utility to see what your system detects right after plugging in your hardware:
sudo dmesg | grep tty
You'll see output indicating the assigned port, such as /dev/ttyUSB0 or /dev/ttyS0. To list all available terminal devices currently active on your machine, run:
ls -l /dev/tty[A-Za-z]*
Check the Linux Documentation Project for historical context on device naming conventions and terminal driver architectures.
Managing Permissions and Access Control
Trying to open a serial port often results in a frustrating Permission denied error. By default, serial device files are owned by the root user and restricted to the root or uucp groups.
Instead of running every terminal tool with sudo, add your current user account to the appropriate group. On Debian- and Ubuntu-based systems, this is usually the dialout group:
sudo usermod -aG dialout $USER
On Fedora, RHEL, and Arch Linux, the group name may differ—often lock or uucp. After running the command, you must log out and back in, or restart your shell session, for the group changes to take effect. You can verify your active groups by running the groups command.
Configuring Port Parameters with stty
Serial communication requires exact agreement between the host computer and the target device on data framing. If parameters don't match, you'll see gibberish characters (garbage output) on your screen.
Use the stty command to inspect current port settings or modify them on the fly. To view the configuration of /dev/ttyUSB0:
stty -F /dev/ttyUSB0 -a
To configure the port for standard serial communication—setting a baud rate of 9600, 8 data bits, no parity, and 1 stop bit—run:
sudo stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb
- Baud Rate: Determines the transmission speed in bits per second. Common values include
9600,115200, and57600. - Data Bits (
cs8): Specifies the size of each data frame, usually 8 bits. - Stop Bits (
-cstopb): Indicates the end of a character frame (1 stop bit vs 2). - Parity (
-parenb): Controls error checking. Disabling parity is standard for most modern microcontrollers.
For deeper technical specifications on system terminal interfaces, consult the GNU C Library Manual.
Connecting via Terminal Emulators
Once your port is configured, you need an interface to send and receive text data. Two lightweight tools dominate Linux serial workflows: Screen and Minicom.
Using GNU Screen
Screen is pre-installed on most Linux distributions and serves as a quick tool for opening a serial console without complex configuration menus. To connect to /dev/ttyUSB0 at 115200 baud, run:
screen /dev/ttyUSB0 115200
To exit a Screen session, press Ctrl+A, then press K (or type quit).
Using Minicom
Minicom provides a feature-rich, menu-driven interface suited for interactive debugging and modem control. Install it via your package manager:
sudo apt install minicom
Launch Minicom in setup mode to configure your default port and speed:
sudo minicom -s
Navigate to Serial port setup, update the serial device path and baud rate to match your hardware, save the configuration as dfl (default), and exit into the terminal workspace.
Scripting Serial Communication in Python
For automated data logging, testing, or firmware flashing, command-line tools fall short. Python's pyserial library provides a robust API for programmatic serial communication.
Install the library using pip:
pip install pyserial
Here is a simple script to open a port, send a command, and read the response:
import serial
import time
# Initialize serial connection
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=115200,
timeout=1
)
# Allow time for connection to settle
time.sleep(2)
# Send a command string terminated with a newline
ser.write(b"STATUS\r\n")
# Read incoming lines
while True:
line = ser.readline()
if line:
print(line.decode('utf-8').strip())
else:
break
ser.close()
Common Mistakes and Troubleshooting
- Garbled Output: This almost always indicates a baud rate mismatch. Verify the target device documentation and match your
sttyor terminal emulator speed precisely. - Hung Terminal: If a process locks up while reading from a serial port, another application (such as a system getty service or a background logging script) may have grabbed exclusive access to the device file. Check active processes with
ps aux | grep tty. - Cable Faults: When connecting two Linux machines or custom hardware modules, remember that standard TX and RX lines must be crossed using a null-modem configuration unless you are using dedicated USB interface chips.
Frequently Asked Questions
How do I fix persistent permission denied errors on serial ports?
Make sure your user account belongs to the group that owns the device file (typically dialout or uucp). Run groups to confirm your membership, and remember that group modifications require a fresh login session to take effect.
Can I communicate with a serial device without installing extra software?
Yes. You can use standard shell redirection to write directly to the device file: echo "HELLO" > /dev/ttyUSB0. To read incoming data, use cat /dev/ttyUSB0. However, these built-in methods lack flow control and baud rate fine-tuning, making terminal emulators or scripts much more reliable.
What is the difference between ttyS and ttyUSB devices?
Device files starting with ttyS represent native serial ports wired directly to the motherboard or system-on-chip UART controllers. Files starting with ttyUSB or ttyACM indicate external hardware connected through USB-to-serial bridge chips like FTDI or Silicon Labs CP210x.
How do I handle custom non-standard baud rates on Linux?
Standard tools like stty support standard POSIX speeds. For custom baud rates on modern Linux kernels, you must use C system programming with the termios2 structure and the TCGETS2 / TCSETS2 ioctl requests to pass custom divisors directly to the driver layer.