Posted Fri, 15 Dec 2023 08:55:10 GMT by Kim, Minseo
Hello.

I would like to measure pulse in the 1.5A @20V region on Keithley 2602B. The pulse width is 1ms and the pulse duty is 10%, so it looks OK in the pulse specification. However, when performing a pulse measurement, the error "-5007: Operation would exceed safe operating area of the instrument" appears. To create a pulse, I used a trigger timer and set it to "smua.trigger.endpulse.action = 0" (smua.trigger.endpulse.action = smua.SOURCE_IDLE).

Is there any other way to set up "Pulse" mode?

Attachment file is captured image of "1KW-60906-0_Series_2600BDatasheet_112718.pdf" file's 2602B pulse specification.
Thank you.
Posted Mon, 18 Dec 2023 23:03:10 GMT by C, Andrea
See how this does for you.
In the attachment is scope shot of the 1.5Amp, 1msec pulse into 50mΩ resistor (~75mV response).

TSP code:
​​​​​​​

function Run_test(show_data, PulsePeriod, PulseWidth, MeasDelay)


   -- when passthrough is true, the timer will "tic" immediately,
   -- which for this application will start as soon as the
   -- trigger model is ARMED.  
   node[1].trigger.timer[1].delay = PulsePeriod
   node[1].trigger.timer[1].stimulus = node[1].smua.trigger.ARMED_EVENT_ID
   node[1].trigger.timer[1].count = 1  --PulseCount - 1
   node[1].trigger.timer[1].passthrough = true
   node[1].trigger.timer[1].clear()
   
   node[1].trigger.timer[2].delay = PulseWidth
   node[1].trigger.timer[2].stimulus = node[1].trigger.timer[1].EVENT_ID
   node[1].trigger.timer[2].count = 1        
   node[1].trigger.timer[2].passthrough = false
   node[1].trigger.timer[2].clear()
   
   node[1].trigger.timer[3].delay = MeasDelay
   node[1].trigger.timer[3].stimulus = node[1].trigger.timer[1].EVENT_ID
   node[1].trigger.timer[3].count = 1        
   node[1].trigger.timer[3].passthrough = false
   node[1].trigger.timer[3].clear()


    
    -- digital output trigger for external equipment
    -- configure digital IO line 1 to output a active LO/falling edge
    -- pulse at start of each current pulse
    digio.trigger[1].clear()
    digio.trigger[1].mode = digio.TRIG_FALLING  --digio.TRIG_RISINGM
    digio.trigger[1].pulsewidth = 100e-6
    digio.trigger[1].stimulus = node[1].trigger.timer[1].EVENT_ID  -- source stimulus too
    
        
   -- clear the reading buffers
   reset_buffers(node[1].smua)
     
 

    -- Turn the outputs on
    smua.source.output                    = smua.OUTPUT_ON
    
    -- after blue light state change, delay a little 
    delay(0.1)  

    -- Start the trigger model execution
    smua.trigger.initiate()   -- start this one last as all the other smus follow this leader
    
    -- Wait until the sweep has completed
    waitcomplete()

--[[
-- hot switch:
-- to bleed off the trapped charge on PN junction capacitance and non-zero voltage
-- briefly set the voltage compliance to small number
restore_val = smua.source.limitv
smua.source.limitv = 0.01
delay(0.001)
smua.source.limitv = restore_val
]]

    -- before blue light state change, delay a little 
    delay(0.1)
    -- Turn the output off
    smua.source.output                    = smua.OUTPUT_OFF
    

    -- IV data for the laser
    if show_data == true then
       -- Print the data back to the Console in tabular format
       print(" Voltage\tCurrent\tResistance")
       for x=1,smua.nvbuffer1.n do
          -- Voltage readings are in nvbuffer2.  Current readings are in nvbuffer1.
          print(smua.nvbuffer2[x], smua.nvbuffer1[x], smua.nvbuffer2[x]/smua.nvbuffer1[x] )
       end
    end
    

    
end

