diff --git a/instrumental/driver_info.py b/instrumental/driver_info.py index d04e5d31..6f1b307f 100644 --- a/instrumental/driver_info.py +++ b/instrumental/driver_info.py @@ -1,4 +1,4 @@ -# Auto-generated 2019-05-06T16:23:11.970004 +# Auto-generated 2019-09-19T15:55:57.247343 from collections import OrderedDict driver_info = OrderedDict([ @@ -35,9 +35,9 @@ ('funcgenerators.rigol', { 'params': ['visa_address'], 'classes': [], - 'imports': [], + 'imports': ['visa'], 'visa_info': { - 'DG800': ('Rigol Technologies', ['DG812']), + 'DG800': ('Rigol Technologies', ['DG811', 'DG812']), }, }), ('funcgenerators.tektronix', { @@ -131,6 +131,14 @@ 'GPD_3303S': ('GW INSTEK', ['GPD-3303S']), }, }), + ('powersupplies.rigol', { + 'params': ['visa_address'], + 'classes': [], + 'imports': ['pyvisa', 'visa'], + 'visa_info': { + 'DP700': ('RIGOL TECHNOLOGIES', ['DP711', 'DP712']), + }, + }), ('scopes.agilent', { 'params': ['visa_address'], 'classes': ['DSO_1000'], @@ -139,6 +147,14 @@ 'DSO_1000': ('Agilent Technologies', ['DSO1024A']), }, }), + ('scopes.rigol', { + 'params': ['visa_address'], + 'classes': [], + 'imports': ['pyvisa', 'visa'], + 'visa_info': { + 'DS1000Z': ('RIGOL TECHNOLOGIES', ['DS1054Z']), + }, + }), ('scopes.tektronix', { 'params': ['visa_address'], 'classes': ['MSO_DPO_2000', 'MSO_DPO_4000', 'TDS_1000', 'TDS_200', 'TDS_2000', 'TDS_3000'], diff --git a/instrumental/drivers/__init__.py b/instrumental/drivers/__init__.py index 0617d251..5593e2d0 100644 --- a/instrumental/drivers/__init__.py +++ b/instrumental/drivers/__init__.py @@ -452,34 +452,40 @@ def write(self, message, *args, **kwds): >>> inst.write('source{}:value {}', channel, value) """ - full_message = message.format(*args, **kwds) + full_message = fmt = message.format(*args, **kwds) if self._in_transaction: - if full_message[0] != ':': - full_message = ':' + full_message + if fmt[0] != ':': + full_message = ':' + fmt self._message_queue.append(full_message) else: - self._rsrc.write(full_message) + self._rsrc.write(fmt) def query(self, message, *args, **kwds): """Query the instrument's VISA resource with `message` Flushes the message queue if called within a transaction. """ + full_message = fmt = message.format(*args, **kwds) if self._in_transaction: - self._flush_message_queue() # TODO: combine query with this message? - return self._rsrc.query(message.format(*args, **kwds)) + if fmt[0] != ':': + full_message = ':' + fmt + self._message_queue.append(full_message) + else: + return self._rsrc.query(fmt) @contextlib.contextmanager def transaction(self): """Transaction context manager to auto-chain VISA messages - Queues individual messages written with the `write()` method and sends them all at once, - joined by ';'. Messages are actually sent (1) when a call to `query()` is made and (2) - upon the end of transaction. + Queues individual messages written with the `write()` and `query()` methods and sends them + all at once, joined by ';'. Messages are sent upon the end of the transaction. + + This is especially useful when using higher-level functions that call `write()` or + `query()`, as it lets you combine multiple logical operations into a single message, + which can be faster than sending lots of little messages. - This is especially useful when using higher-level functions that call `write()`, as it lets - you combine multiple logical operations into a single message (if only using writes), which - can be faster than sending lots of little messages. + Note that all query() calls need to return a string for the transaction. This is important + when using a Facet since it is possible to make a Facet return an object. Be cognizant that a visa resource's write and query methods are not transaction-aware, only VisaMixin's are. If you need to call one of these methods (e.g. write_raw), make sure you @@ -490,9 +496,10 @@ def transaction(self): >>> with myinst.transaction(): ... myinst.write('A') ... myinst.write('B') - ... myinst.query('C?') # Query forces flush. Writes "A;B" and queries "C?" - ... myinst.write('D') - ... myinst.write('E') # End of transaction block, writes "D;E" + ... myinst.query('C?') + ... myinst.query('D?') + ... myinst.write('E') # End of transaction block, writes "A;B;C?;D?;E" + >>> print(myinst.response) # Shows the responses of "C?" and "D?" as a tuple """ self._start_transaction() yield @@ -502,7 +509,7 @@ def _start_transaction(self): self._message_queue = [] def _end_transaction(self): - self._flush_message_queue() + self.response = self._flush_message_queue() self._message_queue = None # signals end of transaction def _flush_message_queue(self): @@ -510,9 +517,13 @@ def _flush_message_queue(self): if not self._in_transaction: return message = ';'.join(self._message_queue) - self._rsrc.write(message) self._message_queue = [] + if message.find('?') != -1: + return self._rsrc.query(message).split(';') + else: + self._rsrc.write(message) + @property def _in_transaction(self): return getattr(self, '_message_queue', None) is not None diff --git a/instrumental/drivers/funcgenerators/rigol.py b/instrumental/drivers/funcgenerators/rigol.py index e1c890ed..1a43cdac 100644 --- a/instrumental/drivers/funcgenerators/rigol.py +++ b/instrumental/drivers/funcgenerators/rigol.py @@ -94,6 +94,9 @@ def version(self): _, _, _, version = self.query('*IDN?').rstrip().split(',', 4) return version + def reset(self): + self.write('*RST') + @property def output1(self): val = self.query('OUTPut1:STATe?') diff --git a/instrumental/drivers/powermeters/newport.py b/instrumental/drivers/powermeters/newport.py index b6a193a7..309eb908 100644 --- a/instrumental/drivers/powermeters/newport.py +++ b/instrumental/drivers/powermeters/newport.py @@ -186,7 +186,7 @@ def attenuator_enabled(self): val = self.write('A?') return bool(val) - def get_valid_power(self, max_attempts=10, polling_interval=0.1*u.s)): + def get_valid_power(self, max_attempts=10, polling_interval=0.1*u.s): """Returns a valid power reading This convience function will try to measure a valid power up to a diff --git a/instrumental/drivers/powersupplies/rigol.py b/instrumental/drivers/powersupplies/rigol.py index bfbcb9d1..b7d7d094 100755 --- a/instrumental/drivers/powersupplies/rigol.py +++ b/instrumental/drivers/powersupplies/rigol.py @@ -10,8 +10,8 @@ import pyvisa import re -_INST_PARAMS_ = ['visa_address'] -_INST_VISA_INFO_ = { +_INST_PARAMS = ['visa_address'] +_INST_VISA_INFO = { 'DP700': ('RIGOL TECHNOLOGIES', ['DP711', 'DP712']), } @@ -53,6 +53,8 @@ class DP700(RigolPowerSupply, VisaMixin): current_protection_state = SCPI_Facet('SOURce:CURRent:PROTection:STATe', convert=OnOffState) output = SCPI_Facet('OUTPut:STATe', convert=OnOffState) beeper = SCPI_Facet('SYSTem:BEEPer', convert=OnOffState) + measured_voltage = SCPI_Facet('MEASure:VOLTage', convert=float, readonly=True, units='A') + measured_current = SCPI_Facet('MEASure:CURRent', convert=float, readonly=True, units='A') @property def manufacturer(self): @@ -74,11 +76,8 @@ def version(self): _, _, _, version = self.query('*IDN?').rstrip().split(',', 4) return version - def get_measured_voltage(self): - return Q_(self.query(':MEASure:VOLTage?'), ureg.volt) - - def get_measured_current(self): - return Q_(self.query(':MEASure:CURRent?'), ureg.ampere) + def reset(self): + self.write('*RST') @current_protection_state.setter def current_protection_state(self, val): diff --git a/instrumental/drivers/scopes/rigol.py b/instrumental/drivers/scopes/rigol.py index df28d923..a6b0c35c 100755 --- a/instrumental/drivers/scopes/rigol.py +++ b/instrumental/drivers/scopes/rigol.py @@ -7,7 +7,7 @@ import visa from pyvisa.constants import InterfaceType import numpy as np -from pint import UndefinedUnitError +from pint import UndefinedUnitError, UnitRegistry from . import Scope from .. import VisaMixin, SCPI_Facet, Facet from ..util import visa_context @@ -20,8 +20,8 @@ import numpy as np from struct import unpack -_INST_PARAMS_ = ['visa_address'] -_INST_VISA_INFO_ = { +_INST_PARAMS = ['visa_address'] +_INST_VISA_INFO = { 'DS1000Z': ('RIGOL TECHNOLOGIES', ['DS1054Z']), } @@ -62,6 +62,9 @@ class RigolScope(Scope, VisaMixin): A base class for Rigol Technologies Scopes """ + probe1 = SCPI_Facet(':CHANnel1:PROBe', convert=float) + scale1 = SCPI_Facet(':CHANnel1:SCALe', convert=float) + timebase_main_scale = SCPI_Facet(':TIMebase:MAIN:SCALe', convert=float) yinc = SCPI_Facet(':WAVeform:YINCrement', convert=float) yref = SCPI_Facet(':WAVeform:YREFerence', convert=float) yorig = SCPI_Facet(':WAVeform:YORigin', convert=float) @@ -92,6 +95,9 @@ def version(self): _, _, _, version = self.query('*IDN?').rstrip().split(',', 4) return version + def reset(self): + self.write('*RST') + @property def beeper(self): val = self.query('SYSTem:BEEPer?') @@ -102,6 +108,18 @@ def beeper(self, val): val = int(bool(val)) self.write('SYSTem:BEEPer %s' % OnOffState(val).name) + @property + def display_data(self): + return self._rsrc.query_binary_values(':DISPlay:DATA? ON,OFF,PNG', datatype='B', container=bytes) + + @property + def ppulses_min(self): + return self.query(':MEASure:STATistic:ITEM? MINimum,PPULses') + + @property + def ppulses_max(self): + return self.query(':MEASure:STATistic:ITEM? MAXimum,PPULses') + @property def vmax_averages(self): return self.query(':MEASure:STATistic:ITEM? AVERages,VMAX') @@ -118,6 +136,9 @@ def vmin_averages(self): def vmin(self): return self.query(':MEASure:ITEM? VMIN') + def autoscale(self): + self.write(':AUToscale') + def get_data(self): self.write(':WAV:SOUR CHAN1') time.sleep(1)