Posted Thu, 01 Feb 2024 11:43:52 GMT by Daniele, Fabrizio Reliability Technician
Hello,
I am very new to the SMU 2602 and I am trying to generate 2 simultaneous 120 degree out of phase sine waves at 100 Hz on the channels A and B of the same SMU 2602 B, could you please advise:
  • if this is possible from the hardware point of view?
  • if this is possible from the software point of view?
  • if there are scripts from where I could find suggestions on how to do it? 
Should I use:
  •  SetupSineFunction(frequency, amplitude, offset, limitI, remoteSense, trigLineIn)
  • or build the waveforms from a table using SetupAWG(startV, rangeV, limitI, wfrmTbl, remoteSense, trigLineIn) and then adjusting the timing to get the frequency I need?

Thank you
Fabrizio
 
Posted Sun, 04 Feb 2024 17:38:01 GMT by C, Andrea
Hello Fabrizio,

Yes, this is very much possible with the 2600B SourceMeter.

Sounds like you have our application note on ARB features of the 2600B SMUs
Github code
ARB Features for testing Ford EMC

Either approach could work for generating sine wave from the SMUs.

Suppose you use a list of 100 points to describe one cycle of the waveform.
If you source those values at 10KHz rate, you’ll have the 100 Hz waveform.

The max source rate is about 12K, so you’re approaching the limits of the speed.

Keeping with the idea of 100 point list sweep:
if trigger count is 100, then one cycle is sourced.
if more than 100, the list is recycled.
If trigger count is 0, then plays until you send abort command.

If you don’t already, download the Test Script Builder application for running TSP code with the instrument.
Then port it out to C# or Python, etc.

Test Script Builder
 
Posted Thu, 08 Feb 2024 13:14:41 GMT by Daniele, Fabrizio Reliability Technician
Hello Andrea,
many thanks for pointing me out in the right direction.

As an initial experiment I have modified below (see also file in attachment) the ARB Features for testing Ford EMC just to generate 2 simultaneous in phase 100 Hz sinewaves with 2V amplitude and 0V offset.
However, the SMU 2602 B outputs
  • a 100 Hz sinewave on chA with 2V Peak to Peak and 0V offset
  • a 100 Hz sinewave on chB with 10V Peak to Peak and offset 1V.
Could you please advise what I am doing wrong?

Thank you
Fabrizio


local _startV -- Used by script to track the starting voltage
local _srcRate = 8000 -- Source Update Rate used by the script Sets the source update rate (pts/sec) used by the script. 
                      --Do not set higher than 8,000 if your waveform will have polarity changes 0V crossings)
    
