Tektronix Technical Forums are maintained by community involvement. Feel free to post questions or respond to questions by other members. Should you require a time-sensitive answer, please contact your local Tektronix support center here.

Triggering timing issue

Models 2601, 2602, 2611, 2612, 2635, 2636
Models 2601A, 2602A, 2611A, 2612A, 2635A, 2636A
Models 2601B, 2602B, 2604B, 2611B, 2612B, 2614B, 2634B, 2635B, 2636B
Post Reply
pedrovfr
Posts: 2
Joined: April 30th, 2021, 10:48 am
Country: Brazil

Triggering timing issue

Post by pedrovfr » May 6th, 2021, 6:21 am

Hello all,
I am developing a TSP script for a SMU 2636A, my application needs a pulse generator on SMUA ( with the number of pulses controlled), a fixed voltage on SMUB, and iv measurements on both channels with frequency higher than the pulses (so I measure several points within a pulse period).
I managed to obtain those functionalities using the trigger model, but the state machine is leaving the trigger layer before it performs the number of pulses that I want. I still can't properly control the time of a full test.

I have used the asyncronous mode for the measurements, and create a timer specifically to maintain the SM in the trigger layer but this did not work.

Following is my code, please someone help me, I can't see where the problem is and I am becoming somehow desperate:

Code: Select all

