Переопределение методов QSerialPort canReadLine() и readLine()

#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