function SetupAWG(startV, rangeV, limitI, wfrmTbl, remoteSense, trigLineIn)
    -- Do some parameter checks
    --=========================
    if startV == nil then startV = 0 end
    if remoteSense ~= true then remoteSense = false end
    if type(trigLineIn) == "number" then
        trigLineIn = math.floor(trigLineIn)
        if trigLineIn < 0 or trigLineIn > 14 then
            return true, "Error: Selected trigger line is not valid.  trigLineIn must be a number between 0 and 14 or nil."
        end
    elseif trigLineIn ~= nil then
        return true,"Error: Invalid parameter trigLineIn.  trigLineIn must be a number between 0 and 14 or nil."
    end
    _startV = startV
    wfrmTbl = {0.078459,0.156434,0.233445,0.309017,0.382683,0.45399,0.522499,0.587785,0.649448,0.707107,0.760406,0.809017,0.85264,0.891007,0.92388,0.951057,0.97237,0.987688,0.996917,1,0.996917,0.987688,0.97237,0.951057,0.92388,0.891007,0.85264,0.809017,0.760406,0.707107,0.649448,0.587785,0.522499,0.45399,0.382683,0.309017,0.233445,0.156434,0.078459,0,-0.078459,-0.156434,-0.233445,-0.309017,-0.382683,-0.45399,-0.522499,-0.587785,-0.649448,-0.707107,-0.760406,-0.809017,-0.85264,-0.891007,-0.92388,-0.951057,-0.97237,-0.987688,-0.996917,-1,-0.996917,-0.987688,-0.97237,-0.951057,-0.92388,-0.891007,-0.85264,-0.809017,-0.760406,-0.707107,-0.649448,-0.587785,-0.522499,-0.45399,-0.382683,-0.309017,-0.233445,-0.156434,-0.078459,0}      
   
    
    
    -- Setup the SMU for arb waveform output
    --======================================
    reset()
    smua.reset()
    smub.reset()
    smua.source.func                    = smua.OUTPUT_DCVOLTS
    smub.source.func                    = smub.OUTPUT_DCVOLTS
    if remoteSense == true then
        smua.sense                        = smua.SENSE_REMOTE
        smub.sense                        = smub.SENSE_REMOTE
    else
        smua.sense                        = smua.SENSE_LOCAL
        smub.sense                        = smub.SENSE_LOCAL
    end
    smua.source.autorangev            = smua.AUTORANGE_OFF
    smua.source.autorangei            = smua.AUTORANGE_OFF
    smua.source.rangev                = rangeV
    smua.source.levelv                = startV
    smua.source.limiti                = limitI
    smua.source.delay                = 0
    smua.source.settling            = smua.SETTLE_FAST_POLARITY
   
    smub.source.autorangev            = smub.AUTORANGE_OFF
    smub.source.autorangei            = smub.AUTORANGE_OFF
    smub.source.rangev                = rangeV
    smub.source.levelv                = startV
    smub.source.limiti                = limitI
    smub.source.delay                = 0
    smub.source.settling            = smub.SETTLE_FAST_POLARITY

    -- Configure the Trigger Model
    --============================
    -- Timer 1 controls the time per point table phase A
    trigger.timer[1].delay            = 1 / _srcRate
    trigger.timer[1].count            = table.getn(wfrmTbl) > 1 and table.getn(wfrmTbl) - 1 or 1
    if trigLineIn == nil then
        -- Immediate
        trigger.timer[1].stimulus    = smua.trigger.ARMED_EVENT_ID
        trigger.timer[1].stimulus    = smub.trigger.ARMED_EVENT_ID
    elseif trigLineIn == 0 then
        -- Front panel TRIG button
        display.trigger.clear()
        trigger.timer[1].stimulus    = display.trigger.EVENT_ID
    else
        -- Digio Trigger
        digio.trigger[trigLineIn].clear()
        digio.trigger[trigLineIn].mode = digio.TRIG_EITHER
        trigger.timer[1].stimulus    = digio.trigger[trigLineIn].EVENT_ID
    end
    trigger.timer[1].passthrough    = true
    
   -- Timer 2 controls the time per point table phase B
    trigger.timer[2].delay            = 1 / _srcRate
    trigger.timer[2].count            = table.getn(wfrmTbl) > 1 and table.getn(wfrmTbl) - 1 or 1
    if trigLineIn == nil then
        -- Immediate
        trigger.timer[2].stimulus    = smua.trigger.ARMED_EVENT_ID
        trigger.timer[2].stimulus    = smub.trigger.ARMED_EVENT_ID
    elseif trigLineIn == 0 then
        -- Front panel TRIG button
        display.trigger.clear()
        trigger.timer[2].stimulus    = display.trigger.EVENT_ID
    else
        -- Digio Trigger
        digio.trigger[trigLineIn].clear()
        digio.trigger[trigLineIn].mode = digio.TRIG_EITHER
        trigger.timer[2].stimulus    = digio.trigger[trigLineIn].EVENT_ID
    end
    trigger.timer[2].passthrough    = true


    -- Configure SMU Trigger Model for arb waveform output
    smua.trigger.source.listv(wfrmTbl)
    smua.trigger.source.limiti        = limitI
    smua.trigger.measure.action        = smua.DISABLE
    smua.trigger.endpulse.action    = smua.SOURCE_HOLD
    smua.trigger.endsweep.action    = smua.SOURCE_HOLD
    smua.trigger.count                = table.getn(wfrmTbl)
    smua.trigger.arm.count            = 1
    smua.trigger.arm.stimulus        = 0
    smua.trigger.source.stimulus    = trigger.timer[1].EVENT_ID
    smua.trigger.measure.stimulus    = 0
    smua.trigger.endpulse.stimulus    = 0
    smua.trigger.source.action        = smua.ENABLE
    
    smub.trigger.source.listv(wfrmTb1)
    smub.trigger.source.limiti        = limitI
    smub.trigger.measure.action        = smub.DISABLE
    smub.trigger.endpulse.action    = smub.SOURCE_HOLD
    smub.trigger.endsweep.action    = smub.SOURCE_HOLD
    smub.trigger.count                = table.getn(wfrmTbl)
    smub.trigger.arm.count            = 1
    smub.trigger.arm.stimulus        = 0
    smub.trigger.source.stimulus    = trigger.timer[2].EVENT_ID
    smub.trigger.measure.stimulus    = 0
    smub.trigger.endpulse.stimulus    = 0
    smub.trigger.source.action        = smub.ENABLE
    
    --==============================
    -- End Trigger Model Configuration
    
    if errorqueue.count > 0 then
        return true,"Error occured during setup.  Please check that your parameters are valid."
    else
        return false,"No error."
    end
end

