PySerial
PySerialDocs

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:

You're ready! PySerial is installed and working. Start building serial communication applications with confidence.

Quick Troubleshooting

ProblemSolution
ModuleNotFoundError: No module named 'serial'Install with pip install pyserial (not serial)
Permission deniedAdd user to dialout group (Linux) or run as admin (Windows)
Port not foundCheck device connection and use correct port name
TimeoutVerify baud rate matches on both ends
Garbage dataCheck 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?