COM Port in python: how to wait for data without loading the CPU

There is a program that accepts data from the COM port. There is a problem, how to make the program wait for data and not run further?

When using an infinite while loop, the program loads the CPU up to 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
Author: MSDN.WhiteKnight, 2016-10-26

4 answers

You have a port configured for non-blocking reading, since timeout=0 is set, either remove this option, or write timeout=None, then the port will wait for the data until it appears.

If you still need a non-blocking connection, then you need to add a small delay to the while loop, then the CPU load will go away.

 3
Author: Avernial, 2016-10-26 02:59:19

There is still such a construction:

    while True:
        while ser.inWaiting() == 0:
            pass
        #необходимая работа с данными...

It checks for the presence of data in the port queue. This way of waiting, the CPU does not load at all.

 0
Author: Andrey Gasparyan, 2016-12-04 08:53:26

So it is clearer

        while ser.inWaiting():
             data = ser.read()

While there is no data in the port, the read is not performed

 0
Author: VitOk, 2017-12-07 09:34:41

Let's say

def recCode(data):#  и поехали проверять по условиям - например
    if data == (b'\x05sRR\r\n')
        print(u'я получил сообщение ')


while True:
    while ser.inWaiting() > 0:# даже если мы поставим без условия
    data = ser.readline()
    recCode(data)

With this construction of the algorithm while True will be executed constantly and recCode(data) will be called when each character (byte) is received in the port, and if 1 the number of bytes in the packet is not known(work on the start and end character) or 2 it is still necessary to maintain the graphical interface and in addition 3 send data (messages ) to the port, then some characters (received ) may be lost, and the program (regardless of how many cores the processor has ) will be occupied only with this , and if you need to service 2 ports ?

In assembler(avr controllers), in VB6 (x86 and 64), it is possible to use hardware interrupts, i.e. an event (receiving a symbol by a port ) can (if the hardware node of the controller or machine is properly configured), stop execution (or redirect the command flow) of the main program body, execute a subroutine (interrupt) of receiving a single character with the possibility of forming a string by starting and ending characters (\х05 and \r\n) and after receiving process the final character directly in the subroutine (if there are few conditions ) - by changing the variables or, setting the flag for the readiness of the received message for the main program, or by changing the global variable for other processes.

Then while True can (for example) check the message readiness flags of one , the second, and the nth port , update the processes of the graphical shell of the type root=Tk () ..(graphical elements ) , and use root. update in the place of root.vfinloop() (), tc as graphical management interfaces are rather slow processes

 0
Author: Анатолий, 2018-06-16 10:54:10