function RunAWG(numCycles)
    if numCycles == nil or numCycles < 0 then
        numCycles = 1
    end
    
    -- Set the number of cycles to output
    smua.trigger.arm.count = numCycles
    smub.trigger.arm.count = numCycles
    -- Turn output on
    smua.source.output = smua.OUTPUT_ON
    smub.source.output = smub.OUTPUT_ON
    -- Start the trigger model execution
    smua.trigger.initiate()
    smub.trigger.initiate()
    
    if errorqueue.count > 0 then
        return true,"Error occurred.  See error queue for details."
    else
        return false,"No error."
    end
end
--[[ Name: StopAWG()

    Usage: err,msg = StopAWG()

    Description:
        This function stops the waveform output and turns the SMU
        output off.
--]]
function StopAWG()
    smua.abort()
    smua.source.output = 0
    smua.source.levelv = _startV
    
    smub.abort()
    smub.source.output = 0
    smub.source.levelv = _startV
    
    if errorqueue.count > 0 then
        return true,"Error occured.  See error queue for details."
    else
        return false,"No error."
    end
end

 
Posted Mon, 26 Feb 2024 21:40:03 GMT by C, Andrea
Hello,

You are almost there.

To accomplish the phase shift, were you thinking to use a different timer for each SMU?
Instead, I would use a single timer to provide the smuX.trigger.source.stimulus to each SMU channel.

Rather than providing a list of source levels, I recommend computing them. in the TSP or Lua code.
You can account for the phase shift in the computed source levels.
   
   -- compute the sine wave
    pts_per_cycle = 72
    wfrmTbl = {}
    for i=1, pts_per_cycle do
        wfrmTbl[i] = 1 * math.sin(i * 2 * math.pi/pts_per_cycle)
    end
    
    -- use some phase shift for smub sine wave
    wfrmTbl_smub = {}
    for i=1, pts_per_cycle do
        wfrmTbl_smub[i] = 1 * math.sin(i * 2 * math.pi/pts_per_cycle + math.rad(90))
    end
Posted Mon, 26 Feb 2024 21:45:33 GMT by C, Andrea
Here is a lightly edited version of your code:
local _startV -- Used by script to track the starting voltage
local _srcRate = 4000 -- Source Update Rate used by the script Sets the source update rate (pts/sec) used by the script. 
                      --Do not set higher than 8,000 if your waveform will have polarity changes 0V crossings)
    
