예제 #1
0
    def block(self):
        self.data_mVRay.clear()
        self.time = {}
        self.status["runblock"] = ps.ps5000aRunBlock(self.chandle,
                                                     self.preTriggerSamples,
                                                     self.postTriggerSamples,
                                                     self.timebase, None, 0,
                                                     None, None)
        assert_pico_ok(self.status["runblock"])

        ready = ctypes.c_int16(0)
        check = ctypes.c_int16(0)
        while ready.value == check.value:
            self.status["isReady"] = ps.ps5000aIsReady(self.chandle,
                                                       ctypes.byref(ready))

        self.status["GetValuesBulk"] = ps.ps5000aGetValuesBulk(
            self.chandle, ctypes.byref(self.cmaxSamples), 0, self.blocks - 1,
            0, 0, ctypes.byref(self.overflow))
        assert_pico_ok(self.status["GetValuesBulk"])
        for i in range(self.blocks):
            self.data_mVRay.append(
                adc2mV(self.bufferMaxRay[i], self.chARange, self.maxADC))
            #self.data_mVRay.append(np.asarray(self.bufferMaxRay[i], dtype=int) * self.chARange / self.maxADC.value)
        self.createTimeAxis()
 def startview_single(self):
     self.gr.setDisabled(True)
     self.grfft.setDisabled(True)
     self.numb.setDisabled(True)
     self.test = QTimer()
     if len(listacq) == 0:
         self.test.setInterval(500)
         self.test.setTimerType(Qt.PreciseTimer)
         self.b = 1
         self.test.timeout.connect(lambda: self.warning("No channel selected, go to Config > Select channels"))
         self.test.start()
     else:
         self.test.stop()
         self.statusBar().setStyleSheet("background-color : #5CDB95; color: #EDF5E1")
         self.statusBar().showMessage('In progress...')
         self.plotChan.clear()
         self.plotChanData = np.arange(0)
         self.timer_single = QTimer()
         self.timer_single.setTimerType(Qt.PreciseTimer)
         status["SetDo"] = pl.pl1000SetDo(chandle, 1, 0)
         self.timer_single.timeout.connect(self.update_accel_single)
         self.startplot_single.setDisabled(True)
         self.startplot_single.setStyleSheet('QPushButton {background-color: #5CDB95; color: #5CDB95;}')
         self.showdata_single.setDisabled(False)
         self.stopplot_single.setDisabled(False)
         self.stopplot_single.setStyleSheet('QPushButton {background-color: #5CDB95; color: #05386B;}')
         self.usForBlock = ctypes.c_uint32(100000)
         self.noOfValues = ctypes.c_uint32(10000)
         channels = ctypes.c_int16(9)
         status["setInterval"] = pl.pl1000SetInterval(chandle, ctypes.byref(self.usForBlock), self.noOfValues,
                                                      ctypes.byref(channels), 1)
         assert_pico_ok(status["setInterval"])
         self.mode = pl.PL1000_BLOCK_METHOD["BM_STREAM"]
         self.timer_single.start()
예제 #3
0
    def createBuffers(self):

        for i in range(self.blocks):
            # Create buffers ready for assigning pointers for data collection
            self.bufferMaxRay[i] = (ctypes.c_int16 * self.maxsamples)()
            self.bufferMinRay[i] = (ctypes.c_int16 * self.maxsamples)()
            self.bufferAMax = (ctypes.c_int16 * self.maxsamples)()
            self.bufferAMin = (ctypes.c_int16 * self.maxsamples)()

            # Setting the data buffer location for data collection from channel A
            # Handle = Chandle
            self.source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
            # Buffer max = ctypes.byref(bufferMaxRay[i])
            # Buffer min = ctypes.byref(bufferMinRay[i])
            # Buffer length = maxsamples
            # Segment index = i
            # Ratio mode = ps5000a_Ratio_Mode_None = 0
            self.status["SetDataBuffers"] = ps.ps5000aSetDataBuffers(
                self.chandle, self.source, ctypes.byref(self.bufferMaxRay[i]),
                ctypes.byref(self.bufferMinRay[i]), self.maxsamples, i, 0)

            assert_pico_ok(self.status["SetDataBuffers"])

        # Creates a overflow location for data
        self.overflow = (ctypes.c_int16 * self.blocks)()
        # Creates converted types maxsamples
        self.cmaxSamples = ctypes.c_int32(self.maxsamples)
    def set_trigger(self,
                    channel_name,
                    threshold=0.,
                    direction='RISING',
                    is_enabled=True,
                    delay=0,
                    auto_trigger=0):
        """Set the oscilloscope trigger condition.

        :param channel_name: the source channel for the trigger (e.g. 'A')
        :param threshold: the trigger threshold (in V)
        :param direction: the direction in which the signal must move to cause
            a trigger
        :param is_enabled: (boolean) enable or disable the trigger
        :param delay: the delay between the trigger occuring and the start of
            capturing data, in number of sample periods
        :param auto_trigger: the maximum amount of time to wait for a trigger
            before starting capturing data in seconds

        The direction parameter can take values of 'ABOVE', 'BELOW', 'RISING',
        'FALLING' or 'RISING_OR_FALLING'.
        """
        channel = _get_channel_from_name(channel_name)
        threshold = self._rescale_V_to_adc(channel_name, threshold)
        direction = _get_trigger_direction_from_name(direction)
        assert_pico_ok(
            ps.ps5000aSetSimpleTrigger(self._handle, is_enabled, channel,
                                       threshold, direction, delay,
                                       auto_trigger))
