Как создать последовательность байтов () длиной 1 - PullRequest
0 голосов
/ 23 января 2019

Я пишу приложение на Python 3, которое общается с устройством через последовательный порт, используя модуль pyserial.

При записи на устройство модуль pyserial ожидает, что данные будут представлены в виде последовательности байтов.

Это работает нормально, если я записываю все данные одновременно, но не получается, если я записываю данные побайтно, с задержкой после каждого байта. Причина, по которой я хочу писать побайтно, заключается в том, что мне приходится иметь дело с устройствами, которые могут обрабатывать данные только с низкой скоростью.

Код, который я использую:

def write_timed(self, data):
    """Write data to serial port,
    taking into account inter-character delay and line-delay

    :param data (str): string to write; any escaped characters will be converted
        e.g. \n will be output as a newline (not as characters '\' and 'n')
    """
    # convert raw string to sequence of bytes
    data = bytes(data.encode('latin-1').decode("unicode_escape"), "latin-1")
    logging.info("TX:{}".format(repr(data)))
    # only write to device if we have something to write
    if data:
        if data and self.char_delay_s == 0:
            self.serial.write(data)
        else:
            for d in data:
                self.serial.write(d)
                time.sleep(self.char_delay_s)
        time.sleep(self.line_delay_s)
        # ensure all data has gone out
        self.serial.flush()

Я получаю ошибку:

  File "C:\projects\maintenance\protocoltest\protocoltest\device\device.py", line 65, in write_timed
    self.serial.write(d)
  File "C:\projects\newplatform\venv3_pyside2\lib\site-packages\serial\serialwin32.py", line 301, in write
    data = to_bytes(data)
  File "C:\projects\newplatform\venv3_pyside2\lib\site-packages\serial\serialutil.py", line 61, in to_bytes
    for item in seq:
TypeError: 'int' object is not iterable

Причина ошибки состоит в том, что когда я выполняю for d in data:, переменная d становится int вместо последовательности байтов длиной 1.

Если я попытаюсь исправить это, используя d = bytes(d), я получу строку нулей, длину значения d.

Как я могу записать отдельные байты в pyserial?

Если я установлю self.char_delay_s на ноль, все работает нормально, даже строки длины 1. Если у меня ненулевое значение, вы получите ошибку выше.

1 Ответ

0 голосов
/ 23 января 2019

К сожалению, как вы обнаружили, когда вы индексируете объект bytes, вы получаете объект int.Самое простое, что нужно сделать, это просто привести int обратно к bytes:

for d in data:
    d = bytes([d])
    # d is now a bytes object and can be used as such

В качестве альтернативы, вы можете использовать слайсы вместо индексации:

for i in range(len(data)):
    d = data[i : i + 1]
    # d is a bytes object because it's a slice of a bytes object
...