Note
General device communication concepts are described on the corresponding page.
Tektronix oscilloscopes
Tektronix produces a large number of very widespread oscilloscopes. They have strongly overlapping, though not entirely identical, interfaces. The library has been tested with TDS2002B, TDS2004B, and DBO2014B.
The generic oscilloscope class is pylablib.devices.Tektronix.ITektronixScope
, and the derived classes for specific devices are pylablib.devices.Tektronix.TDS2000
of TDS2000 series and pylablib.devices.Tektronix.DPO2000
for DPO2000/MSO2000 series.
Software requirements
These oscilloscopes use NI VISA communication interface. Hence, it requires NI VISA Runtime, which is freely available from the National Instruments website
Connection
The devices are identified by their VISA connection strings, which typically start with USB0::0x0699
, e.g., "USB0::0x0699::0x0364::C000001::INSTR"
. To get a list of all connected VISA-enabled devices, you can run pylablib.list_backend_resources("visa")
:
>> import pylablib as pll
>> pll.list_backend_resources("visa")
('USB0::0x0699::0x0364::C000001::INSTR',)
>> from pylablib.devices import Tektronix
>> osc = Tektronix.TDS2000("USB0::0x0699::0x0364::C000001::INSTR")
>> osc.close()
Operation
The method names are usually pretty self-explanatory. A typical operation involves setting up channels, scales, and trigger options, acquiring a waveform, and reading the result:
from pylablib.devices import Tektronix
osc = Tektronix.TDS2000("USB0::0x0699::0x0364::C000001::INSTR") # connect to the oscilloscope
osc.enable_channel([1,2]) # enable channels
osc.set_horizontal_span(0.1) # set up horizontal and vertical spans
osc.set_vertical_span("CH1", 1)
osc.set_vertical_span("CH2", 0.1)
osc.setup_edge_trigger("CH1", 0., "dc", "rise") # set up edge trigger on channel 1 at 0V threshold
osc.grab_single(wait_timeout=10.) # grab a single waveform and wait for up to 10s to finish acquisition
sweeps = osc.read_multiple_sweeps([1,2]) # read out the waveforms
osc.close()
However, there is a couple of points to keep in mind:
The acquisition is controlled using
grab_
methods. Generally, the most convenient way is to useITektronixScope.grab_single()
to acquire a single waveform (analogous to pressing aSingle
button on the oscilloscope panel). By default, this method waits until the acquisition is complete (i.e., the oscilloscope is triggered and the waveform is completely acquired) before continuing. You can also setwait=False
to perform other operations in the meantime. The acquisition status can be queried viaITektronixScope.is_grabbing()
, which returnsTrue
while the trigger is armed or while the data is recording, andFalse
after the acquisition is done.It appears that the software trigger does not work some time (~500 ms) after the acquisition is set up. If it is invoked in
ITektronixScope.grab_single()
method by supplyingsoftware_trigger=True
, a 300ms delay is added automatically. However, if you invoke it manually usingITektronixScope.force_trigger()
, you should keep it in mind.The waveform transfer is usually performed via
ITektronixScope.read_sweep()
orITektronixScope.read_multiple_sweeps()
methods. Since the waveform is transferred in raw form, it requires a preamble data (vertical and horizontal scales and offsets, data format, etc.) to translate into physical units. By default, it is acquired every time before the waveform transfer, which takes some time (up to ~200ms). Alternatively, one can acquire a preamble once and use it in subsequent reading. This method is faster, but will result in an incorrect scaling if the parameters are changed in the meantime (either remotely, or directly on the oscilloscope):>> wfmpres = osc.osc.get_wfmpre([1,2]) >> %time sweeps = osc.read_multiple_sweeps([1,2]) Wall time: 2.2 s >> %time sweeps = osc.read_multiple_sweeps([1,2], wfmpres=wfmpres) Wall time: 450 msThe device class attempts to determine the number of channels automatically on connection, based on which requests raise device errors. However, this process takes some time, and sometimes can raise errors on not fully SCPI-compliant devices. If that is the case, it is always possible to supply the number of channels on construction:
>> osc = Tektronix.TDS2000("USB0::0x0699::0x0364::C000001::INSTR") # use autodetection >> osc.get_channels_number() 2 >> osc.close() >> osc = Tektronix.TDS2000("USB0::0x0699::0x0364::C000001::INSTR", nchannels=2) # specify manually