driver/pyvisa: extend Test and Measurement equipment support#1835
driver/pyvisa: extend Test and Measurement equipment support#1835Sabolik wants to merge 13 commits intolabgrid-project:masterfrom
Conversation
Emantor
left a comment
There was a problem hiding this comment.
remote: client: add remote pyvisa access needs a commit message explaining why the change is done.
I wonder if the current backend() calling mechanic can't be simplified to be more explicit instead of inspecting the imported module backend and calling functions on it again. It looks like we are cramming a lot of calls through the backend() function, while we have the explicit module with function definitions for each instrument. Why not call the functions on the module directly?
| def query(self, cmd): | ||
| return self.proxy.query(self.device_identifier, self.pyvisa_resource.backend, cmd) | ||
| def query(self, cmd, timeout=TIMEOUT_DEFAULT): | ||
| return self.proxy.query(self.device_identifier, self.pyvisa_resource.backend, cmd, timeout).rstrip() |
There was a problem hiding this comment.
This rstrip() is added here, can you add a description to the commit why it was added?
There was a problem hiding this comment.
The termination might differ among instruments. Another option might be to properly set the read_termination parameter of the resource, but I would rather keep rstrip for simplicity.
| from ..util.agentwrapper import AgentWrapper | ||
| from .common import Driver | ||
|
|
||
| TIMEOUT_DEFAULT = 2000 # Default timeout for visa operations in ms |
There was a problem hiding this comment.
I think I prefer having the default in the keyword arguments i.e. def command(self, cmd, timeout=2000) and we also want a docstring which documents this to be in miliseconds.
| Args: | ||
| type (str): device resource type following the pyVISA resource syntax, e.g. ASRL, TCPIP... | ||
| url (str): device identifier on selected resource, e.g. <ip> for TCPIP resource | ||
| url (str, default=''): optional device identifier on selected resource, e.g. <ip> for TCPIP resource |
There was a problem hiding this comment.
Why can the default be changed to an empty string here? Is this not mandatory?
There was a problem hiding this comment.
No, it is optional. Some interfaces are fully specified by the type parameter, e.g. serial devices like ASRL/dev/ttyACM0.
|
|
||
| type = attr.ib(validator=attr.validators.instance_of(str)) | ||
| url = attr.ib(default="", validator=attr.validators.instance_of(str)) | ||
| resource = attr.ib(default="INSTR", validator=attr.validators.instance_of(str)) |
There was a problem hiding this comment.
If there is a finite amount of resource type definitions we might want to extend the validator, but this can be added later.
There was a problem hiding this comment.
It seems to be fixed based on the VISA documantation, but honestly I am not familiar with all of them, so I am not sure what are the consequences. But the most common are INSTR and SOCKET and RAW, might be good idea to create a validator for them.
10cc6cf to
fdda33e
Compare
|
@Emantor thanks a lot for review, all comments should be fixed now. Regarding
|
|
@Sabolik thanks for doing this work. Do you have some example device names you've tested this with? I have an SDG1032X waveform generator which supports VISA that I may try it out on. |
it should be pretty generic from the SCPI commanding point of view. There might be (optionally) backend implemented as SCPI convenient commands wrapper. Few equipment are already supported, listed here. Let me give you few possible ways how to access the equipment (USB rigol DM3068 as example):
Usage example: ## bind target to driver directly in code
from labgrid.resource.pyvisa import PyVISADevice
from labgrid.driver.tminstrument import TMInstrument
from labgrid import Target
t = Target('example')
# equipment connected via USB
PyVISADevice(t, name=None, type='USB0', url='6833::3220::DM3O224500792::0', backend='@py')
# using low-level pvisa driver
from labgrid.driver.pyvisadriver import PyVISADriver
visa_driver = PyVISADriver(t, name="tm-inst-visa-rigol-dmm")
t.activate(visa_driver)
visa_driver.identify()
# equivalent to
visa_driver.query('*IDN?')
# or using of high level driver (TMInstrument) with VISA backend (Reomended way)
from labgrid.driver.tminstrument import TMInstrument
tm_inst_driver = TMInstrument(t, name="tm-inst-visa-rigol-dmm")
t.activate(tm_inst_driver)
tm_inst_driver.identify()
# equivalent to
tm_inst_driver.query('*IDN?')
Config (config_visa.yaml): targets:
main:
resources:
- PyVISADevice:
name: dmm-rigol
type: "USB0"
url: "6833::3220::DM3O224500792::0"
backend: "@py"
drivers:
- PyVISADriver:
name: driver-visa-rigol-dmm
bindings: { pyvisa_resource : 'dmm-rigol'}
- TMInstrument:
bindings: { inst : 'driver-visa-rigol-dmm' }
name: 'tm-inst-visa-rigol-dmm'Usage example: ## bind target to driver using config file
from labgrid import Environment
env = Environment('config_visa.yaml')
targets=env.get_target()
inst_visa_rigol_psu = targets.get_driver(TMInstrument, name="tm-inst-visa-rigol-dmm")
inst_visa_rigol_psu.identify()
# equivalent to
inst_visa_rigol_psu.query('*IDN?')You may control the device also remotely using |
|
@threexc Did you find some time to test this? |
I've been looking at it. I was able to do a basic test on my side with my SDG1032X and confirm it can communicate: This is with the following exporter config for the device: and a client config like: Seems reasonable enough to me. My only major issue with this PR is that there are examples in the commits but not really any updates to the docs? It would be good to have decent examples of the exporter and client configs, along with example commands to run (the ones in some of the commit messages that I've been pointed at are probably enough). @Sabolik, can you add another commit to reflect that? |
| assert isinstance(cmd, str) | ||
| cmd = b2s(cmd.encode("ASCII") + b"\n") | ||
| res = s2b(self.wrapper.usbtmc(self.index, cmd, read=True)) | ||
| res = s2b(self.wrapper.usbtmc(self.dev_index, cmd, read=True)) |
There was a problem hiding this comment.
is any change in this file really needed?
There was a problem hiding this comment.
It seems to be needed. The reason is that the same attribute is used by power resource as power port identification. Power resource is directly supported by tminstrument driver while conflicting with low-level usbtmc driver (usbtmc device identification)
There was a problem hiding this comment.
actually not needed. There was conflict between power driver implementation using USBTMC resource used locally in past in our lab, but this is not part of this PR.
Signed-off-by: Hermann Leinweber <hermann.leinweber@erweka.com>
The agent supports remote access to instruments connected locally, e.g. via USB or a serial port. The pyVISA library also supports USBTMC devices; therefore, the dedicated USBTMC driver can be replaced by pyVISA. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Introduce NetworkPyVISADevice for remote access to pyVISA resources. Use an agent wrapper to support both local and remote resource access. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
It has been replaced by visa_instrument.py agent. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Allow users to configure the timeout for resource I/O operations while keeping the original 2-second default. Remove possible termination characters. This might differ among various instruments/manufacturers. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Supports VISA resource types, see https://www.ni.com/docs/en-US/bundle/ni-visa/page/visa-resource-types.html?srsltid=AfmBOopVXVhQ0TRR_zFesL1Bj90aKB7_MFSa3nbKvgZ47RRAbv-WIlAE Defaults to INSTR resource type. If a raw socket is used (e.g., TCPIP::IPaddress::Port::SOCKET), set the termination character. Always clear the resource after it is opened. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Provides a common interface for SCPI-compatible instruments. The instrument can be controlled using different low-level drivers, such as PyVISA, USBTMC, or custom backends. An appropriate command backend can be mapped within the driver for convenient instrument control. PowerProtocol is supported. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Add a method to the tminstrument driver for querying iterables, such as lists of readings. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Add tminstrument driver access using a remote labgrid client.
Following functions are available:
- command: send a command to the instrument
- query: send a command and read the response from the instrument
- query_iterable: send a command and read the response from the instrument as a list of floats
usage example:
$ labgrid-client -c config_remote.yaml inst identify --name "tm-inst-visa-rigol-psu_ch2"
with "tm-inst-visa-rigol-psu_ch2" driver configured in config_remote.yaml (expected ps-rigol resource exported):
targets:
main:
resources:
RemotePlace:
name: !template 'MyPlace'
drivers:
- PyVISADriver:
name: driver-visa-rigol-psu_ch2
bindings: { pyvisa_resource : 'ps-rigol'}
- TMInstrument:
bindings: { inst : 'driver-visa-rigol-psu_ch2' }
name: 'tm-inst-visa-rigol-psu_ch2'
Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
Add convenient functionality for: - Rigol Technologies DP832, 3-channel laboratory power supply - Siglent Technologies SDM3065X-SC laboratory DMM - RND 320-KD3305P, 3-channel laboratory power supply - ITECH Electronics IT-M3632, power supply and regenerative DC load Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
1a4bb48 to
1d8be29
Compare
apply suggestion from @gastmaier: - use find_spec from importlib to check for module availability. - remove un-necessary try-catch block Co-authored-by: Jorge Marques <2892061+gastmaier@users.noreply.github.com> Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
- update pyvisadriver part - add: - tminstrument driver - tminstrumentpower driver - networkpyvisa resource - extend pyvisa resource usage Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
It shows how to use more then pne instrument. Here as example two USBTMC instrumnets, multimeter / power supply. Signed-off-by: Martin Sabol <martin.sabol@seznam.cz>
|
Description
Main purpose:
The implementation was tested only by using it with devices on our lab environment, both locally and remotely for following interfaces:
Checklist