#This VI assumes that you connect at least two AWG5000 instruments using the LAN interface and no other  VISA TCP/IP resource.
#1) Connect the instruments together using the "Sync IN" "Sync OUT" port and the SYNC cable
#2) The same sequencer is loaded on all the instruments
#3) The VI discovers the Master on the Visa Device list

import pyvisa
import AWG_7000




#Open VISA
try:
    rm = pyvisa.ResourceManager()

    #List of all the connected instruments
    resources = rm.list_resources()
    print(f"\n\n\nConnected devices: {resources}")

    #Consider only the wanted resources
    good_resources = []
    index = input("Dial the index of an instrument (just enter to finish): ")
    while(index != ""):
        good_resources.append(resources[int(index)])
        index = input("Dial the index of an instrument (just enter to finish): ")

    #If you don't use pyvisa, comment the last section and use the line below instead:
    #good_resources = ["address1", "address2",..., "addressn"]

    #Open each resource address
    instruments = []
    for resource in good_resources:
        instrument = rm.open_resource(resource)
        instruments.append(instrument)

    #Initialize AWG
    AWGs = []
    for instrument in instruments:
        AWG = AWG_7000.AWG5000(instrument, 2)
        AWGs.append(AWG)
except Exception as e: print(f"VISA error: {e}")
master_index = 0 #Master index in AWG list




###########################################################################################################
#Channel settings
amplitude_scale = 100 #%
analog_skew = 0 #s
baseline_offset = 0 #V
vocm = 0 #V
polarity = AWG_7000.Polarity.Normal
fine_skew = 0 #s
correction_offset = 0 #V
keeplastmode = AWG_7000.KeepLastMode.KeepLast
offset_on_stop = 0
optimization = AWG_7000.ChannelOptimization.High_Linearity
overshoot = 0
flatness_compensation = AWG_7000.State.OFF
channel_value_on_stop_state = AWG_7000.KeepLastMode.KeepLast
output_value_on_stop = 0

#Sequencer parameters
format = AWG_7000.Format.Amplitude_offset
analog_waveform_names = [["SINE", "SINE"],
                  ["RAMP", "RAMP"],
                  ["SQUARE", "SQUARE"]]
amplitudes = [[1, 1.5],
               [0.75, 0.75],
               [1, 1.2]]
offsets = [[0, 0],
            [0, 0.3],
            [0, 0]]
decreasing_strategies = [[AWG_7000.DecreasingStrategy.Decimation, AWG_7000.DecreasingStrategy.Decimation],
                         [AWG_7000.DecreasingStrategy.Decimation, AWG_7000.DecreasingStrategy.Decimation],
                         AWG_7000.DecreasingStrategy.Decimation, AWG_7000.DecreasingStrategy.Decimation]
increasing_strategies = [[AWG_7000.IncreasingStrategy.Interpolation, AWG_7000.IncreasingStrategy.Interpolation],
                         [AWG_7000.IncreasingStrategy.Interpolation, AWG_7000.IncreasingStrategy.Interpolation],
                         [AWG_7000.IncreasingStrategy.Interpolation, AWG_7000.IncreasingStrategy.Interpolation]]
sub_lengths = [[16384, 16384],
               [16384, 16384],
               [16384, 16384]]
delays = [[0, 0],
          [0, 0],
          [0, 0]]
output_formats = [[AWG_7000.OutputFormat.Waveform, AWG_7000.OutputFormat.Waveform],
                  [AWG_7000.OutputFormat.Waveform, AWG_7000.OutputFormat.Waveform],
                  [AWG_7000.OutputFormat.Waveform, AWG_7000.OutputFormat.Waveform]]
entry_lengths = [16384, 16384, 16384]
repetitions = [1, 1, 1]
sequencer_length = len(analog_waveform_names)
digital_waveforms = ["CLOCK", "COUNTER", "COUNTER"]
marker_custom_pattern = ["", "", ""]
###########################################################################################################




try:
    #Initialize all AWGs and find the master
    for AWG in AWGs:
        AWG.Initialize(True)

        for channel in AWG.channels:
            AWG.ConfigureChannelSettings(channel, 100, analog_skew, fine_skew, correction_offset, vocm, keeplastmode, polarity, offset_on_stop, baseline_offset,
                                     optimization, overshoot, flatness_compensation, channel_value_on_stop_state, output_value_on_stop)
            
        AWG.SetSequencerLength(sequencer_length, AWG_7000.SetValue.PRESENT)

        #Program all wanted sequencer entries
        for i in range(sequencer_length):
            entry = AWG_7000.SequencerEntry(entry_number=i+1, analog_waveform_names=analog_waveform_names[i], amplitudes=amplitudes[i], offsets=offsets[i],
                                            decreasing_strategies=decreasing_strategies[i], increasing_strategies=increasing_strategies[i], sub_lengths=sub_lengths[i],
                                            delays=delays[i], digital_waveform_name=digital_waveforms[i], custom_pattern=marker_custom_pattern[i], length=entry_lengths[i],
                                            repetitions=repetitions[i], output_formats=output_formats[i])
            AWG.ConfigureSequencerElement(entry)

        for channel in AWG.channels: AWG.SetOutputState(channel, AWG_7000.State.ON)

        if AWG.IsSlave() == 0: master_index = AWGs.index(AWG)

    #The master captures all the slaves
    AWGs[master_index].Capture()
    print(f"Captured devices: {AWGs[master_index].GetCapturedDevices()}")


    while(True):
        if input("Press enter to start") == "":
            AWGs[master_index].AWGStart()
            break
    
    while(True):
        if input("Press enter to stop") == "":
            AWGs[master_index].AWGStop()
            break
except Exception as e: print(f"The following exception has occured: {e}")