예제 #5
0
 def setSimpleTrigger(self,
                      channel,
                      threshold_mV,
                      direction,
                      delay_samples,
                      timeout_ms=1000):
     # TODO: handling of external trigger
     maxADC = ctypes.c_int16()
     self.status['maximumValue'] = ps.ps5000aMaximumValue(
         self.chandle, ctypes.byref(maxADC))
     assert_pico_ok(self.status['maximumValue'])
     if (channel.upper() == 'EXT'):
         _channel = ps.PS5000A_CHANNEL['PS5000A_EXTERNAL']
         _voltage_range = ps.PS5000A_RANGE['PS5000A_5V']
     else:
         _channel = ps.PS5000A_CHANNEL['PS5000A_CHANNEL_' + channel.upper()]
         _voltage_range = ps.PS5000A_RANGE[
             'PS5000A_' + self.channel_info[channel]['voltage_range']]
     _threshold_ADC = int(mV2adc(threshold_mV, _voltage_range, maxADC))
     _direction = ps.PS5000A_THRESHOLD_DIRECTION['PS5000A_' +
                                                 direction.upper()]
     self.status["trigger"] = ps.ps5000aSetSimpleTrigger(
         self.chandle, 1, _channel, _threshold_ADC, _direction,
         delay_samples, timeout_ms)
     assert_pico_ok(self.status["trigger"])
     self.trigger_info = {
         'channel': channel.upper(),
         'threshold_mV': threshold_mV,
         'direction': direction.upper(),
         'delay_samples': delay_samples
     }
예제 #6
0
    def connect(self, numberOfChannels=1):
        self.makeConnection()
        #seuraavaksi channel asetukset omiin funktioihinsa. Mahdollisesti 4 kanavalle.
        self.connectChannels(numberOfChannels)

        # find maximum ADC count value
        # handle = chandle
        # pointer to value = ctypes.byref(maxADC)
        self.maxADC = ctypes.c_int16()
        self.status["maximumValue"] = ps.ps5000aMaximumValue(
            self.chandle, ctypes.byref(self.maxADC))
        assert_pico_ok(self.status["maximumValue"])
        self.setTrigger(ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"],
                        int(mV2adc(500, self.chRange[0], self.maxADC)), 1000)

        self.maxSamples = self.preTriggerSamples + self.postTriggerSamples
        #print(self.maxSamples)
        self.returnData = np.zeros((self.numberOfChannels, self.maxSamples))

        self.clearDatabuffers()
        for index in range(0, self.numberOfChannels):
            self.setDatabuffer(index)
        self.setTimebase(8)
        self.overflow = ctypes.c_int16()
        # create converted type maxSamples
        self.cmaxSamples = ctypes.c_int32(self.maxSamples)
예제 #7
0
    def setTrigger(self, triggermV, external, delay):
        self.threshold = triggermV
        self.external = external
        # Set up single trigger
        # handle = chandle
        # enabled = 1
        if external:
            source = ps.PS5000A_CHANNEL["PS5000A_EXTERNAL"]
        else:
            source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_A"]
        threshold = int(mV2adc(self.threshold, self.chARange, self.maxADC))
        # direction = PS5000A_RISING = 2
        # delay = 0 s
        # auto Trigger = 0 (never) (whole number for milliseconds)
        if (self.runtimeNs) > 2 ^ 16 - 1:
            autotriggerDelay = 2 ^ 16 - 1
        else:
            autotriggerDelay = int(self.runtimeNs)

        try:
            self.status["trigger"] = ps.ps5000aSetSimpleTrigger(
                self.chandle, 1, source, threshold, 2, delay,
                ctypes.c_int16(100))
            assert_pico_ok(self.status["trigger"])
        except:
            print("Invalid picoscope trigger settings")