function SetupAWG(startV, rangeV, limitI, wfrmTbl, remoteSense, trigLineIn)
    -- Do some parameter checks
    --=========================
    if startV == nil then startV = 0 end
    if remoteSense ~= true then remoteSense = false end
    if type(trigLineIn) == "number" then
        trigLineIn = math.floor(trigLineIn)
        if trigLineIn < 0 or trigLineIn > 14 then
            return true, "Error: Selected trigger line is not valid.  trigLineIn must be a number between 0 and 14 or nil."
        end
    elseif trigLineIn ~= nil then
        return true,"Error: Invalid parameter trigLineIn.  trigLineIn must be a number between 0 and 14 or nil."
    end
    _startV = startV
    
    --wfrmTbl = {0.078459,0.156434,0.233445,0.309017,0.382683,0.45399,0.522499,0.587785,0.649448,0.707107,0.760406,0.809017,0.85264,0.891007,0.92388,0.951057,0.97237,0.987688,0.996917,1,0.996917,0.987688,0.97237,0.951057,0.92388,0.891007,0.85264,0.809017,0.760406,0.707107,0.649448,0.587785,0.522499,0.45399,0.382683,0.309017,0.233445,0.156434,0.078459,0,-0.078459,-0.156434,-0.233445,-0.309017,-0.382683,-0.45399,-0.522499,-0.587785,-0.649448,-0.707107,-0.760406,-0.809017,-0.85264,-0.891007,-0.92388,-0.951057,-0.97237,-0.987688,-0.996917,-1,-0.996917,-0.987688,-0.97237,-0.951057,-0.92388,-0.891007,-0.85264,-0.809017,-0.760406,-0.707107,-0.649448,-0.587785,-0.522499,-0.45399,-0.382683,-0.309017,-0.233445,-0.156434,-0.078459,0}      
   
   -- compute the sine wave
    pts_per_cycle = 72
    wfrmTbl = {}
    for i=1, pts_per_cycle do
        wfrmTbl[i] = 1 * math.sin(i * 2 * math.pi/pts_per_cycle)
    end
    
    -- use some phase shift for smub sine wave
    wfrmTbl_smub = {}
    for i=1, pts_per_cycle do
        wfrmTbl_smub[i] = 1 * math.sin(i * 2 * math.pi/pts_per_cycle + math.rad(90))
    end
    
    
    
        
    -- Setup the SMU for arb waveform output
    --======================================
    reset()
    smua.reset()
    smub.reset()
    
    -- 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.trigger[1].pulsewidth = 10e-6
    digio.trigger[1].stimulus = trigger.timer[1].EVENT_ID
    
    smua.source.func                    = smua.OUTPUT_DCVOLTS
    smub.source.func                    = smub.OUTPUT_DCVOLTS
    if remoteSense == true then
        smua.sense                        = smua.SENSE_REMOTE
        smub.sense                        = smub.SENSE_REMOTE
    else
        smua.sense                        = smua.SENSE_LOCAL
        smub.sense                        = smub.SENSE_LOCAL
    end
    smua.source.autorangev            = smua.AUTORANGE_OFF
    smua.source.autorangei            = smua.AUTORANGE_OFF
    smua.source.rangev                = rangeV
    smua.source.levelv                = startV
    smua.source.limiti                = limitI
    smua.source.delay                = 0
    smua.source.settling            = smua.SETTLE_FAST_POLARITY
    
       
    smub.source.autorangev            = smub.AUTORANGE_OFF
    smub.source.autorangei            = smub.AUTORANGE_OFF
    smub.source.rangev                = rangeV
    smub.source.levelv                = startV
    smub.source.limiti                = limitI
    smub.source.delay                = 0
    smub.source.settling            = smub.SETTLE_FAST_POLARITY
    
    
    -- Configure the Trigger Model
    --============================
    -- Timer 1 controls the time per point table phase A
    trigger.timer[1].delay            = 1 / _srcRate
    trigger.timer[1].count            = table.getn(wfrmTbl) > 1 and table.getn(wfrmTbl) - 1 or 1
    if trigLineIn == nil then
        -- Immediate
        trigger.timer[1].stimulus    = smua.trigger.ARMED_EVENT_ID
        
    elseif trigLineIn == 0 then
        -- Front panel TRIG button
        display.trigger.clear()
        trigger.timer[1].stimulus    = display.trigger.EVENT_ID
    else
        -- Digio Trigger
        digio.trigger[trigLineIn].clear()
        digio.trigger[trigLineIn].mode = digio.TRIG_EITHER
        trigger.timer[1].stimulus    = digio.trigger[trigLineIn].EVENT_ID
    end
    trigger.timer[1].passthrough    = true
    
    
    

    -- Configure SMU Trigger Model for arb waveform output
    smua.trigger.source.listv(wfrmTbl)
    smua.trigger.source.limiti        = limitI
    smua.trigger.measure.action        = smua.DISABLE
    smua.trigger.endpulse.action    = smua.SOURCE_HOLD
    smua.trigger.endsweep.action    = smua.SOURCE_HOLD  
    smua.trigger.count                = table.getn(wfrmTbl)
    smua.trigger.arm.count            = 1
    smua.trigger.arm.stimulus        = 0
    smua.trigger.source.stimulus    = trigger.timer[1].EVENT_ID
    smua.trigger.measure.stimulus    = 0
    smua.trigger.endpulse.stimulus    = 0
    smua.trigger.source.action        = smua.ENABLE
    
        
    smub.trigger.source.listv(wfrmTbl_smub)
    smub.trigger.source.limiti        = limitI
    smub.trigger.measure.action        = smub.DISABLE
    smub.trigger.endpulse.action    = smub.SOURCE_HOLD
    smub.trigger.endsweep.action    = smub.SOURCE_HOLD
    smub.trigger.count                = table.getn(wfrmTbl)
    smub.trigger.arm.count            = 1
    smub.trigger.arm.stimulus        = 0
    smub.trigger.source.stimulus    = trigger.timer[1].EVENT_ID  -- ALC
    smub.trigger.measure.stimulus    = 0
    smub.trigger.endpulse.stimulus    = 0
    smub.trigger.source.action        = smub.ENABLE
    
    --==============================
    -- End Trigger Model Configuration
    
    if errorqueue.count > 0 then
        return true,"Error occured during setup.  Please check that your parameters are valid."
    else
        return false,"No error."
    end
end


function RunAWG(numCycles)
    if numCycles == nil or numCycles < 0 then
        numCycles = 1
    end
    
    -- Set the number of cycles to output
    smua.trigger.arm.count = numCycles
    smub.trigger.arm.count = numCycles
    -- Turn output on
    smua.source.output = smua.OUTPUT_ON
    smub.source.output = smub.OUTPUT_ON
    -- Start the trigger model execution
    smub.trigger.initiate()  -- start this first
    smua.trigger.initiate()
    
    if errorqueue.count > 0 then
        return true,"Error occurred.  See error queue for details."
    else
        return false,"No error."
    end
end


--[[ Name: StopAWG()

    Usage: err,msg = StopAWG()

    Description:
        This function stops the waveform output and turns the SMU
        output off.
--]]
function StopAWG()
    smua.abort()
    smua.source.output = 0
    smua.source.levelv = _startV
    
    smub.abort()
    smub.source.output = 0
    smub.source.levelv = _startV
    
    if errorqueue.count > 0 then
        return true,"Error occured.  See error queue for details."
    else
        return false,"No error."
    end
