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 hereError 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
| Problem | Fix |
|---|---|
ModuleNotFoundError | pip install pyserial (not serial) |
Permission denied | sudo usermod -a -G dialout $USER (Linux) |
Port not found | Check device connection, verify port name |
| Timeout, no data | Verify baud rate matches on both ends |
| Garbage characters | TX/RX wires may be swapped |