Source code for pylablib.devices.AWG.specific

from .generic import GenericAWG


[docs] class Agilent33500(GenericAWG): """ Agilent 33500 AWG. Args: channels_number: number of channels; if ``"auto"``, try to determine automatically (by certain commands causing errors) """ def __init__(self, addr, channels_number="auto"): self._channels_number=channels_number GenericAWG.__init__(self,addr)
[docs] class Agilent33220A(GenericAWG): """ Agilent 33220A AWG. """ pass
[docs] class InstekAFG2225(GenericAWG): """ Instek AFG2225 AWG. Compared to 2000/2100 series, has one extra channel and a bit more capabilities (burst trigger, pulse function) """ _exclude_commands={"output_polarity","output_sync","trigger_output","output_trigger_slope"} _supported_functions={"sine","square","noise","ramp","pulse","user"} _set_angle_unit=False _force_channel_source_pfx=True _channels_number=2 _range_mode="amp_off" _amplitude_opc_check=True def __init__(self, addr): GenericAWG.__init__(self,addr) for ch in range(1,self._channels_number+1): self._modify_scpi_parameter("offset","DCOFFSET",channel=ch) self._modify_scpi_parameter("duty_cycle","SQUARE:DCYCLE",channel=ch) self._modify_scpi_parameter("ramp_symmetry","RAMP:SYMMETRY",channel=ch) self._modify_scpi_parameter("pulse_width","PULSE:WIDTH",channel=ch) self._modify_scpi_parameter("trigger_source","BURST:TRIG:SOURCE",channel=ch) self._modify_scpi_parameter("trigger_slope","BURST:TRIG:SLOPE",channel=ch) def _set_vpp_unit(self, channel=None): if self._check_command("voltage_unit",channel,raise_error=False): if self._ask_channel("VOLTAGE:UNIT?",name="voltage_unit",channel=channel).upper()!="VPP": self._write_channel("VOLTAGE:UNIT","VPP",name="voltage_unit",channel=channel)
[docs] def get_offset(self, channel=None): self._set_vpp_unit(channel=channel) return self._ask_channel("DCOFFSET?","float",name="offset",channel=channel)
[docs] def set_offset(self, offset, channel=None): self._set_vpp_unit(channel=channel) if self._amplitude_opc_check: self._write_channel("DCOFFSET {:.3f};*OPC?".format(offset),name="offset",channel=channel) self.read() else: self._write_channel("DCOFFSET",offset,"float",name="offset",channel=channel) return self.get_offset(channel=channel)
[docs] def get_amplitude(self, channel=None): self._set_vpp_unit(channel=channel) return self._ask_channel("AMPLITUDE?","float",name="amplitude",channel=channel)/2.
[docs] def set_amplitude(self, amplitude, channel=None): self._set_vpp_unit(channel=channel) if self._amplitude_opc_check: self._write_channel("AMPLITUDE {:.3f};*OPC?".format(amplitude*2),name="amplitude",channel=channel) self.read() else: self._write_channel("AMPLITUDE",amplitude*2,"float",name="amplitude",channel=channel) return self.get_amplitude(channel=channel)
[docs] class InstekAFG2000(InstekAFG2225): """ Instek AFG2000/2100 series AWG. Compared to AFG2225, has only one channel and fewer capabilities. """ _channels_number=1 _supported_functions=InstekAFG2225._supported_functions-{"pulse"} _exclude_commands=InstekAFG2225._exclude_commands|{"pulse_width", "burst_enabled","burst_mode","burst_ncycles","gate_polarity", "trigger_source","trigger_slope"} _amplitude_opc_check=False
[docs] class RSInstekAFG21000(InstekAFG2000): """ RS Instek AFG21000 series AWG. Compared to Instek AFG2000, it takes care of the amplitude output bug. """
[docs] def get_offset(self, channel=None): inf_load=self.get_load(channel=channel)>1E3 off=InstekAFG2000.get_offset(self,channel=channel) return off*2 if inf_load else off # seems to be the case, that returned values are not adjusted for highZ load (set values are, though)
[docs] def get_amplitude(self, channel=None): inf_load=self.get_load(channel=channel)>1E3 amp=InstekAFG2000.get_amplitude(self,channel=channel) return amp*2 if inf_load else amp # seems to be the case, that returned values are not adjusted for highZ load (set values are, though)
[docs] class TektronixAFG1000(GenericAWG): _function_aliases=GenericAWG._function_aliases.copy() _function_aliases["noise"]="PRN" _supported_functions={"sine","square","ramp","pulse","noise","user","*"} _single_channel_commands={"burst_enabled","burst_mode","burst_ncycles"} _exclude_commands={ "duty_cycle","ramp_symmetry", "output_polarity","output_sync","voltage_unit","phase_unit", "gate_polarity","trigger_source","trigger_slope","trigger_output","output_trigger_slope"} _range_mode="amp_off" _set_angle_unit=False _default_angle_unit="rad" def __init__(self, addr, channels_number="auto"): self._channels_number=channels_number GenericAWG.__init__(self,addr) for ch in range(1,self._channels_number+1): self._modify_scpi_parameter("output_load","IMPEDANCE",comm_kind="output",channel=ch) self._add_scpi_parameter("pulse_duty_cycle","PULSE:DCYCLE",channel=ch,add_variable=False) self._add_settings_variable("pulse_width",self.get_pulse_width,self.set_pulse_width,channel=ch)
[docs] def get_pulse_width(self, channel=None): dcycle=self._get_channel_scpi_parameter("pulse_duty_cycle",channel=channel) return (1./self.get_frequency(channel=channel))*(dcycle/100)
[docs] def set_pulse_width(self, width, channel=None): dcycle=width*self.get_frequency(channel=channel)*100 self._set_channel_scpi_parameter("pulse_duty_cycle",dcycle,channel=channel) return self.get_pulse_width(channel=channel)
[docs] class RigolDG1000(GenericAWG): """ Rigol DG1000 AWG. """ _channels_number=2 _supported_functions={"sine","square","noise","ramp","pulse","dc","user"} _single_channel_commands={ "output_sync", "burst_enabled","burst_mode","burst_ncycles","gate_polarity", "trigger_source","trigger_slope","trigger_output","output_trigger_slope"} _range_mode="both" _set_angle_unit=False def __init__(self, addr): GenericAWG.__init__(self,addr) for ch in range(1,self._channels_number+1): self._modify_scpi_parameter("pulse_width","PULSE:WIDTH",channel=ch) def _instr_read(self, raw=False, size=None): data=GenericAWG._instr_read(self,raw=raw,size=size) if not raw: for pfx in [b"CH1:",b"CH2:"]: if data.startswith(pfx): data=data[len(pfx):].strip() break return data def _build_channel_command(self, comm, channel, kind="source"): """Build channel-specific command""" channel=self._get_channel(channel) sfx="" if comm.endswith("?"): sfx="?" comm=comm[:-1] if kind=="output": comm="OUTPUT:"+comm if comm else "OUTPUT" if channel==2: comm=comm+":CH2" return comm+sfx
[docs] def sync_phase(self): """Synchronize phase between two channels""" self.write("PHASE:ALIGN")