Finding symbol sequences within a pattern waveform

This Python example, find_bit_sequence.py, demonstrates locating and displaying symbol sequences within a pattern waveform in Oscilloscope mode. Eacy instance of a symbol sequence is located within the waveform. A simulated module is installed.

Example Script

Copy

find-bit-sequence.py

""" Script on PC controls FlexDCA or DCA-X from PC).
This script demonstrates locating and displaying symbol sequences
within a pattern waveform in Oscilloscope mode. The script opens
a connection to FlexDCA and installs a simulated module.
Requires a  DCA-X with precision timebase option.
"""
import pyvisa as visa  # import VISA library

ADDRESS = 'TCPIP0::localhost::hislip0,4880::INSTR'
#ADDRESS = 'TCPIP0::K-86100D-00003::hislip0,4880::INSTR'  # DCA-X
CHANNEL = '5A'


def open_flexdca_connection(address):
    """ Opens visa connection to FlexFlexDCA. """
    print('Connecting to Flexdca ...')
    try:
        rm = visa.ResourceManager()
        connection = rm.open_resource(address)
        connection.timeout = 20000  # Set connection timeout to 20s
        connection.read_termination = '\n'
        connection.write_termination = '\n'
        inst_id = connection.query('*IDN?')
        print('\nFlexDCA connection established to:\n' + inst_id, flush=True)
    except (visa.VisaIOError, visa.InvalidSession):
        print('\nVISA ERROR: Cannot open instrument address.\n', flush=True)
        return None
    except Exception as other:
        print('\nVISA ERROR: Cannot connect to instrument:', other, flush=True)
        print('\n')
        return None
    return connection


def all_channels_off(FlexDCA):
    """ Turns all available channels off. """
    for slot in '12345678':
        for letter in 'ABCD':
            channel = slot + letter
            FlexDCA.write(':CHANnel' + channel + ':DISPlay OFF')


def install_simulated_module(FlexDCA, channel, model, signal='NRZ'):
    """ Simplified installation of a simulated FlexDCA module.
    model is type of simulated module. "DEM" is a dual-electrical module.
    "QEM" is a quad-electrical module. "DOM" is a dual-optical
    module. "QEM" is a electrical-optical module.
    signal if format of signal: NRZ or PAM4.
    """
    slot = channel[0]
    FlexDCA.write(':EMODules:SLOT' + slot + ':SELection ' + model)
    if signal in 'NRZ':
        FlexDCA.write(':SOURce' + channel + ':FORMat NRZ')
    else:
        FlexDCA.write(':SOURce' + channel + ':FORMat PAM4')
    FlexDCA.write(':SOURce' + channel + ':DRATe 9.95328E+9')
    FlexDCA.write(':SOURce' + channel + ':WTYPe DATA')
    FlexDCA.write(':SOURce' + channel + ':PLENgth 127')
    FlexDCA.write(':SOURce' + channel + ':AMPLitude 90E-3')
    FlexDCA.write(':SOURce' + channel + ':NOISe:RN 3.0E-6')
    FlexDCA.write(':SOURce' + channel + ':JITTer:RJ 4.0E-12')
    FlexDCA.write(':CHANnel' + channel + ':DISPlay ON')


def setup(FlexDCA):
    FlexDCA.query(':SYSTem:MODE OSCilloscope;*OPC?')
    FlexDCA.query(':TRIGger:PLOCk ON;*OPC?')
    FlexDCA.query(':SYSTem:AUToscale;*OPC?')
    FlexDCA.write(':ACQuire:EPATtern ON')
    FlexDCA.write(':ACQuire:RUN')


def view_entire_pattern(FlexDCA):
    PatternLength = FlexDCA.query(':TRIGger:PLENgth?')
    FlexDCA.write(':TIMebase:UIRange ' + PatternLength)
    print('\nThe entire {0} symbol pattern is displayed.'
          .format(PatternLength))


def waveform_acquisition(FlexDCA):
    """ Performs waveform acquisition limit test. """
    FlexDCA.write(':ACQuire:STOP')  # single acquisition mode
    FlexDCA.write(':ACQuire:CDISplay')  # Clear display
    FlexDCA.write(':LTESt:ACQuire:CTYPe:WAVeforms 32')
    FlexDCA.write(':LTESt:ACQuire:STATe ON')
    print('\nAcquiring 32 waveforms. Please wait...', flush=True)
    FlexDCA.query(':ACQuire:RUN;*OPC?')
    FlexDCA.write(':LTESt:ACQuire:STATe OFF')


def find_bit_sequence(FlexDCA, channel):
    print('*' * 30)
    print('A symbol sequence is a string of "1" and "0" characters.\n' +
          'For example: 1110')
    sequence = input('Enter a symbol sequence using symbols 0 and 1: ').strip()
    if (sequence in 'qQ') or (sequence == ''):
        return
    sequence = sequence.strip('"')
    sequence = sequence.strip("'")
    FlexDCA.write(':TIMebase:UNITs UINTerval')
    FlexDCA.write(':TIMebase:FIND:SIGNal CHAN' + channel)
    FlexDCA.write(':TIMebase:FIND:SEQuence "' + sequence + '"')
    i = float(FlexDCA.query(':TIMebase:UIPosition?'))
    pattern_start = int(i)
    total = 0
    print('*' * 30)
    while True:
        FlexDCA.write(':TIMebase:FIND:NEXT')
        i = float(FlexDCA.query(':TIMebase:UIPosition?'))
        bit_offset = int(i)
        bit = bit_offset - pattern_start
        if bit == 0:
            print('The bit sequence was not found.')
            break
        total += 1  # found sequence
        if total == 1:
            print('\nDisplayed span for "' + sequence + '" sequence is ' +
                  str(len(sequence)) + ' symbol.\n')
            print('REPEATEDLY PRESS ENTER KEY until all sequences are found.')
            print('Or, press "q" to exit.\n')
            print('Symbol Sequences Found'.center(30, ' '))
            print('-' * 30)
            print('      Number    Symbol Offset')
            print('-' * 30)
            first_found = bit
        elif bit == first_found:  # starting to repeat from beginning
            print('\n' + str(total-1) + ' sequences have been found.')
            break
        s = str(total).rjust(3, ' ') + '      '
        s += str(bit).ljust(5, ' ')
        print(s.center(30, ' '), end='')
        s = input()
        if (s == 'q'):
            break


FlexDCA = open_flexdca_connection(ADDRESS)
FlexDCA.query(':SYSTem:DEFault;*OPC?')
all_channels_off(FlexDCA)
install_simulated_module(FlexDCA, CHANNEL, 'DEM')
FlexDCA.write(':CHANnel' + CHANNEL + ':DISPlay ON')
setup(FlexDCA)
view_entire_pattern(FlexDCA)
waveform_acquisition(FlexDCA)
find_bit_sequence(FlexDCA, CHANNEL)
FlexDCA.write(':SYSTem:GTLocal')
FlexDCA.close()