可以写入RS232串口设备,但无法读取数据
我有一个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 个回答
我猜你的问题可能和“终止字符”有关。你可以试着把终止字符设置为\n或者\r\n。如果这样还不行,使用pyserial进行串口通信其实很简单。你需要定义一个自定义的方法,类似于pysvisa的ask,可以使用write和readline来实现,可能还需要一个del方法来关闭端口,以防出现问题。祝你好运!
更新 - 2020年5月:六年后我又遇到了同样的问题。写这篇文章时,最新版本是PyVisa 1.10.1
。这一点很重要,因为PyVisa 1.5
在语法上有一些重大变化。不过,整体形式还是很相似的。
在串行通信中,发送每个命令时,确保发送正确的结束字符是非常重要的。设备制造商通常会指定期望的结束字符(或字符序列)。
最常见的结束字符有:
\r
或CR
:回车\n
或LF
:换行\r\n
或CRLF
:上面两个的组合
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'
设置为相同的值解决了这个问题。