David Odebade
David Odebade

Reputation: 11

Reading from COM port into a text file in python

I have a list of commands saved in text file ('command.log') which I want to run against a unit connected to 'COM5' and save the response for each command in a text file ('output.log'). The script gets stuck on the first command and I could get it to run the remaining commands. Any help will be appreciated.

import serial

def cu():
    ser = serial.Serial(
    port='COM5',
    timeout=None,
    baudrate=115200,
    parity='N',
    stopbits=1,
    bytesize=8
        ) 
    ser.flushInput()
    ser.flushOutput()
##    ser.write('/sl/app_config/status \r \n') #sample command
    fw = open('output.log','w')
    with open('data\command.log') as f:
        for line in f:
            ser.write(line + '\r\n')
            out = ''
            while out != '/>':
                out += ser.readline()
                fw.write(out)
                print(out)
    fw.close()
    ser.close()
    print "Finished ... "
cu()

Upvotes: 1

Views: 4214

Answers (1)

Spirine
Spirine

Reputation: 1877

The bytes problem

First of all, you're misusing the serial.readline function: it returns a bytes object, and you act like it was a str object, by doing out += ser.readline(): a TypeError will be raised. Instead, you must write out += str(ser.readline(), 'utf-8'), which first converts the bytes into a str.


How to check when the transmission is ended ?

Now, the problem lays in the out != '/>' condition: I think you want to test if the message sent by the device is finished, and this message ends with '/<'. But, in the while loop, you do out += [...], so in the end of the message, out is like '<here the message>/>', which is totally different from '/>'. However, you're lucky: there is the str.endswith function! So, you must replace while out != '\>' by while not out.endswith('\>'.


WWhatWhat'sWhat's theWhat's the f*** ?

Also, in your loop, you write the whole message, if it's not already ended, in each turn. This will give you, in output.log, something like <<me<mess<messag<messag<message>/>. Instead, I think you want to print only the received characters. This can be achieved using a temporary variable.


Another issue

And, you're using the serial.readline function: accordingly to the docstrings,

The line terminator is always b'\n'

It's not compatible with you're code: you want your out to finish with "\>", instead, you must use only serial.read, which returns all the received characters.


Haaaa... the end ! \o/

Finally, your while loop will look as follows:

# Check if the message is already finished
while not out.endswith('/>'):
    # Save the last received characters
    # A `bytes` object is encoded in 'utf-8'
    received_chars = str(ser.read(), 'utf-8')

    # Add them to `out`
    out += received_chars

    # Log them
    fw.write(received_chars)

    # Print them, without ending with a new line, more "user-friendly"
    print(received_chars, end='')

# Finally, print a new line for clarity
print()

Upvotes: 2

Related Questions