#methods #pyqt #serial-port #pyserial #qtserialport
Вопрос:
Я пытаюсь получать необработанные байты в пользовательском формате через QSerialPort, используя значение 0 в качестве разделителя в асинхронном режиме (используя сигналы вместо опроса).
Неудобство заключается в том, что QSerialPort, похоже, не имеет метода, который может считывать последовательные данные до тех пор, пока не будет найдено указанное значение байта, например, read_until (значение разделителя) в pyserial.
Мне было интересно, можно ли переопределить функцию readLine() QSerialPort в Python, чтобы она считывала до тех пор, пока не будет найдено значение 0 байт вместо «n». Аналогично, было бы удобно также переопределить функцию canReadLine ().
Я знаю, что можно использовать метод ReadAll (), а затем проанализировать данные для значения разделителя. Но такой подход, скорее всего, подразумевает больше кода и снижение эффективности. Я хотел бы иметь как можно меньшие накладные расходы при обработке кадров (скорость передачи последовательных данных в бодах и количество входящих байтов большие). Однако, если вы знаете быстрый подход к этому, я хотел бы взглянуть.
Ответ №1:
Я закончил разбором кадра, похоже, он работает достаточно хорошо. Ниже приведен метод извлечения из моего скрипта, который асинхронно получает и анализирует последовательные данные. self.serial_buffer-это массив QByteArray, инициализированный внутри пользовательского метода инициализации класса. Вы также можете использовать глобально объявленный bytearray, но вам придется проверить значение разделителя другим способом.
@pyqtSlot()
def receive(self):
self.serial_buffer = self.serial.readAll() # Read all data from serial buffer
start_pos, del_pos = 0, 0
while True:
del_pos = self.serial_buffer.indexOf(b'x00', start_pos) # b'x00' is delimiter byte
if del_pos == -1: break # del_pos is -1 if b'x00' is not found
frame = self.serial_buffer[start_pos: del_pos] # Copy data until delimiter
start_pos = del_pos 1 # Exclude old delimiter from your search
self.serial_buffer = self.serial_buffer[start_pos:] # Copy remaining data excluding frame
self.process_frame(frame) # Process frame