end

To run it:
--SetupAWG(startV, rangeV, limitI, wfrmTbl, remoteSense, trigLineIn)
SetupAWG(0, 20, 0.1, wfrmC, false, nil)

--RunAWG(numCycles)
RunAWG(8)

See scope shot attached.
Posted Tue, 05 Mar 2024 16:58:18 GMT by Daniele, Fabrizio Reliability Technician
Hi Andrea,
thanks for your help.

I have extended the approach you suggested to create 3 sinewaves at 120 degree using 2 SMUs. Please see also below script.

Below (in Italic) some answers/comments to your question and suggestions (in Bold):

To accomplish the phase shift, were you thinking to use a different timer for each SMU?
Yes, because I was also trying to adjust the delay that the script's calculations seem to introduce while generating the waveforms.
However, I was not able to do it using several timers as I did not find easy to add a delay for example in the first waveform so that the first and second waveforms remain at 120 degrees out of phase despite the delay that is introduced by the script.

This delay seems to increase as the script calculations become more complex and affects the phase shift.   
For example:
  • when using a list of source levels for each sine waveform, I had to adjust the sequence of source levels for each sine waveform to compensate for the delay,
  • when using the computed source levels I had to define the phase shift for the second sine waveform at -60 degrees and at 250 degrees for the third sine waveform to actually have the 3 sine waveforms with a phase shift of 120 degrees between each other.

However, since in both cases this is not very convenient if I need to change the sine waveform frequency often from 0 to 100 Hz, could you please advise if there is a way to make the timing for the waveform generation independent from the length and complexity of the script?


I have now moved to your approach using one timer for all 3 waveforms and the computed source levels for each sine waveform.


Instead, I would use a single timer to provide the smuX.trigger.source.stimulus to each SMU channel.
Yes, as mentioned above I am going to use this approach, thank you.

Rather than providing a list of source levels, I recommend computing them. in the TSP or Lua code.
You can account for the phase shift in the computed source levels.

I have used a list of source levels because I found it useful when simulating temporary instantaneous voltage failure in one of the 3 phases.
I have also noticed that when using the computed source levels each voltage level is hold a bit longer and this generates a sinewave in which steps are more prevalent than the ones seen when using a list of source levels.
Since I do like the approach of using the computed source levels, could you please advise on what could the reasons for the wider steps and if there is an easy fix?


Thank you



 reset()
   errorqueue.clear()
   
   -- Reset the TSP-Link if it is offline
    if tsplink.state == "offline" then
        local nodesFound = tsplink.reset()
        if nodesFound ~= 2 then
            print(string.format("Error: Found %d Nodes. Expecting 2.", nodesFound))
            exit()
        end
    end
  
            -- Configure the TSPlink Trigger Model
    --============================
function ConfigTSPLinkTriggers(nodenum)
    node[nodenum].tsplink.trigger[1].clear()
    node[nodenum].tsplink.trigger[1].mode        = tsplink.TRIG_FALLING
    node[nodenum].tsplink.trigger[2].clear()
    node[nodenum].tsplink.trigger[2].mode        = tsplink.TRIG_FALLING
    --node[nodenum].tsplink.trigger[3].clear()
    --node[nodenum].tsplink.trigger[3].mode        = tsplink.TRIG_FALLING
end    

local _startV -- Used by script to track the starting voltage
local _srcRate = 4000 -- Source Update Rate used by the script Sets the source update rate (pts/sec) used by the script. 
                      --Do not set higher than 8,000 if your waveform will have polarity changes 0V crossings)
    
