Введение
Работа с последовательными портами остаётся актуальной в индустриальных, IoT, робототехнических и микроконтроллерных системах. Управление устройствами через COM (RS-232/RS-485/USB-Serial) требует стабильного, кроссплатформенного и гибкого инструмента. В Python таким решением является библиотека PySerial.
PySerial обеспечивает простой и мощный интерфейс для подключения, конфигурации и передачи данных по последовательным линиям. Она используется для связи с Arduino, Raspberry Pi, модемами, GPS-приёмниками, контроллерами, сенсорами и многим другим оборудованием.
В этой статье рассмотрим устройство PySerial, все ключевые методы, практические примеры, настройки таймингов и протоколов, работу с буферами и продвинутую интеграцию.
Основная часть
Установка и подключение
pip install pyserial
Подключение:
import serial
Базовая структура работы
-
Открытие соединения
-
Отправка и приём данных
-
Закрытие соединения
ser = serial.Serial('COM3', baudrate=9600, timeout=1)
ser.write(b'command')
data = ser.readline()
ser.close()
Ключевые параметры соединения
-
port
— имя устройства (COM1
,/dev/ttyUSB0
,/dev/ttyAMA0
) -
baudrate
— скорость (обычно 9600, 115200) -
bytesize
— размер символа (5, 6, 7, 8) -
parity
— чётность (N, E, O) -
stopbits
— количество стоп-бит (1, 1.5, 2) -
timeout
— таймаут чтения
Работа с методами Serial
Serial.write(data)
Отправка байтов.
ser.write(b'Hello\n')
Serial.read(size=1)
Чтение указанного количества байтов.
Serial.readline()
Чтение строки до \n
.
Serial.readlines()
Чтение всех строк в буфере.
Serial.read_all()
Полный буфер.
Serial.flush()
/ flushInput()
/ flushOutput()
Очистка буферов.
Управление соединением
Serial.open()
/ Serial.close()
Открытие/закрытие соединения.
Serial.isOpen()
Проверка, открыто ли соединение.
Serial.in_waiting
Сколько байтов ожидает чтения.
Serial.reset_input_buffer()
/ reset_output_buffer()
Очистка входящего/исходящего буфера.
Пример: обмен с Arduino
ser = serial.Serial('COM4', 9600, timeout=1)
ser.write(b'LED_ON\n')
response = ser.readline().decode('utf-8')
print(response)
ser.close()
Обработка ошибок
try:
ser = serial.Serial('COM1', 9600)
except serial.SerialException as e:
print(f"Ошибка: {e}")
Мониторинг портов
Список доступных портов
from serial.tools import list_ports
ports = list_ports.comports()
for port in ports:
print(port.device)
Работа в фоне (треды)
import threading
def reader():
while True:
if ser.in_waiting:
print(ser.readline().decode())
t = threading.Thread(target=reader)
t.start()
Тайминги и задержки
-
timeout
— глобальный таймаут чтения -
write_timeout
— таймаут записи -
inter_byte_timeout
— тайминг между байтами
Используйте задержки time.sleep()
между командами при необходимости.
PySerial и платформы
-
Windows:
COM1
,COM2
, и т.д. -
Linux:
/dev/ttyUSB0
,/dev/ttyS0
,/dev/ttyAMA0
-
macOS:
/dev/cu.usbserial
,/dev/tty.*
Интеграции и расширения
-
PyFirmata — для Arduino через Firmata
-
MQTT — сбор данных с устройств в облако
-
pandas + matplotlib — логирование и визуализация
Преимущества и ограничения
Плюсы:
-
Простота
-
Кроссплатформенность
-
Гибкая конфигурация
Минусы:
-
Синхронность (нет встроенного asyncio)
-
Требует знаний работы с COM
Полный список функций и свойств библиотеки pyserial
с описанием
1. serial.Serial(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, ...)
Создает и открывает последовательный порт.
Основные параметры:
-
port
: имя порта ('COM3'
,'/dev/ttyUSB0'
, и т.д.) -
baudrate
: скорость передачи (обычно 9600, 115200) -
bytesize
: размер байта (5, 6, 7, 8) -
parity
: проверка четности ('N'
,'E'
,'O'
) -
stopbits
: количество стоп-битов (1
,1.5
,2
) -
timeout
: таймаут в секундах (None
— бесконечное ожидание) -
xonxoff
,rtscts
,dsrdtr
: управление потоком
Пример:
2. ser.open()
Открывает порт (если он был создан с port=None
или предварительно закрыт).
3. ser.close()
Закрывает порт.
4. ser.is_open
Свойство: True
, если порт открыт.
5. ser.read(size=1)
Читает size
байт из порта. Блокирует выполнение до получения или истечения timeout
.
Пример:
6. ser.read_all()
Читает все доступные данные из буфера (до конца).
7. ser.read_until(expected=b'\n', size=None)
Читает до указанного символа окончания (по умолчанию до новой строки \n
).
8. ser.readline()
Читает строку (до \n
). Очень удобно для обмена с Arduino.
9. ser.readlines()
Читает все строки (аналогично readline()
, но до опустошения буфера).
10. ser.write(data)
Пишет байты в порт. Аргумент должен быть типа bytes
.
Пример:
11. ser.flush()
Форсирует запись буфера передачи (вывод данных немедленно).
12. ser.flushInput()
или ser.reset_input_buffer()
Очищает буфер входящих данных.
13. ser.flushOutput()
или ser.reset_output_buffer()
Очищает буфер исходящих данных.
14. ser.in_waiting
(или ser.inWaiting()
)
Количество байт, доступных в буфере для чтения.
15. ser.out_waiting
(или ser.outWaiting()
)
Количество байт, ожидающих отправки.
16. ser.timeout
Устанавливает или возвращает таймаут на операции чтения (в секундах).
17. ser.write_timeout
Таймаут на операцию записи.
18. ser.baudrate
Получение или установка скорости порта.
19. ser.port
Имя порта. Можно установить до открытия.
20. ser.bytesize
, ser.parity
, ser.stopbits
Настройки кадра: размер байта, контроль четности, количество стоп-битов.
21. ser.setDTR(state)
Устанавливает или сбрасывает сигнал DTR (Data Terminal Ready).
22. ser.setRTS(state)
Управляет сигналом RTS (Request To Send).
23. ser.getCTS()
Проверяет состояние входного сигнала CTS (Clear To Send).
24. ser.getDSR()
Состояние DSR (Data Set Ready).
25. ser.getRI()
Состояние сигнала RI (Ring Indicator, используется модемами).
26. ser.getCD()
(или ser.cd
)
Состояние сигнала CD (Carrier Detect).
27. serial.serial_for_url(url, ...)
Позволяет использовать URL вместо порта (например, loop://
, spy://
, rfc2217://
).
Полезно для отладки и тестов.
28. serial.tools.list_ports.comports()
Возвращает список доступных COM-портов.
Пример:
29. ser.inter_byte_timeout
Таймаут между байтами в потоке чтения. Используется для побайтного протокола.
30. ser.send_break(duration=0.25)
Отправляет break-сигнал (прерывистая линия) на указанное количество секунд.
31. ser.rts
, ser.dtr
Свойства: установить состояние сигналов RTS и DTR:
Пример простого обмена с Arduino
Заключение
PySerial — это ключевой инструмент для всех, кто работает с COM-портами в Python. Благодаря своей простоте, стабильности и гибкости, он применяется во всех сферах от DIY-проектов до промышленных решений. Он незаменим при работе с Arduino, контроллерами, сетевыми шлюзами, модемами и другими устройствами, использующими последовательную передачу данных.