#python #serial #com_порт
Есть программа, которая принимает данные из COM порта. Возникла проблема, как заставить программу ждать данные и не выполняться дальше? При использовании бесконечного цикла while, программа нагружает ЦП до 50%. forchar = 0 idcom = [] ser = serial.Serial( port = 'COM2',\ baudrate=2400,\ parity=serial.PARITY_NONE,\ stopbits=serial.STOPBITS_ONE,\ bytesize=serial.EIGHTBITS,\ timeout=0) print("connected to: " + ser.portstr) count=1 while True: for line in ser.readline(): forchar = forchar + 1 idcom.append(line) if forchar >= 13: break
Ответы
Ответ 1
У вас порт настроен на неблокирующее чтение, так как установлен timeout=0, Либо уберите эту опцию, либо напишите timeout=None, тогда порт у вас будет ждать данные, до тех пор пока они не появятся. Если же вам все таки нужно неблокирующее соединение, то в цикл while надо добавить небольшую задержку time.sleep, тогда нагрузка процессора уйдет.Ответ 2
Еще есть такая конструкция: while True: while ser.inWaiting() == 0: pass #необходимая работа с данными... Тут выполняется проверка на наличие данных в очереди порта. Такой способ ожидания, ЦП не нагружает совсем.Ответ 3
Так понятнее while ser.inWaiting(): data = ser.read() пока в порте нет данных чтение не выполняетсаОтвет 4
допустим def recCode(data):# и поехали проверять по условиям - например if data == (b'\x05sRR\r\n') print(u'я получил сообщение ') while True: while ser.inWaiting() > 0:# даже если мы поставим без условия data = ser.readline() recCode(data) при таком построении алгоритма while True будет выполнятся постоянно и recCode(data) будет вызываться при приёме каждого символа (байта) в порт, а если 1 количество байтов в пакете не известно(работа по стартовому и конечному символу) или 2 надо ещё обслуживать графический интерфейс и в добавок 3 отправлять данные (сообщения ) в порт , то некоторые символы (принимаемые ) могут потеряться , да и программа (не зависимо сколько ядер у процессора ) будет занята только этим , а если надо 2 порта обслуживать ? в ассемблере (avr контроллеры), в VB6(x86 и 64), есть возможность применения аппаратных прерываний , т е событие (приём символа портом ) может (при правильной настройке аппаратного узла контроллера или машины), остановить выполнение (или перенаправить поток команд) основного тела программы , выполнить подпрограмму (прерывание) приёма одного символа с возможностью формирования строки по стартовым и конечным символам (\х05 и \r\n) и после приёма конечного символа непосредственно в подпрограмме (если условий мало ) обработать - изменив переменные или, выставить флаг готовности принятого сообщения для основной программы , или изменив глобальную переменную для других процессов. тогда while True может заниматься (допустим ) проверкой флагов готовности сообщения одного , второго , н-ого порта , обновлением процессов графической оболочки типа root=Tk() ..(графические элементы ) , и в место root.vfinloop() использовать root.update(), тк как графические интерфейсы управления достаточно медленные процессы
Комментариев нет:
Отправить комментарий