可以写入RS232串口设备,但无法读取数据

4 投票
2 回答
3939 浏览
提问于 2025-04-18 01:12

我有一个rs232串口设备,想用python和pyVISA来读写它。我可以用“write”命令把指令发送给它,但如果我尝试用“read”或“ask”,就会出现超时错误。

我可以通过labview或tera term轻松地读写这个设备,但用python却无法读取。

下面是我无法正常工作的python代码:

import visa as v
si = v.SerialInstrument("COM1", delay = 0.1)
si.clear()
si.timeout = 3 
si.baud_rate = 9600 
si.data_bits = 8
si.stop_bits = 1

command = '0'
while command != 'end':
    rorw = raw_input('ask, read, or write? >>')
    command = raw_input('enter command code >>')
    if rorw == 'write':
        write1 = si.write(command)
        print write1
    elif rorw == 'read':
        read1 = si.read()
        print read1
    else:
        ask1 = si.ask(command)
        print ask

2 个回答

1

我猜你的问题可能和“终止字符”有关。你可以试着把终止字符设置为\n或者\r\n。如果这样还不行,使用pyserial进行串口通信其实很简单。你需要定义一个自定义的方法,类似于pysvisa的ask,可以使用write和readline来实现,可能还需要一个del方法来关闭端口,以防出现问题。祝你好运!

2

更新 - 2020年5月:六年后我又遇到了同样的问题。写这篇文章时,最新版本是PyVisa 1.10.1。这一点很重要,因为PyVisa 1.5在语法上有一些重大变化。不过,整体形式还是很相似的。


在串行通信中,发送每个命令时,确保发送正确的结束字符是非常重要的。设备制造商通常会指定期望的结束字符(或字符序列)。

最常见的结束字符有:

  • \rCR:回车
  • \nLF:换行
  • \r\nCRLF:上面两个的组合

PyVisa库在不同子类(比如SerialInstrument)使用的默认结束字符上有点模糊。如果你可以向设备发送数据,但无法读取数据,很可能是你定义的read_termination字符不正确。

下面是一个设置我设备的例子,它的结束字符是\r

import pyvisa

rm = pyvisa.ResourceManager()
device = rm.open_resource('ASRL3::INSTR', baud_rate = 57600)  # same as ‘COM3’ on Window$
device.write_termination = '\r'
device.read_termination = '\r'

上面的代码也可以写成一行:

device = rm.open_resource('ASRL3::INSTR', baud_rate = 57600,
                           write_termination = '\r',
                           read_termination = '\r')

如果出现不对称的通信问题(也就是说,你可以发送但无法读取),可能是你的结束字符根本不正确,而你的设备对这个问题的要求没有那么严格,反而是PyVisa比较挑剔。这是我最近遇到的问题,让我很困惑:

# I set up my instrument like so:
device = rm.open_resource('COM3', baud_rate = 57600,  write_termination = '\r\n', read_termination = '\r\n')

# '@021FF0' is just a command to set the outputs of my device
device.query('@021FF0')  #< threw a time-out error

device.write('@021FF0')  #< worked fine I could see the change in output,
device.read()            #< but trying to read back the response from the device
                         #< gave me a time-out error once again.

最后发现,期望的结束字符只是一个\r。虽然我的设备足够灵活(或者说有点傻,视角不同),可以简单地忽略多余的\n,但PyVisa却严格要求整个\r\n序列作为结束字符,而设备并没有提供这个序列。

read_termination = write_termination = '\r'设置为相同的值解决了这个问题。

撰写回答