Hello,
I am struggeling to trigger another SMU using a tsplink trigger over tsplink.
I am using two Keithley 2612B System Source Meters. Setting up the tsplink network works and I am able to send commands using node[2].execute(cmd) to the second SMU.
My goal is to output synchronized sweeps on both SMUs. On smua of SMU1 and SMU2 a pulsed sweep should be outputted, on smub of SMU1 and SMU2 also a pulsed sweep with constant voltage should be outputted. In addition, the currents should be measured.
The main idea is to use two timers to control the pulse width and the pulse period. The timer 1 (period time) is stimulated by a tsplink trigger (tsplink.trigger[2].EVENT_ID). If I look at the scope, this works fine for SMU1 (the master SMU) on which I execute the script. However, SMU2 seems never to receive the trigger.
Here is the source code of the script that I am using:
function pm_configure(pulse_levels_v, constant_v, bias_level_v, limit_i, pulse_period_s, pulse_width_s, measure_time_s, measure_delay_s)
-- checks
assert(pulse_width_s > (measure_time_s + measure_delay_s), "pulse width must be longer than measure time + measure delay")
assert(pulse_period_s > pulse_width_s, "pulse period must be longer than pulse width")
-- measure time in number of power line cycles
local measure_nplc = measure_time_s * localnode.linefreq
-- number of pulses
local npulses = table.getn(pulse_levels_v)
-- Use trigger timer 1 to control the period and trigger timer 2 to control the
-- pulse width.
-- period_timer: trigger.timer[1]
-- pulsewidth_timer: trigger.timer[2]
-- Configure the period timer to output.
trigger.timer[1].delay = pulse_period_s
-- The effective count is npulses-1 because the passthrough setting is true.
trigger.timer[1].count = npulses-1
-- Configure the timer to immediately output a trigger event when it is started.
trigger.timer[1].passthrough = true
-- Start the timer with a trigger from tsplink
trigger.timer[1].stimulus = tsplink.trigger[2].EVENT_ID
-- Configure the pulse width timer to output one trigger event for each period.
trigger.timer[2].delay = pulse_width_s
trigger.timer[2].count = 1
-- Do not immediately output a trigger event when pulse width timer is started.
trigger.timer[2].passthrough = false
-- Start the pulse width timer with the period timer output trigger event.
trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID
for _,smu in ipairs({smua, smub} ) do
-- reset SMU such that we are in a defined state
smu.reset()
smu.sense = smu.SENSE_LOCAL -- 2-wire
-- perform calibration measurements
smu.measure.autozero = smu.AUTOZERO_ONCE
-- clear buffers
smu.nvbuffer1.clear()
-- set measurement delay
smu.measure.delay = measure_delay_s
smu.measure.autorangei = smu.AUTORANGE_OFF
-- Configure the source function.
smu.source.func = smu.OUTPUT_DCVOLTS
smu.source.levelv = bias_level_v
smu.source.limiti = limit_i
-- Configure the trigger model to execute a 10-point fixed-level voltage pulse
-- train. No measurements are made.
smu.trigger.source.action = smu.ENABLE
smu.measure.nplc = measure_nplc
smu.trigger.measure.i(smu.nvbuffer1)
smu.trigger.measure.action = smu.ENABLE
-- Set the trigger source limit, which can be different than the bias limit.
-- This is an important setting for pulsing in the extended operating area.
smu.trigger.source.limiti = limit_i
smu.measure.rangei = limit_i
-- Trigger SMU source action with the period timer event.
smu.trigger.source.stimulus = trigger.timer[1].EVENT_ID
-- Configure the endpulse action to achieve a pulse.
smu.trigger.endpulse.action = smu.SOURCE_IDLE
-- Trigger the SMU end pulse action with a pulse width timer event.
smu.trigger.endpulse.stimulus = trigger.timer[2].EVENT_ID
-- Set the trigger model count to generate one npulses pulse train.
smu.trigger.arm.count = 1
smu.trigger.count = npulses
end
smua.trigger.source.listv(pulse_levels_v)
smub.trigger.source.listv({constant_v})
for _,smu in ipairs({smua, smub}) do
smu.source.output = smu.OUTPUT_ON
smu.trigger.initiate()
end
end
function pm_trigger()
tsplink.trigger[2].mode = tsplink.TRIG_SYNCHRONOUS
tsplink.trigger[2].assert()
-- Wait for the sweep to complete.
waitcomplete()
end
function main()
-- empty error queue
errorqueue.clear()
-- tsplink.reset()
tsplink.reset()
assert(tsplink.state == "online", "resetting tsplink was not successful")
node[2].tsplink.group = 2
-- copy script to node 2
node[2].dataqueue.clear()
node[2].dataqueue.add(sweeps.source)
node[2].execute("script.newautorun(dataqueue.next())")
-- perform a reset
reset()
node[2].execute("pm_configure({1,2,3,4,5,6,7,8}, 2.5, 0, 0.1, 50e-3, 25e-3, 5e-3, 1e-3)")
pm_configure({1,2,3,4,5,6,7,8}, 2.5, 0, 0.1, 50e-3, 25e-3, 5e-3, 1e-3)
-- send trigger
pm_trigger()
-- check if errors occured
print(errorqueue.count)
end
The script sets up the network, copies the script from SMU1 to SMU2, sets up the sweeps on both SMUs by calling the function pm_configure and finally sends the trigger. The output of the 1st SMU (master SMU) is as expected. However, the output of SMU2 is not as expected and it seems that the trigger event is never noticed (see attached waveform).
I am confident that the trigger event is the problem, because if I change the trigger event from tsplink (tsplink.trigger[2].EVENT_ID) to display.trigger.EVENT_ID, then I see the sweep at SMU1 if I press the TRIG key of SMU1, and I see the sweep at SMU2 if I press the TRIG key of SMU2.
Why is the trigger event over tspnet not noticed by the 2nd SMU?