function reset_buffers(smu)
        -- Prepare the Reading Buffers
    smu.nvbuffer1.clear()
    smu.nvbuffer1.appendmode        = 1
    smu.nvbuffer1.collecttimestamps    = 1
    smu.nvbuffer2.clear()
    smu.nvbuffer2.appendmode        = 1
    smu.nvbuffer2.collecttimestamps    = 1

end


function config_smu_list_sweep(nodenum, smu, srcRange, srclist, limitV, nplc, remoteSense)
    
    smu.source.func                    = smu.OUTPUT_DCAMPS
    if (remoteSense == true) then
        smu.sense                    = smu.SENSE_REMOTE
    else
        smu.sense                    = smu.SENSE_LOCAL
    end
    smu.source.autorangei            = smu.AUTORANGE_OFF
    smu.source.rangei                = srcRange
    smu.source.leveli                = 0
    smu.source.limitv                = limitV

    -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing
    smu.measure.autozero            = smu.AUTOZERO_ONCE
    smu.measure.autorangev            = smu.AUTORANGE_OFF
    smu.measure.rangev                = limitV
    smu.measure.nplc                = nplc
    -- A timer will be used to set the measure delay and synchronize the measurement
    -- between the SMUs so set the built in delay to 0.
    smu.measure.delay                = 0
    
    -- Configure SMU Trigger Model for Sweep
    --smu.trigger.source.lineari(start, stop, numPoints)
    smu.trigger.source.listi(srclist)
    smu.trigger.source.limitv        = limitV
    smu.trigger.measure.action        = smu.ENABLE
    smu.trigger.measure.iv(smu.nvbuffer1, smu.nvbuffer2)
    smu.trigger.endpulse.action        = smu.SOURCE_IDLE
    smu.trigger.endsweep.action        = smu.SOURCE_IDLE
    smu.trigger.count                = table.getn(srclist)
    smu.trigger.arm.stimulus        = 0
    smu.trigger.source.stimulus        = trigger.timer[1].EVENT_ID
    smu.trigger.measure.stimulus    = trigger.timer[3].EVENT_ID
    smu.trigger.endpulse.stimulus    = trigger.timer[2].EVENT_ID
    smu.trigger.source.action        = smu.ENABLE
end


--  **************************************  MAIN PROGRAM BELOW *****************

reset()
errorqueue.clear()

nodesFound = tsplink.reset(1)

print("Nodes found = " .. nodesFound)

--smua.interlock.enable = smua.DISABLE


-- use of pulse region 4 of 2602B:  10A at up to 20V
-- max 1.8msec pulse with 1% duty cycle
local PulseWidth = 1.0e-3
local PulsePeriod = PulseWidth / 0.01
local MeasDelay = PulseWidth * 0.8
local nplc = (PulseWidth - MeasDelay - 60e-6) * localnode.linefreq


print("Computed NPLC value: "..tostring(nplc))

if tostring(nplc) < "0.001" then
  nplc = 0.001   -- 16.7usec, minimum value allowed
  MeasDelay = 1e-6
end -- if


-- voltage ranges on 2602B:  100mV, 1V, 6V, 40V
-- pick a limit value higher than expected I*DUT_R and
-- puts you on appropriate range.
local voltageLimit = 1

-- ranges:  decades of 10.....100mA, 1A, 3A, 10A
local mySrcRange = 3  
mysrclist = { 1.5}  -- use this one for a single pulse
--local numPulses = table.getn(mysrclist)



   
    --config_smu_list_sweep(nodenum, smu, srcRange, srclist, limitV, nplc, remoteSense)
    config_smu_list_sweep(1, node[1].smua, mySrcRange, mysrclist, voltageLimit, nplc, true)



   timer.reset()
   
   
   Run_test(true, PulsePeriod, PulseWidth, MeasDelay) -- pass true to print data back to console
   
   time = timer.measure.t()
   print("Time to run: "..time)
   print("****************************************")
   print("Current Source Range: "..node[1].smua.source.rangei)

Posted Tue, 19 Dec 2023 13:49:40 GMT by C, Andrea
Needs an update:

