Getting Started with PySerial
Install PySerial and make your first serial connection. Complete setup guide for Windows, Linux, and macOS with working examples.
Get connected to serial devices in minutes. This guide covers installation, setup, and your first working connection.
What is PySerial? Cross-platform Python library for serial port communication. Works with Arduino, Raspberry Pi, GPS modules, and any serial device.
Installation
pip install pyserial
Virtual environment (recommended):
python -m venv serial-env
source serial-env/bin/activate # Linux/macOS
# serial-env\Scripts\activate # Windows
pip install pyserial
conda install -c conda-forge pyserial
New environment:
conda create -n serial-env python=3.9 pyserial
conda activate serial-env
Ubuntu/Debian:
sudo apt update
sudo apt install python3-serial
macOS with Homebrew:
brew install python3
pip3 install pyserial
First Connection
Find Your Device
List all available serial ports:
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
for port in ports:
print(f"{port.device}: {port.description}")
Expected output:
/dev/ttyUSB0: USB-Serial Controller
/dev/ttyACM0: Arduino Uno
COM3: Silicon Labs CP210x USB to UART Bridge
Open Connection
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
print(f"Connected to {ser.name}")
Port names vary by platform:
- Linux:
/dev/ttyUSB0
,/dev/ttyACM0
- Windows:
COM1
,COM3
- macOS:
/dev/cu.usbserial-*
Send Data
# Send bytes
ser.write(b'Hello Serial!\n')
# Send string (convert to bytes)
message = "Temperature?"
ser.write(message.encode('utf-8'))
Read Data
# Read line (until \n)
line = ser.readline()
print(line.decode('utf-8').strip())
# Read specific bytes
data = ser.read(10)
# Read all available
if ser.in_waiting > 0:
available = ser.read(ser.in_waiting)
Close Connection
ser.close()
Complete Example
Here's a working echo test:
import serial
import time
def test_serial():
try:
# Open connection
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=2)
print(f"Connected to {ser.name}")
# Wait for device initialization
time.sleep(1)
# Send test message
test_msg = "AT\r\n"
ser.write(test_msg.encode())
print(f"Sent: {test_msg.strip()}")
# Read response
response = ser.readline()
print(f"Received: {response.decode('utf-8').strip()}")
# Close connection
ser.close()
print("Connection closed")
except serial.SerialException as e:
print(f"Serial error: {e}")
except FileNotFoundError:
print("Port not found - check device connection")
except PermissionError:
print("Permission denied - see troubleshooting guide")
if __name__ == "__main__":
test_serial()
Common Settings
ser = serial.Serial(
port='/dev/ttyUSB0', # Device path
baudrate=115200, # Speed (9600, 115200, etc.)
bytesize=serial.EIGHTBITS, # Data bits
parity=serial.PARITY_NONE, # Parity checking
stopbits=serial.STOPBITS_ONE, # Stop bits
timeout=1, # Read timeout (seconds)
write_timeout=1, # Write timeout
xonxoff=False, # Software flow control
rtscts=False, # Hardware flow control
dsrdtr=False # DTR/DSR flow control
)
Platform Setup
Windows
COM ports, driver installation, admin rights
Linux
Permission groups, udev rules, /dev/tty* ports
macOS
Security settings, /dev/cu.* ports
Raspberry Pi
GPIO UART, enable serial interface
Windows Setup
Find COM ports:
# Command Prompt
mode
# PowerShell
[System.IO.Ports.SerialPort]::getportnames()
Common issues:
- Install USB-serial drivers (FTDI, CH340, CP210x)
- Run as administrator for some operations
- Check Device Manager for driver problems
Linux Setup
Permissions:
# Add user to dialout group
sudo usermod -a -G dialout $USER
# Apply immediately (or logout/login)
newgrp dialout
# Verify
groups
Find ports:
ls /dev/tty{USB,ACM}*
dmesg | grep tty
macOS Setup
Find ports:
ls /dev/cu.* /dev/tty.*
system_profiler SPUSBDataType
Use /dev/cu.*
for output, /dev/tty.*
for input.
Error Handling
Always include proper error handling:
import serial
def safe_serial_connection(port, baudrate=9600):
"""Connect with comprehensive error handling"""
try:
ser = serial.Serial(port, baudrate, timeout=1)
return ser
except serial.SerialException as e:
print(f"Serial port error: {e}")
except PermissionError:
print("Permission denied. Fix:")
print(" Linux: sudo usermod -a -G dialout $USER")
print(" Windows: Run as administrator")
except FileNotFoundError:
print("Port not found. Check:")
print(" - Device connected and powered")
print(" - Correct port name")
print(" - Driver installed")
return None
# Usage
ser = safe_serial_connection('/dev/ttyUSB0')
if ser:
# Use serial connection
ser.close()
Context Manager
Use with
statement for automatic cleanup:
with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:
ser.write(b'data')
response = ser.read(100)
# Port automatically closed
Next Steps
Now that PySerial is working:
- Arduino Integration - Connect Python to Arduino
- Reading Data - Master all read methods
- Raspberry Pi - GPIO UART communication
- Examples - Real-world projects
You're ready! PySerial is installed and working. Start building serial communication applications with confidence.
Quick Troubleshooting
Problem | Solution |
---|---|
ModuleNotFoundError: No module named 'serial' | Install with pip install pyserial (not serial ) |
Permission denied | Add user to dialout group (Linux) or run as admin (Windows) |
Port not found | Check device connection and use correct port name |
Timeout | Verify baud rate matches on both ends |
Garbage data | Check wiring (TX/RX may be swapped) |
Most issues are permissions or incorrect port names. Check the troubleshooting guide for detailed solutions.
How is this guide?