PySerial
PySerialDocs

Getting Started

Open a serial port, send data, read responses, and close the connection. First working PySerial script in under 5 minutes.

Open a port, send bytes, read a response, close. That's the whole workflow.

First Connection

Find Your Device

import serial.tools.list_ports

for port in serial.tools.list_ports.comports():
    print(f"{port.device}: {port.description}")

Port names vary by platform: /dev/ttyUSB0 on Linux, COM3 on Windows, /dev/cu.usbserial-* on macOS.

Open the Port

import serial

ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
print(f"Connected to {ser.name}")

Send Data

ser.write(b'Hello Serial!\n')

# Strings must be encoded first
message = "AT\r\n"
ser.write(message.encode('utf-8'))

Read Data

# Read one line (blocks until \n or timeout)
line = ser.readline()
print(line.decode('utf-8').strip())

# Read a fixed number of bytes
data = ser.read(10)

# Read everything currently in the buffer
if ser.in_waiting > 0:
    available = ser.read(ser.in_waiting)

Close the Port

ser.close()

Complete Example

import serial
import time

def echo_test(port, baudrate=9600):
    try:
        ser = serial.Serial(port, baudrate, timeout=2)
        time.sleep(1)  # wait for device init

        ser.write(b'AT\r\n')
        response = ser.readline()
        print(f"Sent: AT")
        print(f"Received: {response.decode('utf-8').strip()}")

        ser.close()

    except serial.SerialException as e:
        print(f"Serial error: {e}")
    except FileNotFoundError:
        print("Port not found. Check device connection.")
    except PermissionError:
        print("Permission denied. Add yourself to the dialout group (Linux).")

if __name__ == "__main__":
    echo_test('/dev/ttyUSB0')

Log serial data automatically

TofuPilot records test results from your PySerial scripts, tracks pass/fail rates, and generates compliance reports. Free to start.

Context Manager

Use with for automatic cleanup. The port closes when the block exits, even on exceptions.

import serial

with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:
    ser.write(b'data\n')
    response = ser.read(100)
# port is closed here

Error Handling

import serial

try:
    ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
    ser.write(b'test\n')
    print(ser.readline().decode().strip())
except serial.SerialException as e:
    print(f"Serial port error: {e}")
except PermissionError:
    print("Permission denied. Linux: sudo usermod -a -G dialout $USER")
except FileNotFoundError:
    print("Port not found. Check connection and port name.")
finally:
    if 'ser' in locals() and ser.is_open:
        ser.close()

Quick Troubleshooting

ProblemFix
ModuleNotFoundErrorpip install pyserial (not serial)
Permission deniedsudo usermod -a -G dialout $USER (Linux)
Port not foundCheck device connection, verify port name
Timeout, no dataVerify baud rate matches on both ends
Garbage charactersTX/RX wires may be swapped

On this page

Deploy your PySerial test scripts with TofuPilot

Trusted by Lyft, Cobot, Pacific Defense, and more.

TofuPilot provides dashboards and analytics to track serial device testing at scale.

TofuPilot
Get Started