PyQt Принятая по serialport строка разбивается на три
Пишу простое приложение для работы с SerialPort. В Qt Desinger сделал окошко для выбора порта и коннекта, принятые данные пишутся в терминал VScode. Использую для проверки "Virtual Serial Ports Emulator". При коннекте между собой двух терминалов "Terminal v1.9b" данные отправляются корректно, если использую "Terminal v1.9b" в связке со своей программой то принятые данные с терминала бьются на три строки каждый раз разной длинны. При использовании терминала "Termite" данные/строка принимаются моей программой корректно. Также пробовал принимать данные с микроконтроллера через uart с него поступает строчка (массив) такого вида: "uf000F000t" без возврата каретки и начала новой строки, в Тerminal v1.9b данные как и задумывалось принимаются одной длинной строкой (uf000F000tuf000F000tuf000F000tuf000F000t и т.д.), а в моей программе каждый символ с новой строки. Собственно вопрос почему строка бьется на три, а при отправке с микроконтроллера каждый символ с новой строки?
Код:
from PyQt5 import QtWidgets, uic
from threading import *
from PyQt5.QtSerialPort import QSerialPort, QSerialPortInfo
from PyQt5.QtCore import QIODevice
app = QtWidgets.QApplication([])
ui = uic.loadUi("MainWindow.ui")
ui.closePortBut.setEnabled(False)
serial = QSerialPort()
serial.setBaudRate(9600)
# обновить список портов
def updateList():
portList = []
ports = QSerialPortInfo().availablePorts()
for port in ports: portList.append(port.portName())
ui.comBox.clear()
ui.comBox.addItems(portList)
# open serial port
def onOpen():
serial.setPortName(ui.comBox.currentText())
serial.open(QIODevice.ReadWrite)
if serial.OpenMode:
print("openPort")
ui.openPortBut.setEnabled(False)
ui.closePortBut.setEnabled(True)
# закрыть порт
def onClose():
serial.close()
print("closePort")
ui.openPortBut.setEnabled(True)
ui.closePortBut.setEnabled(False)
# прочитать порт
def onRead():
rx = serial.readLine()
rxStrnig = str(rx, "utf-8")
print(rxStrnig)
serial.readyRead.connect(onRead)
ui.openPortBut.clicked.connect(onOpen)
ui.closePortBut.clicked.connect(onClose)
updateList()
ui.show()
app.exec()
Ответы (1 шт):
Все просто - в многозадачной ОС (не важно какой), данные буферизуются - то что программа пишет в порт, сначала поступает в буфер ввода - вывода, а потом драйвер последовательного порта потихоньку отсылает это на устройство.
Верно и обратное - то что присылает устройство, драйвер складывает в буфер, после чего буфер сбрасывается в приложение.
Наличие буфера обусловлено, в частности, наличием многозадачности - приложение, передающее данные, в данный момент может быть вытеснено планировщиком CPU, а данные куда-то девать надо.
Аналогично работают сетевые протоколы, например, TCP.
Чтобы ваше приложение работало корректно, вам нужен свой протокол обмена данными, работающий через UART.
В частности, вам нужно:
Правильно синхронизировать устройство и компьютер, потому что может случиться так, что устройство работало-работало, и тут его подключили к ПК - и вы начали получать сообщения с середины.
Обеспечить обозначение начала и конца сообщения.
Обе данные задачи решаются при помощи, например, использования маркера конца сообщения - например, последовательности байт 0x0D0A ("\r\n"). Понятно, что внутри сообщения эти байты вам придется либо экранировать (например "\\r\\n", либо никогда не использовать.