PulseDualMeas = function (bias, level, numPoints, pulseWidth, pulsePeriod, limitI, nplc, meas_interval)
	
	-- Save settings in temporary variables so they can be restored at the end.
    local l_smua_levelv = smua.source.levelv 
    local l_smua_rangev = smua.source.rangev
    local l_smua_autorangev = smua.source.autorangev 
    local l_smua_func = smua.source.func
    local l_smua_autozero = smua.measure.autozero
    local l_smua_filter = smua.measure.filter.enable
    local l_smub_levelv = smub.source.levelv 
    local l_smub_rangev = smub.source.rangev
    local l_smub_autorangev = smub.source.autorangev 
    local l_smub_func = smub.source.func
    local l_smub_autozero = smub.measure.autozero
    local l_smub_filter = smub.measure.filter.enable
    local l_d_screen = display.screen
	
	
	-- Clear the front panel display then prompt for input parameters if missing.
    display.clear()   
      
    if bias == nil then
        bias = display.prompt(l_volts_fmt, " Volts", "Enter BIAS Voltage.", 0, -l_max_volts, l_max_volts)
        if bias == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
    end
    if level == nil then
        level = display.prompt(l_volts_fmt, " Volts", "Enter PULSE Voltage.", 1, -l_max_volts, l_max_volts)
        if level == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
    end
    if pulseWidth == nil then
        pulseWidth = display.prompt("00.000E+00", " Seconds", "Enter pulse width.", 20E-3, 0, 20)    
        if pulseWidth == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
    end
    if pulsePeriod == nil then
        pulsePeriod = display.prompt("00.000E+00", " Seconds", "Enter pulse period time.", 20E-3, 0, 20)
        if pulsePeriod == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
    end
    if numPoints == nil then
        numPoints = display.prompt("0000", " Pulses", "Enter number of pulses", 10, 1, 1000)   
        if numPoints == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
    end

	if meas_interval == nil then
		meas_interval = display.prompt("0000", " Seconds", "Enter measurement interval", 10, 1, 1000)   
        if meas_interval == nil then
            -- Abort if Exit key pressed
            AbortScript(l_d_screen)
        end
	end

    -- Update display with test info.
    display.settext("PulseDualMeas")  -- Line 1 (20 characters max)
    
	
	reset()
	-- Configure Channel A Settings
	--=============================
	smua.reset()
	smua.source.func					= smua.OUTPUT_DCVOLTS

	smua.source.autorangev			= smua.AUTORANGE_OFF
	smua.source.rangev				= math.max(math.abs(bias), math.abs(level))
	smua.source.levelv				= bias
	-- Set the DC bias limit.  This is not the limit used during the pulses.
	smua.source.limiti				= 0.1

	-- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing
	smua.measure.autozero			= smua.AUTOZERO_ONCE
	smua.measure.autorangei			= smua.AUTORANGE_OFF
	smua.measure.rangei				= limitI
	smua.measure.nplc				= nplc
	-- A timer will be used to set the measure delay and synchronize the measurement
	-- between the two SMUs so set the built in delay to 0.
	smua.measure.delay				= 0
	
	-- Prepare the Reading Buffers
	smua.nvbuffer1.clear()
	smua.nvbuffer1.collecttimestamps= 1
	smua.nvbuffer2.clear()
	--smua.nvbuffer2.collecttimestamps= 1
	--=============================
	-- End Channel A Settings

	-- Configure Channel B Settings
	--=============================
	smub.reset()
	smub.source.func					= smub.OUTPUT_DCVOLTS

	smub.source.autorangev			= l_smub_autorangev
	smub.source.rangev				= l_smub_rangev --math.max(math.abs(bias), math.abs(level))
	smub.source.levelv				= l_smub_levelv -- bias
	-- Set the DC bias limit.  This is not the limit used during the pulses.
	smub.source.limiti				= 0.1

	-- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing
	smub.measure.autozero			= smua.AUTOZERO_ONCE
	smub.measure.autorangei			= 0
	smub.measure.rangei				= limitI
	smub.measure.nplc				= nplc
	-- A timer will be used to set the measure delay and synchronize the measurement
	-- between the two SMUs so set the built in delay to 0.
	smub.measure.delay				= 0

	-- Prepare the Reading Buffers
	smub.nvbuffer1.clear()
	--smub.nvbuffer1.collecttimestamps= 1
	smub.nvbuffer2.clear()
	--smub.nvbuffer2.collecttimestamps= 1
	--=============================
	-- End Channel B Settings

	-- Configure the Trigger Model
	--============================

	-- Timer 1 controls the measurement
	trigger.timer[1].count			= 0

	trigger.timer[1].delay			= meas_interval  
	trigger.timer[1].passthrough	= false
	trigger.timer[1].stimulus		= smub.trigger.ARMED_EVENT_ID--trigger.timer[1].EVENT_ID

	-- Timer 2 controls the pulse period
	trigger.timer[2].count			= 1--numPoints > 1 and numPoints - 1 or 1
	trigger.timer[2].delay			= pulsePeriod-- - pulseWidth
	trigger.timer[2].passthrough	= true
	trigger.timer[2].stimulus		= smua.trigger.PULSE_COMPLETE_EVENT_ID
	--trigger.timer[1].clear()


	-- Timer 3 controls the pulse width
	trigger.timer[3].count			= 1--numPoints > 1 and numPoints - 1 or 1
	trigger.timer[3].delay			= pulseWidth
	trigger.timer[3].passthrough	= true
	trigger.timer[3].stimulus		= trigger.timer[2].EVENT_ID
	--rigger.timer[3].clear()

	-- Timer 4 keeps the sm on trigger layer
	trigger.timer[4].count			= 1--numPoints > 1 and numPoints - 1 or 1
	trigger.timer[4].delay			= pulsePeriod*numPoints + 2
	trigger.timer[4].passthrough	= true
	trigger.timer[4].stimulus		= smub.trigger.ARMED_EVENT_ID
	trigger.timer[4].clear()
	
	-- Configure SMUA Trigger Model for Sweep
	smua.trigger.source.linearv(level, level, 1)--smua.trigger.source.linearv(start, stop, numPoints)
	--smua.trigger.source.limiti		= limitI
	smua.trigger.measure.action		= smua.ASYNC--smua.ENABLE
	smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2)
	smua.trigger.endpulse.action	= smua.SOURCE_IDLE
	smua.trigger.endsweep.action	= smua.SOURCE_IDLE
	smua.trigger.count				= numPoints -- <<<=============== 
	--[[During a sweep, the SMU iterates through the trigger layer of the trigger model this many times. After performing
this many iterations, the SMU returns to the arm layer.
If this count is set to zero (0), the SMU stays in the trigger model indefinitely until aborted.]]
	smua.trigger.arm.stimulus		= 0
	smua.trigger.measure.stimulus	= trigger.timer[1].EVENT_ID
	smua.trigger.source.stimulus	= trigger.timer[2].EVENT_ID
	smua.trigger.endpulse.stimulus	= trigger.timer[3].EVENT_ID
	smua.trigger.source.action		= smua.ENABLE

	-- Configure SMUB Trigger Model for Sweep
	smub.trigger.source.linearv(l_smub_levelv, l_smub_levelv, 1)
	--smub.trigger.source.limiti		= limitI
	smub.trigger.measure.action		= smub.ASYNC--smub.ENABLE
	smub.trigger.measure.iv(smub.nvbuffer1, smub.nvbuffer2)
	smub.trigger.endpulse.action	= smub.SOURCE_HOLD
	smub.trigger.endsweep.action	= smub.SOURCE_IDLE
	smub.trigger.count				= numPoints  -- <<<===============
	smub.trigger.arm.stimulus		= 0
	smub.trigger.source.stimulus	= trigger.timer[2].EVENT_ID
	smub.trigger.measure.stimulus	= trigger.timer[1].EVENT_ID
	smub.trigger.endpulse.stimulus	= trigger.timer[3].EVENT_ID
	--smub.trigger.endsweep.stimulus	= trigger.timer[4].EVENT_ID
	smub.trigger.source.action		= smub.ENABLE
	--==============================
	-- End Trigger Model Configuration

	smua.source.output				= smua.OUTPUT_ON
	smub.source.output				= smub.OUTPUT_ON

	-- Start the trigger model execution
	smua.trigger.initiate()
	smub.trigger.initiate()
	-- Sweep will not start until the TRIG button is pressed
	smua.trigger.source.set()
	smua.trigger.endpulse.set()
	-- Wait until the sweep has completed
	waitcomplete()
	
	smua.source.output				= smua.OUTPUT_OFF
	smub.source.output				= smub.OUTPUT_OFF
	
	-- Update the front panel display and restore modified settings.
    display.setcursor(2,1)             
    display.settext("Test complete.")  -- Line 2 (32 characters max)
    smua.source.levelv = 0
    smua.source.rangev = l_smua_rangev
    smua.source.autorangev = l_smua_autorangev
    smua.source.func = l_smua_func
    smua.source.levelv = l_smua_levelv
    smua.measure.autozero = l_smua_autozero
    smua.measure.filter.enable = l_smua_filter
    smub.source.levelv = 0
    smub.source.rangev = l_smub_rangev
    smub.source.autorangev = l_smub_autorangev
    smub.source.func = l_smub_func
    smub.source.levelv = l_smub_levelv
    smub.measure.autozero = l_smub_autozero
    smub.measure.filter.enable = l_smub_filter
    delay(2)
    display.clear()
    display.screen = l_d_screen
	
	-- Print the data back to the Console in tabular format
	print("Time\tSMUA Voltage\tSMUA Current\tSMUB Voltage\tSMUB Current")
	for x=1,smua.nvbuffer1.n do
		-- Voltage readings are in nvbuffer2.  Current readings are in nvbuffer1.
		print(smua.nvbuffer1.timestamps[x], smua.nvbuffer2[x], smua.nvbuffer1[x], smub.nvbuffer2[x], smub.nvbuffer1[x])
	end
end
Thanks

Andrea C
Keithley Applications
Keithley Applications
Posts: 1562
Joined: October 15th, 2010, 10:35 am
Country: United States
Contact:

Re: Triggering timing issue

Post by Andrea C » May 9th, 2021, 9:35 am

See if the info in this post is helpful:
viewtopic.php?f=14&t=142618

Post Reply

Return to “2600 Series SourceMeter”

Who is online

Users browsing this forum: No registered users and 4 guests