pyvisa / pyvisa-sim

A PyVISA backend that simulates a large part of the "Virtual Instrument Software Architecture" (VISA_)
https://pyvisa-sim.readthedocs.io/en/latest/
MIT License
67 stars 39 forks source link

Communication fails for simulated GPIB/USB/TCPIP devices #40

Open StefanD986 opened 7 years ago

StefanD986 commented 7 years ago

I am trying to communicate to the simulated devices that the pyvisa-sim backend provides. However only if I talk to the device over the (simulated) serial it works. All other interfaces result in a timeout error. I am using the default.yaml configuration for the pyvisa backend.

Below example code with which I tested it:

import visa

rm = visa.ResourceManager('@sim')

device1_serial = rm.open_resource('ASRL1::INSTR')
device1_gpib = rm.open_resource('GPIB0::8::65535::INSTR')
device1_usb = rm.open_resource('USB0::0x1111::0x2222::0x1234::0::INSTR')
device1_tcp = rm.open_resource('TCPIP0::localhost::inst0::INSTR')

device1_serial.query('?IDN') # this works, returns 'LSG Serial #1234\n'
device1_gpib.query('?IDN') # this raises a 'VI_ERROR_TMO' error
device1_tcp.query('?IDN') # this raises a 'VI_ERROR_TMO' error
device1_usb.query('?IDN') # this raises a 'VI_ERROR_TMO' error

gist of the error: https://gist.github.com/StefanD986/830ede22e5a2bad067862874eaef777e

vicyap commented 7 years ago

This might be too late, but I figured something out that might work for you. I had to make two changes.

  1. It seems that the visa attribute VI_ATTR_TERMCHAR_EN is false by default (https://github.com/hgrecco/pyvisa/blob/master/pyvisa/attributes.py#L2532). There's an exception case for serial that ignores this attribute, which is why serial works.
  2. change q: "\n" to q:"\r\n" under the eom: directive

To fix 1, I did device1.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, visa.constants.VI_TRUE) before each respective device query and it worked.

eg.

import visa

rm = visa.ResourceManager('@sim')

device1_serial = rm.open_resource('ASRL1::INSTR')
device1_gpib = rm.open_resource('GPIB0::8::65535::INSTR')
device1_usb = rm.open_resource('USB0::0x1111::0x2222::0x1234::0::INSTR')
device1_tcp = rm.open_resource('TCPIP0::localhost::inst0::INSTR')

device1_serial.query('?IDN') # this works, returns 'LSG Serial #1234\n'
device1_gpib.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, visa.constants.VI_TRUE)
device1_gpib.query('?IDN') # this raises a 'VI_ERROR_TMO' error
device1_tcp.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, visa.constants.VI_TRUE)
device1_tcp.query('?IDN') # this raises a 'VI_ERROR_TMO' error
device1_usb.set_visa_attribute(visa.constants.VI_ATTR_TERMCHAR_EN, visa.constants.VI_TRUE)
device1_usb.query('?IDN') # this raises a 'VI_ERROR_TMO' error

To fix 2, here's an example

devices:
  device 1:
    eom:
      ASRL INSTR:
        q: "\r\n"
        r: "\n"
      USB INSTR:
        q: "\r\n"
        r: "\n"
      TCPIP INSTR:
        q: "\r\n"
        r: "\n"
      TCPIP SOCKET:
        q: "\r\n"
        r: "\n"
      GPIB INSTR:
        q: "\r\n"
        r: "\n"
rjollos commented 5 years ago

To fix 2, here's an example

Or you can just change the termchar when talking to USB, TCPIP or GPIB, as default.yaml configures them with LF on q and r:

$ pyvisa-shell -b sim

Welcome to the VISA shell. Type help or ? to list commands.

(visa) list
( 0) ASRL1::INSTR
( 1) USB0::0x1111::0x2222::0x1234::0::INSTR
( 2) TCPIP0::localhost::inst0::INSTR
( 3) GPIB0::8::0::INSTR
( 4) ASRL2::INSTR
( 5) USB0::0x1111::0x2222::0x2468::0::INSTR
( 6) TCPIP0::localhost:2222::inst0::INSTR
( 7) GPIB0::9::0::INSTR
( 8) ASRL3::INSTR
( 9) USB0::0x1111::0x2222::0x3692::0::INSTR
(10) TCPIP0::localhost:3333::inst0::INSTR
(11) GPIB0::10::0::INSTR
(12) ASRL4::INSTR
(13) USB0::0x1111::0x2222::0x4444::0::INSTR
(14) TCPIP0::localhost:4444::inst0::INSTR
(15) GPIB0::4::0::INSTR
(visa) open 0
ASRL1::INSTR has been opened.
You can talk to the device using "write", "read" or "query".
The default end of message is added to each message.
(open) query ?IDN
Response: LSG Serial #1234

(open) close
The resource has been closed.
(visa) open 1
USB0::0x1111::0x2222::0x1234::0::INSTR has been opened.
You can talk to the device using "write", "read" or "query".
The default end of message is added to each message.
(open) query ?IDN
VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.
(open) termchar
Termchar read: None write: CRLF
(open) termchar LF LF
Done
(open) query ?IDN
Response: LSG Serial #1234
(open) close
The resource has been closed.
urscion commented 5 years ago

I also found that setting the open_resource arguments to match the device eom in default.yaml to work:

rm.open_resource('TCPIP0::localhost:2222::inst0::INSTR',
                              write_termination='\n',
                              read_termination='\n')
bilderbuchi commented 3 years ago

I am encountering the same issue. In my tests the set_visa_attribute call recommended above is still necessary to fix this. I'm a bit unclear - is this something that should be reported upstream to pyvisa?

davidtrem commented 2 years ago

I encounter similar issue...

A minimal code to reproduce and illustrate:

import pyvisa
resource_manager = pyvisa.ResourceManager("mock.yaml@sim")
asrl_instr = resource_manager.open_resource("ASRL0::INSTR")
asrl_instr.query('?IDN')
# Returns expected reply: 'ASRL DEVICE\n'

tcpip_instr = resource_manager.open_resource("TCPIP0::localhost::inst0::INSTR")
tcpip_instr.query('?IDN')
# Returns: VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed.

mock.yaml file:

spec: "1.0"
devices:
  asrl_dev:
    eom:
      ASRL INSTR:
        q: "\r\n"
        r: "\n"
    error: ERROR
    dialogues:
      - q: "?IDN"
        r: "ASRL DEVICE"
  tcpip_dev:
    eom:
      TCPIP INSTR:
        q: "\n"
        r: "\n"
    error: ERROR
    dialogues:
      - q: "?IDN"
        r: "TCPIP DEVICE"
resources:
  ASRL0::INSTR:
    device: asrl_dev
  TCPIP0::localhost::inst0::INSTR:
    device: tcpip_dev