Keywords: PySerial | COM Ports | Serial Communication | Windows | Python Serial Programming
Abstract: This article provides a comprehensive guide to serial port communication using PySerial library in Windows operating systems. Starting from COM port identification and enumeration, it systematically explains how to properly configure and open serial ports, and implement data transmission and reception. The article focuses on resolving the naming differences between Windows and Unix systems, offering complete code examples and best practice recommendations including timeout settings, data encoding processing, and proper resource management. Through practical case studies, it demonstrates how to establish stable serial communication connections ensuring data transmission reliability and efficiency.
COM Port Identification and Enumeration
When performing serial communication in Windows systems, the first step is to identify available COM ports. PySerial provides the serial.tools.list_ports module to obtain the list of currently available serial ports in the system. The following code demonstrates how to enumerate all COM ports:
import serial.tools.list_ports as port_list
ports = list(port_list.comports())
for p in ports:
print(p)Executing the above code will output results similar to:
COM7 - Prolific USB-to-Serial Comm Port (COM7)
COM1 - Communications Port (COM1)
It's important to note that Windows systems use the COMx naming convention (such as COM1, COM7), which is fundamentally different from device file paths like /dev/ttyUSB0 or /dev/ttyS0 in Unix/Linux systems.
Serial Port Configuration and Opening
After identifying the target COM port, it's necessary to properly configure and open the serial connection. PySerial's Serial class provides flexible configuration options:
import serial
# Basic opening method
ser = serial.Serial('COM7')
print(f"Opened port: {ser.name}")
# Opening method with parameter configuration
serialPort = serial.Serial(
port="COM4",
baudrate=9600,
bytesize=8,
timeout=2,
stopbits=serial.STOPBITS_ONE
)Key configuration parameter descriptions:
- port: Serial port name, COM1, COM2, etc. in Windows
- baudrate: Baud rate, common values include 9600, 19200, 115200
- bytesize: Data bits, typically 8 bits
- parity: Parity bit, default is
serial.PARITY_NONE - stopbits: Stop bits, typically 1 bit
- timeout: Read timeout, blocks when set to
None, returns after timeout when set to a numerical value
Data Transmission Operations
To send data to the serial port, use the write() method, noting that data must be passed in byte form:
# Send string data
ser.write(b"Hello World\r\n")
# Send specific commands
command = b"AT\r\n"
ser.write(command)
# Send hexadecimal data
hex_data = bytes([0x01, 0x02, 0x03])
ser.write(hex_data)In Windows systems, line endings typically use \r\n (carriage return + line feed), which differs from the \n used in Unix systems. Adjustments should be made according to specific device requirements.
Data Reception and Processing
There are multiple methods for reading data from serial ports. Choose the appropriate reading method based on specific requirements:
# Read single byte
byte_data = ser.read()
print(f"Received byte: {byte_data}")
# Read specified number of bytes
buffer = ser.read(10) # Read 10 bytes
print(f"Received data: {buffer}")
# Read one line of data (until newline character is encountered)
line = ser.readline()
print(f"Received line: {line}")
# Complete example of continuous data reading
serialString = ""
while True:
# Wait and read data
data = serialPort.readline()
# Attempt to decode and process data
try:
decoded_data = data.decode("ascii")
print(f"Received: {decoded_data}")
serialString += decoded_data
except UnicodeDecodeError:
print(f"Received raw byte data: {data}")Data decoding is a crucial aspect of serial communication. If the device sends ASCII text, use decode('ascii') for decoding; if it sends binary data, process the byte data directly.
Advanced Configuration and Resource Management
To ensure program stability and proper resource release, it's recommended to use context managers for serial port connection management:
# Use with statement for automatic resource management
with serial.Serial('COM7', 9600, timeout=1) as ser:
ser.write(b"Test Message\r\n")
response = ser.readline()
print(f"Device response: {response}")
# Serial port automatically closes after exiting the with blockAlternatively, create a Serial instance first, then configure and open it:
ser = serial.Serial()
ser.port = 'COM1'
ser.baudrate = 19200
ser.timeout = 2
ser.open()
if ser.is_open:
print("Serial port successfully opened")
# Perform communication operations
ser.close()Error Handling and Debugging Techniques
In practical applications, it's essential to properly handle potential exceptions:
import serial
import time
try:
with serial.Serial('COM7', 9600, timeout=2) as ser:
# Send test command
ser.write(b"AT\r\n")
# Wait and read response
time.sleep(0.1) # Allow time for device response
response = ser.read_all()
if response:
print(f"Device response: {response}")
else:
print("No response received from device")
except serial.SerialException as e:
print(f"Serial port operation error: {e}")
except Exception as e:
print(f"Other error: {e}")Debugging recommendations:
- Use
serial.tools.minitermfor port testing - Gradually increase timeout for testing
- Verify data using logic analyzers or serial port debug assistants
- Maintain communication logs for troubleshooting
Platform Compatibility Considerations
Although this article focuses on Windows platform, when writing cross-platform applications, consider:
import serial
import sys
# Select port name based on operating system
if sys.platform.startswith('win'):
port_name = 'COM7'
elif sys.platform.startswith('linux'):
port_name = '/dev/ttyUSB0'
elif sys.platform.startswith('darwin'): # macOS
port_name = '/dev/tty.usbserial'
else:
port_name = None
if port_name:
try:
with serial.Serial(port_name, 9600, timeout=1) as ser:
# Cross-platform communication code
pass
except Exception as e:
print(f"Unable to open port {port_name}: {e}")By following the methods and best practices introduced in this article, you can achieve stable and reliable serial communication in Windows systems, meeting the communication requirements of various embedded devices, sensors, industrial controllers, and other equipment.