예제 #1
0
 def open(self):
     '''
         Open connection with 5 retries.
     '''
     if self.mbSession is not None:
         return
     if self.address is None:
         raise RuntimeError("Attempting to open connection to unknown address.")
     if self.resMan is None:
         self.resMan = pyvisa.ResourceManager()
     try:
         self.mbSession = self.resMan.open_resource(self.address)
         self.mbSession.write_termination = self.termination
         if not self.tempSess:
             logger.debug('Opened %s', self.address)
     except pyvisa.VisaIOError as err:
         logger.warning('There was a problem opening the VISA %s... Error code: %s',
                        self.address, err.error_code)
         if self._open_retries < OPEN_RETRIES:
             self._open_retries += 1
             time.sleep(0.5 * self._open_retries)
             logger.warning('Trying again... (try = %s/%s)', self._open_retries, OPEN_RETRIES)
             self.open()
         else:
             logger.error(err)
             raise
     else:
         if self._open_retries != 0:
             logger.warning('Found it!')
         self._open_retries = 0
예제 #2
0
    def amplAndOffs(self, amplOffs=None):
        ''' Amplitude and offset setting/getting

            Only uses the data-bar because the other one is broken

            Args:
                amplOffs (tuple(float)): new amplitude and offset in volts
                If either is None, returns but does not set

            Returns:
                (tuple(float)): amplitude and offset, read from hardware if specified as None
        '''
        if amplOffs is None:
            amplOffs = (None, None)
        if np.isscalar(amplOffs):
            raise ValueError('amplOffs must be a tuple. ' +
                             'You can specify one element as None if you don\'t want to set it')
        amplitude, offset = amplOffs
        amplitude = np.clip(amplitude, *self.amplitudeRange)

        if amplitude is not None:
            self.setConfigParam('AMP', '{} V'.format(amplitude))
        try:
            ampl = float(self.getConfigParam('AMP').split(' ')[0])
        except VisaIOError:
            logger.error('unable to get the amplitude')
            ampl = None
        if offset is not None:
            self.setConfigParam('OFS', '{} V'.format(offset))
        try:
            offs = float(self.getConfigParam('OFS').split(' ')[0])
        except VisaIOError:
            logger.error('unable to get the offset')
            offs = None
        return (ampl, offs)
예제 #3
0
    def connect(self):
        ''' Connects to the socket and leaves the connection open.
        If already connected, does nothing.

        Returns:
            socket object.
        '''
        if self._socket is None:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
                              socket.IPPROTO_TCP)
            try:
                logger.debug("Attempting new connection (timeout = %s)",
                             str(self.timeout))
                init_time = time.time()
                s.settimeout(self.timeout)
                s.connect((self.ip_address, self.port))
            except socket.error:
                # avoiding shutdown to prevent sending any data to remote socket
                # https://stackoverflow.com/questions/13109899/does-socket-become-unusable-after-connect-fails
                # s.shutdown(socket.SHUT_WR)
                s.close()
                del s
                logger.error('Cannot connect to resource.')
                raise
            else:
                final_time = time.time()
                elapsed_time_ms = 1e3 * (final_time - init_time)
                logger.debug("Connected. Time elapsed: %s msec",
                             '{:.2f}'.format(elapsed_time_ms))
                self._socket = s
            return self._socket
        else:
            return self._socket
예제 #4
0
    def __transferData(self, chan):
        ''' Returns the raw data pulled from the scope as time (seconds) and voltage (Volts)
            Args:
                chan (int): one channel at a time

            Returns:
                :mod:`data.Waveform`: a time, voltage paired signal

            Todo:
                Make this binary transfer to go even faster
        '''
        chStr = 'CH' + str(chan)
        self.setConfigParam('DATA:ENCDG', 'ASCII')
        self.setConfigParam('DATA:SOURCE', chStr)
        self.open()
        try:
            voltRaw = self.mbSession.query_ascii_values('CURV?')
        except pyvisa.VisaIOError as err:
            logger.error('Problem during query_ascii_values(\'CURV?\')')
            try:
                self.close()
            except pyvisa.VisaIOError:
                logger.error('Failed to close! %s', self.address)
            raise err
        self.close()
        return voltRaw
예제 #5
0
 def close(self):
     if self.mbSession is None:
         return
     try:
         self.mbSession.close()
     except pyvisa.VisaIOError:
         logger.error('There was a problem closing the VISA %s', self.address)
         raise
     self.mbSession = None
     if not self.tempSess:
         logger.debug('Closed %s', self.address)
예제 #6
0
 def instrID(self):
     """Overloads the super function because the OSA does not respond to *IDN?
     Instead sends a simple command and waits for a confirmed return
     """
     try:
         self.write('SPSWPMSK?')
     except socket.error:
         logger.error('OSA communication test failed. Sent: \'SPSWPMSK?\'')
         raise
     else:
         return 'Apex AP2440A'
예제 #7
0
 def write(self, writeStr):
     try:
         self.open()
         try:
             self.mbSession.write(writeStr)
         except Exception:
             logger.error('Problem writing to %s', self.address)
             raise
         logger.debug('%s - W - %s', self.address, writeStr)
     finally:
         if self.tempSess:
             self.close()
예제 #8
0
    def __getFullHardwareConfig(self, subgroup=''):
        ''' Get everything that is returned by the SET? query

            Args:
                subgroup (str): default '' means everything

            Returns:
                TekConfig: structured configuration object
        '''
        self.initHardware()
        logger.info('Querying SET? response of %s', self.instrID())
        try:
            resp = self.query('SET?')
            return TekConfig.fromSETresponse(resp, subgroup=subgroup)
        except VisaIOError as err:  # SET timed out. You are done.
            logger.error(
                '%s timed out on \'SET?\'. \
                         Try resetting with \'*RST\'.', self.instrID())
            raise err
예제 #9
0
 def query(self, queryStr, withTimeout=None):
     retStr = None
     try:
         self.open()
         logger.debug('%s - Q - %s', self.address, queryStr)
         toutOrig = self.timeout
         try:
             if withTimeout is not None:
                 self.timeout = withTimeout
             retStr = self.mbSession.query(queryStr)
             if withTimeout is not None:
                 self.timeout = toutOrig
         except Exception:
             logger.error('Problem querying to %s', self.address)
             # self.close()
             raise
         retStr = retStr.rstrip()
         logger.debug('Query Read - %s', retStr)
     finally:
         if self.tempSess:
             self.close()
     return retStr
예제 #10
0
    def _getHardwareConfig(self, cStrList):
        ''' Queries all or a subgroup of commands using the state of the 'live' config.

            This does not return, but it puts it in the config['live'] attribute

            Args:
                cStrList (list or str): list of command strings. Can also be a scalar string
        '''
        self.initHardware()
        if type(cStrList) is not list and type(cStrList) is str:
            cStrList = [cStrList]
        for cStr in cStrList:
            if cStr[-1] == '&':  # handle the sibling subdir token
                cStr = cStr[:-2]

            try:
                ret = self.query(cStr + '?')
            except VisaIOError:
                logger.error(
                    'Problematic parameter was %s.\n'
                    'Likely it does not exist in this instrument command structure.',
                    cStr)
                raise
            logger.debug('Queried %s, got %s', cStr, ret)

            if self.header:
                val = ret.split(' ')[-1]
            else:
                val = ret
            # Type detection
            try:
                val = float(val)
            except ValueError:
                pass
            else:
                if val == floor(val):
                    val = int(val)
            self.config['live'].set(cStr, val)