예제 #8
0
    def setDatabuffer(self, channelIndex):

        self.bufferMax.append((ctypes.c_int16 * self.maxSamples)())
        self.bufferMin.append((ctypes.c_int16 * self.maxSamples)(
        ))  # used for downsampling which isn't in the scope of this example
        # used for downsampling which isn't in the scope of this example

        # Set data buffer location for data collection from channel A
        # handle = chandle
        self.source = ps.PS5000A_CHANNEL["PS5000A_CHANNEL_{0}".format(
            self.channels[channelIndex])]
        # pointer to buffer max = ctypes.byref(bufferAMax)
        # pointer to buffer min = ctypes.byref(bufferAMin)
        # buffer length = maxSamples
        # segment index = 0
        # ratio mode = PS5000A_RATIO_MODE_NONE = 0
        self.status["setDataBuffers{0}".format(
            self.channels[channelIndex])] = ps.ps5000aSetDataBuffers(
                self.chandle, self.source,
                ctypes.byref(self.bufferMax[channelIndex]),
                ctypes.byref(self.bufferMin[channelIndex]), self.maxSamples, 0,
                0)
        assert_pico_ok(self.status["setDataBuffers{0}".format(
            self.channels[channelIndex])])
        self.returnData = np.zeros((self.numberOfChannels, self.maxSamples))
 def close(self):
     # Close unit Disconnect the scope
     # handle = chandle
     self.status["close"]=ps.ps5000aCloseUnit(self.chandle)
     assert_pico_ok(self.status["close"])
     # display status returns
     print('The scope was successfully closed')
예제 #10
0
 def run(self):
     self.status['run'] = ps.ps5000aRunBlock(self.chandle,
                                             self.preTrigger_samples,
                                             self.postTrigger_samples,
                                             self.timebase, None, 0, None,
                                             None)
     assert_pico_ok(self.status['run'])
예제 #11
0
    def defaultSetting(self):
        self.status["getTimebase2"] = ps.ps5000aGetTimebase2(self.chandle, \
            self.timebase, self.maxSamples, byref(self.timeInternalns),\
            None, 0)
        assert_pico_ok(self.status["getTimebase2"])

        self.chs['A'].coupling_type = ps.PS5000A_COUPLING["PS5000A_AC"]
        self.chs['A'].range = ps.PS5000A_RANGE["PS5000A_50MV"]
        self.status["setChA"] = self.chs['A'].Enable()
        assert_pico_ok(self.status["setChA"])

        self.chs['B'].coupling_type = ps.PS5000A_COUPLING["PS5000A_AC"]
        self.chs['B'].range = ps.PS5000A_RANGE["PS5000A_50MV"]
        self.status["setChB"] = self.chs['B'].Enable()
        assert_pico_ok(self.status["setChB"])

        self.chs['C'].coupling_type = ps.PS5000A_COUPLING["PS5000A_AC"]
        self.chs['C'].range = ps.PS5000A_RANGE["PS5000A_50MV"]
        self.status["setChC"] = self.chs['C'].Enable()
        assert_pico_ok(self.status["setChC"])

        self.chs['D'].coupling_type = ps.PS5000A_COUPLING["PS5000A_AC"]
        self.chs['D'].range = ps.PS5000A_RANGE["PS5000A_50MV"]
        self.status["setChD"] = self.chs['D'].Enable()
        assert_pico_ok(self.status["setChD"])