The code posted above will not take you into pulse region 4.
These high watt pulse regions are in our Extended Operating Area and have firmware imposed max PW and Duty Cycle limits.

To access the EOA regions, supply a higher voltage value for the trigger.source.limitv which will be applied only during the high watt pulse.
When not sourcing the pulse level, the lower value set for the smuX.source.limitv applies.  The combo of smuX.source.leveli and smuX.source.limitv needs to be within the DC operating area of the SMU.

These three lines in particular for accessing EOA region:

smuX.measure.rangev = EOA_limit

smuX.source.limitv = limitV

smuX.trigger.source.limitv = EOA_limit

I'll upload scope shot of 1.5A into 10Ω.

Revised code:
function Run_test(show_data, PulsePeriod, PulseWidth, MeasDelay)


   -- when passthrough is true, the timer will "tic" immediately,
   -- which for this application will start as soon as the
   -- trigger model is ARMED.  
   node[1].trigger.timer[1].delay = PulsePeriod
   node[1].trigger.timer[1].stimulus = node[1].smua.trigger.ARMED_EVENT_ID
   node[1].trigger.timer[1].count = 1  --PulseCount - 1
   node[1].trigger.timer[1].passthrough = true
   node[1].trigger.timer[1].clear()
   
   node[1].trigger.timer[2].delay = PulseWidth
   node[1].trigger.timer[2].stimulus = node[1].trigger.timer[1].EVENT_ID
   node[1].trigger.timer[2].count = 1        
   node[1].trigger.timer[2].passthrough = false
   node[1].trigger.timer[2].clear()
   
   node[1].trigger.timer[3].delay = MeasDelay
   node[1].trigger.timer[3].stimulus = node[1].trigger.timer[1].EVENT_ID
   node[1].trigger.timer[3].count = 1        
   node[1].trigger.timer[3].passthrough = false
   node[1].trigger.timer[3].clear()


    
    -- digital output trigger for external equipment
    -- configure digital IO line 1 to output a active LO/falling edge
    -- pulse at start of each current pulse
    digio.trigger[1].clear()
    digio.trigger[1].mode = digio.TRIG_FALLING  --digio.TRIG_RISINGM
    digio.trigger[1].pulsewidth = 100e-6
    digio.trigger[1].stimulus = node[1].trigger.timer[1].EVENT_ID  -- source stimulus too
    
        
   -- clear the reading buffers
   reset_buffers(node[1].smua)
     
 

    -- Turn the outputs on
    smua.source.output                    = smua.OUTPUT_ON
    
    -- after blue light state change, delay a little 
    delay(0.1)  

    -- Start the trigger model execution
    smua.trigger.initiate()   -- start this one last as all the other smus follow this leader
    
    -- Wait until the sweep has completed
    waitcomplete()

--[[
-- hot switch:
-- to bleed off the trapped charge on PN junction capacitance and non-zero voltage
-- briefly set the voltage compliance to small number
restore_val = smua.source.limitv
smua.source.limitv = 0.01
delay(0.001)
smua.source.limitv = restore_val
]]

    -- before blue light state change, delay a little 
    delay(0.1)
    -- Turn the output off
    smua.source.output                    = smua.OUTPUT_OFF
    

    -- IV data for the laser
    if show_data == true then
       -- Print the data back to the Console in tabular format
       print(" Voltage\tCurrent\tResistance")
       for x=1,smua.nvbuffer1.n do
          -- Voltage readings are in nvbuffer2.  Current readings are in nvbuffer1.
          print(smua.nvbuffer2[x], smua.nvbuffer1[x], smua.nvbuffer2[x]/smua.nvbuffer1[x] )
       end
    end
    

    
end

function reset_buffers(smu)
        -- Prepare the Reading Buffers
    smu.nvbuffer1.clear()
    smu.nvbuffer1.appendmode        = 1
    smu.nvbuffer1.collecttimestamps    = 1
    smu.nvbuffer2.clear()
    smu.nvbuffer2.appendmode        = 1
    smu.nvbuffer2.collecttimestamps    = 1

