def list_instruments(): """Get a list of all power supplies currently attached""" paramsets = [] search_string = "ASRL?*" rm = ResourceManager() raw_spec_list = rm.list_resources(search_string) for spec in raw_spec_list: try: inst = rm.open_resource(spec, read_termination='\n', write_termination='\n') idn = inst.query("*IDN?") manufacturer, model, serial, version = idn.rstrip().split(',', 4) if re.match('DP7[0-9]{2}', model): paramsets.append( ParamSet(DP700, asrl=spec, manufacturer=manufacturer, serial=serial, model=model, version=version)) except pyvisa.errors.VisaIOError as vio: # Ignore unknown serial devices pass return paramsets
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str], v: float = 0.0, i: float = 1e-6, n: int = 100, nplc: int = 1, comment: str = '', gate_voltage: float = 0.0, sd_current_range: float = 0.0, gd_current_range: float = 0.0, symmetric: bool = False) -> None: super().__init__(signal_interface, path, contacts) self._max_voltage = v self._current_limit = i self._number_of_points = n self._nplc = nplc self._comment = comment self._gate_voltage = gate_voltage resource_man = ResourceManager(self.VISA_LIBRARY) resource = resource_man.open_resource(self.GPIB_RESOURCE, query_delay=self.QUERY_DELAY) self._device = Sourcemeter2636A(resource, sub_device=SMUChannel.channelA) self._device.voltage_driven(0, i, nplc, range=sd_current_range) self._gate = Sourcemeter2636A(resource, sub_device=SMUChannel.channelB) self._gate.voltage_driven(0, i, nplc, range=gd_current_range) self._temperature_controller = Model340(self.TEMP_ADDR) self._symmetric = symmetric
def test_sanity(): register_resources(instruments.resources) rc = ResourceManager(visa_library="@mock") res = rc.open_resource("MOCK0::mock1::INSTR") res.write(":INSTR:CHANNEL1:VOLT 2.3") reply = res.query(":INSTR:CHANNEL1:VOLT?") assert reply == '2.3'
def update_devices(self): rm = ResourceManager('@py') try: self._resources = [x for x in rm.list_resources() if 'GPIB' in x] except: self._resources = [] self._combobox.clear() for item in self._resources: self._combobox.addItem(item) rm.close()
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str], v: float = 0.0, i: float = 1e-6, nplc: int = 3, comment: str = '', time_difference: float=0, gpib: str='GPIB0::10::INSTR', temperatures: str = '[2,10,100,300]'): super().__init__(signal_interface, path, contacts) self._max_voltage = v self._current_limit = i self._nplc = nplc self._comment = comment self._time_difference = time_difference self._gpib = gpib resource_man = ResourceManager('@py') resource = resource_man.open_resource(self._gpib) resource.timeout = 30000 self._device = SMUTempSweepIV._get_sourcemeter(resource) self._device.voltage_driven(0, i, nplc) self._temp = ITC(get_gpib_device(24)) step1 = np.linspace(0, self._max_voltage, 25, endpoint=False) step2 = np.linspace(self._max_voltage, -self._max_voltage, 50, endpoint=False) step3 = np.linspace(-self._max_voltage, 0, 25) self._voltages = np.concatenate((step1, step2, step3)) try: self._temperatures = literal_eval(temperatures) except: print('ERROR', 'Malformed String for Temperatures') self.abort() return if type(self._temperatures) is not list: print('ERROR', 'Temperature String is not a List') self.abort() return for k in self._temperatures: t = type(k) if t is not int and t is not float: print('ERROR', 'Temperature List does not only contain ints or floats') self.abort() return self._temperatures = np.array(self._temperatures)
def list_instruments(): """Get a list of all spectrometers currently attached""" paramsets = [] search_string = "USB?*?{VI_ATTR_MANF_ID==0x1313 && ((VI_ATTR_MODEL_CODE==0x8081) || (VI_ATTR_MODEL_CODE==0x8083) || (VI_ATTR_MODEL_CODE==0x8085) || (VI_ATTR_MODEL_CODE==0x8087) || (VI_ATTR_MODEL_CODE==0x8089))}" rm = ResourceManager() try: raw_spec_list = rm.list_resources(search_string) except: return paramsets for spec in raw_spec_list: _, _, model, serial, _ = spec.split('::', 4) model = SpecTypes(int(model, 0)) paramsets.append(ParamSet(CCS, usb=spec, serial=serial, model=model)) return paramsets
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str], v: float = 0.0, i: float = 1e-6, n: int = 100, nplc: int = 1, comment: str = '', range:float=1e-8) -> None: super().__init__(signal_interface, path, contacts) self._max_voltage = v self._current_limit = i self._number_of_points = n self._nplc = nplc self._comment = comment resource_man = ResourceManager(self.VISA_LIBRARY) resource = resource_man.open_resource(self.GPIB_RESOURCE, query_delay=self.QUERY_DELAY) self._device = Sourcemeter2602A(resource) self._device.voltage_driven(0, i, nplc, range=range)
def __init__(self, ip_address): """ Constructor for scope object Resets scope :param ip_address: Ethernet address of scope """ if not ip_address: print("No ip address specified. Running in test mode.") return self.inst = ResourceManager("@py").open_resource("TCPIP0::" + ip_address + "::inst0::INSTR") if "LECROY" in self.inst.query("*IDN?;"): print("Connected to LeCroy WavePro") self.inst.timeout = 60000
def __init__(self, rm: visa.ResourceManager): super().__init__() self.rm = rm # Get a list of resources, open comms, and poll them for their ID string self.instruments = rm.list_resources() self.instr_ids = [] for instr in self.instruments: current_instr = self.rm.open_resource(instr) try: self.instr_ids.append(current_instr.query("*IDN?")) except VisaIOError: print( 'Error getting instrument ID string from {}'.format(instr)) current_instr.close() self.instr_combo_box = QComboBox() self.instr_combo_box.addItems(self.instruments) self.instr_id_label = QLabel() self.ok_btn = QPushButton('Ok') self.form_layout = QFormLayout() self.init_layout() self.init_connections()
def __init__(self, rm: visa.ResourceManager, addr): self.addr = addr self.inst = rm.open_resource(addr) self.inst.baud_rate = 57600 self.inst.data_bits = 8 self.inst.query("t?") # dummy query to clear buffer self.inst.query("t0") # Disable periodic temp report
def __init__(self, location: str, manager: ResourceManager): """ Create a visa connection using loc and manager to the Vidia-Swept laser. :param location: the GPIB location of the laser :param manager: the PyVisa resource manager """ self.device = manager.open_resource(location) # type: GPIBInstrument
def list_instruments(): """Get a list of all spectrometers currently attached""" paramsets = [] model_string = '|'.join('{:04X}'.format(spec.value) for spec in SpecTypes) search_string = "USB[0-9]*::0x{:04X}::0x({})".format(MANUFACTURER_ID, model_string) rm = ResourceManager() try: raw_spec_list = rm.list_resources(search_string) except: return paramsets for spec in raw_spec_list: _, _, model, serial, _ = spec.split('::', 4) model = SpecTypes(int(model, 0)) paramsets.append(ParamSet(DG800, usb=spec, serial=serial, model=model)) return paramsets
def __init__(self, loc: str, manager: ResourceManager): """ Opens a GPIB connection with the device at the specified location. :param loc: the location of the device :param manager: the PyVisa Resource Manager """ self.device = manager.open_resource( loc, read_termination="\n", open_timeout=2500) # type: GPIBInstrument
def _init_smus(self): rm = ResourceManager('@py') dev1 = rm.open_resource(self.GPIB_RESOURCE_2400) dev2 = rm.open_resource(self.GPIB_RESOURCE_2636A) dev3 = rm.open_resource(self.GPIB_RESOURCE_2602A) self._smus = [ Sourcemeter2400(dev1), Sourcemeter2636A(dev2, sub_device=SMUChannel.channelA), Sourcemeter2636A(dev2, sub_device=SMUChannel.channelB), Sourcemeter2602A(dev3, sub_device=SMUChannel.channelA), Sourcemeter2602A(dev3, sub_device=SMUChannel.channelB) ] for index, smu in enumerate(self._smus): sample = self._samples[index] smu.voltage_driven(sample['v'], current_limit=sample['i'], nplc=sample['nplc'])
def __init__(self, rm: visa.ResourceManager, addr: str): self.dev = rm.open_resource(addr) self.dev.clear() self.idn = self.dev.query("*IDN?") #assert(self.idn == "HP3458A") self.dev.write("DISPLAY OFF") self.dev.write("CONF:VOLT:DC 10") self.dev.write("SENSE:ZERO:AUTO ON") self.dev.write("VOLT:DC:NPLC 100")
def __init__(self, address, reset=True): '''Initialization sequence for the SourceMeter''' # Open the K2400SM self.inst = ResourceManager().open_resource(address) #Shorthand self.w = self.inst.write self.r = self.inst.read self.q = self.inst.query #Print K2400SM string for confirmation print(self.q('*IDN?')) if reset: self.w('*RST')
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str], v: float = 0.0, i: float = 1e-6, n: int = 100, nplc: int = 1, comment: str = '', gpib: str = '') -> None: super().__init__(signal_interface, path, contacts) self._max_voltage = v self._current_limit = i self._number_of_points = n self._nplc = nplc self._comment = comment resource_man = ResourceManager(self.VISA_LIBRARY) resource = resource_man.open_resource(gpib, query_delay=self.QUERY_DELAY) try: self._device = SMU2Probe._get_sourcemeter(resource) except visa.VisaIOError: # Should only occur when pyvisa-sim is used: self._device = Sourcemeter2400(resource) self._device.voltage_driven(0, i, nplc)
def refresh_resources(n): list_of_resources = ResourceManager().list_resources() default_resources = [s for s in list_of_resources if 'GPIB' in s] if len(default_resources) > 1: sourcemeter_resource = default_resources[0] multimeter_resource = default_resources[1] else: sourcemeter_resource = None multimeter_resource = None options = [{'label': name, 'value': name} for name in list_of_resources] return multimeter_resource, options, sourcemeter_resource, options
def list_instruments(): """ Get a list of all spectrometers currently attached. """ spectrometers = [] search_string = "USB?*?{VI_ATTR_MANF_ID==0x1313 && ((VI_ATTR_MODEL_CODE==0x8081) || (VI_ATTR_MODEL_CODE==0x8083) || (VI_ATTR_MODEL_CODE==0x8085) || (VI_ATTR_MODEL_CODE==0x8087) || (VI_ATTR_MODEL_CODE==0x8089))}" rm = ResourceManager() try: raw_spec_list = rm.list_resources(search_string) except: return spectrometers for spec in raw_spec_list: _, _, model, serial_number, _ = spec.split("::") model = SpecTypes(int(model, 0)) params = _ParamDict("<Thorlabs_CCS_Spectrometer '{}-{}'>".format( model.name, serial_number)) params.module = 'spectrometers.thorlabs_ccs' params['ccs_usb_address'] = spec params['ccs_model'] = model params['ccs_serial_number'] = serial_number spectrometers.append(params) return spectrometers
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str], v: float = 0.0, i: float = 1e-6, nplc: int = 3, comment: str = '', time_difference: float = 0, gpib: str = 'GPIB0::10::INSTR'): super().__init__(signal_interface, path, contacts) self._max_voltage = v self._current_limit = i self._nplc = nplc self._comment = comment self._time_difference = time_difference self._gpib = gpib resource_man = ResourceManager('@py') resource = resource_man.open_resource(self._gpib) self._device = SMU2ProbeIvt._get_sourcemeter(resource) self._device.voltage_driven(0, i, nplc)
def __init__(self, rm: visa.ResourceManager, addr: str): self.dev = rm.open_resource(addr) self.dev.read_termination = '\r\n' self.dev.write_termination = '\n' self.dev.clear() self.idn = self.dev.query("ID?") assert (self.idn == "HP3458A") print("id is {}".format(self.idn)) self.dev.write("DISP MSG,\" \"") # Stop auto-trigger self.dev.write("TRIG HOLD") self.dev.write("NPLC 100") self.dev.write("NRDGS 1,LINE")
def list_instruments(): """Get a list of all spectrometers currently attached""" paramsets = [] model_string = '' for spec in SpecTypes: model_string += '(VI_ATTR_MODEL_CODE==0x{:04X}) || '.format(spec.value) model_string = model_string.rstrip(' || ') search_string = "USB?*?{{VI_ATTR_MANF_ID==0x{:04X} && ({})}}".format( MANUFACTURER_ID, model_string) rm = ResourceManager() try: raw_spec_list = rm.list_resources(search_string) except: return paramsets for spec in raw_spec_list: _, _, model, serial, _ = spec.split('::', 4) model = SpecTypes(int(model, 0)) paramsets.append(ParamSet(DG800, usb=spec, serial=serial, model=model)) return paramsets
def __init__(self): """ Constructor """ self.logger = logging.getLogger('scopeout.utilities.ScopeFinder') self.logger.info('ScopeFinder Initialized') self.resource_manager = ResourceManager() self.resources = [] self.instruments = [] self.scopes = [] self.blacklist = set() self.refresh()
def __init__(self, signal_interface: SignalInterface, path: str, contacts: Tuple[str, str, str, str], comment: str = '', gpib: str='GPIB0::12::INSTR', sweep_rate:float = 1.0, temperature_end: float = 2, nplc: int = 3, voltage:float = 0.1, current_limit: float=1e-6): super().__init__(signal_interface, path, contacts) self._comment = comment self._temp = ITC(get_gpib_device(24)) self._sweep_rate = sweep_rate self._voltage = voltage self._current_limit = current_limit self._gpib = gpib if not (0 <= temperature_end <= 299): print("end temperature too high or too low. (0 ... 299)") self.abort() return if not (0 <= sweep_rate <= 2.5): print("you're insane! sweep rate is too high. (0 ... 2.5)") self.abort() return resource_man = ResourceManager('@py') resource = resource_man.open_resource(self._gpib) self._device = SMU2ProbeIvTBlue._get_sourcemeter(resource) self._device.voltage_driven(0, current_limit, nplc) self._temperature_end = temperature_end self._last_toggle = time() sleep(1)
def laser_scan(laser_gpib = "GPIB::19", #1600 GPIB::20 1550 GPIB::4 #1400 GPIB::19 daq_channel = "dev1/ai1", wrange = (1560,1600), offsetWL = 0.00, sample_rate = 5e3, speed = .5, # nm/s (only options are .5 5 40) plot_hook = None): # calculate the output total_samples = ((wrange[1] - wrange[0]) /speed * sample_rate ) wl = np.linspace(wrange[0],wrange[1], total_samples) print('Total Samples {:}'.format(total_samples)) ## Configure task voltage_task = daq.InputTask() voltage_task.add_analog_voltage_channel(daq_channel, terminal_config = "rse") voltage_task.configure_sample_clock_timing( sample_rate, source=b"", sample_mode=daq.DAQmx_Val_FiniteSamps, samples_per_channel = int(total_samples)) ## Set trigger from laser to NIdaq voltage_task.set_digital_trigger(b"PFI0") daq.nidaq.DAQmxSetReadReadAllAvailSamp(voltage_task.task_handle, daq.bool32(True)) ## Connect to laser rm = ResourceManager() inst = rm.open_resource(laser_gpib) sleep(.1) print('The identification of this instrument is : ' + inst.query("*idn?")) ## configure and set to start wl inst.write("wav %f nm"%wrange[0]) inst.write("wav:sweep:start %f nm"%wrange[0]) inst.write("wav:sweep:STOP %f nm"%wrange[1]) inst.write("wav:sweep:speed %f nm/s"%(0.5)) inst.write("TRIGGER:OUTPUT SWStart") inst.write("wav:sweep:mode Cont") sleep(5) with voltage_task: # start the task (to avoid lockdown of the nidaq in case of crash) ## Start acquisition voltage_task.start() ## Start scan inst.write("WAV:SWEEP:STATE 1") # To avoid warnings when the we rea warnings.filterwarnings('ignore', 'Read') ## reading loop. Scan is longer than a second, so we keep ## probing to have faster update samples_read = 0 data_buffer = np.zeros(total_samples) while samples_read < total_samples: b = voltage_task.read() if len(b)> 0: data_buffer[samples_read:samples_read+len(b)] = b # give an update print(len(b), samples_read/total_samples) if plot_hook is not None: plot_hook(wl, data_buffer) samples_read += len(b) sleep(.3) return wl, data_buffer
class ScopeFinder: def __init__(self): """ Constructor """ self.logger = logging.getLogger('scopeout.utilities.ScopeFinder') self.logger.info('ScopeFinder Initialized') self.resource_manager = ResourceManager() self.resources = [] self.instruments = [] self.scopes = [] self.blacklist = set() self.refresh() def __enter__(self): # Entry point for the *with* statement, which allows this object to close properly on program exit. return self def __exit__(self, type, value, traceback): # Exit point for with statement pass def query(self, inst, command): """ Issues query to instrument and returns response. Parameters: :inst: the instrument to be queried. :command: the command to be issued. :Returns: the response of inst as a string. """ return inst.query(command).strip() # strip newline def get_scopes(self): """ Getter for array of connected oscilloscopes. :Returns: an array of PyVisa instrument objects representing USB oscilloscopes connected to the computer. """ return self.scopes def refresh(self): """ Re-run scope acquisition to update scope array. :Returns: the ScopeFinder object, for convenience. """ self.scopes = [] self.resources = [] try: self.resources = self.resource_manager.list_resources() except VisaIOError as e: self.resources = [] if self.resources: self.logger.info("%d VISA Resource(s) found", len(self.resources)) self.instruments = [] for resource in set(self.resources) - self.blacklist: try: inst = self.resource_manager.open_resource(resource) self.instruments.append(inst) self.logger.info('Resource {} converted to instrument'.format(resource)) except Exception as e: self.logger.error(e) self.blacklist.add(resource) for ins in self.instruments: try: info = self.query(ins, '*IDN?').split(',') # Parse identification string if info[1] == 'TDS 2024B': # TDS 2024B oscilloscope info.append(info.pop().split()[1][3:]) # get our identification string into array format scope = oscilloscopes.TDS2024B(ins, info[1], info[2], info[3]) self.scopes.append(scope) self.logger.info("Found %s", str(scope)) elif re.match('GDS-1.*A', info[1]): scope = oscilloscopes.GDS1000A(ins, info[1], info[2], info[3]) self.scopes.append(scope) self.logger.info("Found %s", str(scope)) elif re.match('GDS-2.*A', info[1]): scope = oscilloscopes.GDS2000A(ins, info[1], info[2], info[3]) self.scopes.append(scope) self.logger.info("Found %s", str(scope)) # Support for other scopes to be implemented here! except VisaIOError or IndexError: self.logger.error('{} could not be converted to an oscilloscope'.format(ins)) return self def check_scope(self, scope_index): """ Check if the scope at scopeIndex is still connected. Parameters: :scopeIndex: the index of the scopes array to check. :Returns: True if connected, false otherwise """ try: if self.scopes[scope_index].getTriggerStatus(): return True else: return False except: return False
import dash_html_components as html import dash_daq as daq from dash.dependencies import Input, Output, State from pyInstruments.pid import TemperatureController from threading import Thread from collections import deque from visa import ResourceManager import getopt import sys global N_CLICK_PREVIOUS, MAX_LENGTH N_CLICK_PREVIOUS = 0 MAX_LENGTH = 500 # Listing the available resources lresources = ResourceManager().list_resources() # Initialize the pid task p = TemperatureController() # Preparing the plot plot_layout = dict(margin = {'l': 60, 'r': 60, 'b': 60, 't': 20},\ legend = {'x': 0, 'y': 1, 'xanchor': 'left'},\ xaxis = dict(title = "Timestamp", font = dict(size = 24)),\ yaxis = dict( title = "Temperature (°C)", font = dict(size = 24)) ) calc_status = lambda x: bool(abs(int((1j**x).real))) external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
def initialise(self): rm = ResourceManager() self.handle = rm.open_resource(self.address)
from visa import ResourceManager from time import sleep rm = ResourceManager() ip = "192.168.0.6" pna = rm.open_resource("TCPIP0::%s::hpib7,16::INSTR" %ip) pna.read_termination = '\n' pna.timeout = 8000 #milisecond pna.write("*RST") pna.write("FORMat:DATA ASCII,0") status = pna.query("CALC1:PAR:CAT?") Catalog = status.replace('"', '').split(',') print(Catalog) Mname = Catalog[0] print("Mname: %s" %Mname) # sweeping type pna.write("SENS:SWE:TYPE CW") sweep_type = pna.query("SENS:SWE:TYPE?") print("sweep type is %s" %sweep_type) #sweeping point pna.write("SENSe:SWEep:POINTs 1001") point = pna.query("SENSe:SWEep:POINTs?") print("point = %s" %point) #sweep frequency pna.write("SENS:FREQuency:STARt 1e9")
def __init__(self, address): rm = ResourceManager() self.device = rm.open_resource(address) idn = self.query('*IDN?') assert '34970A' in idn, 'invalid device identity: %s' % idn
""" ##################### ### CONFIGURATION ### ##################### FG_ADDRESS = 10 MC_ADDRESS = 20 LIA_ADDRESS = 9 ###################### ### INITIALIZATION ### ###################### rm = ResourceManager() fg = FuncGenAgilent33220(FG_ADDRESS, rm) mc = MotionControllerNewportESP300(MC_ADDRESS, rm) sdr = RtlSdrInterface(40e6, 2.048e6, 512**2, 30e3, 1, 1) lia = LockInAmpSrs830(LIA_ADDRESS, rm) linescan = LineScan(sdr, fg, mc) biassweep = BiasSweep(sdr, fg) biassweepcv = BiasSweepWithCV(sdr, fg, lia) ###################### ### MAIN ### ###################### gui = SdrGUI(sdr, fg, mc, lia, linescan, biassweep, biassweepcv)
class MMC_Wrapper(object): """ Wrapper to the MMC dll from Physik Instrumente """ stages = { 'M521DG': dict(cts_units_num=2458624, cts_units_denom=81, units="mm") } VISA_rm = ResourceManager() ress = VISA_rm.list_resources_info() aliases = [] ports = [] for key in ress.keys(): if 'COM' in ress[key].alias: aliases.append(ress[key].alias) ports.append(ress[key].interface_board_number) baudrates = [9600, 19200] def __init__(self, stage='M521DG', com_port='COM1', baud_rate=9600): if stage not in self.stages.keys(): raise Exception('not valid stage') if com_port not in self.aliases: raise IOError('invalid com port') if baud_rate not in self.baudrates: raise IOError('invalid baudrate') self.stage = stage super(MMC_Wrapper, self).__init__() self._comport = com_port self._baudrate = baud_rate self._dll = windll.LoadLibrary( os.path.join(os.path.split(__file__)[0], 'MMC.dll')) @property def comport(self): return self._comport @comport.setter def comport(self, port): if not isinstance(port, str): raise TypeError( "not a valid port type, should be a string: 'COM6'") if port not in self.ports: raise IOError('{} is an invalid COM port'.format(port)) self._comport = port @property def baudrate(self): return self._comport @baudrate.setter def baudrate(self, rate): if not isinstance(rate, int): raise TypeError("not a valid baudrate") if rate not in self.baudrates: raise IOError('{} is an invalid baudrate'.format(rate)) self._baudrate = rate def counts_to_units(self, counts): return counts * 1 / (self.stages[self.stage]['cts_units_num'] / self.stages[self.stage]['cts_units_denom']) def units_to_counts(self, units): return int(units / (self.stages[self.stage]['cts_units_denom'] / self.stages[self.stage]['cts_units_num'])) def moveAbs(self, axis, units): """ displacement in the selected stage units Parameters ---------- units: (float) """ self.MMC_moveA(axis, self.units_to_counts(units)) def moveRel(self, axis, units): """ displacement in the selected stage units Parameters ---------- units: (float) """ self.MMC_moveR(axis, self.units_to_counts(units)) def getPos(self): return self.counts_to_units(self.MMC_getPos()) def open(self): port = self.ports[self.aliases.index(self._comport)] self.MMC_COM_open(port, self._baudrate) def find_home(self): self.MMC_sendCommand('FE1') def moving(self): target = self.MMC_getVal(2) self.MMC_sendCommand('TE') st = self.MMC_getStringCR() if '-' in st: pos = -int(st.split('E:-')[1]) else: pos = int(st.split('E:+')[1]) return abs(target - pos) > 100 def MMC_getStringCR(self): st = create_string_buffer(128) res = self._dll.MMC_getStringCR(byref(st)) if res != 0: return st.decode() else: raise IOError('wrong return from dll') def MMC_COM_open(self, port_number, baudrate): res = self._dll.MMC_COM_open(port_number, baudrate) if res != 0: raise IOError('wrong return from dll') def MMC_COM_close(self): """ Closes the COM port previously opened by the MMC_COM_open function. """ res = self._dll.MMC_COM_close() if res != 0: raise IOError('wrong return from dll') def MMC_COM_EOF(self): """ Returns the number of characters available in the COM-port input buffer Returns ------- int: Number of characters in the input buffer """ res = self._dll.MMC_COM_EOF() return res def MMC_COM_clear(self): """ Clears the COM-port input buffer. """ res = self._dll.MMC_COM_clear() if res != 0: raise IOError('wrong return from dll') def MMC_getDLLversion(self): """ Delivers the version number of the DLL Returns ------- int: version number as integer """ res = self._dll.MMC_getDLLversion() return res def MMC_getPos(self): """ Reads the current motor position of the currently selected Mercury™ controller. The reading process does not interrupt running compound commands. Returns ------- int: Current motor position in counts/steps or error code. The error code is derived from maximum integer value minus the error number: 2,147,483,647 (maxint) : Wrong Content 2,147,483,646 (maxint-1) : Error in _getString 2,147,483,645 (maxint-2) : Error in _sendString 2,147,483,644 (maxint-3) : Error during conversion """ res = self._dll.MMC_getPos() return res def MDC_getPosErr(self): """ Reads the current motor-position error of the currently selected Mercury™ controller. Returns ------- int: Current motor position error in counts or error code. The error code is derived from maximum integer value minus the error number: 2,147,483,647 (maxint) : Wrong Content 2,147,483,646 (maxint-1) : Error in _getString 2,147,483,645 (maxint-2) : Error in _sendString 2,147,483,644 (maxint-3) : Error during conversion """ res = self._dll.MDC_getPosErr() return res def MMC_getVal(self, command_ID: int): """ Reads the value of the requested parameter. The function can be called on the fly. Running compound commands or macros are not interrupted. Parameters ---------- command_ID: (int) Identifier for the requested item: 1 = TP (Tell Position) 2 = TT (Tell Target) 3 = TF (Tell profile following error) 4 = TE (Tell distance to target) 5 = TY (Tell velocity setting) 6 = TL (Tell acceleration setting) 7 = GP (Get p-term setting) 8 = GI (Get i-term setting) 9 = GD (Get d-term setting) 10 = GL (Get i-limit setting) Returns ------- int: The requested value or error code is returned as 32-bit integer. Error codes: 2,147,483,647 (MaxInt) = content error 2,147,483,646 (MaxInt-1) = getString error 2,147,483,645 (MaxInt-2) = sendString error 2,147,483,644 (MaxInt-3) = conversion error """ res = self._dll.MMC_getVal(command_ID) return res def MMC_initNetwork(self, maxAxis: int = 16): """ Searches all addresses, starting at address maxAxis down to 1 for Mercury™ devices connected. If a Mercury™ device (can be C-862, C-863, C-663 or C-170) is found, it is registered so as to allow access through the MMC_select() function. The function MMC_initNetwork is optional. If it is not used, devices can be activated anyway using the MMC_setDevice function. Parameters ---------- maxAxis: (int) This parameter represents the highest device number from which the search is to run, continuing downwards. If you have 3 Mercury™s connected at the addresses 0,1 and 2 (this equals the device numbers 1,2 and 3) you may call the function as MMC_initNetwork(3). If you do no know what addresses the controllers are set to, call the function with maxAxis = 16 to find all devices connected. (Remember that valid device numbers range from 1 to 16.) The range of maxAxis is 1 to 16 Because scanning each address takes about 0.5 seconds, it saves time to not start at device numbers higher than required. Returns ------- list: list of integers corresponding to the connected devices """ devices = [] res = self._dll.MMC_initNetwork(maxAxis) if res < 0: raise IOError('wrong return from dll') if res > 0: bits = Bits(int=res, length=32).bin for ind in range(maxAxis): if bits[-1 - ind] == '1': devices.append(ind + 1) return devices def MMC_moveA(self, axis: int = 0, position: int = 0): """ Moves the motor of the specified axis (device number) to specified position. Parameters ---------- axis: (int) If this parameter is 0 then the move command is sent to the currently selected device. If it is >0 then an address selection code will be sent for the specified axis addressed before the move command is sent. position: (int) The new target position Returns ------- int: Error codes: 0: No error 1: Error, wrong axis 2: Error, not connected 3: Error, sendString """ res = self._dll.MMC_moveA(axis, position) return res def MMC_moveR(self, axis: int = 0, shift: int = 0): """ Moves the motor of the specified axis (device number) relative to its current position by shift counts or steps. Parameters ---------- axis: (int) If this parameter is 0 then the move command is sent to the currently selected device. If it is >0 then an address selection code will be sent for the specified axis before the move command is sent. shift: (int) Position increment added to the current position. Returns ------- int: Error codes: 0: No error 1: Error, wrong axis 2: Error, not connected 3: Error, sendString """ res = self._dll.MMC_moveR(axis, shift) return res def MDC_moving(self): """ Returns the motion status of the currently selected C-862 or C-863 Mercury™ DC motor controller. For C-663 Mercury™-Step controllers, an equivalent function is available. Returns ------- bool: moving status 0: Not moving 1: moving """ res = self._dll.MDC_moving() if res < 0: raise IOError('wrong return from dll') else: return bool(res) def MST_moving(self): """ Returns the moving status of the currently selected Mercury™-Step controller. For Mercury™ DC motor controllers, an equivalent function is available. Returns ------- bool: moving status 0: Not moving 1: moving """ res = self._dll.MST_moving() if res < 0: raise IOError('wrong return from dll') else: return bool(res) def MMC_setDevice(self, axis: int = 0): """ Addresses the selected axis (controller). This function works anytime and it is not required to have registered the devices connected with the MMC_intNetwork function. See also -------- MMC_select() Parameters ---------- axis: (int) Range 1 to 16, Device number of the controller that shall be selected for communication. The device number or address can be set by the controller's front panel DIP switches. """ res = self._dll.MMC_setDevice(axis) if res == 1: raise IOError('Wrong axis number') def MMC_select(self, axis: int = 0): """ Selects the specified axis (device) to enable communication with it. Unlike the MMC_setDevice function, here the registration status is checked, so this function requires that the MMC_initNetwork function have been called previously at the beginning of the program. Parameters ---------- axis: (int) range 1 to 16 Device number of the controller that is to be selected for communication. """ res = self._dll.MMC_select(axis) if res == 1: raise IOError('Wrong axis number') elif res == 2: raise IOError('axis not registered') def MMC_sendCommand(self, cmd): c_cmd = create_string_buffer(cmd.encode()) res = self._dll.MMC_sendCommand(byref(c_cmd)) if res == 114: raise IOError('Write error') elif res == 116: raise IOError('Length Error') def MDC_waitStop(self): """ For C-862 Mercury™ (DC motor) C-863 Mercury™ (DC motor) Waits until the current move has terminated or interrupted by user command (function MCC_GlobalBreak). """ res = self._dll.MDC_waitStop() if res == 1: raise IOError('Error, query') elif res == 2: raise IOError('User break') def MST_waitStop(self): """ For C-663 Mercury™-Step Waits until the current move has terminated or interrupted by user command (function MCC_GlobalBreak). """ res = self._dll.MST_waitStop() if res == 1: raise IOError('Error, query') elif res == 2: raise IOError('User break') def MMC_globalBreak(self): """ This function interrupts pending operations waiting for termination of a move. Can be used with _moving() or _waitStop functions. """ res = self._dll.MMC_globalBreak() if res != 0: raise IOError('wrong return from dll')
resolution_parameter)) self.dev.write('SENS:{:s}:NPLC {:f}'.format(method_string, integration_time)) def get_errors(self): return self.dev.query('SYST:ERR?') def read(self): return self.dev.query('READ?') @property def resistance(self) -> float: return float(self.read()) if __name__ == '__main__': from visa import ResourceManager from time import sleep rm = ResourceManager('@py') dev = rm.open_resource('GPIB0::9::INSTR') mux = Multimeter34401A(dev) mux.set_sense(SenseMethod.four_probe_resistance) print(mux.get_errors()) print(mux.read())