예제 #12
0
    def configurePSD(self, binWidth, spectrumRange, nTimes=None):
        spectrumRange = spectrumRange * 2
        requiredSamplingInterval = 1 / spectrumRange
        requiredMeasureTime = 1 / binWidth
        self.maxSamples = ceil(requiredMeasureTime / requiredSamplingInterval)
        self.timebase = floor(requiredSamplingInterval * 125000000 + 2)  #14bit
        #self.timebase = floor(requiredSamplingInterval * 62500000 + 3) #16bit

        self.status["getTimebase2"] = ps.ps5000aGetTimebase2(self.chandle, \
            self.timebase, self.maxSamples, byref(self.timeInternalns),\
            None, 0)
        assert_pico_ok(self.status["getTimebase2"])

        self.maxSamples = ceil(requiredMeasureTime * 1e9 /
                               self.timeInternalns.value)

        assert self.timeInternalns.value <= requiredSamplingInterval * 1e9

        if bool(nTimes):
            nMaxSamples = c_long()
            ps.ps5000aMemorySegments(self.chandle, 1, byref(nMaxSamples))
            print(nMaxSamples)
            nMaxSamples.value = math.floor(nMaxSamples.value /
                                           self.nEnabledChannels())
            if nTimes == 'Max':
                nTimes = math.floor(nMaxSamples.value / (self.maxSamples)) - 25
            print(nTimes, self.maxSamples)
            assert self.maxSamples * nTimes < nMaxSamples.value
            self.maxSamples = nTimes * self.maxSamples
            return nTimes, int(self.maxSamples / nTimes)
    def set_channel(self,
                    channel_name,
                    coupling_type='DC',
                    range_value=1,
                    offset=0,
                    is_enabled=True):
        """Set up input channels.

        :param channel_name: channel name ('A', 'B', etc.)
        :param coupling_type: 'AC' or 'DC' coupling
        :param range_value: (float) input voltage range in volts
        :param offset: analogue offset of the input signal
        :param is_enabled: enable or disable the channel
        :type is_enabled: boolean

        The input voltage range can be 10, 20, 50 mV, 100, 200, 500 mV, 1, 2,
        5 V or 10, 20, 50 V, but is given in volts. For example, a range of
        20 mV is given as 0.02.
        """
        channel = _get_channel_from_name(channel_name)
        coupling_type = _get_coupling_type_from_name(coupling_type)
        range = _get_range_from_value(range_value)
        assert_pico_ok(
            ps.ps5000aSetChannel(self._handle, channel, is_enabled,
                                 coupling_type, range, offset))

        self._input_voltage_ranges[channel_name] = float(range_value)
        self._input_offsets[channel_name] = float(offset)
        max_adc_value = ctypes.c_int16()
        assert_pico_ok(
            ps.ps5000aMaximumValue(self._handle, ctypes.byref(max_adc_value)))
        self._input_adc_ranges[channel_name] = max_adc_value.value
        self._channels_enabled[channel_name] = is_enabled
예제 #14
0
 def setResolution(self, resolution):
     self.resolution = resolution.upper()
     _resolution = ps.PS5000A_DEVICE_RESOLUTION['PS5000A_DR_' +
                                                self.resolution.upper()]
     self.status['setRes'] = ps.ps5000aSetDeviceResolution(
         self.chandle, _resolution)
     assert_pico_ok(self.status['setRes'])
 def setTrigger(self, source, thresholdmv, delay, timeout=10000):
     thresh = int(mV2adc(thresholdmv, self.channela_range, self.maxADC))
     enabled = 1  #obvs...
     direction = 2  #PS5000A_RISING
     self.status["trigger"] = ps.ps5000aSetSimpleTrigger(
         self.chandle, enabled, source, thresh, direction, delay, timeout)
     assert_pico_ok(self.status["trigger"])
예제 #16
0
 def set_buffer(self, channel: str, enable: bool):
     if self.samples is None:
         raise ValueError
     if enable:
         if channel in self.buffers:
             del self.buffers[channel]
         buffer = (ctypes.c_int16 * self.samples)()
         assert_pico_ok(
             self.__dispatch_call(
                 "SetDataBuffer",
                 self.handle,
                 self.CHANNELS[channel],
                 ctypes.byref(buffer),
                 self.samples,
             ))
         self.buffers[channel] = buffer
     else:
         assert_pico_ok(
             self.__dispatch_call(
                 "SetDataBuffer",
                 self.handle,
                 self.CHANNELS[channel],
                 None,
                 self.samples,
             ))
         del self.buffers[channel]
예제 #17
0
    def set_timewindow(self, Samples, Timebase):
        # self.user['Trigger']['maxSamples'] = 50 # self.user['Trigger']['PreSamp'] + self.user['Trigger']['PostSamp']

        #print(Samples)
        #print(Timebase)
        self.dev.set_timewindow(Samples, Timebase)
        assert_pico_ok(self.dev.status["getTimebase2"])
