def __init__(self, init=1): self.SLOT_NUM = {"CHASSIS": 1, "AWG1": 2, # M3202A AWG1 "AWG2": 3, # M3202A AWG2 "DIG": 4, # M3102A Digitizer "MARK1": 5, # M3201A Marker1 "MARK2": 6} # M3201A Marker1 if init == 1: self.AWG1 = keysightSD1.SD_AOU() AWG1_ID = self.AWG1.openWithSlot("", self.SLOT_NUM["CHASSIS"], self.SLOT_NUM["AWG1"]) if AWG1_ID < 0: raise NameError('Cannot find AWG1') self.MARK1 = keysightSD1.SD_AOU() MARK1_ID = self.MARK1.openWithSlot("", self.SLOT_NUM["CHASSIS"], self.SLOT_NUM["MARK1"]) if MARK1_ID < 0: raise NameError('Cannot find MARK1') else: raise NameError('Plz fix the code') self.Digitizer = keysightSD1.SD_AIN() Digitizer_ID = self.Digitizer.openWithSlot("", self.SLOT_NUM["CHASSIS"], self.SLOT_NUM["DIG"]) if Digitizer_ID < 0: raise NameError('Cannot find Digitizer') self.HVI = keysightSD1.SD_HVI()
def __init__(self, slot): self.handle = key.SD_AOU() self.sampleRate = 1E+06 self.slot = slot # Discover the chassis number chassis = key.SD_Module.getChassisByIndex(1) if chassis < 0: raise AwgError(chassis) log.info("Configuring AWG in slot {}...".format(slot)) error = self.handle.openWithSlotCompatibility( '', chassis, slot, key.SD_Compatibility.KEYSIGHT) if error < 0: log.info("Error Opening - {}".format(error)) self.handle.waveformFlush() if error < 0: log.info("Error Flushing waveforms - {}".format(error)) self.channels = 0 for channel in range(1, 5): error = self.handle.AWGflush(channel) if error < 0: log.info("Error Flushing AWG - {}".format(error)) else: self.channels = self.channels + 1 log.info("Finished setting up AWG in slot {}...".format(slot))
def configureAwg(chassis, module): log.info("Configuring AWG in slot {}...".format(module.slot)) module.handle = key.SD_AOU() awg = module.handle error = awg.openWithSlotCompatibility('', chassis, module.slot, key.SD_Compatibility.KEYSIGHT) if error < 0: log.info("Error Opening - {}".format(error)) log.info("Loading FPGA image: {}".format(module.fpga.file_name)) error = awg.FPGAload(os.getcwd() + '\\' + module.fpga.file_name) if error < 0: log.error('Loading FPGA bitfile: {} {}'.format( error, key.SD_Error.getErrorMessage(error))) #Clear all queues and waveforms awg.waveformFlush() for channel in range(module.channels): awg.AWGflush(channel + 1) #Set up the channels suppporting interleaving setupLOs(module) for register in module.fpga.registers: error = module.handle.FPGAwritePCport(0, [register.value], register.address, key.SD_AddressingMode.FIXED, key.SD_AccessMode.NONDMA) if error < 0: log.error('WriteRegister: {} {}'.format( error, key.SD_Error.getErrorMessage(error))) log.error('Address: {}'.format(8)) log.error('Buffer [{}]'.format(module.mode)) loadWaves(module) enqueueWaves(module) trigmask = 0 for channel in range(module.channels): awg.channelWaveShape(channel + 1, key.SD_Waveshapes.AOU_AWG) trigmask = trigmask | 2**channel
def __init__(self, name, chassis, slot): ## identify chassis, slot id & so on super().__init__(name, tags=['physical']) self.mask = 0 self.module = keysightSD1.SD_AOU() self.module_id = self.module.openWithSlotCompatibility( "M3202A", chassis, slot, compatibility=keysightSD1.SD_Compatibility.LEGACY) self.amplitudes = [0.2] * 4 self.offsets = [0.0] * 4 self.clock = None self.add_parameter('amplitude_channel_{}', type=float, flags=Instrument.FLAG_SOFTGET, channels=(1, 4), unit='Volts', minval=-2, maxval=2, channel_prefix='ch%d_') self.add_parameter('offset_channel_{}', type=float, flags=Instrument.FLAG_SOFTGET, channels=(1, 4), unit='Volts', minval=-2, maxval=2, channel_prefix='ch%d_') for channel_id in range(4): self.set_amplitude(0.2, channel_id) self.set_offset(0.0, channel_id)
def performOpen(self, options={}): """Perform the operation of opening the instrument connection""" # add compatibility with pre-1.5.4 version of Labber if not hasattr(self, 'getTrigChannel'): self.getTrigChannel = self._getTrigChannel # timeout self.timeout_ms = int(1000 * self.dComCfg['Timeout']) # get PXI chassis self.chassis = int(self.dComCfg.get('PXI chassis', 1)) # create AWG instance # get PXI chassis self.chassis = int(self.dComCfg.get('PXI chassis', 1)) self.AWG = keysightSD1.SD_AOU() AWGPart = self.AWG.getProductNameBySlot(self.chassis, int(self.comCfg.address)) if not isinstance(AWGPart, str): raise Error('Unit not available') # check that model is supported dOptionCfg = self.dInstrCfg['options'] for validId, validName in zip(dOptionCfg['model_id'], dOptionCfg['model_str']): if AWGPart.find(validId) >= 0: # id found, stop searching break else: # loop fell through, raise ID error raise IdError(AWGPart, dOptionCfg['model_id']) # set model self.setModel(validName) self.AWG.openWithSlot(AWGPart, self.chassis, int(self.comCfg.address)) # sampling rate and number of channles is set by model if validName in ('M3202', 'H3344'): # 1GS/s models self.dt = 1E-9 self.nCh = 4 elif validName == 'M3302': # two-channel, 500 MS/s model self.dt = 2E-9 self.nCh = 2 else: # assume 500 MS/s for all other models self.dt = 2E-9 self.nCh = 4 # keep track of if waveform was updated self.waveform_updated = [False] * self.nCh self.previous_upload = dict() self.waveform_sizes = dict() # get hardware version - changes numbering of channels hw_version = self.AWG.getHardwareVersion() if hw_version >= 4: # KEYSIGHT - channel numbers start with 1 self.ch_index_zero = 1 else: # SIGNADYNE - channel numbers start with 0 self.ch_index_zero = 0 # clear old waveforms self.clearOldWaveforms()
def performOpen(self): #SD_AOU module dict_parse=self._parse_addr(self.addr) CHASSIS=dict_parse.get('CHASSIS') #default 1 SLOT=dict_parse.get('SLOT') self.handle = keysightSD1.SD_AOU() self.model = self.handle.getProductNameBySlot(CHASSIS,SLOT) moduleID = self.handle.openWithSlot(self.model, CHASSIS, SLOT) if moduleID < 0: print("Module open error:", moduleID)
def openModules(hwSimulated): # Simulation or real HW if hwSimulated: options = ",simulate=true" elif hwSimulated == False: options = "" else: print("hwSimulated not set to valid value") sys.exit() # Channel numbering option channelOption = "channelNumbering=keysight" options = channelOption + options # Update chassis and slot numbers to your modules' values moduleDescriptors = [ ModuleDescriptor(chassisNumber=1, slotNumber=8, options=options, instrType="dig"), ModuleDescriptor(chassisNumber=1, slotNumber=11, options=options) ] moduleList = [] minChassis = 1 maxChassis = 1 # Open modules for descriptor in moduleDescriptors: newModule = keysightSD1.SD_AIN( ) if descriptor.instrType == "dig" else keysightSD1.SD_AOU() # newModule = keysightSD1.SD_AOU() # change to SD_AIN() if you want to use digitizers chassisNumber = descriptor.chassisNumber productName = "" # change to "" for a generic instrument id = newModule.openWithOptions(productName, chassisNumber, descriptor.slotNumber, options) if id < 0: print( "Error opening module in chassis {}, slot {}! Error code: {}, {}" .format(descriptor.chassisNumber, descriptor.slotNumber, id, keysightSD1.SD_Error.getErrorMessage(id))) print("Press any key to exit...") input() sys.exit() moduleList.append(newModule) if minChassis == 0 or minChassis > chassisNumber: minChassis = chassisNumber if maxChassis == 0 or maxChassis < chassisNumber: maxChassis = chassisNumber return (moduleList, minChassis, maxChassis)
class testSimple: wave = signadyne.SD_Wave() card = signadyne.SD_AOU() def burstexample(self): waveformFile = ['', '', ''] waveformFile[0] = os.path.join(path_noisefiles, 'Signadyne/AWGN_A.csv') print waveformFile[0] waveformFile[1] = os.path.join(path_noisefiles, 'Signadyne/AWGN_B.csv') waveformFile[2] = os.path.join(path_noisefiles, 'Signadyne/AWGN_C.csv') # Create waveforms objects in PC RAM from waveforms files print(self.card.waveformFlush()) print('wave0') print(self.wave.newFromFile(waveformFile[0])) print(self.card.waveformLoad(self.wave, 0)) print('wave1') print(self.wave.newFromFile(waveformFile[1])) print(self.card.waveformLoad(self.wave, 1)) print('wave2') print(self.wave.newFromFile(waveformFile[2])) print(self.card.waveformLoad(self.wave, 2)) print('Channel') print(self.card.channelWaveShape(nChannel=1, waveShape=6)) print(self.card.channelAmplitude(nChannel=1, amplitude=1.5)) print('queues') print(self.card.AWGflush(1)) print( self.card.AWGqueueWaveform(nAWG=1, waveformNumber=0, triggerMode=0, startDelay=0, cycles=1, prescaler=0)) print( self.card.AWGqueueWaveform(nAWG=1, waveformNumber=1, triggerMode=0, startDelay=0, cycles=1, prescaler=0)) print( self.card.AWGqueueWaveform(nAWG=1, waveformNumber=2, triggerMode=0, startDelay=0, cycles=1, prescaler=0)) print('queueConfig', self.card.AWGqueueConfig(nAWG=1, mode=1)) time.sleep(2) print('AWGstart', self.card.AWGstart(nAWG=1)) return (True, "No Error")
def performOpen(self): #SD_AOU module self.AWG = keysightSD1.SD_AOU() self.model = self.AWG.getProductNameBySlot(self.chassis, self.slot) moduleID = self.AWG.openWithSlot(self.model, self.chassis, self.slot) if moduleID < 0: print("Module open error:", moduleID) self.caches_file = caches_dir() / (self.model + '_config_caches.yaml') try: self.loadcfg() except Exception: log.exception(Exception) self.newcfg() self.savecfg()
def performOpen(self, options={}): """Perform the operation of opening the instrument connection""" # timeout self.timeout_ms = int(1000 * self.dComCfg['Timeout']) # create AWG instance self.AWG = keysightSD1.SD_AOU() AWGPart = self.AWG.getProductNameBySlot(1, int(self.comCfg.address)) if not isinstance(AWGPart, str): raise Error('Unit not available') # check that model is supported dOptionCfg = self.dInstrCfg['options'] for validId, validName in zip(dOptionCfg['model_id'], dOptionCfg['model_str']): if AWGPart.find(validId)>=0: # id found, stop searching break else: # loop fell through, raise ID error raise IdError(AWGPart, dOptionCfg['model_id']) # set model self.setModel(validName) self.AWG.openWithSlot(AWGPart, 1, int(self.comCfg.address)) # sampling rate and number of channles is set by model if validName in ('M3202', 'H3344'): # 1GS/s models self.dt = 1E-9 self.nCh = 4 elif validName in ('M3302',): # two-channel, 500 MS/s model self.dt = 2E-9 self.nCh = 2 else: # assume 500 MS/s for all other models self.dt = 2E-9 self.nCh = 4 # keep track of if waveform was updated self.lWaveUpdated = [False]*self.nCh # get hardware version - changes numbering of channels hw_version = self.AWG.getHardwareVersion() if hw_version >= 4: # KEYSIGHT - channel numbers start with 1 self.ch_index_zero = 1 else: # SIGNADYNE - channel numbers start with 0 self.ch_index_zero = 0 self.log('HW:', hw_version) # clear old waveforms self.AWG.waveformFlush() for ch in range(self.nCh): self.AWG.AWGflush(self.get_hw_ch(ch))
def create_module_inventory(module_array): # Takes array of module locations in format [chassis, slot], and returns a dictionary of modules with specific module type & location information dictionary = {} for mod in module_array: temp_mod = keysightSD1.SD_AOU( ) #Doesn't matter if it's dig or awg, it will be able to retrieve module name module_type = temp_mod.getProductNameBySlot(mod[0], mod[1]) print("Found {} in Chassis {}, Slot {}".format(module_type, mod[0], mod[1])) name = "{}_chassis{}_slot{}".format(module_type, mod[0], mod[1]) dictionary.update({name: [mod[0], mod[1]]}) temp_mod.close() return dictionary
def open_modules(self, slots, type): ''' slots = list of slot numbers of device type = string 'awg' to open awg modules, 'dig' to open digitizer modules open_modules creates and returns a list keysightSD1 module objects ''' log_string = "" log_status = 20 options = "channelNumbering=keysight" model = "" modules = [] if slots: for slot in slots: if type == 'awg': module = keysightSD1.SD_AOU() elif type == 'dig': module = keysightSD1.SD_AIN() else: raise Error('Only AWGs and digitizers are supported') # check that we haven't already assigned module to this slot if self.slot_free[slot - 1] == True: id_num = module.openWithOptions(model, self.chassis, slot, options) if id_num < 0: raise Error( "Error opening module in chassis {}, slot {}, opened with ID: {}" .format(self.chassis, slot, id_num)) if not module.hvi: raise Error( "Module in chassis {} and slot {} does not support HVI2.0... exiting" .format(awgModule.getChassis(), awgModule.getSlot())) modules.append(module) self.slot_free[slot - 1] = False log_string += 'slots status: ' + str(self.slot_free) + '\n' else: log_string += 'slot taken, check behavior' + '\n' log_status = 30 return modules, log_string, log_status
def __init__(self, chassis): ''' set up chassis the main function connects to hardware, writes a trigger instruction sequence to all hardware, then runs triggering until user interrupt ''' # modules chassis and slot numbers if self.__initialized: return self.__initialized = True self.awg_slots = [] self.dig_slots = [] self.slot_free = [True] * 18 # Ext trigger module (TODO: not sure if these values might ever change) self.chassis = chassis slotNumber = 6 partNumber = "" extTrigModule = keysightSD1.SD_AOU() status = extTrigModule.openWithSlot(partNumber, self.chassis, slotNumber) if (status < 0): raise Error( "Invalid external trigger module. Name, Chassis or Slot numbers might be invalid!" ) # Create HVI instance moduleResourceName = "KtHvi" self.hvi = pyhvi.KtHvi(moduleResourceName) # Add chassis self.hvi.platform.chassis.add_auto_detect() # initialize lists for clarity self.awgs = [] self.digs = [] # ensure that when program quits, the hardware resources will be released atexit.register(self.close)
def __init__(self, module_dict): super().__init__() self.module_dict = module_dict for key, value in self.module_dict.items(): if key[2] == '1': sd1_obj = keysightSD1.SD_AIN() sd1_obj_id = sd1_obj.openWithSlot("", value[0], value[1]) if sd1_obj_id < 0: print( "[ERROR] Test.__init__: Error opening {}".format(key)) self._module_instances.append([sd1_obj, key, value]) elif key[2] == '2': sd1_obj = keysightSD1.SD_AOU() sd1_obj_id = sd1_obj.openWithSlot("", value[0], value[1]) if sd1_obj_id < 0: print( "[ERROR] Test.__init__: Error opening {}".format(key)) self._module_instances.append([sd1_obj, key, value]) else: print( "[ERROR] Test.__init__: Did not properly parse instrument type string." )
import keysightSD1 import time num_waveforms = 1000 num_trigs = 1000 awg = keysightSD1.SD_AOU() awg_id = awg.openWithSlot("", 1, 7) # error_flush = awg.AWGflush(1) error_waveshape = awg.channelWaveShape(1, keysightSD1.SD_Waveshapes.AOU_AWG) wave = keysightSD1.SD_Wave() error_createwave = wave.newFromFile(r"C:\Users\Administrator\PycharmProjects\HVITestBench\Sin_10MHz_20456_samples.csv") # error_createwave = wave.newFromFile(r'C:\Users\Public\Documents\Keysight\SD1\Examples\Waveforms\Sin_10MHz_50samples_192cycles.csv') error_waveformload = awg.waveformLoad(wave, 1, 0) error_queueconfig = awg.AWGqueueConfig(1, keysightSD1.SD_QueueMode.CYCLIC) for i in range(0,num_waveforms): error_queue = awg.AWGqueueWaveform(1, 1, keysightSD1.SD_TriggerModes.SWHVITRIG_CYCLE, 0, 1, 0) # awg.AWGqueueWaveform(nAWG, waveformNumber=, triggerMode=, startDelay=,cycles=,prescaler=) for i in range(0,num_trigs): print("Sending %s trigger"%i) error_trigger = awg.AWGtrigger(1) time.sleep(.3)
def main(): # Initialize variables used in 'finally:' block (in case an exception is thrown early) hvi = 0 module_list = [] try: # Parse the optional --simulate argument args = parse_args() hardware_simulated = args.simulate # Set the options string based on the value of the optional --simulate argument options = 'simulate=true' if hardware_simulated else '' # Define list of module descriptors module_descriptors = [{ 'chassis_number': 1, 'slot_number': 9, 'options': options }, { 'chassis_number': 1, 'slot_number': 10, 'options': options }] # Open SD modules module_list = [] for descriptor in module_descriptors: module = keysightSD1.SD_AOU() id = module.openWithOptions('M3201A', descriptor['chassis_number'], descriptor['slot_number'], descriptor['options']) if id < 0: raise Exception( f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}" ) module_list.append(module) # Obtain SD_AOUHvi interface from modules module_hvi_list = [] for module in module_list: if not module.hvi: raise Exception( f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2' ) module_hvi_list.append(module.hvi) # Create list of triggers to use in KtHvi sequence trigger_list = [ module_hvi_list[0].triggers.front_panel_1, module_hvi_list[1].triggers.front_panel_1 ] # Create KtHvi instance module_resource_name = 'KtHvi' hvi = pyhvi.KtHvi(module_resource_name) # ********************************* # Config resource in KtHvi instance # Add chassis to KtHvi instance if hardware_simulated: hvi.platform.chassis.add_with_options( 1, 'Simulate=True,DriverSetup=model=M9018B,NoDriver=True') else: hvi.platform.chassis.add_auto_detect() # Get engine IDs from module's SD_AOUHvi interface and add each engine to KtHvi instance engine_index = 0 for module_hvi in module_hvi_list: sd_engine = module_hvi.engines.master_engine hvi.engines.add(sd_engine, f'SdEngine{engine_index}') engine_index += 1 # Configure the trigger used by the sequence for index in range(0, hvi.engines.count): engine = hvi.engines[index] trigger = engine.triggers.add(trigger_list[index], 'SequenceTrigger') trigger.configuration.direction = pyhvi.Direction.OUTPUT trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW # trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_HIGH trigger.configuration.delay = 0 trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL trigger.configuration.pulse_length = 250 # ******************************* # Start KtHvi sequences creation for index in range(0, hvi.engines.count): # Get engine in the KtHvi instance engine = hvi.engines[index] # Obtain main sequence from engine to add instructions sequence = engine.main_sequence # Add instructions to specific sequence (using sequence.programming interface) instruction1 = sequence.programming.add_instruction( 'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id ) # Add trigger write instruction to the sequence instruction1.set_parameter( hvi.instructions.instructions_trigger_write.trigger, engine.triggers['SequenceTrigger'] ) # Specify which trigger is going to be used instruction1.set_parameter( hvi.instructions.instructions_trigger_write.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction1.set_parameter( hvi.instructions.instructions_trigger_write.value, pyhvi.TriggerValue.ON ) # Specify trigger value that is going to be applyed instruction2 = sequence.programming.add_instruction( 'TriggerOff', 500, hvi.instructions.instructions_trigger_write. id) # Add trigger write instruction to the sequence instruction2.set_parameter( hvi.instructions.instructions_trigger_write.trigger, engine.triggers['SequenceTrigger'] ) # Specify which trigger is going to be used instruction2.set_parameter( hvi.instructions.instructions_trigger_write.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction2.set_parameter( hvi.instructions.instructions_trigger_write.value, pyhvi.TriggerValue.OFF ) # Specify trigger value that is going to be applyed # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface) hvi.programming.add_end('EndOfSequence', 10) # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc hvi.platform.sync_resources = [ pyhvi.TriggerResourceId.PXI_TRIGGER0, pyhvi.TriggerResourceId.PXI_TRIGGER1 ] # Compile the instrument sequence(s) hvi.compile() # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc hvi.load_to_hw() # Execute KtHvi instance time = timedelta(seconds=1) hvi.run(time) except Exception as ex: print(ex) print('helloworldmimo.py encountered the error above - exiting') finally: # Release KtHvi instance from HW (unlock resources) if hvi: hvi.release_hw() # Close all modules for module in module_list: module.close()
def main(): # Initialize variables used in 'finally:' block (in case an exception is thrown early) hvi = 0 module_list = [] try: # Parse the optional --simulate argument args = parse_args() hardware_simulated = args.simulate # Set the options string based on the value of the optional --simulate argument options = 'HVI2=true,factory=true,' + ('simulate=true' if hardware_simulated else '') # Define list of module descriptors module_descriptors = [ { 'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 9, 'options': options }, { 'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 10, 'options': options } # {'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 3, 'options': options }, # {'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 8, 'options': options }, # {'model_number': 'M3201A', 'chassis_number': 2, 'slot_number': 17, 'options': options }, # {'model_number': 'M3201A', 'chassis_number': 3, 'slot_number': 15, 'options': options }, # {'model_number': 'M3201A', 'chassis_number': 4, 'slot_number': 16, 'options': options } ] chassis_list = set() # Open SD modules for descriptor in module_descriptors: module = keysightSD1.SD_AOU() id = module.openWithOptions(descriptor['model_number'], descriptor['chassis_number'], descriptor['slot_number'], descriptor['options']) if id < 0: raise Exception( f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}" ) module_list.append(module) chassis_list.add(descriptor['chassis_number']) # Obtain SD_AOUHvi interface from modules module_hvi_list = [] for module in module_list: if not module.hvi: raise Exception( f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2' ) module_hvi_list.append(module.hvi) # Create lists of triggers to use in KtHvi sequence wait_trigger = module_hvi_list[0].triggers.pxi_2 trigger_list = [] engine_list = [] for module in module_hvi_list: trigger_list.append(module.triggers.front_panel_1) engine_list.append(module.engines.master_engine) # Create KtHvi instance module_resource_name = 'KtHvi' hvi = pyhvi.KtHvi(module_resource_name) # ********************************* # Config resource in KtHvi instance # Add chassis to KtHvi instance if hardware_simulated: for chassis_number in chassis_list: hvi.platform.chassis.add_with_options( chassis_number, 'Simulate=True,DriverSetup=model=M9018B,NoDriver=True') else: hvi.platform.chassis.add_auto_detect() # interconnects = hvi.platform.interconnects # interconnects.add_squidboards(1, 9, 2, 9) # interconnects.add_squidboards(2, 14, 3, 9) # interconnects.add_squidboards(3, 14, 4, 9) # Add each engine to KtHvi instance engine_index = 0 for engine in engine_list: hvi.engines.add(engine, f'SdEngine{engine_index}') engine_index += 1 # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for). start_trigger = hvi.engines[0].triggers.add(wait_trigger, 'StartTrigger') start_trigger.configuration.direction = pyhvi.Direction.INPUT start_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW # Add start event start_event = hvi.engines[0].events.add(wait_trigger, 'StartEvent') for index in range(0, hvi.engines.count): # Get engine in the KtHvi instance engine = hvi.engines[index] # Add trigger to engine trigger = engine.triggers.add(trigger_list[index], 'PulseOut') trigger.configuration.direction = pyhvi.Direction.OUTPUT trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW trigger.configuration.delay = 0 trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL trigger.configuration.pulse_length = 250 # ******************************* # Start KtHvi sequences creation # Add wait statement to first engine sequence (using sequence.programming interface) engine_aou1_sequence = hvi.engines[0].main_sequence wait_event = engine_aou1_sequence.programming.add_wait_event( 'wait external_trigger', 10) wait_event.event = hvi.engines[0].events['StartEvent'] wait_event.set_mode( pyhvi.EventDetectionMode.HIGH, pyhvi.SyncMode.IMMEDIATE ) # Configure event detection and synchronization modes # Add global synchronized junction to HVI instance (to all sequences!!! - using hvi.programming interface) global_junction = 'GlobalJunction' junction_time_ns = 100 hvi.programming.add_junction(global_junction, junction_time_ns) for index in range(0, hvi.engines.count): # Get engine in the KtHvi instance engine = hvi.engines[index] # Obtain main sequence from engine to add instructions sequence = engine.main_sequence # Add instructions to specific sequence (using sequence.programming interface) instruction1 = sequence.programming.add_instruction( 'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id ) # Add trigger write instruction to the sequence instruction1.set_parameter( hvi.instructions.instructions_trigger_write.trigger, engine.triggers['PulseOut'] ) # Specify which trigger is going to be used instruction1.set_parameter( hvi.instructions.instructions_trigger_write.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction1.set_parameter( hvi.instructions.instructions_trigger_write.value, pyhvi.TriggerValue.ON ) # Specify trigger value that is going to be applyed instruction2 = sequence.programming.add_instruction( 'TriggerOff', 100, hvi.instructions.instructions_trigger_write. id) # Add trigger write instruction to the sequence instruction2.set_parameter( hvi.instructions.instructions_trigger_write.trigger, engine.triggers['PulseOut'] ) # Specify which trigger is going to be used instruction2.set_parameter( hvi.instructions.instructions_trigger_write.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction2.set_parameter( hvi.instructions.instructions_trigger_write.value, pyhvi.TriggerValue.OFF ) # Specify trigger value that is going to be applyed jump_name = 'JumpStatement' jump_time = 1000 jump_destination = "Start" hvi.programming.add_jump(jump_name, jump_time, jump_destination) # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface) hvi.programming.add_end('EndOfSequence', 10) # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc hvi.platform.sync_resources = [ pyhvi.TriggerResourceId.PXI_TRIGGER5, pyhvi.TriggerResourceId.PXI_TRIGGER6, pyhvi.TriggerResourceId.PXI_TRIGGER7 ] # Compile the instrument sequence(s) hvi.compile() # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc hvi.load_to_hw() # Execute KtHvi instance time = timedelta(seconds=0) hvi.run(time) # If running with hardware, stop execution here until the user presses a key to finish if not hardware_simulated: print("Press enter to finish...") input() except Exception as ex: print(ex) print('mimoresync.py encountered the error above - exiting') finally: # Release KtHvi instance from HW (unlock resources) if hvi: hvi.release_hw() # Close all modules for module in module_list: module.close()
class test_fastbranching(Test): # Dummy attributes # Add if needed # Attributes accessible through object initialization test_key = "fastbranching" # Attributes accessible through class methods number_modules = None # set in init() chassis_list = [] # set in init() hvi = None #This gets set in the hvi_configurator master_module_index = None #set in init() seq_master = None #set at end of hvi_configurator extTrigModule = keysightSD1.SD_AOU() def __init__(self, module_dict, master_module_location ): #master_module_location is a dict {chassis: x, slot: y} super().__init__(module_dict) self.number_modules = len(module_dict) for i in range(0, self.number_modules): self.chassis_list.append(self.module_instances[i][2][1]) if master_module_location["chassis"] == self.module_instances[i][ 2][0] and master_module_location[ "slot"] == self.module_instances[i][2][1]: self.master_module_index = i def run_hvi(self): # Compile the instrument sequence(s) self.hvi.compile() # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc self.hvi.load_to_hw() # Execute KtHvi instance time = timedelta(seconds=0) self.hvi.run(time) def release_hvi(self): self.hvi.release_hw() def setup_ext_trig_module(self, trig_mod_location): partNumber = "" # Connect to trigger module status = self.extTrigModule.openWithSlot(partNumber, trig_mod_location[0], trig_mod_location[1]) if (status < 0): print("Error opening trigger module. Press enter to exit") input() sys.exit() def triggerPXI2(self, moduleAOU): moduleAOU.PXItriggerWrite( keysightSD1.SD_TriggerExternalSources.TRIGGER_PXI2, keysightSD1.SD_TriggerValue.HIGH) moduleAOU.PXItriggerWrite( keysightSD1.SD_TriggerExternalSources.TRIGGER_PXI2, keysightSD1.SD_TriggerValue.LOW) moduleAOU.PXItriggerWrite( keysightSD1.SD_TriggerExternalSources.TRIGGER_PXI2, keysightSD1.SD_TriggerValue.HIGH) def close_modules(self): for module_inst in self.module_instances: module_inst[0].close() def loop(self): wfNum = 1 nWfm = 2 # Loop as many times as desired, press q to exit while True: for index in range(0, self.hvi.engines.count): engine = self.hvi.engines[index] seq = engine.main_sequence seq.registers["WfNum"].write(wfNum) print("N. of external triggers received at Module0: cycleCnt = {}". format(self.seq_master.registers["cycleCnt"].read())) print("Press enter to trigger PXI2, press q to exit") key = input() if key == 'q': break else: self.triggerPXI2(self.extTrigModule) # Change wfNum at each iteration if (wfNum >= nWfm): # general case of nWfm wfNum = 1 else: wfNum = wfNum + 1 # Release HVI instance from HW (unlock resources) print("Exiting...")
def main(): # Initialize variables used in 'finally:' block (in case an exception is thrown early) hvi = 0 module_list = [] try: # Parse the optional --simulate argument args = parse_args() hardware_simulated = args.simulate # Set the options string based on the value of the optional --simulate argument options = 'simulate=true' if hardware_simulated else '' # Define list of module descriptors module_descriptors = [{ 'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 9, 'options': options }, { 'model_number': 'M3201A', 'chassis_number': 1, 'slot_number': 10, 'options': options }] # Open SD modules nModules = 0 for descriptor in module_descriptors: module = keysightSD1.SD_AOU() id = module.openWithOptions(descriptor['model_number'], descriptor['chassis_number'], descriptor['slot_number'], descriptor['options']) if id < 0: raise Exception( f"Error opening module in chassis: {descriptor['chassis_number']}, {descriptor['slot_number']}, opened with ID: {id}" ) module_list.append(module) nModules += 1 # Queue AWG Waveforms for index in range(0, nModules): awgQueueWaveform(module_list[index]) # Obtain SD_AOUHvi interface from modules module_hvi_list = [] for module in module_list: if not module.hvi: raise Exception( f'Module in chassis {module.chassis} and slot {module.slot} does not support HVI2' ) module_hvi_list.append(module.hvi) # Create lists of triggers to use in KtHvi sequence wait_trigger = module_hvi_list[0].triggers.pxi_2 trigger_list = [] engine_list = [] for module in module_hvi_list: trigger_list.append(module.triggers.front_panel_1) engine_list.append(module.engines.master_engine) # Create KtHvi instance module_resource_name = 'KtHvi' hvi = pyhvi.KtHvi(module_resource_name) # ********************************* # Config resource in KtHvi instance # Add chassis to KtHvi instance if hardware_simulated: hvi.platform.chassis.add_with_options( 1, 'Simulate=True,DriverSetup=model=M9018B,NoDriver=True') else: hvi.platform.chassis.add_auto_detect() # Add each engine to KtHvi instance engine_index = 0 for engine in engine_list: hvi.engines.add(engine, f'SdEngine{engine_index}') engine_index += 1 # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for). start_trigger = hvi.engines[0].triggers.add(wait_trigger, 'StartTrigger') start_trigger.configuration.direction = pyhvi.Direction.INPUT start_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW # Add start event start_event = hvi.engines[0].events.add(wait_trigger, 'StartEvent') print("HVI Engine Count {} \n".format(hvi.engines.count)) # ******************************* # Start KtHvi sequences creation # Add wait statement to first engine sequence (using sequence.programming interface) engine_aou1_sequence = hvi.engines[0].main_sequence wait_event = engine_aou1_sequence.programming.add_wait_event( 'wait external_trigger', 10) wait_event.event = hvi.engines[0].events['StartEvent'] wait_event.set_mode( pyhvi.EventDetectionMode.HIGH, pyhvi.SyncMode.IMMEDIATE ) # Configure event detection and synchronization modes # Add global synchronized junction to HVI instance (to all sequences!!! - using hvi.programming interface) global_junction = 'GlobalJunction' junction_time_ns = 10 hvi.programming.add_junction(global_junction, junction_time_ns) #Create a list of possible actions for AWG modules actions = module_list[0].hvi.actions # Define global AWG Trigger Action and Add it to the HVI Engine hvi.engines[0].actions.add(actions.awg1_trigger, 'AWG1_trigger') hvi.engines[0].actions.add(actions.awg2_trigger, 'AWG2_trigger') hvi.engines[0].actions.add(actions.awg3_trigger, 'AWG3_trigger') hvi.engines[0].actions.add(actions.awg4_trigger, 'AWG4_trigger') #Add AWG trigger to each module's sequence for index in range(0, hvi.engines.count): # Get engine in the KtHvi instance engine = hvi.engines[index] # Obtain main sequence from engine to add instructions sequence = engine.main_sequence #list of module possible actions actionList = [ hvi.engines[0].actions['AWG1_trigger'], hvi.engines[0].actions['AWG2_trigger'], hvi.engines[0].actions['AWG3_trigger'], hvi.engines[0].actions['AWG4_trigger'] ] #Add AWG trigger instruction to the sequence actionExecute = hvi.instructions.instructions_action_execute instruction1 = sequence.programming.add_instruction( "AWG trigger", 100, actionExecute.id) instruction1.set_parameter(actionExecute.action, actionList) #Synchronized jump jump_name = 'JumpStatement' jump_time = 1000 jump_destination = "Start" hvi.programming.add_jump(jump_name, jump_time, jump_destination) # Add global synchronized end to close KtHvi execution (close all sequences - using hvi-programming interface) hvi.programming.add_end('EndOfSequence', 10) # Assign triggers to KtHvi object to be used for HVI-managed synchronization, data sharing, etc #NOTE: In a multi-chassis setup ALL the PXI lines listed below need to be shared among each squid board pair by means of SMB cable connections hvi.platform.sync_resources = [ pyhvi.TriggerResourceId.PXI_TRIGGER5, pyhvi.TriggerResourceId.PXI_TRIGGER6, pyhvi.TriggerResourceId.PXI_TRIGGER7 ] #Assign clock frequencies that are outside the set of the clock frequencies of each HVI engine hvi.synchronization.non_hvi_core_clocks = [10e6] #Force synchronization hvi.synchronization.synchronize(True) # Compile the instrument sequence(s) hvi.compile() print("HVI Compiled") # Load the KtHvi instance to HW: load sequence(s), config triggers/events/..., lock resources, etc hvi.load_to_hw() print("HVI Loaded to HW") # Execute KtHvi instance time = timedelta(seconds=0) hvi.run(time) print("HVI Running...") # If running with hardware, stop execution here until the user presses a key to finish if not hardware_simulated: print("Press enter to finish...") input() except Exception as ex: print(ex) print('HD1_AN1_Multi.py encountered the error above - exiting') finally: # Release KtHvi instance from HW (unlock resources) if hvi: hvi.release_hw() # Close all modules for module in module_list: module.close()
moduleInID = moduleIn.openWithSlot(PRODUCT, CHASSIS, SLOT_IN) if moduleInID < 0: print("Error opening module IN - error code:", moduleInID) else: print("===== MODULE IN =====") print("ID:\t\t", moduleInID) print("Product name:\t", moduleIn.getProductName()) print("Serial number:\t", moduleIn.getSerialNumber()) print("Chassis:\t", moduleIn.getChassis()) print("Slot:\t\t", moduleIn.getSlot()) print() # CREATE AND OPEN MODULE OUT moduleOut = keysightSD1.SD_AOU() moduleOutID = moduleOut.openWithSlot(PRODUCT, CHASSIS, SLOT_OUT) if moduleOutID < 0: print("Error opening module OUT - error code:", moduleOutID) else: print("===== MODULE OUT =====") print("ID:\t", moduleOutID) print("Product name:\t", moduleOut.getProductName()) print("Serial number:\t", moduleOut.getSerialNumber()) print("Chassis:\t", moduleOut.getChassis()) print("slot:\t\t", moduleOut.getSlot()) if moduleInID > -1 and moduleOutID > -1: # CONFIGURE TRIGGERS
AWG_a_channel = 1 #Remember to ensure these registers get set AWG_b_channel = 1 AWG_NAME = 'M3201A' waveshape = keysightSD1.SD_Waveshapes.AOU_AWG prescaler = 0 product = '' ResourceName = "KtHvi" #user defined constants #Defining wave with saved file wave_id = 1 wave = keysightSD1.SD_Wave() wave.newFromFile('Gaussian.csv') #initialize AWG AWG_a = keysightSD1.SD_AOU() AWG_b = keysightSD1.SD_AOU() AWG_ID_a = AWG_a.openWithSlot(product,chassis,AWG_slot_a) AWG_ID_b = AWG_b.openWithSlot(product,chassis,AWG_slot_b) if AWG_ID_a < 0: print("Error opening AWG_a") error_chanWaveShape = AWG_a.channelWaveShape(AWG_a_channel,waveshape) AWG_a.waveformFlush() AWG_a.AWGflush(AWG_a_channel) #clear waveform from channel if AWG_ID_b < 0: print("Error opening AWG_b") error_chanWaveShape = AWG_b.channelWaveShape(AWG_b_channel,waveshape) AWG_b.waveformFlush()
class Test_HVIexternaltrigger(Test): # Dummy attributes Amplitude = 1 wave_id = 1 prescaler = 0 start_delay = 0 cycles = 0 # Attributes accessible through object initialization test_key = "HVI external trigger" module_a_slot = None module_a_channel = None module_b_slot = None module_b_channel = None # Attributes accessible through class methods module_a = keysightSD1.SD_AOU() module_b = keysightSD1.SD_AOU() waveform = keysightSD1.SD_Wave() hvi = keysightSD1.SD_HVI() def __init__(self, module_dict, module_a_slot, module_a_channel, module_b_slot, module_b_channel): super().__init__(module_dict) self.module_a_slot = module_a_slot self.module_a_channel = module_a_channel self.module_b_slot = module_b_slot self.module_b_channel = module_b_channel self._associate() # This private method associates the module modules (publicly accessible) of this test with the modules # created in the base class def _associate(self): for module in self._module_instances: if module[2][ 1] == self.module_a_slot: # if a module was found in master_slot, assign it to master_module self.module_a = module[0] elif module[2][1] == self.module_b_slot: self.module_b = module[0] else: print( "[ERROR] Associate function: Module found in slot that was not specified as master or slave" ) def send_PXI_trigger_pulse(self, PXI_line_nbr, delay=.2): time.sleep(delay) self.module.PXItriggerWrite(PXI_line_nbr, 0) time.sleep(delay) self.module.PXItriggerWrite(PXI_line_nbr, 1) def set_waveform(self, filestr): self.waveform.newFromFile(filestr) print( "Loaded {} into HVI Trigger Sync Test's waveform".format(filestr)) def set_hvi(self, filestr): self.hvi.open(filestr) self.hvi.compile() self.hvi.load() print("Loaded {}.HVI into HVI Trigger Sync Test".format(filestr))
def on_activate(self): self.analog_amplitudes = {} self.analog_offsets = {} # loaded sequence self.last_sequence = None # loaded waveforms, channel -> waveform name self.loaded_waveforms = {} # uploaded waveforms, waveform name -> instrument wfm number self.written_waveforms = {} self.chcfg = { 'a_ch1': M3202ChannelCfg(), 'a_ch2': M3202ChannelCfg(), 'a_ch3': M3202ChannelCfg(), 'a_ch4': M3202ChannelCfg(), } constraints = PulserConstraints() constraints.sample_rate.min = 4e8 constraints.sample_rate.max = 1e9 constraints.sample_rate.step = 1.0 constraints.sample_rate.default = 1e9 constraints.a_ch_amplitude.min = 0 constraints.a_ch_amplitude.max = 1.5 constraints.a_ch_amplitude.step = 0.01 constraints.a_ch_amplitude.default = 1.5 constraints.a_ch_offset.min = 0 constraints.a_ch_offset.max = 1.5 constraints.a_ch_offset.step = 0.01 constraints.a_ch_offset.default = 0.0 # FIXME: Enter the proper digital channel low constraints: constraints.d_ch_low.min = 0.0 constraints.d_ch_low.max = 0.0 constraints.d_ch_low.step = 0.0 constraints.d_ch_low.default = 0.0 # FIXME: Enter the proper digital channel high constraints: constraints.d_ch_high.min = 0.0 constraints.d_ch_high.max = 0.0 constraints.d_ch_high.step = 0.0 constraints.d_ch_high.default = 0.0 constraints.waveform_length.min = 30 constraints.waveform_length.max = 1e9 constraints.waveform_length.step = 10 constraints.waveform_length.default = 1000 # FIXME: Check the proper number for your device constraints.waveform_num.min = 1 constraints.waveform_num.max = 1024 constraints.waveform_num.step = 1 constraints.waveform_num.default = 1 # FIXME: Check the proper number for your device constraints.sequence_num.min = 1 constraints.sequence_num.max = 1 constraints.sequence_num.step = 1 constraints.sequence_num.default = 1 # FIXME: Check the proper number for your device constraints.subsequence_num.min = 0 constraints.subsequence_num.max = 0 constraints.subsequence_num.step = 0 constraints.subsequence_num.default = 0 # If sequencer mode is available then these should be specified constraints.repetitions.min = 0 constraints.repetitions.max = 65536 constraints.repetitions.step = 1 constraints.repetitions.default = 0 # ToDo: Check how many external triggers are available constraints.event_triggers = ['SOFT', 'EXT', 'SOFT_CYCLE', 'EXT_CYCLE'] constraints.flags = [] constraints.sequence_steps.min = 1 constraints.sequence_steps.max = 1024 constraints.sequence_steps.step = 1 constraints.sequence_steps.default = 1 activation_config = OrderedDict() activation_config['all'] = frozenset({'a_ch1', 'a_ch2', 'a_ch3', 'a_ch4'}) activation_config['one'] = frozenset({'a_ch1'}) activation_config['two'] = frozenset({'a_ch1', 'a_ch2'}) activation_config['three'] = frozenset({'a_ch1', 'a_ch2', 'a_ch3'}) constraints.activation_config = activation_config # FIXME: additional constraint really necessary? constraints.dac_resolution = {'min': 14, 'max': 14, 'step': 1, 'unit': 'bit'} constraints.sequence_option = SequenceOption.FORCED self._constraints = constraints self.awg = ksd1.SD_AOU() aouID = self.awg.openWithSerialNumberCompatibility( 'M3202A', self.serial, ksd1.SD_Compatibility.KEYSIGHT) # Check AWG Connection for errors if aouID < 0: self.awg.close() raise Exception('AWG Error: {0} {1}'.format(aouID, ksd1.SD_Error.getErrorMessage(aouID))) self.ser = self.awg.getSerialNumber() self.model = self.awg.getProductName() self.fwver = self.awg.getFirmwareVersion() self.hwver = self.awg.getHardwareVersion() self.chassis = self.awg.getChassis() self.ch_slot = self.awg.getSlot() self.reset() self.log.info('Keysight AWG Model: {} serial: {} ' 'FW Ver: {} HW Ver: {} Chassis: {} Slot: {}' ''.format(self.model, self.ser, self.fwver, self.hwver, self.chassis, self.ch_slot))
sys.path.append('C:\Research\measurements\libs') import keysightSD1 as ks import matplotlib.pyplot as plt import numpy as np import time # MODULE CONSTANTS product = "" chassis = 1 # change slot numbers to your values slot_awg = 2 AWGobj = ks.SD_AOU() AWGid = AWGobj.openWithSlot(product, chassis, slot_awg) if AWGid < 0: print("Error opening module IN - error code:", AWGid) else: print("===== MODULE IN =====") print("ID:\t\t", AWGid) print("Product name:\t", AWGobj.getProductName()) print("Serial number:\t", AWGobj.getSerialNumber()) print("Chassis:\t", AWGobj.getChassis()) print("Slot:\t\t", AWGobj.getSlot()) def waveform_gen_test(channel=0, fc=50e6,
0.98, 0.99, 1] # MODULE CONSTANTS PRODUCT = "" CHASSIS = 1 # change slot number to your value SLOT = 5 CHANNEL = 0 AMPLITUDE = 1.0 # CREATE AND OPEN MODULE module = keysightSD1.SD_AOU() moduleID = module.openWithSlot(PRODUCT, CHASSIS, SLOT) if moduleID < 0: print("Module open error:", moduleID) else: print("Module opened:", moduleID) print("Module name:", module.getProductName()) print("slot:", module.getSlot()) print("Chassis:", module.getChassis()) print() module.channelWaveShape(0, keysightSD1.SD_Waveshapes.AOU_AWG) module.channelAmplitude(0, AMPLITUDE)
class Test_FastBranching(Test): # Dummy attributes Amplitude = 1 wave_id_array = [0, 1, 2, 3] prescaler = 0 start_delay = 1 cycles = 1 # Attributes accessible through object initialization test_key = "FastBranching" master_slot = None slave_slot = None master_index = None #index in HVI sequence (might need this if HVI project is built in simulate mode) slave_index = None #index in HVI sequence (might need this if HVI project is built in simulate mode) master_channel = None slave_channel = None # Attributes accessible through class methods master_module = keysightSD1.SD_AOU( ) #assigned with call to associate() method slave_module = keysightSD1.SD_AOU( ) #assigned with call to associate() method waveform_array = [] hvi = keysightSD1.SD_HVI() def __init__(self, module_dict, master_slot, slave_slot, master_channel, slave_channel, master_index=0, slave_index=1): super().__init__(module_dict) self.master_slot = master_slot self.slave_slot = slave_slot self.master_index = master_index self.slave_index = slave_index self.master_channel = master_channel self.slave_channel = slave_channel self._associate() # This private method associates the master & slave modules (publicly accessible) of this test with the modules # created in the base class def _associate(self): for module in self._module_instances: if module[2][ 1] == self.master_slot: # if a module was found in master_slot, assign it to master_module self.master_module = module[0] elif module[2][ 1] == self.slave_slot: # if a module was found in slave_slot, assign it to slave_module self.slave_module = module[0] else: print( "[ERROR] Associate function: Module found in slot that was not specified as master or slave" ) def send_PXI_trigger_pulse(self, PXI_line_nbr, delay=.1): time.sleep(delay) self.master_module.PXItriggerWrite(PXI_line_nbr, 0) time.sleep(delay) self.master_module.PXItriggerWrite(PXI_line_nbr, 1) def add_waveform(self, filestr): wave = keysightSD1.SD_Wave() wave.newFromFile(filestr) self.waveform_array.append(wave) print("Loaded {} into Fast Branching Test's waveform array".format( filestr)) def set_hvi(self, filestr): self.hvi.open(filestr) self.hvi.compile() self.hvi.load() print("Loaded {}.HVI into Fast Branching Test".format(filestr))
def main(): # Initialize variables used in 'finally:' block (in case an exception is thrown early) hvi = 0 module = None try: # Parse the optional --simulate argument args = parse_args() hardware_simulated = args.simulate # Set the options string based on the value of the optional --simulate argument options = 'simulate=true' if hardware_simulated else '' # Open SD module module = keysightSD1.SD_AOU() chassis_number = 1 slot_number = 4 module_id = module.openWithOptions('M3201A', chassis_number, slot_number, options) if module_id < 0: raise Exception( f'Error opening module in chassis: {chassis_number}, {slot_number}, opened with ID: {module_id}' ) print(f'Module ID {module_id} opened') # Create SD_AOUHvi object from SD module sd_hvi = module.hvi if not sd_hvi: raise Exception('Module does not support HVI2') # Get engine from SD module's SD_AOUHvi object sd_engine_aou = sd_hvi.engines.master_engine # Create KtHvi instance module_resource_name = 'KtHvi' hvi = pyhvi.KtHvi(module_resource_name) # Add SD HVI engine to KtHvi instance engine = hvi.engines.add(sd_engine_aou, 'SdEngine1') # Configure the trigger used by the sequence sequence_trigger = engine.triggers.add(sd_hvi.triggers.pxi_5, 'SequenceTrigger') sequence_trigger.configuration.direction = pyhvi.Direction.OUTPUT sequence_trigger.configuration.drive_mode = pyhvi.DriveMode.PUSH_PULL sequence_trigger.configuration.trigger_polarity = pyhvi.TriggerPolarity.ACTIVE_LOW sequence_trigger.configuration.delay = 0 sequence_trigger.configuration.trigger_mode = pyhvi.TriggerMode.LEVEL sequence_trigger.configuration.pulse_length = 250 # ******************************* # Start KtHvi sequences creation sequence = engine.main_sequence # Obtain main squence from the created HVI instrument instruction1 = sequence.programming.add_instruction( 'TriggerOn', 10, hvi.instructions.instructions_trigger_write.id ) # Add trigger write instruction to the sequence instruction1.set_parameter( hvi.instructions.instructions_trigger_write.parameters.trigger, sequence_trigger) # Specify which trigger is going to be used instruction1.set_parameter( hvi.instructions.instructions_trigger_write.parameters.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction1.set_parameter( hvi.instructions.instructions_trigger_write.parameters.value, pyhvi.TriggerValue.ON ) # Specify trigger value that is going to be applied instruction2 = sequence.programming.add_instruction( 'TriggerOff', 100, hvi.instructions.instructions_trigger_write.id ) # Add trigger write instruction to the sequence instruction2.set_parameter( hvi.instructions.instructions_trigger_write.parameters.trigger, sequence_trigger) # Specify which trigger is going to be used instruction2.set_parameter( hvi.instructions.instructions_trigger_write.parameters.sync_mode, pyhvi.SyncMode.IMMEDIATE) # Specify synchronization mode instruction2.set_parameter( hvi.instructions.instructions_trigger_write.parameters.value, pyhvi.TriggerValue.OFF ) # Specify trigger value that is going to be applied hvi.programming.add_end( 'EndOfSequence', 10) # Add the end statement at the end of the sequence # Assign triggers to HVI object to be used for HVI-managed synchronization, data sharing, etc trigger_resources = [ pyhvi.TriggerResourceId.PXI_TRIGGER0, pyhvi.TriggerResourceId.PXI_TRIGGER1 ] hvi.platform.sync_resources = trigger_resources hvi.compile() # Compile the instrument sequence(s) hvi.load_to_hw() # Load the instrument sequence(s) to HW time = timedelta(seconds=1) hvi.run(time) # Execute the instrument sequence(s) except Exception as ex: print(ex) print('helloworld.py encountered the error above - exiting') finally: # Release KtHvi instance from HW (unlock resources) if hvi: hvi.release_hw() # Close module if module: module.close()
import sys sys.path.append(r"C:\Program Files (x86)\Keysight\SD1\Libraries\Python") import keysightSD1 as key import hvi_wrap as hvi logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) # Define a simple AWG 'test' module module1 = hvi.ModuleDescriptor("AWG_0") module2 = hvi.ModuleDescriptor("AWG_1") modules = [module1, module2] module1.handle = key.SD_AOU() module1.handle.openWithOptions( "M3202A", 1, 2, "simulate=true, channelNumbering=Keysight", ) module2.handle = key.SD_AOU() module2.handle.openWithOptions( "M3202A", 1, 4, "simulate=true, channelNumbering=Keysight", ) # Create the main Sequencer and assign all the resources to be used
def main(): hwSimulated = False if hwSimulated: options = ",simulated=true" elif hwSimulated == False: options = "" else: print("hwSimulated not set to valid value") sys.exit() # Create module definitions moduleDescriptors = [ ModuleDescriptor(1, 7, options), ModuleDescriptor(1, 15, options) ] moduleList = [] minChassis = 0 maxChassis = 0 # Open modules for descriptor in moduleDescriptors: newModule = keysightSD1.SD_AOU() chassisNumber = descriptor.chassisNumber id = newModule.openWithSlot("", chassisNumber, descriptor.slotNumber) if id < 0: print( "Error opening module in chassis {}, slot {}, opened with ID: {}" .format(descriptor.chassisNumber, descriptor.slotNumber, id)) print("Press any key to exit...") input() sys.exit() # Determine what minChassis is based off information in module descriptors moduleList.append(newModule) if minChassis == 0 or minChassis > chassisNumber: minChassis = chassisNumber if maxChassis == 0 or maxChassis < chassisNumber: maxChassis = chassisNumber # Queue waveforms for index in range(0, len(moduleList)): AWGqueueWfm(moduleList[index]) # Obtain HVI interface from modules moduleHviList = [] for module in moduleList: if not module.hvi: print( "Module in chassis {} and slot {} does not support HVI2.0... exiting" .format(module.getChassis(), module.getSlot())) sys.exit() moduleHviList.append(module.hvi) ###################################### ## Configure resources in HVI instance ###################################### # Add engines to the engineList engineList = [] for module in moduleHviList: engineList.append(module.engines.master_engine) # Create HVI instance moduleResourceName = "KtHvi" hvi = pyhvi.KtHvi(moduleResourceName) # Assign triggers to HVI object to be used for HVI-managed synch, data sharing, etc. triggerResources = [ pyhvi.TriggerResourceId.PXI_TRIGGER5, pyhvi.TriggerResourceId.PXI_TRIGGER6, pyhvi.TriggerResourceId.PXI_TRIGGER7 ] hvi.platform.sync_resources = triggerResources # Assign clock frequences that are outside the set of the clock frequencies of each hvi engine nonHVIclocks = [10e6] hvi.synchronization.non_hvi_core_clocks = nonHVIclocks if engineList.__len__() > 1: # Add chassis if hwSimulated: for chassis in range(minChassis, maxChassis + 1): hvi.platform.chassis.add_with_options( chassis, "Simulate=True,DriverSetup=model=M9018B,NoDriver=True") else: hvi.platform.chassis.add_auto_detect() ##### Uncomment for debugging with squidboard # for chassis in range(minChassis, maxChassis): # lowSlot = 14 # if chassis == minChassis: # lowSlot = 9 # # hvi.platform.add_squidboards(chassis, lowSlot, chassis + 1, 9) # Get engine IDs engine_count = 0 for engineID in engineList: hvi.engines.add(engineID, "SdEngine{}".format(engine_count)) engine_count += 1 ###################################### ## Start HVI sequence creation ###################################### print("Press enter to begin creation of the HVI sequence") input() # Create register cycleCnt in module0, the module waiting for external trigger events seq0 = hvi.engines[0].main_sequence cycleCnt = seq0.registers.add("cycleCnt", pyhvi.RegisterSize.SHORT) # Create a register WfNum in each PXI module. WfNum will be used to queue waveforms for index in range(0, hvi.engines.count): engine = hvi.engines[index] seq = engine.main_sequence seq.registers.add("WfNum", pyhvi.RegisterSize.SHORT) # Create list of module resources to use in HVI sequence waitTrigger = moduleHviList[0].triggers.pxi_2 hvi.engines[0].events.add(waitTrigger, "extEvent") # Add wait statement to first engine sequence (using sequence.programming interface) waitEvent = seq0.programming.add_wait_event("wait_external_trigger", 10) waitEvent.event = hvi.engines[0].events["extEvent"] waitEvent.set_mode(pyhvi.EventDetectionMode.TRANSITION_TO_IDLE, pyhvi.SyncMode.IMMEDIATE) # Add wait trigger just to be sure Pxi from the cards is not interfering Pxi2 triggering from a third card (the trigger the waitEvent is waiting for). trigger = hvi.engines[0].triggers.add(waitTrigger, "extTrigger") trigger.configuration.direction = pyhvi.Direction.INPUT trigger.configuration.polarity = pyhvi.TriggerPolarity.ACTIVE_HIGH # Add global synchronized junction to HVI instance using hvi.programming interface junctionName = "GlobalJunction" junctionTime_ns = 10 hvi.programming.add_junction(junctionName, junctionTime_ns) # Parameters for AWG queue WFM with register startDelay = 0 nCycles = 1 prescaler = 0 nAWG = 0 # Add actions to HVI engines for index in range(0, hvi.engines.count): moduleActions = moduleList[index].hvi.actions engine = hvi.engines[index] engine.actions.add(moduleActions.awg1_start, "awg_start1") engine.actions.add(moduleActions.awg2_start, "awg_start2") engine.actions.add(moduleActions.awg1_trigger, "awg_trigger1") engine.actions.add(moduleActions.awg2_trigger, "awg_trigger2") # Add AWG queue waveform and AWG trigger to each module's sequence for index in range(0, hvi.engines.count): engine = hvi.engines[index] # Obtain main sequence from engine to add instructions seq = engine.main_sequence # Add AWG queue waveform instruction to the sequence AwgQueueWfmInstrId = moduleList[ index].hvi.instructions.queuewaveform.id AwgQueueWfmId = moduleList[ index].hvi.instructions.queuewaveform.waveform.id instruction0 = seq.programming.add_instruction("awgQueueWaveform", 10, AwgQueueWfmInstrId) instruction0.set_parameter(AwgQueueWfmId, seq.registers["WfNum"]) instruction0.set_parameter( moduleList[index].hvi.instructions.queuewaveform.channel.id, nAWG) instruction0.set_parameter( moduleList[index].hvi.instructions.queuewaveform.trigger_mode.id, keysightSD1.SD_TriggerModes.SWHVITRIG) instruction0.set_parameter( moduleList[index].hvi.instructions.queuewaveform.start_delay.id, startDelay) instruction0.set_parameter( moduleList[index].hvi.instructions.queuewaveform.cycles.id, nCycles) instruction0.set_parameter( moduleList[index].hvi.instructions.queuewaveform.prescaler.id, prescaler) awgTriggerList = [ engine.actions["awg_trigger1"], engine.actions["awg_trigger2"] ] instruction2 = seq.programming.add_instruction( "AWG trigger", 2e3, hvi.instructions.action_execute.id) instruction2.set_parameter(hvi.instructions.action_execute.action, awgTriggerList) # Increment cycleCnt in module0 instructionRYinc = seq0.programming.add_instruction( "add", 10, hvi.instructions.add.id) instructionRYinc.set_parameter(hvi.instructions.add.left_operand, 1) instructionRYinc.set_parameter(hvi.instructions.add.right_operand, cycleCnt) instructionRYinc.set_parameter(hvi.instructions.add.result_register, cycleCnt) # Global Jump jumpName = "jumpStatement" jumpTime = 10000 jumpDestination = "Start" hvi.programming.add_jump(jumpName, jumpTime, jumpDestination) # Add global synchronized end to close HVI execution (close all sequences - using hvi-programming interface) hvi.programming.add_end("EndOfSequence", 100) ############################################ ## Compile and run HVI2.0 virtual instrument ############################################ # Compile the sequence hvi.compile() # Load the HVI to HW: load sequences, config triggers/events/..., lock resources, etc. hvi.load_to_hw() print("Press enter to start HVI...") input() time = timedelta(seconds=0) hvi.run(time) status = 1 chassisNumber = 1 slotNumber = 8 extTrigModule = keysightSD1.SD_AOU() partNumber = "" # Connect to trigger module status = extTrigModule.openWithSlot(partNumber, chassisNumber, slotNumber) if (status < 0): print( "Invalid Module Name, Chassis or Slot numbers might be invalid! Press enter to quit" ) input() sys.exit() # initialize register cycleCnt seq0.registers["cycleCnt"].write(0) wfNum = 1 nWfm = 2 # Loop as many times as desired, press q to exit while True: for index in range(0, hvi.engines.count): engine = hvi.engines[index] seq = engine.main_sequence seq.registers["WfNum"].write(wfNum) print("N. of external triggers received at Module0: cycleCnt = {}". format(seq0.registers["cycleCnt"].read())) print("Press enter to trigger PXI2, press q to exit") key = input() if key == 'q': break else: triggerPXI2(extTrigModule) # Change wfNum at each iteration if (wfNum >= nWfm): # general case of nWfm wfNum = 1 else: wfNum = wfNum + 1 # Release HVI instance from HW (unlock resources) print("Exiting...") hvi.release_hw() # Close modules for module in moduleList: module.close()
import numpy # Import numpy which is used to make an array # ---------- # Specify values for variables product = 'M3202A' # Product's model number chassis = 0 # Chassis number holding product slot = 7 # Slot number of product in chassis channel = 2 # Channel being used amplitude = 1 # (Unit: Vp) Amplitude of AWG output signal (0.1 Vp) waveshape = keysightSD1.SD_Waveshapes.AOU_AWG # Specify AWG output delay = 0 # (Unit: ns) Delay after trigger before generating output. cycles = 0 # Number of cycles. Zero specifies infinite cycles. # Otherwise, a new trigger is required to actuate each cycle prescaler = 0 # Integer division reduces high freq signals to lower frequency # ---------- # Select settings and use specified variables awg = keysightSD1.SD_AOU() # Creates SD_AOU object called awg awg.openWithSlot(product, chassis, slot) # Connects awg object to module awg.channelAmplitude(channel, amplitude) # Sets output amplitude for awg awg.channelWaveShape(channel, waveshape) # Sets output signal type for awg awg.waveformFlush() # Cleans the queue awg.AWGflush(channel) # Stops signal from outputing out of channel 1 # Create an array that represents a sawtooth signal using "numpy" array = numpy.zeros(10000) # Create array of zeros with 1000 elements array[0] = -1 # Initialize element 0 as -0.5 for i in range(1, len(array)): # This for..loop will increment from -0.5 array[i] = array[i - 1] + .0002 # Increment by .001 every iteration wave = keysightSD1.SD_Wave() # Create SD_Wave object and call it "wave" # (will place the array inside "wave") error = wave.newFromArrayDouble( keysightSD1.SD_WaveformTypes.WAVE_ANALOG, array.tolist()) # Place the array into the "wave" object