从COM端口读取到python中的文本文件

时间:2021-06-07 20:29:40

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.

我有一个保存在文本文件('command.log')中的命令列表,我想对连接到'COM5'的单元运行,并将每个命令的响应保存在文本文件('output.log')中。脚本卡在第一个命令上,我可以让它运行剩余的命令。任何帮助将不胜感激。

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()

1 个解决方案

#1


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.

首先,你是在滥用serial.readline函数:它返回一个bytes对象,你就像是一个str对象,通过执行+ = ser.readline():将引发一个TypeError。相反,你必须写出+ = str(ser.readline(),'utf-8'),它首先将字节转换为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('\>'.

现在,问题在于out!='/>'条件:我想你想测试设备发送的消息是否完成,这条消息以'/ <'结尾。但是,在while循环中,你输出+ = [...],所以在消息的最后,out就像' />',这与'/>'完全不同。但是,你很幸运:有str.endswith功能!所以,你必须在out!='\>'之前替换,而不是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.

此外,在循环中,您可以在每个回合中编写整个消息(如果尚未结束)。这将在output.log中为您提供类似<< me />的内容。相反,我认为你只想打印收到的字符。这可以使用临时变量来实现。


Another issue

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

并且,您正在使用serial.readline函数:相应于docstrings,

The line terminator is always b'\n'

行终止符总是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.

它与您的代码不兼容:您希望您的外出以“\>”结束,而您必须仅使用serial.read,它将返回所有收到的字符。


Haaaa... the end ! \o/

Finally, your while loop will look as follows:

最后,您的while循环将如下所示:

# 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()

#1


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.

首先,你是在滥用serial.readline函数:它返回一个bytes对象,你就像是一个str对象,通过执行+ = ser.readline():将引发一个TypeError。相反,你必须写出+ = str(ser.readline(),'utf-8'),它首先将字节转换为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('\>'.

现在,问题在于out!='/>'条件:我想你想测试设备发送的消息是否完成,这条消息以'/ <'结尾。但是,在while循环中,你输出+ = [...],所以在消息的最后,out就像' />',这与'/>'完全不同。但是,你很幸运:有str.endswith功能!所以,你必须在out!='\>'之前替换,而不是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.

此外,在循环中,您可以在每个回合中编写整个消息(如果尚未结束)。这将在output.log中为您提供类似<< me />的内容。相反,我认为你只想打印收到的字符。这可以使用临时变量来实现。


Another issue

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

并且,您正在使用serial.readline函数:相应于docstrings,

The line terminator is always b'\n'

行终止符总是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.

它与您的代码不兼容:您希望您的外出以“\>”结束,而您必须仅使用serial.read,它将返回所有收到的字符。


Haaaa... the end ! \o/

Finally, your while loop will look as follows:

最后,您的while循环将如下所示:

# 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()