Тайм-аут PySerial, загрузка процессора и сканирование штрих-кода - PullRequest
2 голосов
/ 16 марта 2019

Стоит отметить, что, хотя у меня есть опыт работы с CS, количество написанных мной скриптов Python, скорее всего, может быть подсчитано по количеству пальцев на лапе ленивца. Тем не менее, я начал играть с PySerial для чтения с USB-сканера штрих-кода. У меня одна проблема - тайм-аут. Если установить слишком низкое значение, я пропущу сканирование. Если я установлю его слишком высоко, загрузка процессора будет огромной. Конечно, это упоминается в документации для PySerial:

Будьте осторожны при использовании readline (). Укажите тайм-аут при открытии последовательный порт в противном случае он мог бы заблокировать навсегда, если нет новой строки персонаж получен. Также обратите внимание, что readlines () работает только с тайм-аут. readlines () зависит от времени ожидания и интерпретирует это как EOF (конец файла). Возникает исключение, если порт не открыт правильно.

правый. Итак, вот мой простой код:

#!/usr/bin/env python

import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True, timeout=0.05)
ser.baudrate = 115200

while True:
    s = ser.readline()
    if s:
        print(s)

Как правильно читать с последовательного устройства, не рискуя пропустить сканирование? Конечно, с таким небольшим временем ожидания шансы невероятно малы, но я хочу использовать это для производственных целей в моем бизнесе, поэтому давайте предположим, что это критически важно. Как правильно подойти к этой проблеме (опять же, при условии, что мое понимание Python равно нулю)?

Спасибо всем!

РЕДАКТИРОВАТЬ: Возможное решение?

Я придумал следующее, которое не использует тайм-аут и просто читает по одному символу за раз, пока не достигнет новой строки. Кажется, что это довольно легкий на загрузке процессора (который был целой проблемой, которую я имел). Конечно, мне нужно учитывать другие возможности новой строки с разных сканеров, но есть ли причина, по которой это не сработает?

#!/usr/bin/env python

import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True)
ser.baudrate = 115200

string = ""

while 1:
    char = ser.read(1)
    string += char
    if char == '\r':
        print(string)
        string = ""

1 Ответ

1 голос
/ 16 марта 2019

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

ser = serial.Serial('/dev/ttyUSBx',timeout=y)
ser.write('<trigger scan>')
value = ser.readline()
ser.close()

ДляНепрерывное чтение, лучший способ сделать это - сохранить чтение байтов в цикле тайм-аута, например

time_start = datetime.datetime.now()
time_end = time_start + datetime.timedelta(seconds=timeout)

output = []
while datetime.datetime.now() < time_end:
        output.append(ser.read(100))

...