예제 #18
0
 def set_trigger(self, active, channel, Type, Level, Delay, Auto, Range=0):
     if channel in 'External':
         LevelADC = int(
             mV2adc(
                 ur(Level.replace(' ', '')).m_as('mV'),
                 ps.PS5000A_RANGE["PS5000A_5V"], ctypes.c_int16(32767)))
         self.dev.setup_trigger(
             active, ps.PS5000A_CHANNEL["PS5000A_EXTERNAL"], LevelADC,
             ps.PS5000A_THRESHOLD_DIRECTION["PS5000A_{}".format(
                 Type.upper())], Delay,
             int(ur(Auto.replace(' ', '')).m_as('ms')))
     else:
         LevelADC = int(
             mV2adc(
                 ur(Level.replace(' ', '')).m_as('mV'),
                 ps.PS5000A_RANGE["PS5000A_{}".format(
                     Range.replace(' ', '').replace('m', 'M'))],
                 self.dev.maxADC))
         self.dev.setup_trigger(
             active,
             ps.PS5000A_CHANNEL["PS5000A_CHANNEL_{}".format(channel)],
             LevelADC, ps.PS5000A_THRESHOLD_DIRECTION["PS5000A_{}".format(
                 Type.upper())], Delay,
             int(ur(Auto.replace(' ', '')).m_as('ms')))
     assert_pico_ok(self.dev.status["trigger"])
예제 #19
0
    def __init__(self):
        # Create chandle and status ready for use
        self.status = {}
        self.chandle = ctypes.c_int16()

        # Opens the device/s
        self.status["openunit"] = ps.ps3000aOpenUnit(
            ctypes.byref(self.chandle), None)

        try:
            assert_pico_ok(self.status["openunit"])
        except:

            # powerstate becomes the status number of openunit
            powerstate = self.status["openunit"]

            # If powerstate is the same as 282 then it will run this if statement
            if powerstate == 282:
                # Changes the power input to "PICO_POWER_SUPPLY_NOT_CONNECTED"
                self.status["ChangePowerSource"] = ps.ps3000aChangePowerSource(
                    self.chandle, 282)
                # If the powerstate is the same as 286 then it will run this if statement
            elif powerstate == 286:
                # Changes the power input to "PICO_USB3_0_DEVICE_NON_USB3_0_PORT"
                self.status["ChangePowerSource"] = ps.ps3000aChangePowerSource(
                    self.chandle, 286)
            else:
                raise

            assert_pico_ok(self.status["ChangePowerSource"])
 def set_channel(self, **kwargs):
     '''
     set-up an oscilloscope channel. 
     arguments: none
     keyword arguments (defaults in channel.settings):
         enabled: True/False
         coupling_type: DC/AC
         chRange: channel voltage range (from 10mV up to 50V)
         analogueOffset: channel analogue offset (roughly -chRange up to +chRange) 
     after successfully setting the channel,  self.settings is updated
     '''
     # Set up channel
     settings = {} #in case of failure, settings is updated only at the end
     for key,current_value in self.settings.items():
         settings[key] = kwargs[key] if key in kwargs else current_value
     
     #checks
     check_kwargs_scope(**kwargs)
     if 'analogueOffset' in kwargs:
         self.check_analogueOffset(settings)
     
     # handle = chandle
     self._source = ps.PS5000A_CHANNEL[channel_index[self.source]]
     _enabled = int(settings['enabled'])
     _coupling_type = ps.PS5000A_COUPLING[coupling_type_index[settings['coupling_type']]]
     _chRange = ps.PS5000A_RANGE[range_index[settings['chRange']]]
     _analogueOffset = ctypes.c_float(settings['analogueOffset']) #V
     self.status["setCh"] = ps.ps5000aSetChannel(self.chandle, self._source, _enabled, 
                                             _coupling_type, _chRange, _analogueOffset)
     assert_pico_ok(self.status["setCh"])
     self.settings = settings
 def resolution(self,value,at_startup=False):
     value = value.upper()
     possible_values = [str(r)+'BIT' for r in [8,12,14,15,16]]
     assert value in possible_values, 'resolution can be 8,12,14, 15 or 16BIT'
     res = ps.PS5000A_DEVICE_RESOLUTION["PS5000A_DR_"+value.upper()]
     status = ps.ps5000aSetDeviceResolution(self.chandle,res)
     assert_pico_ok(status)
     self.settings['resolution'] = value
 def _maxADC(self):
     # find maximum ADC count value
     # handle = chandle
     # pointer to value = ctypes.byref(maxADC)
     maxADC = ctypes.c_int16()
     self.status["maximumValue"] = ps.ps5000aMaximumValue(self.chandle, ctypes.byref(maxADC))
     assert_pico_ok(self.status["maximumValue"])
     return maxADC
