Source code for msl.equipment.resources.picotech.picoscope.ps4000

"""
A wrapper around the PicoScope ps4000 SDK.
"""
from __future__ import annotations

from ctypes import addressof
from ctypes import byref
from ctypes import c_int16
from ctypes import c_int64
from ctypes import c_int8
from ctypes import c_uint32
from ctypes import string_at

from msl.equipment.resources import register
from .functions import ps4000Api_funcptrs
from .picoscope_api import PicoScopeApi
from .. import c_enum


[docs] @register(manufacturer=r'Pico\s*Tech', model=r'4[24][26][24]') class PicoScope4000(PicoScopeApi): MAX_OVERSAMPLE_12BIT = 16 MAX_OVERSAMPLE_8BIT = 256 PS4XXX_MAX_ETS_CYCLES = 400 PS4XXX_MAX_INTERLEAVE = 80 PS4262_MAX_VALUE = 32767 PS4262_MIN_VALUE = -32767 MAX_VALUE = 32764 MIN_VALUE = -32764 LOST_DATA = -32768 EXT_MAX_VALUE = 32767 EXT_MIN_VALUE = -32767 MAX_PULSE_WIDTH_QUALIFIER_COUNT = 16777215 MAX_DELAY_COUNT = 8388607 MIN_SIG_GEN_FREQ = 0.0 MAX_SIG_GEN_FREQ = 100000.0 MAX_SIG_GEN_FREQ_4262 = 20000.0 MIN_SIG_GEN_BUFFER_SIZE = 1 MAX_SIG_GEN_BUFFER_SIZE = 8192 MIN_DWELL_COUNT = 10 PS4262_MAX_WAVEFORM_BUFFER_SIZE = 4096 PS4262_MIN_DWELL_COUNT = 3 MAX_SWEEPS_SHOTS = ((1 << 30) - 1) # EXT_MAX_VOLTAGE = ? def __init__(self, record): """A wrapper around the PicoScope ps4000 SDK. Do not instantiate this class directly. Use the :meth:`~.EquipmentRecord.connect` method to connect to the equipment. Parameters ---------- record : :class:`~.EquipmentRecord` A record from an :ref:`equipment-database`. """ super(PicoScope4000, self).__init__(record, ps4000Api_funcptrs)
[docs] def get_probe(self): """ This function is in the header file, but it is not in the manual. """ probe = c_enum() self.sdk.ps4000GetProbe(self._handle, byref(probe)) return probe.value
[docs] def get_trigger_channel_time_offset(self, segment_index, channel): """ This function gets the time, as two 4-byte values, at which the trigger occurred, adjusted for the time skew of the specified channel relative to the trigger source. Call it after block-mode data has been captured or when data has been retrieved from a previous block-mode capture. """ time_upper = c_uint32() time_lower = c_uint32() time_units = c_enum() self.sdk.ps4000GetTriggerChannelTimeOffset(self._handle, byref(time_upper), byref(time_lower), byref(time_units), segment_index, channel) return time_upper.value, time_lower.value, time_units.value
[docs] def get_trigger_channel_time_offset64(self, segment_index, channel): """ This function gets the time, as a single 8-byte value, at which the trigger occurred, adjusted for the time skew of the specified channel relative to the trigger source. Call it after block-mode data has been captured or when data has been retrieved from a previous block-mode capture. """ time = c_int64() time_units = c_enum() self.sdk.ps4000GetTriggerChannelTimeOffset64(self._handle, byref(time), byref(time_units), segment_index, channel) return time.value, time_units.value
[docs] def get_values_trigger_channel_time_offset_bulk(self, from_segment_index, to_segment_index, channel): """ This function retrieves the time offset, as lower and upper 32-bit values, for a group of waveforms obtained in rapid block mode, adjusted for the time skew relative to the trigger source. The array size for ``timesUpper`` and ``timesLower`` must be greater than or equal to the number of waveform time offsets requested. The segment indexes are inclusive. """ times_upper = c_uint32() times_lower = c_uint32() time_units = c_enum() self.sdk.ps4000GetValuesTriggerChannelTimeOffsetBulk(self._handle, byref(times_upper), byref(times_lower), byref(time_units), from_segment_index, to_segment_index, channel) return times_upper.value, times_lower.value, time_units.value
[docs] def get_values_trigger_channel_time_offset_bulk64(self, from_segment_index, to_segment_index, channel): """ This function retrieves the time offset, as a 64-bit integer, for a group of waveforms captured in rapid block mode, adjusted for the time skew relative to the trigger source. The array size of ``times`` must be greater than or equal to the number of waveform time offsets requested. The segment indexes are inclusive. """ times = c_int64() time_units = c_enum() self.sdk.ps4000GetValuesTriggerChannelTimeOffsetBulk64(self._handle, byref(times), byref(time_units), from_segment_index, to_segment_index, channel) return times.value, time_units.value
[docs] def open_unit_async_ex(self): """ This function opens a scope device selected by serial number without blocking the calling thread. You can find out when it has finished by periodically calling :meth:`~.PicoScopeApi.open_unit_progress` until that function returns a non-zero value. """ status = c_int16() serial = c_int8() self.sdk.ps4000OpenUnitAsyncEx(byref(status), byref(serial)) return status.value, string_at(addressof(serial)).decode('utf-8').strip()
[docs] def open_unit_ex(self): """ This function opens a scope device. The maximum number of units that can be opened is determined by the operating system, the kernel driver and the PC's hardware. """ handle = c_int16() serial = c_int8() self.sdk.ps4000OpenUnitEx(byref(handle), byref(serial)) if handle.value > 0: self._handle = handle return string_at(addressof(serial)).decode('utf-8').strip()
[docs] def run_streaming_ex(self, sample_interval_time_units, max_pre_trigger_samples, max_post_pre_trigger_samples, auto_stop, down_sample_ratio, down_sample_ratio_mode, overview_buffer_size): """ This function tells the oscilloscope to start collecting data in streaming mode and with a specified data reduction mode. When data has been collected from the device it is aggregated and the values returned to the application. Call :meth:`~.PicoScopeApi.get_streaming_latest_values` to retrieve the data. """ sample_interval = c_uint32() self.sdk.ps4000RunStreamingEx(self._handle, byref(sample_interval), sample_interval_time_units, max_pre_trigger_samples, max_post_pre_trigger_samples, auto_stop, down_sample_ratio, down_sample_ratio_mode, overview_buffer_size) return sample_interval.value
[docs] def set_bw_filter(self, channel, enable): """ This function enables or disables the bandwidth-limiting filter on the specified channel. """ return self.sdk.ps4000SetBwFilter(self._handle, channel, enable)
[docs] def set_data_buffer_with_mode(self, channel, buffer_length, mode): """ This function registers your data buffer, for non-aggregated data, with the PicoScope 4000 driver. You need to allocate the buffer before calling this function. """ buffer = c_int16() self.sdk.ps4000SetDataBufferWithMode(self._handle, channel, byref(buffer), buffer_length, mode) return buffer.value
[docs] def set_data_buffers_with_mode(self, channel, buffer_length, mode): """ This function registers your data buffers, for receiving aggregated data, with the PicoScope 4000 driver. You need to allocate memory for the buffers before calling this function. """ buffer_max = c_int16() buffer_min = c_int16() self.sdk.ps4000SetDataBuffersWithMode(self._handle, channel, byref(buffer_max), byref(buffer_min), buffer_length, mode) return buffer_max.value, buffer_min.value
[docs] def set_ext_trigger_range(self, ext_range): """ This function sets the range of the external trigger. """ return self.sdk.ps4000SetExtTriggerRange(self._handle, ext_range)
[docs] def set_probe(self, probe, range_): """ This function is in the header file, but it is not in the manual. """ return self.sdk.ps4000SetProbe(self._handle, probe, range_)