Чтение данных из COM порта пока есть данные в порту

Всем добрый день. Имеется устройство с которого нужно получать данные. Данные устройство выдает только после отправки команды на него. Команду отправляем, в ответ получаем несколько строк (в зависимости от настроек устройства количество получаемых строк может меняться). После отправки команды из программы устройство выдает строки, программа их читает и зависает. Т.е. нет возможности дальше обработать полученные данные и нормально освободить COM-порт. Черновой вариант кода без обработки:

import serial.tools.list_ports
#
#ports = serial.tools.list_ports.comports()
#
#for port in ports:
#    print(port.device)

try:
    # Find and open the COM port
    ports = serial.tools.list_ports.comports()
    port = next((p.device for p in ports), None)
    print("Select port",port)
    if port is None:
        raise ValueError("No COM port found.")

    ser = serial.Serial(port, baudrate=19200)
    ser.flushInput()
    ser.flushOutput()
    serial_command=b"T LIST\r\n" #отправляем команду на получение данных
    ser.write(serial_command)
    data=""
    while str(data)!="": # Читаем данные их порта
        data=ser.readline()
        print(data)
    ser.flushInput()
    ser.flushOutput()

    # Perform operations on the COM port

    ser.close()  # Close the connection when done
    print("Finish!")

except ValueError as ve:
    print("Error:", str(ve))

except serial.SerialException as se:
    print("Serial port error:", str(se))

except Exception as e:
    print("An error occurred:", str(e))

В результате имеем поток:

b'T  014:18:15  0002  RANGE=1000.0 UGM\r\n'
b'T  014:18:15  0002  STABIL=0.0 UGM\r\n'
b'T  014:18:15  0002  PRES=30.5 IN-HG-A\r\n'
b'T  014:18:15  0002  SAMP FL=0 CC/M\r\n'
b'T  014:18:15  0002  PMT=13.7 MV\r\n'
b'T  014:18:15  0002  NORM PMT=16.0 MV\r\n'
b'T  014:18:15  0002  UV LAMP=3364.4 MV\r\n'
b'T  014:18:15  0002  LAMP RATIO=95.5 %\r\n'
b'T  014:18:15  0002  STR. LGT=22.1 UGM\r\n'
b'T  014:18:15  0002  DRK PMT=40.9 MV\r\n'
b'T  014:18:15  0002  DRK LMP=-1.1 MV\r\n'
b'T  014:18:15  0002  SLOPE=1.000\r\n'
b'T  014:18:15  0002  OFFSET=15.5 MV\r\n'
b'T  014:18:15  0002  HVPS=670 VOLTS\r\n'
b'T  014:18:15  0002  RCELL TEMP=50.0 C\r\n'
b'T  014:18:15  0002  BOX TEMP=31.6 C\r\n'
b'T  014:18:15  0002  PMT TEMP=8.2 C\r\n'
b'T  014:18:15  0002  TIME=18:15:13\r\n'

Если в строку serial.Serial(port, baudrate=19200) добавить timeout=1, программа начинает бесконечное чтение данных. Т.е. на выходе имеем:

b''
b''
...

Необходимо, чтобы после получения данных порт освобождался, и можно было обработать данные. Где затык - никак понять не могу.


Ответы (1 шт):

Автор решения: CrazyElf
    data=""
    while str(data)!="": # Читаем данные их порта
        data=ser.readline()
        print(data)

Поменяйте этот цикл на такой:

    while True:
        data = ser.readline()
        if not data:
            break
        print(data)

Когда таймаут сработает, readline вернёт пустой набор байт b'', проверка if not data: сработает и прервёт цикл.

Когда вы делаете str(data) вы превращаете пустой набор байт в строку "b''", естественно, эта строка не будет равняться пустой строке "". Пустые строки и коллекции принято проверять в Питоне через конструкцию if data: (не пустая data) или if not data: (пустая data).

→ Ссылка