예제 #23
0
    def close(self):
        self.status["stop"] = ps.ps3000aStop(self.chandle)
        assert_pico_ok(self.status["stop"])

        # Closes the unit
        # Handle = chandle
        self.status["close"] = ps.ps3000aCloseUnit(self.chandle)
        assert_pico_ok(self.status["close"])
예제 #24
0
 def getTimebase(self):
     self.status["GetTimebase"] = ps.ps5000aGetTimebase2(
         self.chandle, self.timebase, self.maxsamples,
         ctypes.byref(self.timeIntervalns),
         ctypes.byref(self.returnedMaxSamples), 0)
     assert_pico_ok(self.status["GetTimebase"])
     print("Picoscope sampling interval:" + str(self.timeIntervalns.value) +
           " ns")
예제 #25
0
 def LPF20M(self, ch, On):
     if On:
         self.status["SetBWlimiter"] = ps.ps5000aSetBandwidthFilter(\
             self.chandle, self.chs[ch].channel, c_int32(1))
     else:
         self.status["SetBWlimiter"] = ps.ps5000aSetBandwidthFilter(\
             self.chandle, self.chs[ch].channel, c_int32(0))
     assert_pico_ok(self.status["SetBWlimiter"])
예제 #26
0
 def change_powersupply(self, state):
     if state == 286:  # USB3_0_DEVICE_NON_USB3_0_PORT (Does this work?)
         self.status["changePowerSource"] = ps.ps5000aChangePowerSource(self.chandle, state)  # Change powersource to USB2
     elif state == 282:  # POWER_SUPPLY_NOT_CONNECTED
         self.status["changePowerSource"] = ps.ps5000aChangePowerSource(self.chandle, state)  # Change powersource to USB3
     else:
         self.status["changePowerSource"] = state
     assert_pico_ok(self.status["changePowerSource"])  # Check whether the powerchange was successful
예제 #27
0
    def disconnect(self):
        self.status["stop"] = ps.ps5000aStop(self.chandle)
        assert_pico_ok(self.status["stop"])

        # Closes the unit
        # Handle = chandle
        self.status["close"] = ps.ps5000aCloseUnit(self.chandle)
        assert_pico_ok(self.status["close"])
        print("\n----------------- \nConnection closed \n-----------------")
 def softTrig(self,state):
     '''
     activates the AWG with the soft trigger
     only triggerSouce = soft_trig can allow using software trigger
     '''
     assert self.settings['triggerSource']=='soft_trig', 'only triggerSouce = soft_trig can allow using software trigger. See help(set_builtin())'
     if self.settings['direction']=='gate_low':
         state = 1-int(state)
     self.status["softTrig"] = ps.ps5000aSigGenSoftwareControl(self.chandle,state)
     assert_pico_ok(self.status["softTrig"])    
예제 #29
0
 def get_variant(self):
     if self._variant is not None:
         return self._variant
     info = (ctypes.c_int8 * 6)()
     size = ctypes.c_int16(6)
     assert_pico_ok(
         self.__dispatch_call("GetUnitInfo", self.handle,
                              ctypes.byref(info), size, 3))
     self._variant = "".join(chr(i) for i in info[:size.value])
     return self._variant
 def check_analogueOffset(self,settings):
     #queries maximum allowable analogueOffset range
     _chRange = ps.PS5000A_RANGE[range_index[settings['chRange']]]
     _coupling_type = ps.PS5000A_COUPLING[coupling_type_index[settings['coupling_type']]]
     minOffset = ctypes.c_float()
     maxOffset = ctypes.c_float()
     status = ps.ps5000aGetAnalogueOffset(self.chandle, _chRange,_coupling_type, ctypes.byref(maxOffset),ctypes.byref(minOffset))
     assert_pico_ok(status)
     assert_msg = 'analogue offset should be within [{0}, {1}]V'.format(minOffset.value,maxOffset.value)
     assert (settings['analogueOffset']<=maxOffset.value and settings['analogueOffset']>=minOffset.value), assert_msg