end


function config_smu_list_sweep(nodenum, smu, srcRange, srclist, limitV, EOA_limit, nplc, remoteSense)
    
    smu.source.func                    = smu.OUTPUT_DCAMPS
    if (remoteSense == true) then
        smu.sense                    = smu.SENSE_REMOTE
    else
        smu.sense                    = smu.SENSE_LOCAL
    end
    smu.source.autorangei            = smu.AUTORANGE_OFF
    smu.source.rangei                = srcRange
    smu.source.leveli                = 0
    smu.source.limitv                = limitV

    -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing
    smu.measure.autozero            = smu.AUTOZERO_ONCE
    smu.measure.autorangev            = smu.AUTORANGE_OFF
    smu.measure.rangev                = EOA_limit
    smu.measure.nplc                = nplc
    -- A timer will be used to set the measure delay and synchronize the measurement
    -- between the SMUs so set the built in delay to 0.
    smu.measure.delay                = 0
    
    -- Configure SMU Trigger Model for Sweep
    --smu.trigger.source.lineari(start, stop, numPoints)
    smu.trigger.source.listi(srclist)
    smu.trigger.source.limitv        = EOA_limit
    smu.trigger.measure.action        = smu.ENABLE
    smu.trigger.measure.iv(smu.nvbuffer1, smu.nvbuffer2)
    smu.trigger.endpulse.action        = smu.SOURCE_IDLE
    smu.trigger.endsweep.action        = smu.SOURCE_IDLE
    smu.trigger.count                = table.getn(srclist)
    smu.trigger.arm.stimulus        = 0
    smu.trigger.source.stimulus        = trigger.timer[1].EVENT_ID
    smu.trigger.measure.stimulus    = trigger.timer[3].EVENT_ID
    smu.trigger.endpulse.stimulus    = trigger.timer[2].EVENT_ID
    smu.trigger.source.action        = smu.ENABLE
end


--  **************************************  MAIN PROGRAM BELOW *****************

reset()
errorqueue.clear()

nodesFound = tsplink.reset(1)

print("Nodes found = " .. nodesFound)

--smua.interlock.enable = smua.DISABLE


-- use of pulse region 4 of 2602B:  10A at up to 20V
-- max 1.8msec pulse with 1% duty cycle
local PulseWidth = 1.0e-3
local PulsePeriod = PulseWidth / 0.01
local MeasDelay = PulseWidth * 0.8
local nplc = (PulseWidth - MeasDelay - 60e-6) * localnode.linefreq


print("Computed NPLC value: "..tostring(nplc))

if tostring(nplc) < "0.001" then
  nplc = 0.001   -- 16.7usec, minimum value allowed
  MeasDelay = 1e-6
end -- if


-- voltage ranges on 2602B:  100mV, 1V, 6V, 40V
-- pick a limit value higher than expected I*DUT_R and
-- puts you on appropriate range.
local voltageLimit = 1
local duringPulse_voltageLimit = 20

-- ranges:  decades of 10.....100mA, 1A, 3A, 10A
local mySrcRange = 3  
mysrclist = { 1.5}  -- use this one for a single pulse
--local numPulses = table.getn(mysrclist)



   
    --config_smu_list_sweep(nodenum, smu, srcRange, srclist, limitV, EOA_limit, nplc, remoteSense)
    config_smu_list_sweep(1, node[1].smua, mySrcRange, mysrclist, voltageLimit, duringPulse_voltageLimit, nplc, true)



   timer.reset()
   
   
   Run_test(true, PulsePeriod, PulseWidth, MeasDelay) -- pass true to print data back to console
   
   time = timer.measure.t()
   print("Time to run: "..time)
   print("****************************************")
   print("Current Source Range: "..node[1].smua.source.rangei)

​​​​​​​
Posted Wed, 20 Dec 2023 01:07:51 GMT by Kim, Minseo
Hello.
2nd script about EOA region is what I needed.
Thank you for your help.!

You must be signed in to post in this forum.