function SetupAWG(startV, rangeV, limitI, wfrmTbl, remoteSense, trigLineIn)
    -- Do some parameter checks
    --=========================
    if startV == nil then startV = 0 end
    if remoteSense ~= true then remoteSense = false end
    if type(trigLineIn) == "number" then
        trigLineIn = math.floor(trigLineIn)
        if trigLineIn < 0 or trigLineIn > 14 then
            return true, "Error: Selected trigger line is not valid.  trigLineIn must be a number between 0 and 14 or nil."
        end
    elseif trigLineIn ~= nil then
        return true,"Error: Invalid parameter trigLineIn.  trigLineIn must be a number between 0 and 14 or nil."
    end
    _startV = startV
    
    --wfrmTbl = {0.078459,0.156434,0.233445,0.309017,0.382683,0.45399,0.522499,0.587785,0.649448,0.707107,0.760406,0.809017,0.85264,0.891007,0.92388,0.951057,0.97237,0.987688,0.996917,1,0.996917,0.987688,0.97237,0.951057,0.92388,0.891007,0.85264,0.809017,0.760406,0.707107,0.649448,0.587785,0.522499,0.45399,0.382683,0.309017,0.233445,0.156434,0.078459,0,-0.078459,-0.156434,-0.233445,-0.309017,-0.382683,-0.45399,-0.522499,-0.587785,-0.649448,-0.707107,-0.760406,-0.809017,-0.85264,-0.891007,-0.92388,-0.951057,-0.97237,-0.987688,-0.996917,-1,-0.996917,-0.987688,-0.97237,-0.951057,-0.92388,-0.891007,-0.85264,-0.809017,-0.760406,-0.707107,-0.649448,-0.587785,-0.522499,-0.45399,-0.382683,-0.309017,-0.233445,-0.156434,-0.078459,0}      
   
   -- compute the sine wave
    pts_per_cycle = 40
    wfrmTbl = {}
    for i=1, pts_per_cycle do
        wfrmTbl[i] = 27 * math.sin(i * 2 * math.pi/pts_per_cycle)
    end
    
    -- use some phase shift for smub sine wave
    wfrmTbl_smub = {}
    for i=1, pts_per_cycle do
        wfrmTbl_smub[i] = 27 * math.sin(i * 2 * math.pi/pts_per_cycle + math.rad(-60))
    end
    
    -- phase shift for node[2].smua sine wave
    wfrmTbl_node = {}
    for i=1, pts_per_cycle do
        wfrmTbl_node[i] = 27 * math.sin(i * 2 * math.pi/pts_per_cycle + math.rad(250))
    end
    
        
    -- Setup the SMU for arb waveform output
    --======================================
    --reset()
    --smua.reset()
    --smub.reset()
    -- Setup the SMU for arb waveform output
    --======================================
    reset()
    node[1].smua.reset()
    node[1].smub.reset()
    node[2].smua.reset()
    
    
    -- 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.trigger[1].pulsewidth = 10e-6
    digio.trigger[1].stimulus = trigger.timer[1].EVENT_ID
    
    node[1].smua.source.func                    = smua.OUTPUT_DCVOLTS
    node[1].smub.source.func                    = smub.OUTPUT_DCVOLTS
    node[2].smua.source.func                    = smua.OUTPUT_DCVOLTS
    if remoteSense == true then
        node[1].smua.sense                        = smua.SENSE_REMOTE
        node[1].smub.sense                        = smub.SENSE_REMOTE
        node[2].smua.sense                        = smua.SENSE_REMOTE
    else
        node[1].smua.sense                        = smua.SENSE_LOCAL
        node[1].smub.sense                        = smub.SENSE_LOCAL
        node[2].smua.sense                        = smua.SENSE_LOCAL
    end
    node[1].smua.source.autorangev            = smua.AUTORANGE_OFF
    node[1].smua.source.autorangei            = smua.AUTORANGE_OFF
    node[1].smua.source.rangev                = rangeV
    node[1].smua.source.levelv                = startV
    node[1].smua.source.limiti                = limitI
    node[1].smua.source.delay                = 0
    node[1].smua.source.settling            = smua.SETTLE_FAST_POLARITY
   
    node[1].smub.source.autorangev            = smub.AUTORANGE_OFF
    node[1].smub.source.autorangei            = smub.AUTORANGE_OFF
    node[1].smub.source.rangev                = rangeV
    node[1].smub.source.levelv                = startV
    node[1].smub.source.limiti                = limitI
    node[1].smub.source.delay                = 0
    node[1].smub.source.settling            = smub.SETTLE_FAST_POLARITY

    node[2].smua.source.autorangev            = smua.AUTORANGE_OFF
    node[2].smua.source.autorangei            = smua.AUTORANGE_OFF
    node[2].smua.source.rangev                = rangeV
    node[2].smua.source.levelv                = startV
    node[2].smua.source.limiti                = limitI
    node[2].smua.source.delay                = 0
    node[2].smua.source.settling            = smua.SETTLE_FAST_POLARITY
    

    
 -- for each tsplink node  -- The TSP-Link triggers are used to synchronize the two instruments  
    ConfigTSPLinkTriggers(1)
    ConfigTSPLinkTriggers(2)
    
    
    --smua.source.func                    = smua.OUTPUT_DCVOLTS
    --smub.source.func                    = smub.OUTPUT_DCVOLTS
    --if remoteSense == true then
        --smua.sense                        = smua.SENSE_REMOTE
        --smub.sense                        = smub.SENSE_REMOTE
    --else
        --smua.sense                        = smua.SENSE_LOCAL
        --smub.sense                        = smub.SENSE_LOCAL
    --end
    --smua.source.autorangev            = smua.AUTORANGE_OFF
    --smua.source.autorangei            = smua.AUTORANGE_OFF
    --smua.source.rangev                = rangeV
    --smua.source.levelv                = startV
    --smua.source.limiti                = limitI
    --smua.source.delay                = 0
    --smua.source.settling            = smua.SETTLE_FAST_POLARITY
    
       
    --smub.source.autorangev            = smub.AUTORANGE_OFF
    --smub.source.autorangei            = smub.AUTORANGE_OFF
    --smub.source.rangev                = rangeV
    --smub.source.levelv                = startV
    --smub.source.limiti                = limitI
    --smub.source.delay                = 0
    --smub.source.settling            = smub.SETTLE_FAST_POLARITY
    
    
    -- Configure the Trigger Model
    --============================
    -- Timer 1 controls the time per points of the table 
    trigger.timer[1].delay            = 1 / _srcRate
    trigger.timer[1].count            = table.getn(wfrmTbl) > 1 and table.getn(wfrmTbl) - 1 or 1
    if trigLineIn == nil then
        -- Immediate
        node[1].trigger.timer[1].stimulus    = node[1].smua.trigger.ARMED_EVENT_ID
        
    elseif trigLineIn == 0 then
        -- Front panel TRIG button
        display.trigger.clear()
        trigger.timer[1].stimulus    = display.trigger.EVENT_ID
    else
        -- Digio Trigger
        digio.trigger[trigLineIn].clear()
        digio.trigger[trigLineIn].mode = digio.TRIG_EITHER
        trigger.timer[1].stimulus    = digio.trigger[trigLineIn].EVENT_ID
    end
    trigger.timer[1].passthrough    = true
    
    -- Configure SMU Trigger Model for Phase A waveform output
    
    node[1].smua.trigger.source.listv(wfrmTbl)
    node[1].smua.trigger.source.limiti        = limitI
    node[1].smua.trigger.measure.action        = node[1].smua.DISABLE
    node[1].smua.trigger.endpulse.action    = node[1].smua.SOURCE_HOLD
    node[1].smua.trigger.endsweep.action    = node[1].smua.SOURCE_HOLD
    node[1].smua.trigger.count                = table.getn(wfrmTbl)
    node[1].smua.trigger.arm.count            = 1
    node[1].smua.trigger.arm.stimulus        = 0
    node[1].smua.trigger.source.stimulus    = trigger.timer[1].EVENT_ID
    --node[nodenum].trigger.timer[1].stimulus = node[nodenum].tsplink.trigger[1].EVENT_ID
    node[1].smua.trigger.measure.stimulus        = 0
    node[1].smua.trigger.endpulse.stimulus    = 0
    node[1].smua.trigger.source.action        = node[1].smua.ENABLE
    
    
    -- Configure SMU Trigger Model for Phase B waveform output
    node[1].smub.trigger.source.listv(wfrmTbl_smub)
    node[1].smub.trigger.source.limiti        = limitI
    node[1].smub.trigger.measure.action        = node[1].smub.DISABLE
    node[1].smub.trigger.endpulse.action    = node[1].smub.SOURCE_HOLD
    node[1].smub.trigger.endsweep.action    = node[1].smub.SOURCE_HOLD
    node[1].smub.trigger.count                = table.getn(wfrmTbl_smub)
    node[1].smub.trigger.arm.count            = 1
    node[1].smub.trigger.arm.stimulus        = 0
    node[1].smub.trigger.source.stimulus    = trigger.timer[1].EVENT_ID
    node[1].smub.trigger.measure.stimulus    = 0
    node[1].smub.trigger.endpulse.stimulus    = 0
    node[1].smub.trigger.source.action        = node[1].smub.ENABLE
    
    -- Configure SMU Trigger Model for Phase C waveform output
    node[1].tsplink.trigger[2].stimulus     = node[1].trigger.timer[1].EVENT_ID
    --node[2].tsplink.trigger[2].stimulus     = node[1].trigger.timer[1].EVENT_ID
    node[2].smua.trigger.source.listv(wfrmTbl_node)
    node[2].smua.trigger.source.limiti        = limitI
    node[2].smua.trigger.measure.action        = node[2].smua.DISABLE
    node[2].smua.trigger.endpulse.action    = node[2].smua.SOURCE_HOLD
    node[2].smua.trigger.endsweep.action    = node[2].smua.SOURCE_HOLD
    node[2].smua.trigger.count                = table.getn(wfrmTbl_node)
    node[2].smua.trigger.arm.count            = 1
    node[2].smua.trigger.arm.stimulus        = 0
    --node[2].smua.trigger.source.stimulus    = trigger.timer[3].EVENT_ID
    --node[2].smua.trigger.source.stimulus    = tsplink.trigger[2]
    --node[2].smua.trigger.source.stimulus    = node[1].trigger.timer[3].EVENT_ID
    node[2].smua.trigger.source.stimulus    = node[2].tsplink.trigger[2].EVENT_ID
    node[2].smua.trigger.measure.stimulus    = 0
    node[2].smua.trigger.endpulse.stimulus    = 0
    node[2].smua.trigger.source.action        = node[2].smua.ENABLE
    
 
    -- Configure SMU Trigger Model for arb waveform output
    --smua.trigger.source.listv(wfrmTbl)
    --smua.trigger.source.limiti        = limitI
    --smua.trigger.measure.action        = smua.DISABLE
    --smua.trigger.endpulse.action    = smua.SOURCE_HOLD
    --smua.trigger.endsweep.action    = smua.SOURCE_HOLD  
    --smua.trigger.count                = table.getn(wfrmTbl)
    --smua.trigger.arm.count            = 1
    --smua.trigger.arm.stimulus        = 0
    --smua.trigger.source.stimulus    = trigger.timer[1].EVENT_ID
    --smua.trigger.measure.stimulus    = 0
    --smua.trigger.endpulse.stimulus    = 0
    --smua.trigger.source.action        = smua.ENABLE
    
        
    --smub.trigger.source.listv(wfrmTbl_smub)
    --smub.trigger.source.limiti        = limitI
    --smub.trigger.measure.action        = smub.DISABLE
    --smub.trigger.endpulse.action    = smub.SOURCE_HOLD
    --smub.trigger.endsweep.action    = smub.SOURCE_HOLD
    --smub.trigger.count                = table.getn(wfrmTbl)
    --smub.trigger.arm.count            = 1
    --smub.trigger.arm.stimulus        = 0
    --smub.trigger.source.stimulus    = trigger.timer[1].EVENT_ID  -- ALC
    --smub.trigger.measure.stimulus    = 0
    --smub.trigger.endpulse.stimulus    = 0
    --smub.trigger.source.action        = smub.ENABLE
    
    --==============================
    -- End Trigger Model Configuration
    
    if errorqueue.count > 0 then
        return true,"Error occured during setup.  Please check that your parameters are valid."
    else
        return false,"No error."
    end
