PySerial API Reference: Complete Documentation
Complete PySerial API documentation. All classes, methods, parameters, and exceptions with examples. Essential reference for serial programming.
Complete documentation for PySerial classes, methods, and utilities.
Serial Class
Main class for serial communication.
Constructor
serial.Serial(
port=None, # device name or None
baudrate=9600, # baud rate
bytesize=EIGHTBITS, # data bits
parity=PARITY_NONE, # parity
stopbits=STOPBITS_ONE, # stop bits
timeout=None, # read timeout
xonxoff=False, # XON/XOFF flow control
rtscts=False, # RTS/CTS flow control
write_timeout=None, # write timeout
dsrdtr=False, # DSR/DTR flow control
inter_byte_timeout=None, # inter-byte timeout
exclusive=None # exclusive access
)
Parameter | Type | Description | Default |
---|---|---|---|
port | str or None | Device name (/dev/ttyUSB0 , COM3 ) | None |
baudrate | int | Speed in bits per second | 9600 |
bytesize | int | Data bits (5, 6, 7, 8) | 8 |
parity | str | Parity (N , E , O , M , S ) | N |
stopbits | float | Stop bits (1, 1.5, 2) | 1 |
timeout | float or None | Read timeout in seconds | None |
write_timeout | float or None | Write timeout in seconds | None |
xonxoff | bool | Software flow control | False |
rtscts | bool | Hardware (RTS/CTS) flow control | False |
dsrdtr | bool | DSR/DTR flow control | False |
inter_byte_timeout | float or None | Inter-byte timeout | None |
exclusive | bool or None | Exclusive access (Linux only) | None |
# Basic connection
ser = serial.Serial('/dev/ttyUSB0', 9600)
# Full configuration
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=115200,
bytesize=8,
parity='N',
stopbits=1,
timeout=1,
write_timeout=1,
rtscts=True
)
# Create without opening
ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600
ser.open()
Port naming:
- Windows:
COM1
,COM3
,\\.\COM10
(for COM10+) - Linux:
/dev/ttyUSB0
,/dev/ttyACM0
,/dev/ttyS0
- macOS:
/dev/cu.usbserial-*
,/dev/tty.usbserial-*
Feature availability:
exclusive
: Linux onlyset_buffer_size()
: Platform dependentout_waiting
: Limited platform support
Properties
Port Information
port
str: Port name/path
name
str: Device name (same as port)
is_open
bool: True if port is open
print(f"Port: {ser.port}")
print(f"Name: {ser.name}")
print(f"Open: {ser.is_open}")
Communication Settings
# Current settings (read/write)
ser.baudrate = 115200 # int: baud rate
ser.bytesize = 8 # int: data bits (5-8)
ser.parity = 'N' # str: parity setting
ser.stopbits = 1 # float: stop bits
ser.timeout = 2.0 # float: read timeout
ser.write_timeout = 1.0 # float: write timeout
ser.inter_byte_timeout = 0.1 # float: inter-byte timeout
# Example: Change baud rate
old_baud = ser.baudrate
ser.baudrate = 57600
print(f"Baud rate changed from {old_baud} to {ser.baudrate}")
Flow Control
# Flow control settings (read/write)
ser.xonxoff = True # bool: software flow control
ser.rtscts = False # bool: RTS/CTS flow control
ser.dsrdtr = False # bool: DSR/DTR flow control
# Example: Enable hardware flow control
ser.rtscts = True
print(f"RTS/CTS flow control: {ser.rtscts}")
Buffer Status
# Buffer information (read-only)
waiting_bytes = ser.in_waiting # int: bytes in input buffer
out_bytes = ser.out_waiting # int: bytes in output buffer (if supported)
print(f"Input buffer: {waiting_bytes} bytes")
if hasattr(ser, 'out_waiting'):
print(f"Output buffer: {out_bytes} bytes")
Modem Control Lines
# Modem status lines (read-only)
print(f"CTS (Clear To Send): {ser.cts}")
print(f"DSR (Data Set Ready): {ser.dsr}")
print(f"RI (Ring Indicator): {ser.ri}")
print(f"CD (Carrier Detect): {ser.cd}")
# Modem control lines (read/write)
ser.dtr = True # bool: Data Terminal Ready
ser.rts = False # bool: Request To Send
print(f"DTR: {ser.dtr}")
print(f"RTS: {ser.rts}")
Read Methods
read(size=1)
Read up to size
bytes from the serial port.
def read(size=1):
"""Read up to size bytes"""
pass
Parameters:
size
(int): Maximum number of bytes to read
Returns: bytes
object (may be shorter than requested)
Examples:
# Read 10 bytes
data = ser.read(10)
print(f"Read {len(data)} bytes: {data}")
# Read single byte
byte = ser.read(1)
if byte:
print(f"Byte value: {byte[0]:02X}")
# Read with timeout handling
ser.timeout = 2
data = ser.read(100)
if len(data) < 100:
print(f"Timeout: only got {len(data)} bytes")
readline(size=-1)
Read until line terminator or size limit.
def readline(size=-1):
"""Read until \\n or size limit"""
pass
Parameters:
size
(int): Maximum bytes to read (-1 for unlimited)
Returns: bytes
object including line terminator
Examples:
# Read complete line
line = ser.readline()
text = line.decode('utf-8').strip()
# Read with size limit
line = ser.readline(100) # Max 100 bytes
# Handle different line endings
line = ser.readline()
if line.endswith(b'\r\n'):
text = line[:-2].decode('utf-8')
elif line.endswith(b'\n'):
text = line[:-1].decode('utf-8')
read_until(expected=b'\n', size=None)
Read until specific bytes found.
def read_until(expected=b'\\n', size=None):
"""Read until expected bytes found"""
pass
Parameters:
expected
(bytes): Bytes to search forsize
(int or None): Maximum bytes to read
Returns: bytes
object including expected bytes
Examples:
# Read until "OK"
response = ser.read_until(b'OK')
# Read until custom delimiter
data = ser.read_until(b'</packet>')
# With size limit
data = ser.read_until(b'END', size=1000)
# Binary packet reading
packet = ser.read_until(b'\xAA\x55') # Read until header
read_all()
Read all available bytes.
def read_all():
"""Read all available data"""
pass
Returns: bytes
object with all buffered data
Examples:
# Read everything in buffer
data = ser.read_all()
print(f"Got {len(data)} bytes")
# Wait for data, then read all
time.sleep(1) # Let data accumulate
if ser.in_waiting:
data = ser.read_all()
Write Methods
write(data)
Write bytes to the serial port.
def write(data):
"""Write bytes to port"""
pass
Parameters:
data
(bytes or bytearray): Data to write
Returns: int
number of bytes written
Examples:
# Write bytes
bytes_written = ser.write(b'Hello')
print(f"Wrote {bytes_written} bytes")
# Write string (must encode first)
message = "Temperature: 25.6C"
bytes_written = ser.write(message.encode('utf-8'))
# Write with line ending
ser.write(b'AT+GMR\r\n')
# Write binary data
import struct
data = struct.pack('>HHf', 1234, 5678, 25.6)
ser.write(data)
writelines(lines)
Write list of byte strings.
def writelines(lines):
"""Write sequence of bytes"""
pass
Parameters:
lines
(iterable): Sequence of bytes objects
Returns: None
Examples:
# Write multiple commands
commands = [
b'AT\r\n',
b'ATE0\r\n',
b'AT+GMR\r\n'
]
ser.writelines(commands)
# Equivalent to:
for cmd in commands:
ser.write(cmd)
flush()
Force transmission of buffered data.
def flush():
"""Force write buffer flush"""
pass
Examples:
# Send data immediately
ser.write(b'URGENT_COMMAND\r\n')
ser.flush() # Don't wait for buffer
# Read immediate response
response = ser.readline()
Control Methods
open()
Open the serial port.
def open():
"""Open serial port"""
pass
Raises: SerialException
if port cannot be opened
Examples:
# Create and open manually
ser = serial.Serial()
ser.port = '/dev/ttyUSB0'
ser.baudrate = 9600
try:
ser.open()
print("✅ Port opened")
except serial.SerialException as e:
print(f"❌ Failed to open: {e}")
close()
Close the serial port.
def close():
"""Close serial port"""
pass
Examples:
# Always close in finally block
try:
ser = serial.Serial('/dev/ttyUSB0', 9600)
# Use serial port
finally:
if ser.is_open:
ser.close()
print("Port closed")
reset_input_buffer()
Clear input buffer.
def reset_input_buffer():
"""Clear input buffer"""
pass
Examples:
# Clear stale data before sending command
ser.reset_input_buffer()
ser.write(b'AT+GMR\r\n')
response = ser.readline()
reset_output_buffer()
Clear output buffer.
def reset_output_buffer():
"""Clear output buffer"""
pass
send_break(duration=0.25)
Send break condition.
def send_break(duration=0.25):
"""Send break signal"""
pass
Parameters:
duration
(float): Break duration in seconds
Examples:
# Send standard break
ser.send_break()
# Send long break for attention
ser.send_break(1.0)
# Break sequence for modem
ser.send_break(0.5)
time.sleep(0.1)
ser.write(b'+++')
set_buffer_size(rx_size=4096, tx_size=None)
Set buffer sizes (platform dependent).
def set_buffer_size(rx_size=4096, tx_size=None):
"""Set buffer sizes"""
pass
Parameters:
rx_size
(int): Receive buffer sizetx_size
(int or None): Transmit buffer size
Examples:
# Set larger buffers for high-speed
try:
ser.set_buffer_size(rx_size=8192, tx_size=4096)
print("✅ Buffer sizes set")
except AttributeError:
print("⚠️ Platform doesn't support buffer size control")
Port Discovery
list_ports.comports()
List all available serial ports.
def comports(include_links=False):
"""List available serial ports"""
pass
Parameters:
include_links
(bool): Include symbolic links (Linux/macOS)
Returns: List of ListPortInfo
objects
Examples:
import serial.tools.list_ports
# Basic port listing
ports = serial.tools.list_ports.comports()
for port in ports:
print(f"{port.device}: {port.description}")
# Detailed information
for port in ports:
print(f"Device: {port.device}")
print(f"Description: {port.description}")
print(f"Hardware ID: {port.hwid}")
if hasattr(port, 'vid') and port.vid:
print(f"VID:PID: {port.vid:04X}:{port.pid:04X}")
print()
ListPortInfo Properties
# Port information object properties
port.device # str: device name ('/dev/ttyUSB0', 'COM3')
port.name # str: short device name
port.description # str: human readable description
port.hwid # str: hardware ID string
# USB device information (if available)
port.vid # int: vendor ID
port.pid # int: product ID
port.serial_number # str: serial number
port.location # str: physical location
port.manufacturer # str: manufacturer name
port.product # str: product name
port.interface # str: interface description
# Platform-specific properties
port.subsystem # str: subsystem (Linux)
port.usb_info() # method: detailed USB info
Port Filtering
def find_ports_by_description(description_filter):
"""Find ports by description"""
matching_ports = []
for port in serial.tools.list_ports.comports():
if description_filter.lower() in port.description.lower():
matching_ports.append(port.device)
return matching_ports
# Find specific devices
arduino_ports = find_ports_by_description("Arduino")
ftdi_ports = find_ports_by_description("FTDI")
prolific_ports = find_ports_by_description("Prolific")
print(f"Arduino ports: {arduino_ports}")
def find_ports_by_vid_pid(vid, pid=None):
"""Find ports by Vendor ID and optional Product ID"""
matching_ports = []
for port in serial.tools.list_ports.comports():
if hasattr(port, 'vid') and port.vid == vid:
if pid is None or port.pid == pid:
matching_ports.append(port.device)
return matching_ports
# Common vendor IDs
FTDI_VID = 0x0403
PROLIFIC_VID = 0x067B
CH340_VID = 0x1A86
ftdi_ports = find_ports_by_vid_pid(FTDI_VID)
print(f"FTDI devices: {ftdi_ports}")
def categorize_ports():
"""Categorize ports by type"""
categories = {
'usb_serial': [],
'built_in': [],
'bluetooth': [],
'other': []
}
for port in serial.tools.list_ports.comports():
desc_lower = port.description.lower()
if 'usb' in desc_lower or hasattr(port, 'vid'):
categories['usb_serial'].append(port.device)
elif 'bluetooth' in desc_lower:
categories['bluetooth'].append(port.device)
elif port.device in ['COM1', 'COM2', '/dev/ttyS0', '/dev/ttyS1']:
categories['built_in'].append(port.device)
else:
categories['other'].append(port.device)
return categories
# Usage
ports_by_type = categorize_ports()
for category, ports in ports_by_type.items():
if ports:
print(f"{category}: {ports}")
Constants
Data Format Constants
# Byte sizes
serial.FIVEBITS = 5
serial.SIXBITS = 6
serial.SEVENBITS = 7
serial.EIGHTBITS = 8
# Parity
serial.PARITY_NONE = 'N'
serial.PARITY_EVEN = 'E'
serial.PARITY_ODD = 'O'
serial.PARITY_MARK = 'M'
serial.PARITY_SPACE = 'S'
# Stop bits
serial.STOPBITS_ONE = 1
serial.STOPBITS_ONE_POINT_FIVE = 1.5
serial.STOPBITS_TWO = 2
Usage Examples
# Using constants for clarity
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE
)
# Or use values directly
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate=9600,
bytesize=8,
parity='E',
stopbits=1
)
Exceptions
SerialException
Base exception for all serial errors.
try:
ser = serial.Serial('/dev/nonexistent')
except serial.SerialException as e:
print(f"Serial error: {e}")
Common causes:
- Port doesn't exist
- Permission denied
- Device disconnected
- Invalid parameters
SerialTimeoutException
Raised on timeout operations (subclass of SerialException).
try:
ser.timeout = 1
data = ser.read(100) # May timeout
except serial.SerialTimeoutException:
print("Read operation timed out")
Exception Hierarchy
Exception
└── SerialException
├── SerialTimeoutException
├── PortNotOpenError
└── WriteTimeoutError
Comprehensive Error Handling
def safe_serial_operation(port, operation):
"""Perform serial operation with complete error handling"""
try:
ser = serial.Serial(port, 9600, timeout=1)
result = operation(ser)
return result
except serial.SerialTimeoutException:
print("⏱️ Operation timed out")
except serial.SerialException as e:
print(f"📡 Serial error: {e}")
except PermissionError:
print("🔒 Permission denied")
except FileNotFoundError:
print("📁 Port not found")
except Exception as e:
print(f"❌ Unexpected error: {e}")
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
return None
# Usage
def my_operation(ser):
ser.write(b'test')
return ser.read(10)
result = safe_serial_operation('/dev/ttyUSB0', my_operation)
Context Manager Support
PySerial supports Python's with
statement for automatic resource management.
# Automatic port closing
with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:
ser.write(b'data')
response = ser.read(100)
# Port automatically closed when exiting 'with' block
# Equivalent to:
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
try:
ser.write(b'data')
response = ser.read(100)
finally:
ser.close()
URL Handlers
PySerial supports URL-style port specifications:
socket://
TCP/IP socket connection
rfc2217://
Remote serial port over network
loop://
Loopback connection for testing
hwgrep://
Hardware-based port selection
URL Examples
# TCP socket
ser = serial.Serial('socket://192.168.1.100:7777', timeout=1)
# RFC2217 remote serial
ser = serial.Serial('rfc2217://server.example.com:4000', baudrate=9600)
# Loopback for testing
ser = serial.Serial('loop://', timeout=1)
# Hardware grep
ser = serial.Serial('hwgrep://0403:6001') # Find FTDI device
ser = serial.Serial('hwgrep://.*Arduino.*') # Find Arduino by description
Version Information
import serial
# PySerial version
print(f"PySerial version: {serial.__version__}")
# Check for specific features
if hasattr(serial, 'VERSION'):
print(f"Version tuple: {serial.VERSION}")
# Platform-specific version info
try:
import serial.win32
print("Windows serial support available")
except ImportError:
pass
try:
import serial.posix
print("POSIX serial support available")
except ImportError:
pass
Complete API Coverage: This reference covers all PySerial classes, methods, properties, and exceptions. Use it as your definitive guide for PySerial programming.
Next Steps
Getting Started
Begin with basic PySerial usage
Examples
See API methods in real projects
Configuration
Deep dive into port settings
Common Errors
Troubleshoot API-related issues
This API reference provides complete documentation for PySerial. For specific use cases and implementation patterns, see the examples and configuration guides.
How is this guide?