end
 
 
--function RunAWG(numCycles)
    --if numCycles == nil or numCycles < 0 then
        --numCycles = 1
    --end
    
    -- Set the number of cycles to output
    --smua.trigger.arm.count = numCycles
    --smub.trigger.arm.count = numCycles
    -- Turn output on
    --smua.source.output = smua.OUTPUT_ON
    --smub.source.output = smub.OUTPUT_ON
    -- Start the trigger model execution
    --smub.trigger.initiate()  -- start this first
    --smua.trigger.initiate()
    
    --if errorqueue.count > 0 then
        --return true,"Error occurred.  See error queue for details."
    --else
        --return false,"No error."
    --end
--end
 
 
--[[ Name: StopAWG()
 
    Usage: err,msg = StopAWG()
 
    Description:
        This function stops the waveform output and turns the SMU
        output off.
--]]
--function StopAWG()
    --smua.abort()
    --smua.source.output = 0
    --smua.source.levelv = _startV
    
    --smub.abort()
    --smub.source.output = 0
    --smub.source.levelv = _startV
    
    --if errorqueue.count > 0 then
        --return true,"Error occured.  See error queue for details."
    --else
        --return false,"No error."
    --end
--end

function RunAWG(numCycles)
    if numCycles == nil or numCycles < 0 then
        numCycles = 1
    end
    
    -- Set the number of cycles to output
    node[1].smua.trigger.arm.count = numCycles
    node[1].smub.trigger.arm.count = numCycles
    node[2].smua.trigger.arm.count = numCycles
    -- Turn output on
    node[1].smua.source.output = node[1].smua.OUTPUT_ON
    node[1].smub.source.output = node[1].smub.OUTPUT_ON
    node[2].smua.source.output = node[2].smua.OUTPUT_ON
    -- Start the trigger model execution
    node[1].smua.trigger.initiate()
    node[1].smub.trigger.initiate()
    node[2].smua.trigger.initiate()
    if errorqueue.count > 0 then
        return true,"Error occurred.  See error queue for details."
    else
        return false,"No error."
    end
end
--[[ Name: StopAWG()

    Usage: err,msg = StopAWG()

    Description:
        This function stops the waveform output and turns the SMU
        output off.
--]]
function StopAWG()
    node[1].smua.abort()
    node[1].smua.source.output = 0
    node[1].smua.source.levelv = _startV
    
    node[1].smub.abort()
    node[1].smub.source.output = 0
    node[1].smub.source.levelv = _startV
    
    node[2].smua.abort()
    node[2].smua.source.output = 0
    node[2].smua.source.levelv = _startV
    
    if errorqueue.count > 0 then
        return true,"Error occured.  See error queue for details."
    else
        return false,"No error."
    end
end
----------------------
 

You must be signed in to post in this forum.