diff --git a/TSP_Examples/2450/Leakage_Curr/.vscode/settings.json b/TSP_Examples/2450/Leakage_Curr/.vscode/settings.json new file mode 100644 index 0000000..3307ca8 --- /dev/null +++ b/TSP_Examples/2450/Leakage_Curr/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2450\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2450\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..11bd473 --- /dev/null +++ b/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2450" +} \ No newline at end of file diff --git a/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2450/Leakage_Curr/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2450/Leakage_Curr/2450_Lkg_Curr.tsp b/TSP_Examples/2450/Leakage_Curr/2450_Lkg_Curr.tsp new file mode 100644 index 0000000..a276432 --- /dev/null +++ b/TSP_Examples/2450/Leakage_Curr/2450_Lkg_Curr.tsp @@ -0,0 +1,61 @@ +--[[ + + Description: This Model 2450 example shows you how to measure the + leakage current of a device such as a capacitor. The Model 2450 + voltage source outputs 20V as the Model 2450 ammeter measures the + resulting leakage current as a function of time. This application + is set up to take current measurements at 200 ms intervals for 60 s. + Once the measurements are made, the capacitor is discharged to 0V and + the output is turned off. The current and time measurements are printed + to the Instrument Console. You can copy and paste these readings into a + spreadsheet for further analysis and graphing. The program is set up + to use the rear panel terminals so that low noise triax cables can + be used to connect to the device. + + If you are measuring small current values, the device should be + electrostatically shielded. If the capacitor is greater than 20nF, + the high capacitance mode may need to be enabled for best results. + For sourcing voltages greater than 37V, the interlock on the rear panel + of the Model 2450 must be enabled. + + Further information on making optimal capacitor leakage measurements + can be found in the Keithley Low Level Measurements Handbook. + + ]] + +--reset +reset() +defbuffer1.clear() + +--set up source function +smu.source.func = smu.FUNC_DC_VOLTAGE +smu.source.ilimit.level = 10e-3 +smu.source.level = 20 +smu.source.delay = 0.2 + +--set up measure function +smu.measure.func = smu.FUNC_DC_CURRENT +smu.measure.terminals = smu.TERMINALS_REAR +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 +smu.source.highc = smu.OFF + +--turn on output and initiate readings +smu.source.output = smu.ON +trigger.model.load("DurationLoop", 60) + +trigger.model.initiate() + +--wait for complete +waitcomplete() + +--parse index and data into three columns +print("Rdg #", "Time (s)", "Current (A)") +for i=1, defbuffer1.n do + print(i, defbuffer1.relativetimestamps[i], defbuffer1[i]) +end + +--Discharge the capacitor to 0V and turn off the output +smu.source.level = 0 +delay(2) +smu.source.output = smu.OFF \ No newline at end of file diff --git a/TSP_Examples/2450/Leakage_Curr/Lkg Curr View This First.pdf b/TSP_Examples/2450/Leakage_Curr/Lkg Curr View This First.pdf new file mode 100644 index 0000000..7250994 Binary files /dev/null and b/TSP_Examples/2450/Leakage_Curr/Lkg Curr View This First.pdf differ diff --git a/TSP_Examples/2450/SweepI_MeasV/.vscode/settings.json b/TSP_Examples/2450/SweepI_MeasV/.vscode/settings.json new file mode 100644 index 0000000..3307ca8 --- /dev/null +++ b/TSP_Examples/2450/SweepI_MeasV/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2450\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2450\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..11bd473 --- /dev/null +++ b/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2450" +} \ No newline at end of file diff --git a/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2450/SweepI_MeasV/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2450/SweepI_MeasV/2450_SweepI_MeasV.tsp b/TSP_Examples/2450/SweepI_MeasV/2450_SweepI_MeasV.tsp new file mode 100644 index 0000000..38e1b09 --- /dev/null +++ b/TSP_Examples/2450/SweepI_MeasV/2450_SweepI_MeasV.tsp @@ -0,0 +1,44 @@ +--[[ + + Description: This Model 2450 example shows you how to sweep the + test current and measure the resulting voltage drop on a low + resistance device. The Model 2450 current source outputs a sweep + from -100 mA to 100 mA in 101 steps as the Model 2450 voltmeter + measures the resulting voltage drop across the resistor. This + application is set up to take 101 readings with a 100 ms interval + time. Once the measurements are made, the output is turned off. + The current and voltage readings are printed to the Instrument + Console. You can copy and paste these readings into a spreadsheet + for further analysis and graphing. + + --]] + +--Reset the instrument +reset() +defbuffer1.clear() + +--Measure Settings +smu.measure.func = smu.FUNC_DC_VOLTAGE +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 +smu.measure.sense=smu.SENSE_4WIRE + +--Source Settings +smu.source.func = smu.FUNC_DC_CURRENT +smu.source.vlimit.level = 1 +smu.source.delay = 0.1 +smu.source.sweeplinear('LowR', -100e-3, 100e-3, 101) + +--Run trigger model and wait for it to complete +trigger.model.initiate() +waitcomplete() + +--Print Results +if defbuffer1.n == 0 then + print("Buffer is empty\n") +else + print("Current\tVoltage") + for i=1,defbuffer1.n do + print(string.format("%g\t%g", defbuffer1.sourcevalues[i], defbuffer1.readings[i])) + end +end diff --git a/TSP_Examples/2450/SweepI_MeasV/Sweep I Meas V View This First.pdf b/TSP_Examples/2450/SweepI_MeasV/Sweep I Meas V View This First.pdf new file mode 100644 index 0000000..7e273f7 Binary files /dev/null and b/TSP_Examples/2450/SweepI_MeasV/Sweep I Meas V View This First.pdf differ diff --git a/TSP_Examples/2460/PulseItrain/.vscode/settings.json b/TSP_Examples/2460/PulseItrain/.vscode/settings.json new file mode 100644 index 0000000..62733c3 --- /dev/null +++ b/TSP_Examples/2460/PulseItrain/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2460\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2460\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..3db91f8 --- /dev/null +++ b/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2460" +} \ No newline at end of file diff --git a/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2460/PulseItrain/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2460/PulseItrain/PulseITrain.tsp b/TSP_Examples/2460/PulseItrain/PulseITrain.tsp new file mode 100644 index 0000000..5ff2939 --- /dev/null +++ b/TSP_Examples/2460/PulseItrain/PulseITrain.tsp @@ -0,0 +1,89 @@ +--[[This particular example shows how to generate a current pulse train. +In particular, this code generates 10 pulses with a magnitude of 6 A and a pulse width +of 1 ms. The pulse period is 4 ms and the load that is used is 1 ohm. More information +about this tsp code can be found in the View This First document. +]] + +reset() + +--[[Set Up Pulse parameters + *biaslevel: the offset current for the pulse train + *pulselevel: the amplitude current of each pulse (from zero, not bias level) + *biaswidth: the time at the bias level + *pulsewidth: the time at amplitude level for each pulse + *points: total number of pulses + *limit: the source limit level +]] + +--User specified test parameters: +local biaslevel = 0 +local pulselevel = 6 +local biaswidth = 3e-3 +local pulsewidth = 1e-3 +local period = pulsewidth + biaswidth +local points = 10 +local limit = 7 + +--Set to current source and set up source config list +smu.source.configlist.create("OutputList") +smu.source.func = smu.FUNC_DC_CURRENT +smu.source.readback = smu.OFF + +--Set up measure commands +smu.measure.func = smu.FUNC_DC_VOLTAGE +smu.measure.nplc = 0.01 +smu.measure.autozero.once() + +smu.measure.terminals = smu.TERMINALS_FRONT +smu.measure.range = limit +smu.measure.sense = smu.SENSE_4WIRE + +local measuredelay = pulsewidth -((1/localnode.linefreq)*smu.measure.nplc + 450e-6) +if measuredelay < 50e-6 then measuredelay = 50e-6 end + +-- Set the source range large enough to fit both the bias and level. +smu.source.range = math.max(math.abs(biaslevel), math.abs(pulselevel)) +smu.source.delay = 0 +smu.source.vlimit.level = limit + +--Set to pulselevel (amplitude) and save to list +smu.source.level = pulselevel +smu.source.configlist.store("OutputList") + +--Set to biaslevel and save to list +smu.source.level = biaslevel +smu.source.configlist.store("OutputList") + +--Setup Timers +-- Use timer[1] to control the Period of the pulse train +trigger.timer[1].reset() +trigger.timer[1].start.generate = trigger.ON +trigger.timer[1].delay = period +trigger.timer[1].count = points - 1 -- Effective count will be points because trigger.timer[1].start.generate = trigger.ON + +-- Use timer[2] to control the Pulse Width of the pulses +trigger.timer[2].reset() +trigger.timer[2].start.stimulus = trigger.EVENT_TIMER1 +trigger.timer[2].start.generate = trigger.OFF +trigger.timer[2].delay = pulsewidth +trigger.timer[2].count = 1 +trigger.timer[2].enable = trigger.ON + +--Trigger model setup +trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR) +trigger.model.setblock(2, trigger.BLOCK_SOURCE_OUTPUT, smu.ON) +trigger.model.setblock(3, trigger.BLOCK_WAIT, trigger.EVENT_TIMER1) +trigger.model.setblock(4, trigger.BLOCK_CONFIG_RECALL, "OutputList") +trigger.model.setblock(5, trigger.BLOCK_DELAY_CONSTANT, measuredelay) +trigger.model.setblock(6, trigger.BLOCK_MEASURE_DIGITIZE) +trigger.model.setblock(7, trigger.BLOCK_WAIT, trigger.EVENT_TIMER2) +trigger.model.setblock(8, trigger.BLOCK_CONFIG_NEXT, "OutputList") +trigger.model.setblock(9, trigger.BLOCK_BRANCH_COUNTER, points, 3) +trigger.model.setblock(10, trigger.BLOCK_SOURCE_OUTPUT, smu.OFF) + +--Start the trigger model +defbuffer1.clear() +trigger.model.initiate() +delay(0.001) +trigger.timer[1].enable = trigger.ON +waitcomplete() diff --git a/TSP_Examples/2460/PulseItrain/PulseTrain_View_This_First.pdf b/TSP_Examples/2460/PulseItrain/PulseTrain_View_This_First.pdf new file mode 100644 index 0000000..9622170 Binary files /dev/null and b/TSP_Examples/2460/PulseItrain/PulseTrain_View_This_First.pdf differ diff --git a/TSP_Examples/2460/SolarPanel/.vscode/settings.json b/TSP_Examples/2460/SolarPanel/.vscode/settings.json new file mode 100644 index 0000000..62733c3 --- /dev/null +++ b/TSP_Examples/2460/SolarPanel/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2460\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2460\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..3db91f8 --- /dev/null +++ b/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2460" +} \ No newline at end of file diff --git a/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2460/SolarPanel/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2460/SolarPanel/SolarPanel_Sweep.tsp b/TSP_Examples/2460/SolarPanel/SolarPanel_Sweep.tsp new file mode 100644 index 0000000..a1601ce --- /dev/null +++ b/TSP_Examples/2460/SolarPanel/SolarPanel_Sweep.tsp @@ -0,0 +1,67 @@ +--[[ +This example demonstrates how to generate an I-V sweep on a solar panel. +In this particular example the voltage is swept from 0V to 20V and the resulting current +is measured. The maximum power, maximum current, maximum voltage, short circuit current, +and open circuit voltage are calculated and displayed in the Instrument Console along with +all the I-V sweep data. More information about this tsp code can be found in the +View This First document. +--]] + +--Define the number of points in the sweep. +num = 115 + +--Reset the Model 2460 and clear the buffer. +reset() + +--Set the source and measure functions. +smu.measure.func = smu.FUNC_DC_CURRENT +smu.source.func = smu.FUNC_DC_VOLTAGE + +--Configure the measurement settings. +smu.measure.terminals = smu.TERMINALS_FRONT +smu.measure.sense = smu.SENSE_4WIRE +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 + +--Configure the source settings. +smu.source.highc = smu.OFF +smu.source.range = 20 +smu.source.readback = smu.ON +smu.source.highc = smu.OFF +smu.source.ilimit.level = 4 +smu.source.sweeplinear("SolarCell", 0, 20, num, 0.05) + +--Start the trigger model and wait for it to complete. +trigger.model.initiate() +waitcomplete() + +--Define initial values. +local voltage = defbuffer1.sourcevalues +local current = defbuffer1 +local isc = current[1] +local mincurr = current[1] +local imax = current[1] +local voc = voltage[1] +local vmax = voltage[1] +local pmax = voltage[1]*current[1] + +--Calculate values. +for i = 1, num do +print(voltage[i],current[i],voltage[i]*current[i]) + if (voltage[i]*current[i] < pmax) then +pmax = voltage[i]*current[i] +imax = current[i] +vmax = voltage[i] + end + if math.abs(current[i]) < math.abs(mincurr) then +voc = voltage[i] + end +end +pmax = math.abs(pmax) +imax = math.abs(imax) +print("Pmax = ", pmax, ", Imax = ", imax, ", Vmax = ", vmax, ", Isc = ", isc, ",Voc = ", voc) + +--Display values on the Model 2460 front panel. +display.changescreen(display.SCREEN_USER_SWIPE) +display.settext(display.TEXT1, string.format("Pmax = %.4fW", pmax)) +display.settext(display.TEXT2, string.format("Isc = %.4fA, Voc = %.2fV", isc, voc)) \ No newline at end of file diff --git a/TSP_Examples/2460/SolarPanel/SolarPanel_View_This_First.pdf b/TSP_Examples/2460/SolarPanel/SolarPanel_View_This_First.pdf new file mode 100644 index 0000000..8fbc965 Binary files /dev/null and b/TSP_Examples/2460/SolarPanel/SolarPanel_View_This_First.pdf differ diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/settings.json b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/settings.json new file mode 100644 index 0000000..37e432d --- /dev/null +++ b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2461\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2461\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffabc0d --- /dev/null +++ b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2461" +} \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2461/PulseSweepIDigitizeV/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/2461_PulseSweepI_DigitizeV.tsp b/TSP_Examples/2461/PulseSweepIDigitizeV/2461_PulseSweepI_DigitizeV.tsp new file mode 100644 index 0000000..6d81ada --- /dev/null +++ b/TSP_Examples/2461/PulseSweepIDigitizeV/2461_PulseSweepI_DigitizeV.tsp @@ -0,0 +1,58 @@ +--[[ + + Description: This Model 2461 example shows you how to set up + a pulsed current sweep that starts at -10mA and stop at 10mA + The Model 2461 current source creates 201 pulses and is constantly + taking digitizer readings at a rate of 500,000 samples per second. + The application is set up to make 500us pulses with 500us of off + time after each pulse. + + The Model 2461's pulse commands are used to generate the trigger model + necessary for pulsing. All of the source and measure settings are + configured before the pulse command (smu.source.pulsesweeplinear) + is sent to the instrument. The pulse command accepts a lot of arguments + so the the arguments are stored in variables to make them easier to + read. + +--]] + + +--Reset the instrument +reset() + +--Source settings +smu.source.func = smu.FUNC_DC_CURRENT +smu.source.range = 10e-3 +smu.source.readback = smu.ON + + +--Digitize settings +smu.digitize.func = smu.FUNC_DIGITIZE_VOLTAGE +smu.digitize.sense = smu.SENSE_4WIRE +smu.digitize.range = 20 +smu.digitize.samplerate = 500000 +defbuffer1.capacity = 1000000 + +--Pulse command parameters +local configListName = "myPulseSweep" +local bias_level = 0 -- Bias level between pulses +local start = -10e-3 -- Sweep start point +local stop = 10e-3 -- Sweep end point +local points = 201 -- 201 points in the sweep +local pulse_width = 500e-6 -- Pulse width +local MeasureEnable = smu.ON -- Enables digitized measurements +local bufferName = defbuffer1 -- Buffer to save results +local pulse_delay = 0 -- Delay before each pulse +local offTime = 500e-6 -- Off time after each pulse +local count = 1 -- Number of times to repeat the pulse sweep +local xBiasLimit = 2 -- Voltage limit between pulses +local xPulseLimit = 20 -- Voltage limit during pulses +local failAbort = smu.ON -- Abort pulse sweep if voltage limit is hit +local dual = smu.OFF -- Only sweep from -10ma to 10ma, but not back down again + +--Pulse command +smu.source.pulsesweeplinear(configListName, bias_level, start, stop, points, pulse_width, MeasureEnable, bufferName, pulse_delay, offTime, count, xBiasLimit, xPulseLimit, failAbort, dual) + +--Intiate trigger model to start pulse sweep +trigger.model.initiate() +waitcomplete() \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepIDigitizeV/Pulse Sweep I Digitize V View This First.pdf b/TSP_Examples/2461/PulseSweepIDigitizeV/Pulse Sweep I Digitize V View This First.pdf new file mode 100644 index 0000000..6c53a31 Binary files /dev/null and b/TSP_Examples/2461/PulseSweepIDigitizeV/Pulse Sweep I Digitize V View This First.pdf differ diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/settings.json b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/settings.json new file mode 100644 index 0000000..37e432d --- /dev/null +++ b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2461\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2461\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffabc0d --- /dev/null +++ b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2461" +} \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2461/PulseSweepTriggerOut/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/2461_PulseSweep_TriggerOut.tsp b/TSP_Examples/2461/PulseSweepTriggerOut/2461_PulseSweep_TriggerOut.tsp new file mode 100644 index 0000000..c1b9b80 --- /dev/null +++ b/TSP_Examples/2461/PulseSweepTriggerOut/2461_PulseSweep_TriggerOut.tsp @@ -0,0 +1,152 @@ +--[[ + + Description: This Model 2461 example shows you how to set up + a pulsed voltage sweep that produces a trigger on a digital I/O pin + when finished with the sweep. You can use this trigger to notify + other instruments that the 2461 completed its pulse sweep. + + The Model 2461 voltage source outputs a pulse sweep from 1V to 5V + in 101 steps as the Model 2461 ammeter measures the resulting current + through the DUT. The application is set up to make 10ms pulses with + 90ms of off time; 45ms before each pulse and 45ms after each pulse + Once the measurements are made, the output is turned off. + + The Model 2461's pulse commands are utilized to generate the config + lists used by the trigger model for pulsing, but the trigger model + is replaced with one that produces the output trigger. The function + pulse_delay_cal is used to compute the length of the constant delay + block used to set the width of each pulse in the sweep. The computation + is normally done by the instrument when the pulse commands build the + trigger model, but the script must do it because the strandard trigger + model is being erased and replaced for this example. The current + and voltage readings are printed to the Instrument Console. You can + copy and paste these readings into a spreadsheet for further analysis. + +--]] + + +--Function to calculate the pulse width delay block's time +local function pulse_delay_calc(pulseWidth) + + --Gather status information from the the SMU + local NPLC = smu.measure.nplc + local line_freq = localnode.linefreq + local sreadback = smu.source.readback + local autoZero = smu.measure.autozero.enable + local filter = smu.measure.filter.enable + local filterType = smu.measure.filter.type + local filterCount = smu.measure.filter.count + local reading_count = 1 + + if (filter == smu.ON and filterType == smu.FILTER_REPEAT_AVG) then + reading_count = reading_count + filterCount - 1 --Account for the number of repeat filter readings + else + filterCount = 1 + end + + if (autoZero == smu.ON and sreadback == smu.OFF) then + reading_count = reading_count*3 --The SMU takes 3 readings if autozero is on + elseif (autoZero == smu.ON and sreadback == smu.ON) then + reading_count = reading_count*4 --The SMU takes 4 readings if autozero and source readback are on + elseif (autoZero == smu.OFF and sreadback == smu.ON) then + reading_count = reading_count*2 --The SMU takes 2 readings if source readback is on + end + + + --The delays in the meas_time calculation come from: + --200us for reading post processing EVERY reading + --repeat average filtering shaves 50us off of this time for every set of readings + local meas_time = (1/line_freq)*NPLC*reading_count + 200e-6*reading_count - filterCount*50e-6 + + + --Calculate the(not quite finalized) final_delay by subtracting + --calculated measure time and 80us of pulse output block overhead + local final_delay = pulseWidth - meas_time - 80e-6 + + + if (sreadback == smu.ON) then + final_delay = final_delay - .41e-3*filterCount --Source readback takes an extra 410us for every set of readings + end + if (autoZero == smu.ON) then + final_delay = final_delay - 1.28e-3*filterCount --Autozero takes an extra 1.28ms for every set of readings + end + if(final_delay > 0) then + return final_delay --Pass the final delay as an output + else + print("Measure time too long!") -- The measure time exceeds the desired pulse width + return 0 + end +end + +--Reset the instrument +reset() +smu.source.func = smu.FUNC_DC_VOLTAGE +smu.source.range = 7 +smu.measure.func = smu.FUNC_DC_CURRENT +smu.measure.sense = smu.SENSE_2WIRE +smu.measure.autorange = smu.ON +-- The instrument will select a best fixed range to fit the pulses + +smu.source.readback = smu.ON +smu.measure.autozero.enable = smu.OFF +smu.measure.nplc = .01 +-- NPLC can be increased to improve measurement accuracy. +-- However, it has to remain small enough to fit the measurement +-- within the width of the settled part of the pulse. + +--Set up the pulse parameters +local configListName = "myPulseSweep" +local biasLevel = 0 -- Bias level between pulses +local start = 1 -- Sweep start point +local stop = 5 -- Sweep end point +local points = 101 -- 101 points in the sweep +local pulseWidth = 10e-3 -- Pulse width +local MeasureEnable = smu.ON -- Enables measurements on each pulse +local bufferName = defbuffer1 -- Buffer to save results +local pulse_delay = 45e-3 -- Delay before each pulse +local offTime = 45e-3 -- Off time after each pulse +local count = 1 -- Number of times to repeat the pulse sweep +local xBiasLimit = 1e-3 -- Current limit between pulses +local xPulseLimit = 100e-3 -- Current limit during pulses +local failAbort = smu.OFF -- Abort pulse sweep if current limit is hit +local dual = smu.OFF -- Only sweep from 1V to 5V, but not back down again + +--2461 Pulse Command +smu.source.pulsesweeplinear(configListName, biasLevel, start, stop, points, pulseWidth, MeasureEnable, bufferName, pulse_delay, offTime, count, xBiasLimit, xPulseLimit, failAbort, dual) + +--Configure tsplink triggering + +digio.line[1].mode = digio.MODE_TRIGGER_OUT +trigger.digout[1].logic = trigger.LOGIC_NEGATIVE +trigger.digout[1].stimulus = trigger.EVENT_NOTIFY1 + +--Configure the trigger model with TSP +trigger.model.load("Empty") +trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR, bufferName) +trigger.model.setblock(2, trigger.BLOCK_CONFIG_RECALL,"MeasmyPulseSweep", 1, "myPulseSweep", 1) +trigger.model.setblock(3, trigger.BLOCK_SOURCE_OUTPUT, smu.ON) +trigger.model.setblock(4, trigger.BLOCK_BRANCH_ALWAYS, 6) +trigger.model.setblock(5, trigger.BLOCK_CONFIG_NEXT, "myPulseSweep") +trigger.model.setblock(6, trigger.BLOCK_DELAY_CONSTANT, pulse_delay) +trigger.model.setblock(7, trigger.BLOCK_SOURCE_PULSE_OUTPUT, smu.ON) +trigger.model.setblock(8, trigger.BLOCK_DELAY_CONSTANT, pulse_delay_calc(pulseWidth)) +trigger.model.setblock(9, trigger.BLOCK_MEASURE_DIGITIZE, bufferName) +trigger.model.setblock(10, trigger.BLOCK_SOURCE_PULSE_OUTPUT, smu.OFF) +trigger.model.setblock(11, trigger.BLOCK_DELAY_CONSTANT, offTime) +trigger.model.setblock(12, trigger.BLOCK_BRANCH_COUNTER, points, 5) +trigger.model.setblock(13, trigger.BLOCK_SOURCE_OUTPUT, smu.OFF) +trigger.model.setblock(14, trigger.BLOCK_NOTIFY, trigger.EVENT_NOTIFY1) + +--Run trigger model and wait for it to complete +trigger.model.initiate() +waitcomplete() + +--Print Results +if defbuffer1.n == 0 then + print("Buffer is empty\n") +else + print("Current\tVoltage") + for i=1,defbuffer1.n do + print(string.format("%g\t%g", defbuffer1.sourcevalues[i], defbuffer1.readings[i])) + end +end \ No newline at end of file diff --git a/TSP_Examples/2461/PulseSweepTriggerOut/Pulse Sweep Trigger Out View This First.pdf b/TSP_Examples/2461/PulseSweepTriggerOut/Pulse Sweep Trigger Out View This First.pdf new file mode 100644 index 0000000..e0d2827 Binary files /dev/null and b/TSP_Examples/2461/PulseSweepTriggerOut/Pulse Sweep Trigger Out View This First.pdf differ diff --git a/TSP_Examples/2470/Drain_Family/.vscode/settings.json b/TSP_Examples/2470/Drain_Family/.vscode/settings.json new file mode 100644 index 0000000..33f27db --- /dev/null +++ b/TSP_Examples/2470/Drain_Family/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\tspLinkSupportedCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..db50cb3 --- /dev/null +++ b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2470" + }, + "node2":{ + "model": "2470" + } + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..4b93c7d --- /dev/null +++ b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/nodeTable.tsp @@ -0,0 +1,2 @@ +node[1] = model2470 +node[2] = model2470 diff --git a/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/Drain_Family/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/Drain_Family/drain-family.tsp b/TSP_Examples/2470/Drain_Family/drain-family.tsp new file mode 100644 index 0000000..e15ab85 --- /dev/null +++ b/TSP_Examples/2470/Drain_Family/drain-family.tsp @@ -0,0 +1,126 @@ +--[[ + +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP code uses the trigger model to generate a drain family of curves on a FET using + two 2470 SMU instruments communicating with each other via TSP-Link. The SMU at Node 1 is + connected to the gate and steps voltage from 2 to 5 volts in 4 steps. The SMU at Node 2 is connected + to the drain and sweeps voltage from 0 to 5 volts with 51 points at each step. + +After the code is executed, the measurement results are displayed in the Instrument Console of Test + Script Builder. From the Instrument Console, you can copy the data into a spreadsheet for graphing. + +]] + +--######################## Settings and TSP-Link setup ################ +local gateVstart = 2 +local gateVstop = 5 +local gateStepSize = 1 +local gateIlimit = 1e-3 + +local drainVstart = 0 +local drainVstop = 5 +local drainStepSize = 0.1 +local drainIlimit = 1e-3 + +-- Reset the instruments and the TSP-Link connection, and clear the buffers. +tsplink.initialize() +reset() +-- If the tsplink state is not online, print an error message and quit +state = tsplink.state +if state ~= "online" then + print("Error:\n-Check that all SMUs have a different node number") + print("-Check that all SMUs are connected correctly\n") + return +end +-- Set up the TSP-Link node shortcuts. +local gate = node[1] +local drain = node[2] + +--######################## Model 2470 #1 (gate) setup ################ +-- Set up the source function. +gate.smu.source.configlist.create("stepVals") +gate.smu.source.func = gate.smu.FUNC_DC_VOLTAGE +gate.smu.source.autorange = gate.smu.ON +gate.smu.source.ilimit.level = gateIlimit +-- Set up the measure function. +gate.smu.measure.func = gate.smu.FUNC_DC_CURRENT +gate.smu.measure.autorange = gate.smu.ON +gate.smu.measure.terminals = gate.smu.TERMINALS_REAR +-- Set up TSP-Link triggering. +tsplink.line[1].reset() +gate.tsplink.line[1].mode = gate.tsplink.MODE_SYNCHRONOUS_MASTER +gate.trigger.tsplinkout[1].stimulus = gate.trigger.EVENT_NOTIFY1 +-- Populate the stepVals source config list, with source levels 2 V to 5 V +for i = gateVstart, gateVstop, gateStepSize do + gate.smu.source.level = i + gate.smu.source.configlist.store("stepVals") +end +local stepPoints = (gateVstop - gateVstart) * (1 / gateStepSize) + 1 +-- Set up the trigger model. +gate.trigger.model.setblock(1, trigger.BLOCK_CONFIG_RECALL, "stepVals") +gate.trigger.model.setblock(2, trigger.BLOCK_SOURCE_OUTPUT, gate.smu.ON) +gate.trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE) +gate.trigger.model.setblock(4, trigger.BLOCK_NOTIFY, gate.trigger.EVENT_NOTIFY1) +gate.trigger.model.setblock(5, trigger.BLOCK_WAIT, gate.trigger.EVENT_TSPLINK1) +gate.trigger.model.setblock(6, trigger.BLOCK_CONFIG_NEXT, "stepVals") +gate.trigger.model.setblock(7, trigger.BLOCK_BRANCH_COUNTER, stepPoints, 3) +gate.trigger.model.setblock(8, trigger.BLOCK_SOURCE_OUTPUT, gate.smu.OFF) + +--########################## Model 2470 #2 (drain) setup ################ +-- Set up the source function. +drain.smu.source.configlist.create("sweepVals") +drain.smu.source.func = drain.smu.FUNC_DC_VOLTAGE +drain.smu.source.autorange = drain.smu.ON +drain.smu.source.ilimit.level = drainIlimit +-- Set up the measure function. +drain.smu.measure.func = drain.smu.FUNC_DC_CURRENT +drain.smu.measure.autorange = drain.smu.OFF +drain.smu.measure.terminals = drain.smu.TERMINALS_REAR +drain.smu.measure.range = drainIlimit +-- Set up TSP-Link triggering. +drain.tsplink.line[1].mode = drain.tsplink.MODE_SYNCHRONOUS_ACCEPTOR +drain.trigger.tsplinkout[1].stimulus = drain.trigger.EVENT_NOTIFY1 +-- Populate the sweepVals source config list, with source levels +-- 0 V to 5 V in 100 mV steps +for i = drainVstart, drainVstop, drainStepSize do + drain.smu.source.level = i + drain.smu.source.configlist.store("sweepVals") +end +local sweepPoints = (drainVstop - drainVstart) * (1 / drainStepSize) + 1 +-- Set up the trigger model. +drain.trigger.model.setblock(1, drain.trigger.BLOCK_CONFIG_RECALL, "sweepVals") +drain.trigger.model.setblock(2, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.ON) +drain.trigger.model.setblock(3, drain.trigger.BLOCK_WAIT, drain.trigger.EVENT_TSPLINK1) +drain.trigger.model.setblock(4, drain.trigger.BLOCK_DELAY_CONSTANT, 0.01) +drain.trigger.model.setblock(5, drain.trigger.BLOCK_MEASURE_DIGITIZE) +drain.trigger.model.setblock(6, drain.trigger.BLOCK_CONFIG_NEXT, "sweepVals") +drain.trigger.model.setblock(7, drain.trigger.BLOCK_BRANCH_COUNTER, sweepPoints, 4) +drain.trigger.model.setblock(8, drain.trigger.BLOCK_NOTIFY, drain.trigger.EVENT_NOTIFY1) +drain.trigger.model.setblock(9, drain.trigger.BLOCK_BRANCH_COUNTER, stepPoints,3) +drain.trigger.model.setblock(10, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.OFF) + +-- Start the trigger model for both SMUs and wait until it is complete +drain.trigger.model.initiate() +gate.trigger.model.initiate() +print("Test Running...") +waitcomplete() +-- Print the formatted readings. +if defbuffer1.n == 0 then + print("\nNo readings in buffer\n") +else + print(string.format("drainV,\tdrainI(1),\t\tdrainV,\tdrainI(2),\t\tdrainV,\tdrainI(3),\t\tdrainV,\tdrainI(4)")) + for k = 1, sweepPoints do + print( + string.format("%f,\t%f,\t\t%f,\t%f,\t\t%f,\t%f,\t\t%f,\t%f", + drain.defbuffer1.sourcevalues[k], drain.defbuffer1[k], + drain.defbuffer1.sourcevalues[k+sweepPoints], drain.defbuffer1[k+sweepPoints], + drain.defbuffer1.sourcevalues[k+sweepPoints*2], drain.defbuffer1[k+sweepPoints*2], + drain.defbuffer1.sourcevalues[k+sweepPoints*3], drain.defbuffer1[k+sweepPoints*3] + ) + ) + end +end \ No newline at end of file diff --git a/TSP_Examples/2470/Insulation_Resistance/.vscode/settings.json b/TSP_Examples/2470/Insulation_Resistance/.vscode/settings.json new file mode 100644 index 0000000..93c1a10 --- /dev/null +++ b/TSP_Examples/2470/Insulation_Resistance/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ac9e1f4 --- /dev/null +++ b/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/Insulation_Resistance/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/Insulation_Resistance/insulation-resistance.tsp b/TSP_Examples/2470/Insulation_Resistance/insulation-resistance.tsp new file mode 100644 index 0000000..6eb5e38 --- /dev/null +++ b/TSP_Examples/2470/Insulation_Resistance/insulation-resistance.tsp @@ -0,0 +1,38 @@ +--[[ +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP commands make insulation resistance measurements by sourcing 300 V and + measuring the resistance. The Simple Loop trigger model template is used to make + 10 measurements at 100 ms intervals. After the code is executed, the measurement results are + displayed in the Instrument Console of Test Script Builder. + +]] + +-- Reset the instrument +reset() +-- Set up the source function. +smu.source.func = smu.FUNC_DC_VOLTAGE +smu.source.ilimit.level = 1e-3 +smu.source.level = 300 +-- Set up the measure function +smu.measure.func = smu.FUNC_DC_CURRENT +smu.measure.unit = smu.UNIT_OHM +smu.measure.terminals = smu.TERMINALS_REAR +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 +-- Turn on the source output and take readings. +trigger.model.load("SimpleLoop", 10, 0.1) +smu.source.output = smu.ON +trigger.model.initiate() +-- Wait for the measurements to complete. +waitcomplete() +-- Parse index and the data into three columns. +print("Rdg #", "Time (s)", "Resistance (Ohm)") +for i = 1, defbuffer1.n do + print(i, defbuffer1.relativetimestamps[i], defbuffer1[i]) +end +-- Turn off the output. +smu.source.output = smu.OFF \ No newline at end of file diff --git a/TSP_Examples/2470/Leakage/.vscode/settings.json b/TSP_Examples/2470/Leakage/.vscode/settings.json new file mode 100644 index 0000000..93c1a10 --- /dev/null +++ b/TSP_Examples/2470/Leakage/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/Leakage/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/Leakage/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ac9e1f4 --- /dev/null +++ b/TSP_Examples/2470/Leakage/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/Leakage/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/Leakage/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2470/Leakage/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/Leakage/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/Leakage/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/Leakage/leakage.tsp b/TSP_Examples/2470/Leakage/leakage.tsp new file mode 100644 index 0000000..ad2ad1e --- /dev/null +++ b/TSP_Examples/2470/Leakage/leakage.tsp @@ -0,0 +1,44 @@ +--[[ ` + +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP code performs a capacitor leakage measurement by sourcing 300 V and measuring + the resulting leakage current. The Duration Loop trigger model template applies the voltage for 60 + seconds and makes measurements at 200 ms intervals. After the duration time, the capacitor is + discharged at 0 V and the output is turned off. + +After the code is executed, the measurement results are displayed in the Instrument Console of Test + Script Builder. From the Instrument Console, you can copy the data into a spreadsheet for graphing. + +]] + +-- Reset the instrument, which also clears the buffer. +reset() +--smu. here +-- Set up the source function. +smu.source.func = smu.FUNC_DC_VOLTAGE +smu.source.ilimit.level = 10e-3 +smu.source.level = 300 +--smu. here +-- Set up measure function. +smu.measure.func = smu.FUNC_DC_CURRENT +smu.measure.terminals = smu.TERMINALS_REAR +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 +-- Turn on the output and initiate readings. +trigger.model.load("DurationLoop", 60, 0.2) +trigger.model.initiate() +-- Wait for the trigger model to complete. +waitcomplete() +-- Parse index and data into three columns. +print("Rdg #", "Time (s)", "Current (A)") +for i = 1, defbuffer1.n do + print(i, defbuffer1.relativetimestamps[i], defbuffer1[i]) +end +-- Discharge the device to 0 V and turn off the output. +smu.source.level = 0 +delay(2) +smu.source.output = smu.OFF \ No newline at end of file diff --git a/TSP_Examples/2470/MOSFET_Leakage/.vscode/settings.json b/TSP_Examples/2470/MOSFET_Leakage/.vscode/settings.json new file mode 100644 index 0000000..93c1a10 --- /dev/null +++ b/TSP_Examples/2470/MOSFET_Leakage/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ac9e1f4 --- /dev/null +++ b/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/MOSFET_Leakage/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/MOSFET_Leakage/MOSFET-leakage.tsp b/TSP_Examples/2470/MOSFET_Leakage/MOSFET-leakage.tsp new file mode 100644 index 0000000..8eb9ea2 --- /dev/null +++ b/TSP_Examples/2470/MOSFET_Leakage/MOSFET-leakage.tsp @@ -0,0 +1,38 @@ +--[[ ` + +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP code performs a MOSFET leakage measurement by sourcing 600 V and measuring + the resulting leakage current. The Duration Loop trigger model template applies the voltage for 60 + seconds and makes measurements at 200 ms intervals. + +After the code is executed, the measurement results are displayed in the Instrument Console of Test + Script Builder. From the Instrument Console, you can copy the data into a spreadsheet for graphing. + +]] + +-- Reset the instrument, which also clears the buffer. +reset() +-- Set up the source function. +smu.source.func = smu.FUNC_DC_VOLTAGE +smu.source.ilimit.level = 10e-3 +smu.source.level = 600 +-- Set up measure function. +smu.measure.func = smu.FUNC_DC_CURRENT +smu.measure.terminals = smu.TERMINALS_REAR +smu.measure.autorange = smu.ON +smu.measure.nplc = 1 +-- Turn on the output and initiate readings. +trigger.model.load("DurationLoop", 60, 0.2) +trigger.model.initiate() +-- Wait for the trigger model to complete. +waitcomplete() +smu.source.output = smu.OFF +-- Parse index and data into three columns. +print("Rdg #,", "Time (s),", "Current (A),") +for i = 1, defbuffer1.n do + print(string.format("%i, %.5f, %.6e", i, defbuffer1.relativetimestamps[i], defbuffer1[i])) +end \ No newline at end of file diff --git a/TSP_Examples/2470/Source_Drain_Resistance/.vscode/settings.json b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/settings.json new file mode 100644 index 0000000..33f27db --- /dev/null +++ b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\tspLinkSupportedCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..5448d81 --- /dev/null +++ b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1": { + "model": "2470" + }, + "node2": { + "model": "2470" + } + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..4b93c7d --- /dev/null +++ b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/nodeTable.tsp @@ -0,0 +1,2 @@ +node[1] = model2470 +node[2] = model2470 diff --git a/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/Source_Drain_Resistance/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/Source_Drain_Resistance/source-drain-resistance.tsp b/TSP_Examples/2470/Source_Drain_Resistance/source-drain-resistance.tsp new file mode 100644 index 0000000..70add62 --- /dev/null +++ b/TSP_Examples/2470/Source_Drain_Resistance/source-drain-resistance.tsp @@ -0,0 +1,111 @@ +--[[ + +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP commands make source-drain resistance measurements, R_DS(On), using two 2470 SMU + instruments communicating with each other via TSP-Link. The SMU at Node 1 is connected to + the gate to sweep voltage. The SMU at Node 2 is connected to the drain and applies + a bias voltage while measuring current to obtain the source-drain resistance as a function + of applied gate voltage. + +After the code is executed, the measurement results are displayed in the Instrument Console of Test + Script Builder. From the Instrument Console, you can copy the data into a spreadsheet for graphing. + +]] + +--######################## Settings and TSP-Link setup ################ +local gateVstart = 2 +local gateVstop = 5 +local gateStepSize = 0.1 + +local drainV = 10 +local drainIlimit = 0.1 + +-- Reset the instruments and the TSP-Link connection, and clear the buffers. +tsplink.initialize() +reset() +-- If the tsplink state is not online, print an error message and quit +local state = tsplink.state +if state ~= "online" then + print("Error:\n-Check that all SMUs have a different node number") + print("-Check that all SMUs are connected correctly\n") + return +end +-- Set up TSP-Link node shortcuts. +local gate = node[1] +local drain = node[2] + +--######################## 2470 SMU #1 (gate) setup ################ +-- Set up the source function. +gate.smu.source.configlist.create("stepVals") +gate.smu.source.func = gate.smu.FUNC_DC_VOLTAGE +gate.smu.source.autorange = gate.smu.ON +-- Set up the measure function. +gate.smu.measure.func = gate.smu.FUNC_DC_CURRENT +gate.smu.measure.autorange = gate.smu.ON +gate.smu.measure.terminals = gate.smu.TERMINALS_REAR +-- Set up TSP-Link triggering. +gate.tsplink.line[1].reset() +gate.tsplink.line[1].mode = gate.tsplink.MODE_SYNCHRONOUS_MASTER +gate.trigger.tsplinkout[1].stimulus = gate.trigger.EVENT_NOTIFY1 +-- Populate the stepVals source config list, with source levels gateVstart volts to gateVstop volts +for i = gateVstart, gateVstop, gateStepSize do + gate.smu.source.level = i + gate.smu.source.configlist.store("stepVals") +end +local stepPoints = (gateVstop - gateVstart) * (1 / gateStepSize) + 1 +-- Set up the trigger model. +gate.trigger.model.setblock(1, gate.trigger.BLOCK_CONFIG_RECALL, "stepVals") +gate.trigger.model.setblock(2, gate.trigger.BLOCK_SOURCE_OUTPUT, gate.smu.ON) +gate.trigger.model.setblock(3, gate.trigger.BLOCK_MEASURE_DIGITIZE) +gate.trigger.model.setblock(4, gate.trigger.BLOCK_NOTIFY, gate.trigger.EVENT_NOTIFY1) +gate.trigger.model.setblock(5, gate.trigger.BLOCK_WAIT, gate.trigger.EVENT_TSPLINK1) +gate.trigger.model.setblock(6, gate.trigger.BLOCK_CONFIG_NEXT, "stepVals") +gate.trigger.model.setblock(7, gate.trigger.BLOCK_BRANCH_COUNTER, stepPoints, 3) +gate.trigger.model.setblock(8, gate.trigger.BLOCK_SOURCE_OUTPUT, gate.smu.OFF) + +--######################## 2470 SMU #2 (drain) setup ################ +-- Set up the source function. +drain.smu.source.func = drain.smu.FUNC_DC_VOLTAGE +drain.smu.source.ilimit.level = drainIlimit +drain.smu.source.level = drainV +-- Set up measure function. +drain.smu.measure.func = drain.smu.FUNC_DC_CURRENT +drain.smu.measure.terminals = drain.smu.TERMINALS_REAR +drain.smu.measure.autorange = drain.smu.ON +drain.smu.measure.nplc = 1 +drain.smu.measure.unit = drain.smu.UNIT_OHM +-- Set up TSP-Link triggering. +drain.tsplink.line[1].mode = drain.tsplink.MODE_SYNCHRONOUS_ACCEPTOR +drain.trigger.tsplinkout[1].stimulus = drain.trigger.EVENT_NOTIFY1 +-- Set up the trigger model. +drain.trigger.model.setblock(1, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.ON) +drain.trigger.model.setblock(2, drain.trigger.BLOCK_WAIT, drain.trigger.EVENT_TSPLINK1) +drain.trigger.model.setblock(3, drain.trigger.BLOCK_DELAY_CONSTANT, 0.01) +drain.trigger.model.setblock(4, drain.trigger.BLOCK_MEASURE_DIGITIZE) +drain.trigger.model.setblock(5, drain.trigger.BLOCK_NOTIFY, drain.trigger.EVENT_NOTIFY1) +drain.trigger.model.setblock(6, drain.trigger.BLOCK_BRANCH_COUNTER, stepPoints, 2) +drain.trigger.model.setblock(7, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.OFF) + +--######################## Start test ################ +-- Start the trigger model for both SMUs and wait until it is complete. +gate.trigger.model.initiate() +drain.trigger.model.initiate() +print("Test Running...") +waitcomplete() +-- Print the formatted readings. +if drain.defbuffer1.n == 0 then + print("\nNo readings in buffer\n") +else + print("Index,".."\t".."gateV,".."\t".."R_DS") + for k = 1, stepPoints do + print( + string.format("%d,\t%1.5f,\t%1.6E", + k, gate.defbuffer1.sourcevalues[k], drain.defbuffer1.readings[k] + ) + ) + end +end \ No newline at end of file diff --git a/TSP_Examples/2470/SubThreshold_Swing/.vscode/settings.json b/TSP_Examples/2470/SubThreshold_Swing/.vscode/settings.json new file mode 100644 index 0000000..33f27db --- /dev/null +++ b/TSP_Examples/2470/SubThreshold_Swing/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\AllTspCommands", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2470\\tspLinkSupportedCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..db50cb3 --- /dev/null +++ b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2470" + }, + "node2":{ + "model": "2470" + } + }, + "self": "2470" +} \ No newline at end of file diff --git a/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..4b93c7d --- /dev/null +++ b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/nodeTable.tsp @@ -0,0 +1,2 @@ +node[1] = model2470 +node[2] = model2470 diff --git a/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2470/SubThreshold_Swing/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2470/SubThreshold_Swing/subthreshold-swing.tsp b/TSP_Examples/2470/SubThreshold_Swing/subthreshold-swing.tsp new file mode 100644 index 0000000..72a8dae --- /dev/null +++ b/TSP_Examples/2470/SubThreshold_Swing/subthreshold-swing.tsp @@ -0,0 +1,149 @@ +--[[ + +*********************************************************** +*** Copyright Tektronix, Inc. *** +*** See www.tek.com/sample-license for licensing terms. *** +*********************************************************** + +The following TSP code uses the trigger model to find the subthreshold swing, S, of a FET using + two 2470 SMU instruments communicating with each other via TSP-Link. The SMU at Node 1 is + connected to the gate and steps voltage from 0 to 5 volts. The SMU at Node 2 is connected + to the drain and applies a bias voltage while measuring current. + +After the measurement is complete, a simple numerical exponential fit is found and the subthreshold + swing, S, is taken as the inverse of the exponential slope. Finally, the result and measurement + data is displayed in the Instrument Console of Test Script Builder. From the Instrument Console, + you can copy the data into a spreadsheet for graphing. + +]] + +--######################## Settings and TSP-Link setup ################ +local gateVstart = 0 +local gateVstop = 5 +local gateStepSize = 0.1 +local gateIlimit = 0.1 + +local drainV = 10 +local drainIlimit = 0.1 +-- Fit settings, the slope is calculated between these gateV points +-- fitHighV should be less than or equal to the threshold voltage +local fitLowV = 1 +local fitHighV = 2 + +-- Reset the instruments and the TSP-Link connection, and clear the buffers. +tsplink.initialize() +reset() +-- If the tsplink state is not online, print an error message and quit +local state = tsplink.state +if state ~= "online" then + print("Error:\n-Check that all SMUs have a different node number") + print("-Check that all SMUs are connected correctly\n") + return +end +-- Set up TSP-Link node shortcuts. +local gate = node[1] +local drain = node[2] + +--######################## 2470 SMU #1 (gate) setup ################ +-- Set up the source function. +gate.smu.source.configlist.create("stepVals") +gate.smu.source.func = gate.smu.FUNC_DC_VOLTAGE +gate.smu.source.autorange = gate.smu.ON +gate.smu.source.ilimit.level = gateIlimit +-- Set up the measure function. +gate.smu.measure.func = gate.smu.FUNC_DC_CURRENT +gate.smu.measure.autorange = gate.smu.ON +gate.smu.measure.terminals = gate.smu.TERMINALS_REAR +-- Set up TSP-Link triggering. +gate.tsplink.line[1].reset() +gate.tsplink.line[1].mode = gate.tsplink.MODE_SYNCHRONOUS_MASTER +gate.trigger.tsplinkout[1].stimulus = gate.trigger.EVENT_NOTIFY1 +-- Populate the stepVals source config list, with source levels gateVstart volts to gateVstop volts +for i = gateVstart, gateVstop, gateStepSize do + gate.smu.source.level = i + gate.smu.source.configlist.store("stepVals") +end +local stepPoints = (gateVstop - gateVstart) * (1 / gateStepSize) + 1 +-- Set up the trigger model. +gate.trigger.model.setblock(1, gate.trigger.BLOCK_CONFIG_RECALL, "stepVals") +gate.trigger.model.setblock(2, gate.trigger.BLOCK_SOURCE_OUTPUT, gate.smu.ON) +gate.trigger.model.setblock(3, gate.trigger.BLOCK_MEASURE_DIGITIZE) +gate.trigger.model.setblock(4, gate.trigger.BLOCK_NOTIFY, gate.trigger.EVENT_NOTIFY1) +gate.trigger.model.setblock(5, gate.trigger.BLOCK_WAIT, gate.trigger.EVENT_TSPLINK1) +gate.trigger.model.setblock(6, gate.trigger.BLOCK_CONFIG_NEXT, "stepVals") +gate.trigger.model.setblock(7, gate.trigger.BLOCK_BRANCH_COUNTER, stepPoints, 3) +gate.trigger.model.setblock(8, gate.trigger.BLOCK_SOURCE_OUTPUT, gate.smu.OFF) + +--######################## 2470 SMU #2 (drain) setup ################ +-- Set up the source function. +drain.smu.source.func = drain.smu.FUNC_DC_VOLTAGE +drain.smu.source.ilimit.level = drainIlimit +drain.smu.source.level = drainV +-- Set up measure function. +drain.smu.measure.func = drain.smu.FUNC_DC_CURRENT +drain.smu.measure.terminals = drain.smu.TERMINALS_REAR +drain.smu.measure.autorange = drain.smu.ON +-- Set up TSP-Link triggering. +drain.tsplink.line[1].mode = drain.tsplink.MODE_SYNCHRONOUS_ACCEPTOR +drain.trigger.tsplinkout[1].stimulus = drain.trigger.EVENT_NOTIFY1 +-- Set up the trigger model. +drain.trigger.model.setblock(1, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.ON) +drain.trigger.model.setblock(2, drain.trigger.BLOCK_WAIT, drain.trigger.EVENT_TSPLINK1) +drain.trigger.model.setblock(3, drain.trigger.BLOCK_DELAY_CONSTANT, 0.01) +drain.trigger.model.setblock(4, drain.trigger.BLOCK_MEASURE_DIGITIZE) +drain.trigger.model.setblock(5, drain.trigger.BLOCK_NOTIFY, drain.trigger.EVENT_NOTIFY1) +drain.trigger.model.setblock(6, drain.trigger.BLOCK_BRANCH_COUNTER, stepPoints, 2) +drain.trigger.model.setblock(7, drain.trigger.BLOCK_SOURCE_OUTPUT, drain.smu.OFF) + +--######################## Start test ################ +-- Start the trigger model for both SMUs and wait until it is complete. +gate.trigger.model.initiate() +drain.trigger.model.initiate() +print("Test Running...") +waitcomplete() +if drain.defbuffer1.n == 0 or gate.defbuffer1.n == 0 then + print("\nNo readings in buffer\n") + return +end +-- Perform basic exponential fit +local diffHighV, diffLowV = 9.9e37, 9.9e37 +local fitHighIndex = 0 +local fitLowIndex = 0 +local gateV = 0 +local gateHighV = 0 +local gateLowV = 0 +-- Find actual gate voltage (and indexes) closest to fitHighV and fitLowV +for i = 1, gate.defbuffer1.n do + gateV = gate.defbuffer1.sourcevalues[i] + if math.abs(gateV - fitHighV) < diffHighV then + diffHighV = math.abs(gateV - fitHighV) + gateHighV = gateV + fitHighIndex = i + end + if math.abs(gateV - fitLowV) < diffLowV then + diffLowV = math.abs(gateV - fitLowV) + gateLowV = gateV + fitLowIndex = i + end +end +-- Find drain current and natural log of current at the two fit voltages +local drainHighI = drain.defbuffer1.readings[fitHighIndex] +local drainLowI = drain.defbuffer1.readings[fitLowIndex] +local ln_drainHighI = math.log(drainHighI) +local ln_drainLowI = math.log(drainLowI) +-- Find subthreshold swing, S, inverse of subthreshold slope, multiply by 1000 for mV/dec +local diffgateV = gateHighV - gateLowV +local diff_ln_drainI = ln_drainHighI - ln_drainLowI +local S = (diffgateV / diff_ln_drainI) * 1000 + +-- Print the results +print(string.format("Subthreshold Swing = %.4f mV/decade", S)) +print(string.format("High current in fit = %.6E amps, low current in fit = %.6E amps", drainHighI, drainLowI)) +print("Index,".."\t".."gateV (V),".."\t".."drainI (A)") +for k = 1, stepPoints do + print( + string.format("%d,\t%.5f,\t%.6E", + k, gate.defbuffer1.sourcevalues[k], drain.defbuffer1.readings[k] + ) + ) +end diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/settings.json b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/settings.json new file mode 100644 index 0000000..2ba36c4 --- /dev/null +++ b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2601B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2601B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..0141f38 --- /dev/null +++ b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2601B" +} \ No newline at end of file diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2601B_PULSE/BasicDiodeTest/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/BasicDiodeTest.tsp b/TSP_Examples/2601B_PULSE/BasicDiodeTest/BasicDiodeTest.tsp new file mode 100644 index 0000000..ce39a14 --- /dev/null +++ b/TSP_Examples/2601B_PULSE/BasicDiodeTest/BasicDiodeTest.tsp @@ -0,0 +1,249 @@ +--[[ +################################################################################ + +Script File: BasicDiodeTest.tsp + + ************************************************************************ + *** Copyright Tektronix, Inc. *** + *** See www.tek.com/sample-license for licensing terms. *** + ************************************************************************ + +Description: + This script is example code, which creates (and subsequently calls) several + functions that can be used with the Model 2601B-PULSE to perform a basic + diode test. The purpose is show that you can use the current pulser and the + SMU within the same application. As written, the functions use the current + pulser to perform a 4-point forward bias IV sweep, and the SMU to perform a + reverse bias leakage current measurement. Upon completion of each test, the + data is printed to the Test Script Builder Instrument Console in a format + that is suitable for copying and pasting into Microsoft Excel for graphing + and analysis. + +Required Equipment: 1 Model 2601B-PULSE System SourceMeter instrument + +Note: The functions do not perform any error checking. It is the user's + responsibility to specify settings that are compatible with the + instrument model being used, and with its power envelope. + +Note: It is the user's responsibility to follow all safety guidelines given in + the instrument's Reference Manual. This is especially critical if + voltages in excess of 42VDC will be present in the test circuits. Such + voltage levels are hazardous. + +Functions created by this script: + * diode_iv(curr_level_list,pulse_period,pulse_width,meas_delay,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current) + * diode_ir(src_rangev,src_levelv,src_limiti,meas_rangei,nplc,apply_time ) + * test_diode() + +Example Usage: + * diode_iv({1,2,3},10e-3,20e-6,15e-6,5e-6,10,10,40,20,0) + * diode_ir(6,-5,1e-6,100e-9,1,20e-3) + * test_diode() + +See additional detailed information in the individual functions. + +################################################################################ +--]] + +function diode_iv(curr_level_list,pulse_period,pulse_width,meas_delay,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current ) +--[[ + This function configures and initiates a current pulse list sweep for the + 2601B-PULSE pulser. It is used to perform a forward bias IV sweep on a + diode. The pulse is generated using the instrument's Synchronous Trigger + Model. The Pulse Period is controlled using a standard Trigger Timer. The + Pulse Width and Measure Delay (settling time) are determined by new + pulser commands for the pulse width and measure delay, which provide more + precise timing than a Trigger Timer. Using the dual 1MS/s digitizers built + into the current pulser, the voltage and current are measured + simultaneously at the top of each pulse. Upon completion of the sweep, the + data is printed to the Test Script Builder Instrument Console in a format + that is suitable for copying and pasting into Microsoft Excel for graphing + and analysis. + + Prerequisites: None + + Pass Parameters: + * curr_level_list : Table of pulse levels to sweep thru; values in amps + * pulse_period : Time between start of consecutive pulses in seconds + * pulse_width : Width of current pulses in seconds + * meas_delay : Time from pulse start to measure start in seconds + * meas_aperture : Effective integration time in seconds + * rangev : Voltage measure range in volts + * rangei : Current source and measure range in amps + * source_protectv : Voltage protection level at source terminals + * sense_protectv : Voltage protection level at sense terminals + * bias_current : Idle current level in amps (base level for pulses) + + Returned values: None +--]] + + -- Reset the pulser and SMU to default conditions + smua.reset() + + -- Enable the fast current pulser + smua.pulser.enable = smua.ENABLE + + -- Configure the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer2.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.collecttimestamps = 1 + + -- Set ranges + smua.pulser.rangei = rangei + smua.pulser.rangev = rangev + + -- Set the idle current level + smua.source.leveli = bias_current + + -- Set voltage protection levels + smua.pulser.protect.sourcev = source_protectv + smua.pulser.protect.sensev = sense_protectv + + -- Determine the number of current levels in the list + local npulse = table.getn(curr_level_list) + + -- Use Trigger Timer 1 to control pulse period + trigger.timer[1].reset() + trigger.timer[1].count = npulse + trigger.timer[1].delay = pulse_period + trigger.timer[1].passthrough = false + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + + -- Set measure delay and aperture + smua.pulser.measure.delay = meas_delay + smua.pulser.measure.aperture = meas_aperture + + -- Configure Trigger Model to perform a current pulse list sweep + smua.trigger.count = npulse + smua.trigger.source.listi(curr_level_list) + smua.trigger.source.pulsewidth = pulse_width + smua.trigger.source.action = smua.ENABLE + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) -- I in nvbuffer1 + -- V in nvbuffer2 + + -- Turn on the output + smua.source.output = smua.OUTPUT_ON + + -- Initiate the Trigger Model and wait for the sweep to complete + smua.trigger.initiate() + waitcomplete() + + -- Turn off the output and disable the current pulser + smua.source.output = smua.OUTPUT_OFF + smua.pulser.enable = smua.DISABLE + + -- Output the data in tab-separated format + print("Time (s)\tCurrent (A)\tVoltage (V)") + for i = 1, smua.nvbuffer1.n do + print(smua.nvbuffer1.timestamps[i],smua.nvbuffer1[i],smua.nvbuffer2[i]) + end --for + +end --function diode_iv() + +function diode_ir(src_rangev,src_levelv,src_limiti,meas_rangei,nplc,apply_time ) +--[[ + This function uses the 2601B-PULSE SMU to force a DC voltage and measure + the resulting current. It is used to measure the reverse bias leakage + current (Ir) of a diode. Using the dual integrating analog-to-digital + converters built the SMU, the voltage and current are measured + simultaneously for the spot test. Upon completion of the sweep, the + data is printed to the Test Script Builder Instrument Console in a format + that is suitable for copying and pasting into Microsoft Excel for analysis. + + Prerequisites: None + + Pass Parameters: + * src_rangev : Voltage source range in volts + * src_levelv : Voltage source level in volts + * meas_rangei : Current measure range in amps + * nplc : Measure integration time; number of power line cycles + * apply_time : Time in seconds for which voltage is applied before + the current is measured + + Returned values: None +--]] + + -- Reset the pulser and SMU to default conditions + smua.reset() + + -- Disable the current pulser, which enables the SMU. This is the default + -- condition, but show explicitly for clarity + smua.pulser.enable = smua.DISABLE + + -- Use 4-wire voltage sensing + smua.sense = smua.SENSE_REMOTE + + -- Configure source settings + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.autorangei = smua.AUTORANGE_OFF + smua.source.autorangev = smua.AUTORANGE_OFF + smua.source.rangev = src_rangev + smua.source.limiti = src_limiti + smua.source.levelv = src_levelv + -- See 2600B Series Ref Manual for cautions about using following command + smua.source.settling = smua.SETTLE_FAST_RANGE + + -- Configure measure settings; perform autozero once after setting NPLC val + smua.measure.autorangei = smua.AUTORANGE_OFF + smua.measure.autorangev = smua.AUTORANGE_OFF + smua.measure.rangei = meas_rangei + smua.measure.nplc = nplc + smua.measure.autozero = smua.AUTOZERO_ONCE + display.smua.measure.func = display.MEASURE_DCAMPS + + -- Turn on the output + smua.source.output = smua.OUTPUT_ON + + -- Delay the specified apply_time and then measure V and I + delay(apply_time) + local ir, vbias = smua.measure.iv() + + -- Turn off the output + smua.source.output = smua.OUTPUT_OFF + + -- Output the data in tab-separated format + print("\nBias Voltage (V)\tIr (A)") + print(vbias, ir) + +end --function diode_ir() + +function test_diode() +--[[ + This function simply calls the diode_iv() and diode_ir functions after + assigning values to their pass parameters. + + Prerequisites: Functions diode_iv() and diode_ir() must exist before + calling this function. + + Pass Parameters: None + + Returned values: None +--]] + + local curr_level_list = {0.1,1,2,3} + local pulse_period = 10e-3 + local pulse_width = 20e-6 + local meas_delay = 15e-6 + local meas_aperture = 5e-6 + local rangev = 10 + local rangei = 10 + local source_protectv = 40 + local sense_protectv = 20 + local bias_current = 0.001 + diode_iv(curr_level_list,pulse_period,pulse_width,meas_delay,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current ) + + local src_rangev = 6 + local src_levelv = -5 --was 5 + local src_limiti = 1e-3 + local meas_rangei = 100e-9 + local nplc = 1 + local apply_time = 20e-3 + diode_ir(src_rangev,src_levelv, src_limiti,meas_rangei,nplc,apply_time ) + +end --function test_diode() + +-- Call the diode test function +test_diode() diff --git a/TSP_Examples/2601B_PULSE/BasicDiodeTest/ViewThisFirst.pdf b/TSP_Examples/2601B_PULSE/BasicDiodeTest/ViewThisFirst.pdf new file mode 100644 index 0000000..52fe048 Binary files /dev/null and b/TSP_Examples/2601B_PULSE/BasicDiodeTest/ViewThisFirst.pdf differ diff --git a/TSP_Examples/2601B_PULSE/CurrentPulseSweep/CurrentPulseSweep.tsp b/TSP_Examples/2601B_PULSE/CurrentPulseSweep/CurrentPulseSweep.tsp new file mode 100644 index 0000000..47ba270 --- /dev/null +++ b/TSP_Examples/2601B_PULSE/CurrentPulseSweep/CurrentPulseSweep.tsp @@ -0,0 +1,145 @@ +--[[ +################################################################################ + +Script File: CurrentPulseSweep.tsp + + ************************************************************************ + *** Copyright Tektronix, Inc. *** + *** See www.tek.com/sample-license for licensing terms. *** + ************************************************************************ + +Description: + This script is example code, which creates (and subsequently calls) a + single function that can be used with the Model 2601B-PULSE current pulser + to output a current pulse sweep. The sweep is generated using the + instrument's Synchronous Trigger Model. Using the dual 1MS/s digitizers + built into the current pulser, the voltage and current are measured + simultaneously at the top of each pulse. Upon completion of the sweep, the + data is printed to the Test Script Builder Instrument Console in a format + that is suitable for copying and pasting into Microsoft Excel for graphing + and analysis. + +Required Equipment: 1 Model 2601B-PULSE System SourceMeter instrument + +Note: The function does not perform any error checking. It is the user's + responsibility to specify settings that are compatible with the + instrument model being used, and with its power envelope. + +Note: It is the user's responsibility to follow all safety guidelines given in + the instrument's Reference Manual. This is especially critical if + voltages in excess of 42VDC will be present in the test circuits. Such + voltage levels are hazardous. + +Function created by this script: + * sweep_current_level(starti,stopi,npulse,pulse_period,pulse_width,meas_aperture,meas_delay,rangev,rangei,bias_current) + +Example Usage: + * sweep_current_level(1,10,10,10e-3,10e-6,1e-6,9e-6,10,10,0 ) + +See additional detailed information in the individual functions. + +################################################################################ +--]] + +function sweep_current_level(starti,stopi,npulse,pulse_period,pulse_width,meas_aperture,meas_delay,rangev,rangei,bias_current ) + +--[[ + This function configures and initiates a current pulse sweep for the + 2601B-PULSE pulser. The sweep is generated using the instrument's + Synchronous Trigger Model. The Pulse Period is controlled using a standard + Trigger Timer. The Pulse Width and Measure Delay (settling time) are + determined by new pulser commands for the pulse width and measure delay, + which provide more precise timing than a Trigger Timer. The voltage and + current are measured simultaneously at the top of each pulse. Upon + completion of the sweep, the data is printed to the Test Script Builder + Instrument Console in a format that is suitable for copying and pasting + into Microsoft Excel for graphing and analysis. + + Prerequisites: None + + Pass Parameters: + * starti : Current level of the first pulse in amps + * stopi : Current level of the last pulse in amps + * npulse : Number of pulses in the sweep + * pulse_period : Time between start of consecutive pulses in seconds + * pulse_width : Width of current pulses in seconds + * meas_aperture : Effective integration time in seconds + * meas_delay : Time from pulse start to measure start in seconds + * rangev : Voltage measure range in volts + * rangei : Current source and measure range in amps + * bias_current : Idle current level in amps (base level for pulses) + + Returned values: None +--]] + + -- Reset the pulser and SMU to default conditions + smua.reset() + + -- Enable the fast current pulser + smua.pulser.enable = smua.ENABLE + + -- Configure the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer2.clear() + smua.nvbuffer1.collecttimestamps= 1 + smua.nvbuffer2.collecttimestamps= 1 + + -- Set ranges + smua.pulser.rangei = rangei + smua.pulser.rangev = rangev + + -- Set the idle current level + smua.source.leveli = bias_current + + -- Use Trigger Timer 1 to control pulse period + trigger.timer[1].reset() + trigger.timer[1].delay = pulse_period + trigger.timer[1].count = npulse + trigger.timer[1].passthrough = false + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + + -- Set measure delay and aperture + smua.pulser.measure.delay = meas_delay + smua.pulser.measure.aperture = meas_aperture + + -- Configure Trigger Model to perform a linear staircase current pulse sweep + smua.trigger.count = npulse + smua.trigger.source.lineari(starti, stopi, npulse) + smua.trigger.source.action = smua.ENABLE + smua.trigger.source.pulsewidth = pulse_width + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) -- I in nvbuffer1 + -- V in nvbuffer2 + -- Turn on the output + smua.source.output = smua.OUTPUT_ON + + -- Initiate the Trigger Model and wait for the sweep to complete + smua.trigger.initiate() + waitcomplete() + + -- Turn off the output and disable the current pulser + smua.source.output = smua.OUTPUT_OFF + smua.pulser.enable = smua.DISABLE + + -- Output the data in tab-separated format + print("\nTime (s)\tCurrent (A)\tVoltage (V)") + for i = 1, smua.nvbuffer1.n do + print(smua.nvbuffer1.timestamps[i],smua.nvbuffer1[i],smua.nvbuffer2[i]) + end --for + +end --function sweep_current_level() + +-- Call the function. +local starti = 1 +local stopi = 10 +local npulse = 10 +local pulse_period = 10e-3 +local pulse_width = 10e-6 +local meas_aperture = 1e-6 +local meas_delay = 9e-6 +local rangev = 10 +local rangei = 10 +local bias_current = 0 + +sweep_current_level(starti,stopi,npulse,pulse_period,pulse_width,meas_aperture,meas_delay,rangev,rangei,bias_current) \ No newline at end of file diff --git a/TSP_Examples/2601B_PULSE/CurrentPulseSweep/ViewThisFirst.pdf b/TSP_Examples/2601B_PULSE/CurrentPulseSweep/ViewThisFirst.pdf new file mode 100644 index 0000000..c318ef4 Binary files /dev/null and b/TSP_Examples/2601B_PULSE/CurrentPulseSweep/ViewThisFirst.pdf differ diff --git a/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/DigitizeCompletePulse.tsp b/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/DigitizeCompletePulse.tsp new file mode 100644 index 0000000..4a9aef4 --- /dev/null +++ b/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/DigitizeCompletePulse.tsp @@ -0,0 +1,153 @@ +--[[ +################################################################################ + +Script File: DigitizeCompletePulse.tsp + + ************************************************************************ + *** Copyright Tektronix, Inc. *** + *** See www.tek.com/sample-license for licensing terms. *** + ************************************************************************ + +Description: + This script is example code, which creates (and subsequently calls) a + single function that can be used with the Model 2601B-PULSE current pulser + to output and digitize one current pulse. The pulse is generated using the + instrument's Asynchronous Trigger Model. Using the dual 1MS/s digitizers + built into the current pulser, the voltage and current are sampled + simultaneously across the entire pulse. Upon completion, the data is + printed to the Test Script Builder Instrument Console in a format that is + suitable for copying and pasting into Microsoft Excel for graphing and + analysis. + +Required Equipment: 1 Model 2601B-PULSE System SourceMeter instrument + +Note: The function does not perform any error checking. It is the user's + responsibility to specify settings that are compatible with the + instrument model being used, and with its power envelope. + +Note: It is the user's responsibility to follow all safety guidelines given in + the instrument's Reference Manual. This is especially critical if + voltages in excess of 42VDC will be present in the test circuits. Such + voltage levels are hazardous. + +Function created by this script: + * DigitizePulse(current_level,pulse_width,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current) + +Example Usage: digitize_pulse(10,50e-6,1e-6,10,10,40,20,0) + +See additional detailed information in the individual functions. + +################################################################################ +--]] + +function digitize_pulse(current_level,pulse_width,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current) + +--[[ + This function configures and initiates a single current pulse for the + 2601B-PULSE pulser. The pulse is generated using the instrument's + Asynchronous Trigger Model. The voltage and current are sampled + simultaneously across the entire pulse. The effective sample rate is + 1/meas_aperture. The sampling nominally starts 10us before the start of the + pulse and stops 10us after the end of the pulse. + + The pre-pulse acquisition interval is controlled using a standard Trigger + Timer. The total acquistion time is the product of the measure count and + the effective sample rate. The Pulse Width is controlled by the new pulser + command for the pulse width, which provides more precise timing than a + Trigger Timer. Upon completion, the data is printed to the Test Script + Builder Instrument Console in a format that is suitable for copying and + pasting into Microsoft Excel for graphing and analysis. + + Prerequisites: None + + Pass Parameters: + * current_level : Peak current level of pulse in amps + * pulse_width : Width of current pulses in seconds + * meas_aperture : Effective integration time in seconds + * rangev : Voltage measure range in volts + * rangei : Current source and measure range in amps + * source_protectv : Voltage protection level at source terminals + * sense_protectv : Voltage protection level at sense terminals + * bias_current : Idle current level in amps (base level for pulse) + + Returned values: None +--]] + + -- Reset the pulser and SMU to default conditions + smua.reset() + + -- Enable the fast current pulser + smua.pulser.enable = smua.ENABLE + + -- Configure the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer2.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.collecttimestamps = 1 + + -- Set ranges + smua.pulser.rangei = rangei + smua.pulser.rangev = rangev + + -- Set the idle current level + smua.source.leveli = bias_current + + -- Set voltage protection levels + smua.pulser.protect.sourcev = source_protectv + smua.pulser.protect.sensev = sense_protectv + + -- Config Trigger Timer 1 to delay pulse start 10us after measurements begin + trigger.timer[1].reset() + trigger.timer[1].count = 1 + trigger.timer[1].delay = 10e-6 + trigger.timer[1].passthrough = false + trigger.timer[1].stimulus = trigger.generator[1].EVENT_ID + + -- Configure source portion of Trigger Model to perform 1-point list sweep + smua.trigger.source.action = smua.ENABLE + smua.trigger.source.listi({current_level}) + smua.trigger.source.pulsewidth = pulse_width + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + + -- Configure measure portion of Trigger Model and related measure settings + smua.trigger.measure.action = smua.ASYNC + smua.trigger.measure.stimulus = trigger.generator[1].EVENT_ID + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) -- I in nvbuffer1 + -- V in nvbuffer2 + smua.measure.interval = 0 -- Digitize as fast as possible (1MS/s) + smua.pulser.measure.aperture = meas_aperture + smua.measure.count = math.ceil((pulse_width + 2*10e-6) / meas_aperture) + + -- Turn on the output + smua.source.output = smua.OUTPUT_ON + + -- Initiate Trigger Model and allow to reach Source Action Event Detector + smua.trigger.initiate() + delay(0.001) + + -- Start measurements and Trig Timer 1 and wait for Trig Model to complete + trigger.generator[1].assert() + waitcomplete() + + -- Turn off the output and disable the current pulser + smua.source.output = smua.OUTPUT_OFF + smua.pulser.enable = smua.DISABLE + + -- Output the data in tab-separated format + print("\nTime (s)\tCurrent (A)\tVoltage (V)") + for i = 1, smua.nvbuffer1.n do + print(smua.nvbuffer1.timestamps[i],smua.nvbuffer1[i],smua.nvbuffer2[i]) + end --for + +end --function digitize_pulse() + +local current_level = 10 +local pulse_width = 50e-6 +local meas_aperture = 1e-6 +local rangev = 10 +local rangei = 10 +local source_protectv = 40 +local sense_protectv = 20 +local bias_current = 0 + +digitize_pulse(current_level,pulse_width,meas_aperture,rangev,rangei,source_protectv,sense_protectv,bias_current) \ No newline at end of file diff --git a/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/ViewThisFirst.pdf b/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/ViewThisFirst.pdf new file mode 100644 index 0000000..cdce9fe Binary files /dev/null and b/TSP_Examples/2601B_PULSE/DigitizeCompletePulse/ViewThisFirst.pdf differ diff --git a/TSP_Examples/2602/ASimpleTest/.vscode/settings.json b/TSP_Examples/2602/ASimpleTest/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/ASimpleTest/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/ASimpleTest/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/ASimpleTest/main.tsp b/TSP_Examples/2602/ASimpleTest/main.tsp new file mode 100644 index 0000000..043703f --- /dev/null +++ b/TSP_Examples/2602/ASimpleTest/main.tsp @@ -0,0 +1,19 @@ +ON = 1 +OFF = 0 + +beeper.beep(1,500) +smub.reset() +smub.source.output = ON +--TODO turn autozero off later + +for i = 0, 1, 0.01 do + smub.source.levelv = i + local reading = smub.measure.i() + print( "Current reading = " .. reading) +end + +--if reading < 10 then print("pass")end +display.clear() +display.setcursor (1,1) +display.settext ("hello") +smub.source.output = OFF \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Fast/.vscode/settings.json b/TSP_Examples/2602/BJT_Fast/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/BJT_Fast/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/BJT_Fast/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Fast/BJTFast.tsp b/TSP_Examples/2602/BJT_Fast/BJTFast.tsp new file mode 100644 index 0000000..846e65d --- /dev/null +++ b/TSP_Examples/2602/BJT_Fast/BJTFast.tsp @@ -0,0 +1,373 @@ +--[[ +BJTFast(): + +This program performs a sequence of +standard transistor tests with values setup +for a 2N3904 part. + +This script creates the following functions that perform standard tests +for a Bipolar Junction Transistor: + +1) Setup +2) VCEO +3) VCEsat (Performs VCEsat and VBEsat tests simultaneously) +4) HFE/Beta Gain test + +Required equipment: + +(1) Keithley 2602 System Sourcemeter(c) +(1) Keithley 8101-04-TRX Test Fixture +(2) Keithley 2600-DEMO-TRX cables + +Rev1: JAC 4.7.2005 +Rev2: Add Print Data option + JAC 4.22.2005 +]] -- + +------------------ Keithley TSP Function ------------------ +function BJTFast(num, return_data) + local bin_fail_VCEO = 0 + local bin_fail_VCEsat = 0 + local bin_fail_VBEsat = 0 + local bin_fail_HFE = 0 + local bin_all_pass = 0 + + --clear the front panel display and prompt for input parameters if missing + display.clear() + + if num == nil then + num = display.prompt("0000", " Parts", "Enter number of parts to test", 50, 1, 9999) + end --end if + + + function setup() + --Sets up instrument + + Collector = smua + Base = smub + D = 0.0005 + + I = 1 + J = 1 + LabelCount = 4 + GoodParts = 0 + + NPLC2 = 0.05 + NPLC = 0.001 + + VCEO_data = {} + VCEsat_data = {} + VBEsat_data = {} + BETA1_data = {} + + Label = { "**VCEO**", "**VCEsat**", "**VBEsat**", "**BETA1**" } + + + AZERO = smua.AUTOZERO_OFF + --AZERO = smua.AUTOZERO_AUTO + + digio.writeport(0) -- Set All Digital I/O lines lo + display.clear() --Clear 2602 display + + Base.reset() --Reset base + Collector.reset() --Reset collector + + Base.source.func = Base.OUTPUT_DCVOLTS + Base.measure.autozero = Base.AUTOZERO_AUTO + Base.measure.nplc = NPLC + Base.measure.v() + Base.measure.i() + Base.measure.autozero = AZERO + Base.measure.autorangei = Base.AUTORANGE_OFF + Base.measure.autorangev = Base.AUTORANGE_OFF + Base.source.autorangei = Base.AUTORANGE_OFF + Base.source.autorangev = Base.AUTORANGE_OFF + + Base.source.rangei = 0.01 --smu current range + Base.source.levelv = 0 --smu source value + Base.source.output = Base.OUTPUT_ON + + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.measure.autozero = Collector.AUTOZERO_AUTO + Collector.measure.nplc = NPLC + Collector.measure.v() + Collector.measure.i() + Collector.measure.autozero = AZERO + Collector.measure.autorangei = Collector.AUTORANGE_OFF + Collector.measure.autorangev = Collector.AUTORANGE_OFF + Collector.source.autorangei = Collector.AUTORANGE_OFF + Collector.source.autorangev = Collector.AUTORANGE_OFF + + Collector.source.rangev = 40 --smu voltage range + Collector.source.levelv = 0 --smu source value + Collector.source.output = Collector.OUTPUT_ON + end + + function VCEO(i) + --Source current on collector, open base, and + --measure voltage on the collector/emitter + + local VCEOlimit = 40 + + Collector.measure.nplc = NPLC + Base.measure.nplc = NPLC + + Base.source.func = Base.OUTPUT_DCAMPS + Base.source.rangev = 40 + Base.source.limitv = 40 + Base.source.leveli = 0 --smua source value + Base.source.rangei = 100E-9 --smua current range + Base.measure.rangev = 40 + delay(D) --Delay + + Collector.source.func = Collector.OUTPUT_DCAMPS --SMU to source current + Collector.source.rangev = 40 + Collector.source.rangei = 0.01 + Collector.source.leveli = 0.01 --Set Source level + Collector.source.limitv = 40 + Collector.measure.rangev = 40 + delay(D) --Delay + + VCEO_data[i] = Collector.measure.v() --Measure V + + --End of SDM cycle + + if (VCEO_data[i] > 30) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 --Reinitialize Pass + Fail_VCEO = 1 + end --end if + + --Write Pass/Fail + WriteHandler(Pass) + --End of Decision Time + end --end function VCEO() + + function HFE1(i) + --Performs a binary search for the target Gain/Beta/HFE value. + + local k --binary search loop count variable + local VCESource = 1 --VCEsource value + local HIGHIb = 10e-7 --Start Ib high limit + local LOWIb = 1e-9 --Start Ib lo limit + local HFE1limit = 40 --HFE limit + local TARGETIc = 100e-6 --Target Ic for binary search + + Collector.measure.nplc = NPLC2 + Base.measure.nplc = NPLC2 + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.source.limiti = (5 * TARGETIc) + Collector.source.rangev = 6 + Collector.measure.rangei = 10e-3 + + Base.source.func = Base.OUTPUT_DCAMPS + Base.measure.rangei = 100e-6 + Base.source.limiti = HIGHIb + Base.source.rangev = 6 + Base.measure.rangev = 6 + Base.source.limitv = 6 + + --Start test + Collector.source.levelv = VCESource + Base.source.leveli = 0 + Collector.source.output = Collector.OUTPUT_ON --open relay (open base) + delay(0.001) --Delay + + --Search for the right base current + k = 0 + + repeat + k = k + 1 + Ib = ((HIGHIb - LOWIb) / 2) + LOWIb + Base.source.leveli = Ib + delay(0.001) + IcMeas = Collector.measure.i() + + if (TARGETIc < IcMeas) then + HIGHIb = Ib + else + LOWIb = Ib + end --end if + until ((math.abs(IcMeas - TARGETIc) < (0.05 * TARGETIc)) or (k > 10)) + + --iteration limit reached + if (k > 10) then + end --end if + + BETA1_data[i] = IcMeas / Ib + + if (BETA1_data[i] > HFE1limit) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_HFE = 1 + end --end if + + --Write Pass/Fail + WriteHandler(Pass) + end --end function HFE1() + + function VCEsat(i) + SourceCollector = 10E-3 + LimitVCEsat = 0.2 + + SourceBase = 1E-3 + LimitVBEsat = 1.1 + + Collector.measure.rangev = 1 + Collector.source.rangei = SourceCollector + Collector.source.leveli = SourceCollector + + Base.measure.rangev = 1 + Base.source.rangei = SourceBase + Base.source.leveli = SourceBase + delay(0.001) + VCEsat_data[i] = Collector.measure.v() + + VBEsat_data[i] = Base.measure.v() + + if (VCEsat_data[i] < LimitVCEsat) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_VCEsat = 1 + end --end if + + WriteHandler(Pass) + + if (VBEsat_data[i] < LimitVBEsat) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_VBEsat = 1 + end --end if + + --Write Pass/Fail + WriteHandler(Pass) + end --end function VCEsat() + + function WriteHandler(Pass) + if (Pass == 1) then + digio.writebit(2, 1) --Set bit 2 Hi, DUT pass + else + digio.writebit(8, 1) --Set bit 8 Hi, DUT Fail + end + + delay(D) + digio.writeport(0) --Reset Digital I/O + end --end function Writehandler() + + ----------***** Start Test *****---------- + + timer.reset() + setup() + SetupTime = timer.measure.t() + + timer.reset() + + display.settext("Test In Progress") + display.setcursor(2, 1) + display.settext("Testing " .. num .. " parts") + + for i = 1, num do + Fail_VCEO = 0 + Fail_VCEsat = 0 + Fail_VBEsat = 0 + Fail_HFE = 0 + + VCEO(i) + VCEsat(i) + HFE1(i) + + -- Bin + if Fail_VCEO == 1 then + bin_fail_VCEO = bin_fail_VCEO + 1 + PartStatus = " BAD" + elseif Fail_VCEsat == 1 then + bin_fail_VCEsat = bin_fail_VCEsat + 1 + PartStatus = " BAD" + elseif Fail_VBEsat == 1 then + bin_fail_VBEsat = bin_fail_VBEsat + 1 + PartStatus = " BAD" + elseif Fail_HFE == 1 then + bin_fail_HFE = bin_fail_VBEsat + 1 + PartStatus = " BAD" + else + bin_all_pass = bin_all_pass + 1 + PartStatus = " GOOD" + end --end if + end --end Main for loop + + TestTime = timer.measure.t() / num + + --Return instrument to idle state + Base.source.func = Base.OUTPUT_DCVOLTS + Base.source.levelv = 0 + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.source.levelv = 0 + + Base.measure.autozero = smua.AUTOZERO_AUTO + Base.measure.nplc = NPLC + Base.measure.v() + Base.measure.i() + + Collector.measure.autozero = smua.AUTOZERO_AUTO + Collector.measure.nplc = NPLC + Collector.measure.v() + Collector.measure.i() + + Collector.source.output = Collector.OUTPUT_OFF + Base.source.output = Base.OUTPUT_OFF + + -- Show Stats + Throughput = 1 / TestTime + Percent = GoodParts / (num * LabelCount) * 100 + + display.clear() + display.settext("Part Status:" .. PartStatus) + display.setcursor(2, 1) + display.settext("Bin Counts:" .. + bin_fail_VCEO .. " " .. bin_fail_VCEsat .. " " .. bin_fail_VBEsat .. " " .. bin_fail_HFE .. " " .. bin_all_pass) + delay(3) + + + display.clear() + Throughput = 1 / TestTime + display.settext("Parts per sec:" .. string.format("%d", Throughput)) + delay(3) + + display.screen = 2 + + + function Print_data() + for j = 1, LabelCount do + print(Label[j]) + + for i = 1, num do + if j == 1 then + print(VCEO_data[i]) + elseif j == 2 then + print(VCEsat_data[i]) + elseif j == 3 then + print(VBEsat_data[i]) + elseif j == 4 then + print(BETA1_data[i]) + end --end if + end --end for loop + print() + end --end for loop + end --end function Print_data1() + + if return_data == "yes" then + Print_data() + end --if + + --Print_data1() +end --end function BJTFast() + +BJTFast(nil, 'yes') +display.loadmenu.add("BJTTest_Fast", "BJTFast(nil,'no')") diff --git a/TSP_Examples/2602/BJT_Fast/View This First.pdf b/TSP_Examples/2602/BJT_Fast/View This First.pdf new file mode 100644 index 0000000..006d412 Binary files /dev/null and b/TSP_Examples/2602/BJT_Fast/View This First.pdf differ diff --git a/TSP_Examples/2602/BJT_Slow/.vscode/settings.json b/TSP_Examples/2602/BJT_Slow/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/BJT_Slow/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/BJT_Slow/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/BJT_Slow/BJTSlow.tsp b/TSP_Examples/2602/BJT_Slow/BJTSlow.tsp new file mode 100644 index 0000000..1890e7a --- /dev/null +++ b/TSP_Examples/2602/BJT_Slow/BJTSlow.tsp @@ -0,0 +1,414 @@ +--[[ +BJTSlow(): + +This program performs a sequence of +standard transistor tests with values setup +for a 2N3904 part. + +This script creates the following functions that perform standard tests +for a Bipolar Junction Transistor: + +1) Setup +2) VCEO +3) VCEsat (Performs VCEsat and VBEsat tests simultaneously) +4) HFE/Beta Gain test + + Required equipment: + +(1) Keithley 2602 System Sourcemeter(c) +(1) Keithley 8101-04-TRX Test Fixture +(2) Keithley 2600-DEMO-TRX cables + +Rev1: JAC 4.7.2005 +Rev2: Added Print Data Option + JAC 4.22.2005 +]] -- + +------------------ Keithley TSP Function ------------------ +function BJTSlow(num, return_data) + local bin_fail_VCEO = 0 + local bin_fail_VCEsat = 0 + local bin_fail_VBEsat = 0 + local bin_fail_HFE = 0 + local bin_all_pass = 0 + + --clear the front panel display and prompt for input parameters if missing + display.clear() + + if num == nil then + num = display.prompt("0000", " Parts", "Enter number of parts to test", 1, 1, 9999) + end --end if + + + for i = 1, num do + Fail_VCEO = 0 + Fail_VCEsat = 0 + Fail_VBEsat = 0 + Fail_HFE = 0 + + function setup() + --Sets up instrument + + Collector = smua --alias for smua + Base = smub --alias for smub + D = 0.0005 --delay + + J = 1 + LabelCount = 4 + + NPLC2 = 0.05 + NPLC = 0.001 + + VCEO_data = {} + VCEsat_data = {} + VBEsat_data = {} + BETA1_data = {} + + Label = { "**VCEO**", "**VCEsat**", "**VBEsat**", "**BETA1**" } + + + AZERO = smua.AUTOZERO_OFF + --AZERO = smua.AUTOZERO_AUTO + + digio.writeport(0) -- Set All Digital I/O lines lo + + display.clear() --Clear 2602 display + + Base.reset() --Reset base + Collector.reset() --Reset collector + + Base.source.func = Base.OUTPUT_DCVOLTS + Base.measure.autozero = Base.AUTOZERO_AUTO + Base.measure.nplc = NPLC + Base.measure.v() + Base.measure.i() + Base.measure.autozero = AZERO + + Base.measure.autorangei = Base.AUTORANGE_OFF + Base.measure.autorangev = Base.AUTORANGE_OFF + Base.source.autorangei = Base.AUTORANGE_OFF + Base.source.autorangev = Base.AUTORANGE_OFF + + Base.source.rangei = 0.01 --smu current range + Base.source.levelv = 0 --smu source value + Base.source.output = Base.OUTPUT_ON + + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.measure.autozero = Collector.AUTOZERO_AUTO + Collector.measure.nplc = NPLC + Collector.measure.v() + Collector.measure.i() + Collector.measure.autozero = AZERO + + Collector.measure.autorangei = Collector.AUTORANGE_OFF + Collector.measure.autorangev = Collector.AUTORANGE_OFF + Collector.source.autorangei = Collector.AUTORANGE_OFF + Collector.source.autorangev = Collector.AUTORANGE_OFF + + Collector.source.rangev = 40 --smu voltage range + Collector.source.levelv = 0 --smu source value + Collector.source.output = Collector.OUTPUT_ON + end --end function setup() + + function VCEO(index) + --Source current on collector, open base, and + --measure voltage on the collector/emitter + + local VCEOlimit = 40 + + display.clear() --Clear 2602 display + display.settext("VCEO") + delay(1) + + Collector.measure.nplc = NPLC + Base.measure.nplc = NPLC + + Base.source.func = Base.OUTPUT_DCAMPS + Base.source.rangev = 40 + Base.source.limitv = 40 + Base.source.leveli = 0 --smua source value + Base.source.rangei = 100E-9 --smua current range + Base.measure.rangev = 40 + delay(D) --Delay + + Collector.source.func = Collector.OUTPUT_DCAMPS --SMU to source current + Collector.source.rangev = 40 + Collector.source.rangei = 0.01 + Collector.source.leveli = 0.01 --Set Source level + Collector.source.limitv = 40 + Collector.measure.rangev = 40 + delay(D) --Delay + + VCEO_data[index] = Collector.measure.v() --Measure V + + local x = " = " .. tostring(VCEO_data[index]) .. "V" --write measurement to front panel + display.settext(x) + delay(1) + + if (VCEO_data[index] > 30) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 --Reinitialize Pass + Fail_VCEO = 1 --add one to fail bin + end --end of if/else + + WriteHandler(Pass) + + --End of Decision Time + end --end of function VCEO() + + function HFE1(index) + --Performs a binary search for the target Gain/Beta/HFE value. + + local k --binary search loop count variable + local VCESource = 1 --VCEsource value + local HIGHIb = 10e-7 --Start Ib high limit + local LOWIb = 1e-9 --Start Ib lo limit + local HFE1limit = 40 --HFE limit + local TARGETIc = 100e-6 --Target Ic for binary search + + Collector.measure.nplc = NPLC2 + Base.measure.nplc = NPLC2 + + display.clear() --Clear 2602 display + display.settext("hFE") + delay(1) + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.source.limiti = (5 * TARGETIc) + Collector.source.rangev = 6 + Collector.measure.rangei = 10e-3 + + Base.source.func = Base.OUTPUT_DCAMPS + Base.measure.rangei = 100e-6 + Base.source.limiti = HIGHIb + Base.source.rangev = 6 + Base.measure.rangev = 6 + Base.source.limitv = 6 + + --Start test + Collector.source.levelv = VCESource + Base.source.leveli = 0 + Collector.source.output = Collector.OUTPUT_ON --open relay (open base) + delay(0.001) --Delay + + --Search for the right base current + k = 0 + + repeat + k = k + 1 + Ib = ((HIGHIb - LOWIb) / 2) + LOWIb + Base.source.leveli = Ib + delay(0.001) + IcMeas = Collector.measure.i() + + if (TARGETIc < IcMeas) then + HIGHIb = Ib + else + LOWIb = Ib + end + until ((math.abs(IcMeas - TARGETIc) < (0.05 * TARGETIc)) or (k > 10)) + + --iteration limit reached + if (k > 10) then + end + + --Beta calculation + BETA1_data[index] = IcMeas / Ib + + local x = " = " .. tostring(BETA1_data[index]) --write measurement to front panel + display.settext(x) + delay(1) + + --Limit evaluation + if (BETA1_data[index] > HFE1limit) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_HFE = 1 + end --end of if + + --Write Pass/Fail + WriteHandler(Pass) + end --end of function HFE1() + + function VCEsat(index) + --VCEsat and VBEsat measurement + + local sourceCollector = 10E-3 + local limitVCEsat = 0.2 + + local sourceBase = 1E-3 + local limitVBEsat = 1.1 + + display.clear() --Clear 2602 display + display.settext("VCEsat") + delay(1) + + Collector.measure.rangev = 1 + Collector.source.rangei = sourceCollector + Collector.source.leveli = sourceCollector + + Base.measure.rangev = 1 + Base.source.rangei = sourceBase + Base.source.leveli = sourceBase + delay(0.001) + VCEsat_data[index] = Collector.measure.v() + + VBEsat_data[index] = Base.measure.v() + + if (VCEsat_data[index] < limitVCEsat) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_VCEsat = 1 + end --end VCEsat Pass/Fail + + local x = " = " .. tostring(VCEsat_data[index]) .. "V" + display.settext(x) + delay(1) + + --Write Pass/Fail + WriteHandler(Pass) + + display.clear() --Clear 2602 display + display.settext("VBEsat") + delay(1) + + local x = " = " .. tostring(VBEsat_data[index]) .. "V" + display.settext(x) + delay(1) + + if (VBEsat_data[index] < limitVBEsat) then --Evaluate Pass/Fail criterion + Pass = 1 --Pass is True + else + Pass = 0 + Fail_VBEsat = 1 + end --end VBEsat Pass/Fail + + --Write Pass/Fail + WriteHandler(Pass) + end --end function VCEsat() + + function WriteHandler(Pass) + --Write to handler + + if (Pass == 1) then + digio.writebit(2, 1) --Set bit 2 Hi, DUT pass + display.setcursor(2, 1) + display.settext("Test Status: PASS") + else + digio.writebit(8, 1) --Set bit 8 Hi, DUT Fail + display.setcursor(2, 1) + display.settext("Test Status: FAIL") + end + + delay(1) + digio.writeport(0) --Reset Digital I/O + display.setcursor(1, 1) --Reset cursor + end --end function writeHandler() + + ----------***** Start Test *****---------- + + timer.reset() + setup() + SetupTime = timer.measure.t() + + timer.reset() + + VCEO(i) + VCEsat(i) + HFE1(i) + + -- Bin + if Fail_VCEO == 1 then + bin_fail_VCEO = bin_fail_VCEO + 1 + PartStatus = " BAD" + elseif Fail_VCEsat == 1 then + bin_fail_VCEsat = bin_fail_VCEsat + 1 + PartStatus = " BAD" + elseif Fail_VBEsat == 1 then + bin_fail_VBEsat = bin_fail_VBEsat + 1 + PartStatus = " BAD" + elseif Fail_HFE == 1 then + bin_fail_HFE = bin_fail_VBEsat + 1 + PartStatus = " BAD" + else + bin_all_pass = bin_all_pass + 1 + PartStatus = " GOOD" + end + + TestTime = timer.measure.t() / num + + --Return instrument to idle state + Base.source.func = Base.OUTPUT_DCVOLTS + Base.source.levelv = 0 + + Collector.source.func = Collector.OUTPUT_DCVOLTS + Collector.source.levelv = 0 + + Base.measure.autozero = smua.AUTOZERO_AUTO + Base.measure.nplc = NPLC + Base.measure.v() + Base.measure.i() + + Collector.measure.autozero = smua.AUTOZERO_AUTO + Collector.measure.nplc = NPLC + Collector.measure.v() + Collector.measure.i() + + Collector.source.output = Collector.OUTPUT_OFF + Base.source.output = Base.OUTPUT_OFF + + + -- Show Stats + --print(string.format("Setup time = %f", setup_time)) + --print(string.format("Test time per part = %f", test_time)) + + --Percent = good_parts/(num*LabelCount)*100 + + display.clear() + display.settext("Part Status:" .. PartStatus) + display.setcursor(2, 1) + display.settext("Bin Counts:" .. + bin_fail_VCEO .. " " .. bin_fail_VCEsat .. " " .. bin_fail_VBEsat .. " " .. bin_fail_HFE .. " " .. bin_all_pass) + delay(3) + + + --display.clear() + --throughput = 1/test_time + --display.settext("Parts per sec:"..throughput) + --delay(3) + + display.screen = 2 + + + function Print_data() + --prints data to the output queue + for j = 1, LabelCount do + print(Label[j]) + + for i = 1, num do + if j == 1 then + print(VCEO_data[i]) + elseif j == 2 then + print(VCEsat_data[i]) + elseif j == 3 then + print(VBEsat_data[i]) + elseif j == 4 then + print(BETA1_data[i]) + end --end if + end --end for + print() + end --end for + end --end function Print_data + end --end main for loop + + if return_data == "yes" then + Print_data() + end --if +end --end function BJTSlow() + +BJTSlow(nil, 'yes') --run function BJTSlow() +display.loadmenu.add("BJTTest_Slow", "BJTSlow(nil,'yes')") --load function to User Script area diff --git a/TSP_Examples/2602/BJT_Slow/View This First.pdf b/TSP_Examples/2602/BJT_Slow/View This First.pdf new file mode 100644 index 0000000..a0e142f Binary files /dev/null and b/TSP_Examples/2602/BJT_Slow/View This First.pdf differ diff --git a/TSP_Examples/2602/Diode_Fast/.vscode/settings.json b/TSP_Examples/2602/Diode_Fast/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/Diode_Fast/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/Diode_Fast/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Fast/DiodeTest_Fast.tsp b/TSP_Examples/2602/Diode_Fast/DiodeTest_Fast.tsp new file mode 100644 index 0000000..a90896b --- /dev/null +++ b/TSP_Examples/2602/Diode_Fast/DiodeTest_Fast.tsp @@ -0,0 +1,570 @@ +--[[ DiodeTest_Fast.tsp + + Running this script creates functions which can be used to test diodes. It + also adds two menu selections to the SourceMeter display: "DiodeTest_Slow" + and "DiodeTest_Fast". Finally it runs the DiodeTest using smu=smua and + speed="FAST" as defaults. The user enters the number of diodes to test + from the front panel. + + The functions created are: + 1. Vfwd_Vrev(smu, irange, ilevel, srcdelay, vcmpl) + 2. DynZ(i1, v1, i2, v2) + 3. Ileakage(smu, vrange, vlevel, srcdelay, icmpl) + 4. TestStatus(testvalue, lolim, hilim) + 5. TestFail(teststatus) + 6. PartStatus(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + 7. BinPart(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + 8. DisplayTestStatus(testname, teststatus) + 9. DiodeTest(smu, ndiodes, speed) + See detailed information listed in individual functions + + + Revision History: + This script was originally created by Keithley Instruments' Applications + Engineering (Al Ivons) on 08 Apr 2005 +]] + +function Vfwd_Vrev(smu, irange, ilevel, srcdelay, vcmpl) + + -- This function performs a Forward Voltage Test or a Reverse Voltage Breakdown Test + + -- Pass parameters: + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- irange is the source level used to select the source range + -- ilevel is the test current level to use for the test + -- srcdelay is the delay after the source is set before the measurement is started + -- vcmpl is the voltage compliance limit for the test; + -- vcmpl is also used to select the voltage measurement range + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt for input parameters if missing from pass list + + if ilevel == nil then + ilevel = display.prompt("+0.000E+00", " Amps", "Enter Test Current.", 100E-6, -1, 1) + end --if + + if irange == nil then irange = ilevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0, 0, 20) + end --if + + if vcmpl == nil then + vcmpl = display.prompt("+0.000E+00", " Volts", "Enter Compliance", 2, -40, 40) + end --if + + -- Temporary variables used by this function. + local l_testcurrent, l_vmeasured + + -- Configure source and measure settings + smu.source.func = smu.OUTPUT_DCAMPS + smu.source.rangei = irange + smu.source.leveli = ilevel + smu.source.limitv = vcmpl + smu.measure.rangev = vcmpl + + -- Wait before making measurement + delay(srcdelay) + + -- Measure current and voltage + l_testcurrent, l_vmeasured = smu.measure.iv() + + --Set source output to zero + smu.source.leveli = 0 + + return l_vmeasured, l_testcurrent + +end --function Vfwd_Vrev + +function DynZ(i1, v1, i2, v2) + + --[[ This function calculates the Dynamic Impedance based on two forward voltage + or two reverse voltage measurements. ]] + + -- Pass parameters: + -- i1 is the test current used for first forward voltage measurement + -- v1 is the resulting voltage for first forward voltage measurement + -- i2 is the test current used for second forward voltage measurement + -- v2 is the resulting voltage for second forward voltage measurement + + -- Temporary variables used by this function. + local l_dz, l_denominator + + l_denominator = i2 - i1 + if l_denominator == 0 then l_denominator = 1E-37 end + + l_dz = (v2 - v1) / l_denominator -- DynZ = (v2 - v1) / (i2 - i1) + + -- print(l_dz, l_denominator) + + return l_dz + +end --function DynZ + +function Ileakage(smu, vrange, vlevel, srcdelay, icmpl) + + --This function performs a Reverse Leakage Current Test + + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- vrange is the source level used to select the source range + -- vlevel is the test voltage level to use for the test + -- srcdelay is the delay after the source is set before the measurement is started + -- icmpl is the current compliance limit for the test; + -- icmpl is also used to select the current measurement range + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt for input parameters if missing from pass list + + if vlevel == nil then + vlevel = display.prompt("+0.000E+00", " Volts", "Enter Test Voltage.", 1, -40, 40) + end --if + + if vrange == nil then vrange = vlevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0, 0, 20) + end --if + + if icmpl == nil then + icmpl = display.prompt("+0.000E+00", " Amps", "Enter Compliance", 2, -40, 40) + end --if + + -- Temporary variables used by this function. + local l_testvoltage, l_imeasured + + -- Configure source and measure settings + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.rangev = vrange + smu.source.levelv = vlevel + smu.source.limiti = icmpl + smu.measure.rangei = icmpl + + -- Wait before making measurement + delay(srcdelay) + + -- Measure current and voltage + l_imeasured, l_testvoltage = smu.measure.iv() + + --Set source output to 0 + smu.source.levelv = 0 + + return l_testvoltage, l_imeasured + +end --function Ileakage + +function TestStatus(testvalue, lolim, hilim) + + --[[ This function determines the PASS/FAIL status of an individual test + within the test sequence. It also creates a Boolean flag which is TRUE if + the subject test fails.]] + + -- Pass parameters: + -- testvalue is the result (measurement or calculation) of an individual test + -- lolim is the minimum acceptable value for the subject test + -- hilim is the maximum acceptable value for the subject test + + -- Temporary variables used by this function. + local l_status + local l_testfail + + if (testvalue >= lolim) and (testvalue <= hilim) then + l_status = "PASS" + l_testfail = false + else + l_status = "FAIL" + l_testfail = true + end --if + + return l_status, l_testfail + +end --function TestStatus + +function PartStatus(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + + --[[ This function determines the GOOD/BAD status of the part based on the + results of all of the tests in the test sequence. Any individual test failure + causes the part to be BAD. ]] + + -- Pass parameters: + -- tst1fail is the Boolean FAIL flag for test #1 (Vf1) + -- tst2fail is the Boolean FAIL flag for test #2 (Vf2) + -- tst3fail is the Boolean FAIL flag for test #3 (DynZ) + -- tst4fail is the Boolean FAIL flag for test #4 (Ir1) + -- tst5fail is the Boolean FAIL flag for test #5 (Ir2) + -- tst6fail is the Boolean FAIL flag for test #6 (Vr) + + -- Temporary variables used by this function. + local l_status = "GOOD" + + if tst1fail or tst2fail or tst3fail or tst4fail or tst5fail or tst6fail then l_status = "BAD" end + + return l_status + +end --function PartStatus + +function BinPart(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail, bins) + + --[[ This function increments the "Part Bins" table simulating the bins a component + handler may use. The incremented bin corresponds to either the first test a part fails, + or to the ALL PASS/GOOD PART status. Note: The table "bins" is modified by this function. ]] + + if tst1fail then -- If part first failed Forward Voltage Test #1 + bins[2] = bins[2] + 1 + elseif tst2fail then -- If part first failed Forward Voltage Test #2 + bins[3] = bins[3] + 1 + elseif tst3fail then -- If part first failed Dynamic Impedance Test + bins[4] = bins[4] + 1 + elseif tst4fail then -- If first failed Reverse Leakage Current Test #1 + bins[5] = bins[5] + 1 + elseif tst5fail then -- If first failed Reverse Leakage Current Test #2 + bins[6] = bins[6] + 1 + elseif tst6fail then -- If first failed Reverse Voltage Breakdown Test + bins[7] = bins[7] + 1 + else -- Part is GOOD; does not fail any tests + bins[1] = bins[1] + 1 + end --if + +end -- function BinPart + +function DisplayTestStatus(testname, testvalue, testunit, teststatus, disp_delay) + + -- This function displays individual test results on the front panel display + + -- Pass parameters: + -- testname is a the label to display to identify the test (e.g "Vf1: ") + -- testvalue is the result (measurement or calculation) of an individual test + -- testunit is the unit to display with testvalue (e.g. "V", "A") + -- teststatus is the PASS/FAIL status of the subject test + -- disp_delay is a delay time used to pace the display + + display.clear() + display.setcursor (1,1) + display.settext(testname) + delay(disp_delay) + display.settext(tostring(testvalue)..testunit) + delay(disp_delay) + display.setcursor (2,1) + display.settext("Test Status: "..teststatus) + delay(disp_delay) + +end --function + +function DisplayPartStatus(partstatus, bins) + + -- Temporary variables used by this function. + local l_i + + display.clear() + display.setcursor(1,1) + display.settext("Part Status: "..partstatus) + + display.setcursor(2,1) + + display.settext("Bin Counts: ") + + for l_i = 1, 7 do + + display.settext(tostring(bins[l_i]).." ") +-- display.settext("B"..tostring(l_i).."="..tostring(bins[l_i]).." ") + end --for + +end --function DisplayPartStatus + +function DiodeTest(smu, ndiodes, speed) + + --[[ This function performs a complete diode test sequence consisting of 6 tests + (5 measurements and one calculation). The tests include: + 2 Forward Voltage tests (vf1 and vf2) + 1 Dynamic Impedance test (dynz) + 2 Reverse Leakage Current tests (ir1 and ir2) + 1 Reverse Voltage Breakdown test (vr) + + The individual tests are executed in the order they are listed. Test results are + inspected against limits and pass/fail status is displayed on the front panel. + Based on the pass/fail results the part is "binned." Digital I/O port Bit 1 is set + high if the diode is GOOD and Bit 2 is set high if the part is BAD. ]] + + --[[ Revision History: + This test executive function and related supporting functions were + originally created by Al Ivons on 07 Apr 2005 ]] + + -- Pass parameters: + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- ndiodes is the number of diodes to test (i.e. number of times to repeat the test sequence) + -- speed is either FAST or SLOW and affects NPLC, delays, autozero, displays, etc. + --"SLOW" is the default if no speed is specified + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt user to enter Number of Diodes to Test if input parameter is missing. +-- display.clear() + if ndiodes == nil then + ndiodes = display.prompt("0000", " Diodes", "Enter how many diodes to test.", 50, 1, 9999) + end --if + + -- Default to "SLOW" if no speed is specified. + if speed == nil then speed = "SLOW" end + + -- ***** Temporary variables used by this function ***** + + -- Save settings in temporary variables so they can be restored at the end. + local l_s_func = smu.source.func + local l_s_autorangei = smu.source.autorangei + local l_s_rangei = smu.source.rangei + local l_s_leveli = smu.source.leveli + local l_m_autorangev = smu.measure.autorangev + local l_m_rangev = smu.measure.rangev + local l_d_screen = display.screen + + -- Test Inspection Limits (based on Keithley P/N PL-118-1) + local l_vf1_lowlim = 3.078 -- Low inspection limit for vf1 + local l_vf1_highlim = 3.762 -- High inspection limit for vf1 + local l_vf2_lowlim = 3.366 -- Low inspection limit for vf2 + local l_vf2_highlim = 4.114 -- High inspection limit for vf2 + local l_dynz_lowlim = -26.4 -- Low inspection limit for dynz + local l_dynz_highlim = 69.1 -- High inspection limit for dynz + local l_ir1_lowlim = -2E-5 -- Low inspection limit for ir1 + local l_ir1_highlim = 0 -- High inspection limit for ir1 + local l_ir2_lowlim = -20E-5 -- Low inspection limit for ir2 + local l_ir2_highlim = 0 -- High inspection limit for ir2 + local l_vr_lowlim = -39.1 -- Low inspection limit for vr + local l_vr_highlim = -28.9 -- High inspection limit for vr + + -- Source and measure settings are based on Keithley P/N PL-118-1 + -- Variables used to configure source and measure settings for vf1 test + local l_vf1_isrc_rng = 0.005 + local l_vf1_isrc_lev = 0.005 + local l_vf1_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vf1_src_del = 0 end + local l_vf1_vcmpl = 10 + + -- Variables used to configure source and measure settings for vf2 test + local l_vf2_isrc_rng = 0.02 + local l_vf2_isrc_lev = 0.02 + local l_vf2_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vf2_src_del = 0 end + local l_vf2_vcmpl = 10 + + -- Variables used to configure source and measure settings for ir1 test + local l_ir1_vsrc_rng = 40 + local l_ir1_vsrc_lev = -20 + local l_ir1_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_ir1_src_del = 0 end + local l_ir1_icmpl = 100E-6 + + -- Variables used to configure source and measure settings for ir2 test + local l_ir2_vsrc_rng = 40 + local l_ir2_vsrc_lev = -25 + local l_ir2_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_ir2_src_del = 0 end + local l_ir2_icmpl = 100E-6 + + -- Variables used to configure source and measure settings for vr test + local l_vr_isrc_rng = 100E-6 + local l_vr_isrc_lev = -100E-6 + local l_vr_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vr_src_del = 0 end + local l_vr_vcmpl = 40 + + -- Integration time used for all measurements + -- Expressed in terms of powerline cycles (PLC) + local l_nplc = 1 --"SLOW" value is default + if speed == "FAST" then l_nplc = 0.001 end + + -- Boolean flag used to select autozero mode (true = auto and false = once) + local l_azero_on = true --"SLOW" value is default + if speed == "FAST" then l_azero_on = false end + + -- Boolean flag used to select state of the display (true = on and false = off) + local l_disp_on = true --"SLOW" value is default + if speed == "FAST" then l_disp_on = false end + + -- Delay (in seconds) to slow sequence down for viewing when speed = "SLOW" + local l_delay = 1 --"SLOW" value is default + if speed == "FAST" then l_delay = 0 end + + -- Tables used to hold test data and pass/fail status for vf1 test + local l_vf1_test_curr = {} + local l_vf1_data = {} + local l_vf1_status = {} + local l_vf1_fail = {} + + -- Tables used to hold test data and pass/fail status for vf2 test + local l_vf2_test_curr = {} + local l_vf2_data = {} + local l_vf2_status = {} + local l_vf2_fail = {} + + -- Tables used to hold test data and pass/fail status for dynz test + local l_dynz_data = {} + local l_dynz_status = {} + local l_dynz_fail = {} + + -- Tables used to hold test data and pass/fail status for ir1 test + local l_ir1_test_volt = {} + local l_ir1_data = {} + local l_ir1_status = {} + local l_ir1_fail = {} + + -- Tables used to hold test data and pass/fail status for ir2 test + local l_ir2_test_volt = {} + local l_ir2_data = {} + local l_ir2_status = {} + local l_ir2_fail = {} + + -- Tables used to hold test data and pass/fail status for vr test + local l_vr_test_curr = {} + local l_vr_data = {} + local l_vr_status = {} + local l_vr_fail = {} + + -- Table to hold good/bad part status based on cumulative results of all tests + local l_part_status = {} + + -- Table used to count parts put into simulated bins of a component handler + local l_bins = {0,0,0,0,0,0,0} -- Initially set all bins to zero + + -- Variables to hold timing information + local l_start_time, l_stop_time, l_elapsed_time + + -- Counter variable + local l_i + + -- ***** Perform initial setup of the 2602 ***** + -- Individual test functions will configure source and measure settings as necessary. + -- For simplicity, LOCAL (2-wire) voltage sensing is used. + -- It is straightforward to change to REMOTE (4-wire) sensing. + + smu.reset() + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.levelv = 0 + smu.sense = smu.SENSE_LOCAL -- use smu.SENSE_REMOTE for 4-w sensing + smu.measure.nplc = l_nplc + + if l_azero_on then + smu.measure.autozero = smu.AUTOZERO_AUTO + else + smu.measure.autozero = smu.AUTOZERO_ONCE + end --if + + digio.writeport(0) -- Set all unprotected bits to zero + + errorqueue.clear() -- Clear the error queue + + -- ############################## RUN TEST ############################## + + if speed == "FAST" then + display.clear() + display.setcursor (1,1) + display.settext("Test In Progress") + display.setcursor (2,1) + display.settext("Testing "..tostring(ndiodes).." Parts") + end --if + + timer.reset() + l_start_time = timer.measure.t() + + smu.source.output = smu.OUTPUT_ON + + for l_i = 1, ndiodes do + + -- Perform Forward Voltage Test #1 (Vf1) + + l_vf1_data[l_i], l_vf1_test_curr[l_i] = Vfwd_Vrev(smu, l_vf1_isrc_rng, l_vf1_isrc_lev, l_vf1_src_del, l_vf1_vcmpl) + l_vf1_status[l_i], l_vf1_fail[l_i] = TestStatus(l_vf1_data[l_i], l_vf1_lowlim, l_vf1_highlim) + if l_disp_on then DisplayTestStatus("Vf1 = ", l_vf1_data[l_i], "V", l_vf1_status[l_i], l_delay) end + + -- Perform Forward Voltage Test #2 (Vf2) + + l_vf2_data[l_i], l_vf2_test_curr[l_i] = Vfwd_Vrev(smu, l_vf2_isrc_rng, l_vf2_isrc_lev, l_vf2_src_del, l_vf2_vcmpl) + l_vf2_status[l_i], l_vf2_fail[l_i] = TestStatus(l_vf2_data[l_i], l_vf2_lowlim, l_vf2_highlim) + if l_disp_on then DisplayTestStatus("Vf2 = ", l_vf2_data[l_i], "V", l_vf2_status[l_i], l_delay) end + + -- Perform Dynamic Impedance Test (DynZ) + + l_dynz_data[l_i] = DynZ(l_vf1_test_curr[l_i], l_vf1_data[l_i], l_vf2_test_curr[l_i], l_vf2_data[l_i]) + l_dynz_status[l_i], l_dynz_fail[l_i] = TestStatus(l_dynz_data[l_i], l_dynz_lowlim, l_dynz_highlim) + if l_disp_on then DisplayTestStatus("DynZ: ", l_dynz_data[l_i], " Ohm", l_dynz_status[l_i], l_delay) end + + -- Perform Reverse Leakage Current Test #1 (Ir1) + + l_ir1_test_volt[l_i], l_ir1_data[l_i] = Ileakage(smu, l_ir1_vsrc_rng, l_ir1_vsrc_lev, l_ir1_src_del, l_ir1_icmpl) + l_ir1_status[l_i], l_ir1_fail[l_i] = TestStatus(l_ir1_data[l_i], l_ir1_lowlim, l_ir1_highlim) + if l_disp_on then DisplayTestStatus("Ir1 = ", l_ir1_data[l_i], "A", l_ir1_status[l_i], l_delay) end + + -- Perform Reverse Leakage Current Test #2 (Ir2) + + l_ir2_test_volt[l_i], l_ir2_data[l_i] = Ileakage(smu, l_ir2_vsrc_rng, l_ir2_vsrc_lev, l_ir2_src_del, l_ir2_icmpl) + l_ir2_status[l_i], l_ir2_fail[l_i] = TestStatus(l_ir2_data[l_i], l_ir2_lowlim, l_ir2_highlim) + if l_disp_on then DisplayTestStatus("Ir2 = ", l_ir2_data[l_i], "A", l_ir2_status[l_i], l_delay) end + + -- Perform Reverse Voltage Breakdown Test (Vr) + + l_vr_data[l_i], l_vr_test_curr[l_i] = Vfwd_Vrev(smu, l_vr_isrc_rng, l_vr_isrc_lev, l_vr_src_del, l_vr_vcmpl) + l_vr_status[l_i], l_vr_fail[l_i] = TestStatus(l_vr_data[l_i], l_vr_lowlim, l_vr_highlim) + if l_disp_on then DisplayTestStatus("Vr = ", l_vr_data[l_i], "V", l_vr_status[l_i], l_delay) end + + -- Determine cumulative part status + + l_part_status[l_i] = PartStatus(l_vf1_fail[l_i], l_vf2_fail[l_i], l_dynz_fail[l_i], l_ir1_fail[l_i], l_ir2_fail[l_i], l_vr_fail[l_i]) + + -- Bin the part + + BinPart(l_vf1_fail[l_i], l_vf2_fail[l_i], l_dynz_fail[l_i], l_ir1_fail[l_i], l_ir2_fail[l_i], l_vr_fail[l_i], l_bins) + + if l_disp_on then DisplayPartStatus(l_part_status[l_i], l_bins) end + delay(3 * l_delay) + + if l_part_status[l_i] == "GOOD" then + digio.writebit(1,1) -- Set Bit 1 HIGH + delay(l_delay) -- Delay a little + digio.writebit(1,0) -- Set Bit 1 LOW + else -- If "BAD" then ... + digio.writebit(2,1) -- Set Bit 2 HIGH + delay(l_delay) -- Delay a little + digio.writebit(2,0) -- Set Bit 2 LOW + end --if + + end --for + + smu.source.output = smu.OUTPUT_OFF + + l_stop_time = timer.measure.t() + l_elapsed_time = l_stop_time - l_start_time + + display.clear() + display.setcursor (1,1) + display.settext("Parts per sec = "..tostring(ndiodes / l_elapsed_time)) + display.setcursor(2,1) + display.settext("Bin Count: ") + for l_i = 1, 7 do + display.settext(tostring(l_bins[l_i]).." ") + end --for + delay(5) + + -- Update the front panel display and restore modified settings. + smu.source.func = l_s_func + smu.source.autorangei = l_s_autorangei + smu.source.rangei = l_s_rangei + smu.source.leveli = l_s_leveli + smu.measure.autorangev = l_m_autorangev + smu.measure.rangev = l_m_rangev + display.clear() + display.screen = l_d_screen + +end --function DiodeTest + +print("FUNCTIONS CREATED") + +display.loadmenu.add("DiodeTest_Slow", "DiodeTest(smua, nil, 'SLOW')") +display.loadmenu.add("DiodeTest_Fast", "DiodeTest(smua, nil, 'FAST')") + +print("MENU ITEMS ADDED") + +DiodeTest(smua, nil, "FAST") + diff --git a/TSP_Examples/2602/Diode_Fast/View This First.pdf b/TSP_Examples/2602/Diode_Fast/View This First.pdf new file mode 100644 index 0000000..8df461c Binary files /dev/null and b/TSP_Examples/2602/Diode_Fast/View This First.pdf differ diff --git a/TSP_Examples/2602/Diode_Slow/.vscode/settings.json b/TSP_Examples/2602/Diode_Slow/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/Diode_Slow/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/Diode_Slow/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/Diode_Slow/DiodeTest_Slow.tsp b/TSP_Examples/2602/Diode_Slow/DiodeTest_Slow.tsp new file mode 100644 index 0000000..effd61e --- /dev/null +++ b/TSP_Examples/2602/Diode_Slow/DiodeTest_Slow.tsp @@ -0,0 +1,570 @@ +--[[ DiodeTest_Slow.tsp + + Running this script creates functions which can be used to test diodes. It + also adds two menu selections to the SourceMeter display: "DiodeTest_Slow" + and "DiodeTest_Fast". Finally it runs the DiodeTest using smu=smua and + speed="SLOW" as defaults. The user enters the number of diodes to test + from the front panel. + + The functions created are: + 1. Vfwd_Vrev(smu, irange, ilevel, srcdelay, vcmpl) + 2. DynZ(i1, v1, i2, v2) + 3. Ileakage(smu, vrange, vlevel, srcdelay, icmpl) + 4. TestStatus(testvalue, lolim, hilim) + 5. TestFail(teststatus) + 6. PartStatus(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + 7. BinPart(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + 8. DisplayTestStatus(testname, teststatus) + 9. DiodeTest(smu, ndiodes, speed) + See detailed information listed in individual functions + + + Revision History: + This script was originally created by Keithley Instruments' Applications + Engineering (Al Ivons) on 08 Apr 2005 +]] + +function Vfwd_Vrev(smu, irange, ilevel, srcdelay, vcmpl) + + -- This function performs a Forward Voltage Test or a Reverse Voltage Breakdown Test + + -- Pass parameters: + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- irange is the source level used to select the source range + -- ilevel is the test current level to use for the test + -- srcdelay is the delay after the source is set before the measurement is started + -- vcmpl is the voltage compliance limit for the test; + -- vcmpl is also used to select the voltage measurement range + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt for input parameters if missing from pass list + + if ilevel == nil then + ilevel = display.prompt("+0.000E+00", " Amps", "Enter Test Current.", 100E-6, -1, 1) + end --if + + if irange == nil then irange = ilevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0, 0, 20) + end --if + + if vcmpl == nil then + vcmpl = display.prompt("+0.000E+00", " Volts", "Enter Compliance", 2, -40, 40) + end --if + + -- Temporary variables used by this function. + local l_testcurrent, l_vmeasured + + -- Configure source and measure settings + smu.source.func = smu.OUTPUT_DCAMPS + smu.source.rangei = irange + smu.source.leveli = ilevel + smu.source.limitv = vcmpl + smu.measure.rangev = vcmpl + + -- Wait before making measurement + delay(srcdelay) + + -- Measure current and voltage + l_testcurrent, l_vmeasured = smu.measure.iv() + + --Set source output to zero + smu.source.leveli = 0 + + return l_vmeasured, l_testcurrent + +end --function Vfwd_Vrev + +function DynZ(i1, v1, i2, v2) + + --[[ This function calculates the Dynamic Impedance based on two forward voltage + or two reverse voltage measurements. ]] + + -- Pass parameters: + -- i1 is the test current used for first forward voltage measurement + -- v1 is the resulting voltage for first forward voltage measurement + -- i2 is the test current used for second forward voltage measurement + -- v2 is the resulting voltage for second forward voltage measurement + + -- Temporary variables used by this function. + local l_dz, l_denominator + + l_denominator = i2 - i1 + if l_denominator == 0 then l_denominator = 1E-37 end + + l_dz = (v2 - v1) / l_denominator -- DynZ = (v2 - v1) / (i2 - i1) + + -- print(l_dz, l_denominator) + + return l_dz + +end --function DynZ + +function Ileakage(smu, vrange, vlevel, srcdelay, icmpl) + + --This function performs a Reverse Leakage Current Test + + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- vrange is the source level used to select the source range + -- vlevel is the test voltage level to use for the test + -- srcdelay is the delay after the source is set before the measurement is started + -- icmpl is the current compliance limit for the test; + -- icmpl is also used to select the current measurement range + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt for input parameters if missing from pass list + + if vlevel == nil then + vlevel = display.prompt("+0.000E+00", " Volts", "Enter Test Voltage.", 1, -40, 40) + end --if + + if vrange == nil then vrange = vlevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0, 0, 20) + end --if + + if icmpl == nil then + icmpl = display.prompt("+0.000E+00", " Amps", "Enter Compliance", 2, -40, 40) + end --if + + -- Temporary variables used by this function. + local l_testvoltage, l_imeasured + + -- Configure source and measure settings + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.rangev = vrange + smu.source.levelv = vlevel + smu.source.limiti = icmpl + smu.measure.rangei = icmpl + + -- Wait before making measurement + delay(srcdelay) + + -- Measure current and voltage + l_imeasured, l_testvoltage = smu.measure.iv() + + --Set source output to 0 + smu.source.levelv = 0 + + return l_testvoltage, l_imeasured + +end --function Ileakage + +function TestStatus(testvalue, lolim, hilim) + + --[[ This function determines the PASS/FAIL status of an individual test + within the test sequence. It also creates a Boolean flag which is TRUE if + the subject test fails.]] + + -- Pass parameters: + -- testvalue is the result (measurement or calculation) of an individual test + -- lolim is the minimum acceptable value for the subject test + -- hilim is the maximum acceptable value for the subject test + + -- Temporary variables used by this function. + local l_status + local l_testfail + + if (testvalue >= lolim) and (testvalue <= hilim) then + l_status = "PASS" + l_testfail = false + else + l_status = "FAIL" + l_testfail = true + end --if + + return l_status, l_testfail + +end --function TestStatus + +function PartStatus(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail) + + --[[ This function determines the GOOD/BAD status of the part based on the + results of all of the tests in the test sequence. Any individual test failure + causes the part to be BAD. ]] + + -- Pass parameters: + -- tst1fail is the Boolean FAIL flag for test #1 (Vf1) + -- tst2fail is the Boolean FAIL flag for test #2 (Vf2) + -- tst3fail is the Boolean FAIL flag for test #3 (DynZ) + -- tst4fail is the Boolean FAIL flag for test #4 (Ir1) + -- tst5fail is the Boolean FAIL flag for test #5 (Ir2) + -- tst6fail is the Boolean FAIL flag for test #6 (Vr) + + -- Temporary variables used by this function. + local l_status = "GOOD" + + if tst1fail or tst2fail or tst3fail or tst4fail or tst5fail or tst6fail then l_status = "BAD" end + + return l_status + +end --function PartStatus + +function BinPart(tst1fail, tst2fail, tst3fail, tst4fail, tst5fail, tst6fail, bins) + + --[[ This function increments the "Part Bins" table simulating the bins a component + handler may use. The incremented bin corresponds to either the first test a part fails, + or to the ALL PASS/GOOD PART status. Note: The table "bins" is modified by this function. ]] + + if tst1fail then -- If part first failed Forward Voltage Test #1 + bins[2] = bins[2] + 1 + elseif tst2fail then -- If part first failed Forward Voltage Test #2 + bins[3] = bins[3] + 1 + elseif tst3fail then -- If part first failed Dynamic Impedance Test + bins[4] = bins[4] + 1 + elseif tst4fail then -- If first failed Reverse Leakage Current Test #1 + bins[5] = bins[5] + 1 + elseif tst5fail then -- If first failed Reverse Leakage Current Test #2 + bins[6] = bins[6] + 1 + elseif tst6fail then -- If first failed Reverse Voltage Breakdown Test + bins[7] = bins[7] + 1 + else -- Part is GOOD; does not fail any tests + bins[1] = bins[1] + 1 + end --if + +end -- function BinPart + +function DisplayTestStatus(testname, testvalue, testunit, teststatus, disp_delay) + + -- This function displays individual test results on the front panel display + + -- Pass parameters: + -- testname is a the label to display to identify the test (e.g "Vf1: ") + -- testvalue is the result (measurement or calculation) of an individual test + -- testunit is the unit to display with testvalue (e.g. "V", "A") + -- teststatus is the PASS/FAIL status of the subject test + -- disp_delay is a delay time used to pace the display + + display.clear() + display.setcursor (1,1) + display.settext(testname) + delay(disp_delay) + display.settext(tostring(testvalue)..testunit) + delay(disp_delay) + display.setcursor (2,1) + display.settext("Test Status: "..teststatus) + delay(disp_delay) + +end --function + +function DisplayPartStatus(partstatus, bins) + + -- Temporary variables used by this function. + local l_i + + display.clear() + display.setcursor(1,1) + display.settext("Part Status: "..partstatus) + + display.setcursor(2,1) + + display.settext("Bin Counts: ") + + for l_i = 1, 7 do + + display.settext(tostring(bins[l_i]).." ") +-- display.settext("B"..tostring(l_i).."="..tostring(bins[l_i]).." ") + end --for + +end --function DisplayPartStatus + +function DiodeTest(smu, ndiodes, speed) + + --[[ This function performs a complete diode test sequence consisting of 6 tests + (5 measurements and one calculation). The tests include: + 2 Forward Voltage tests (vf1 and vf2) + 1 Dynamic Impedance test (dynz) + 2 Reverse Leakage Current tests (ir1 and ir2) + 1 Reverse Voltage Breakdown test (vr) + + The individual tests are executed in the order they are listed. Test results are + inspected against limits and pass/fail status is displayed on the front panel. + Based on the pass/fail results the part is "binned." Digital I/O port Bit 1 is set + high if the diode is GOOD and Bit 2 is set high if the part is BAD. ]] + + --[[ Revision History: + This test executive function and related supporting functions were + originally created by Al Ivons on 07 Apr 2005 ]] + + -- Pass parameters: + -- smu is the SMU to use for the test (A or B); smua is the default if no SMU is specified + -- ndiodes is the number of diodes to test (i.e. number of times to repeat the test sequence) + -- speed is either FAST or SLOW and affects NPLC, delays, autozero, displays, etc. + --"SLOW" is the default if no speed is specified + + -- Default to smua if no smu is specified. + if smu == nil then smu = smua end + + -- Prompt user to enter Number of Diodes to Test if input parameter is missing. +-- display.clear() + if ndiodes == nil then + ndiodes = display.prompt("0000", " Diodes", "Enter how many diodes to test.", 1, 1, 9999) + end --if + + -- Default to "SLOW" if no speed is specified. + if speed == nil then speed = "SLOW" end + + -- ***** Temporary variables used by this function ***** + + -- Save settings in temporary variables so they can be restored at the end. + local l_s_func = smu.source.func + local l_s_autorangei = smu.source.autorangei + local l_s_rangei = smu.source.rangei + local l_s_leveli = smu.source.leveli + local l_m_autorangev = smu.measure.autorangev + local l_m_rangev = smu.measure.rangev + local l_d_screen = display.screen + + -- Test Inspection Limits (based on Keithley P/N PL-118-1) + local l_vf1_lowlim = 3.078 -- Low inspection limit for vf1 + local l_vf1_highlim = 3.762 -- High inspection limit for vf1 + local l_vf2_lowlim = 3.366 -- Low inspection limit for vf2 + local l_vf2_highlim = 4.114 -- High inspection limit for vf2 + local l_dynz_lowlim = -26.4 -- Low inspection limit for dynz + local l_dynz_highlim = 69.1 -- High inspection limit for dynz + local l_ir1_lowlim = -2E-5 -- Low inspection limit for ir1 + local l_ir1_highlim = 0 -- High inspection limit for ir1 + local l_ir2_lowlim = -20E-5 -- Low inspection limit for ir2 + local l_ir2_highlim = 0 -- High inspection limit for ir2 + local l_vr_lowlim = -39.1 -- Low inspection limit for vr + local l_vr_highlim = -28.9 -- High inspection limit for vr + + -- Source and measure settings are based on Keithley P/N PL-118-1 + -- Variables used to configure source and measure settings for vf1 test + local l_vf1_isrc_rng = 0.005 + local l_vf1_isrc_lev = 0.005 + local l_vf1_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vf1_src_del = 0 end + local l_vf1_vcmpl = 10 + + -- Variables used to configure source and measure settings for vf2 test + local l_vf2_isrc_rng = 0.02 + local l_vf2_isrc_lev = 0.02 + local l_vf2_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vf2_src_del = 0 end + local l_vf2_vcmpl = 10 + + -- Variables used to configure source and measure settings for ir1 test + local l_ir1_vsrc_rng = 40 + local l_ir1_vsrc_lev = -20 + local l_ir1_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_ir1_src_del = 0 end + local l_ir1_icmpl = 100E-6 + + -- Variables used to configure source and measure settings for ir2 test + local l_ir2_vsrc_rng = 40 + local l_ir2_vsrc_lev = -25 + local l_ir2_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_ir2_src_del = 0 end + local l_ir2_icmpl = 100E-6 + + -- Variables used to configure source and measure settings for vr test + local l_vr_isrc_rng = 100E-6 + local l_vr_isrc_lev = -100E-6 + local l_vr_src_del = 0.1 --"SLOW" value is default + if speed == "FAST" then l_vr_src_del = 0 end + local l_vr_vcmpl = 40 + + -- Integration time used for all measurements + -- Expressed in terms of powerline cycles (PLC) + local l_nplc = 1 --"SLOW" value is default + if speed == "FAST" then l_nplc = 0.001 end + + -- Boolean flag used to select autozero mode (true = auto and false = once) + local l_azero_on = true --"SLOW" value is default + if speed == "FAST" then l_azero_on = false end + + -- Boolean flag used to select state of the display (true = on and false = off) + local l_disp_on = true --"SLOW" value is default + if speed == "FAST" then l_disp_on = false end + + -- Delay (in seconds) to slow sequence down for viewing when speed = "SLOW" + local l_delay = 1 --"SLOW" value is default + if speed == "FAST" then l_delay = 0 end + + -- Tables used to hold test data and pass/fail status for vf1 test + local l_vf1_test_curr = {} + local l_vf1_data = {} + local l_vf1_status = {} + local l_vf1_fail = {} + + -- Tables used to hold test data and pass/fail status for vf2 test + local l_vf2_test_curr = {} + local l_vf2_data = {} + local l_vf2_status = {} + local l_vf2_fail = {} + + -- Tables used to hold test data and pass/fail status for dynz test + local l_dynz_data = {} + local l_dynz_status = {} + local l_dynz_fail = {} + + -- Tables used to hold test data and pass/fail status for ir1 test + local l_ir1_test_volt = {} + local l_ir1_data = {} + local l_ir1_status = {} + local l_ir1_fail = {} + + -- Tables used to hold test data and pass/fail status for ir2 test + local l_ir2_test_volt = {} + local l_ir2_data = {} + local l_ir2_status = {} + local l_ir2_fail = {} + + -- Tables used to hold test data and pass/fail status for vr test + local l_vr_test_curr = {} + local l_vr_data = {} + local l_vr_status = {} + local l_vr_fail = {} + + -- Table to hold good/bad part status based on cumulative results of all tests + local l_part_status = {} + + -- Table used to count parts put into simulated bins of a component handler + local l_bins = {0,0,0,0,0,0,0} -- Initially set all bins to zero + + -- Variables to hold timing information + local l_start_time, l_stop_time, l_elapsed_time + + -- Counter variable + local l_i + + -- ***** Perform initial setup of the 2602 ***** + -- Individual test functions will configure source and measure settings as necessary. + -- For simplicity, LOCAL (2-wire) voltage sensing is used. + -- It is straightforward to change to REMOTE (4-wire) sensing. + + smu.reset() + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.levelv = 0 + smu.sense = smu.SENSE_LOCAL -- use smu.SENSE_REMOTE for 4-w sensing + smu.measure.nplc = l_nplc + + if l_azero_on then + smu.measure.autozero = smu.AUTOZERO_AUTO + else + smu.measure.autozero = smu.AUTOZERO_ONCE + end --if + + digio.writeport(0) -- Set all unprotected bits to zero + + errorqueue.clear() -- Clear the error queue + + -- ############################## RUN TEST ############################## + + if speed == "FAST" then + display.clear() + display.setcursor (1,1) + display.settext("Test In Progress") + display.setcursor (2,1) + display.settext("Testing "..tostring(ndiodes).." Parts") + end --if + + timer.reset() + l_start_time = timer.measure.t() + + smu.source.output = smu.OUTPUT_ON + + for l_i = 1, ndiodes do + + -- Perform Forward Voltage Test #1 (Vf1) + + l_vf1_data[l_i], l_vf1_test_curr[l_i] = Vfwd_Vrev(smu, l_vf1_isrc_rng, l_vf1_isrc_lev, l_vf1_src_del, l_vf1_vcmpl) + l_vf1_status[l_i], l_vf1_fail[l_i] = TestStatus(l_vf1_data[l_i], l_vf1_lowlim, l_vf1_highlim) + if l_disp_on then DisplayTestStatus("Vf1 = ", l_vf1_data[l_i], "V", l_vf1_status[l_i], l_delay) end + + -- Perform Forward Voltage Test #2 (Vf2) + + l_vf2_data[l_i], l_vf2_test_curr[l_i] = Vfwd_Vrev(smu, l_vf2_isrc_rng, l_vf2_isrc_lev, l_vf2_src_del, l_vf2_vcmpl) + l_vf2_status[l_i], l_vf2_fail[l_i] = TestStatus(l_vf2_data[l_i], l_vf2_lowlim, l_vf2_highlim) + if l_disp_on then DisplayTestStatus("Vf2 = ", l_vf2_data[l_i], "V", l_vf2_status[l_i], l_delay) end + + -- Perform Dynamic Impedance Test (DynZ) + + l_dynz_data[l_i] = DynZ(l_vf1_test_curr[l_i], l_vf1_data[l_i], l_vf2_test_curr[l_i], l_vf2_data[l_i]) + l_dynz_status[l_i], l_dynz_fail[l_i] = TestStatus(l_dynz_data[l_i], l_dynz_lowlim, l_dynz_highlim) + if l_disp_on then DisplayTestStatus("DynZ: ", l_dynz_data[l_i], " Ohm", l_dynz_status[l_i], l_delay) end + + -- Perform Reverse Leakage Current Test #1 (Ir1) + + l_ir1_test_volt[l_i], l_ir1_data[l_i] = Ileakage(smu, l_ir1_vsrc_rng, l_ir1_vsrc_lev, l_ir1_src_del, l_ir1_icmpl) + l_ir1_status[l_i], l_ir1_fail[l_i] = TestStatus(l_ir1_data[l_i], l_ir1_lowlim, l_ir1_highlim) + if l_disp_on then DisplayTestStatus("Ir1 = ", l_ir1_data[l_i], "A", l_ir1_status[l_i], l_delay) end + + -- Perform Reverse Leakage Current Test #2 (Ir2) + + l_ir2_test_volt[l_i], l_ir2_data[l_i] = Ileakage(smu, l_ir2_vsrc_rng, l_ir2_vsrc_lev, l_ir2_src_del, l_ir2_icmpl) + l_ir2_status[l_i], l_ir2_fail[l_i] = TestStatus(l_ir2_data[l_i], l_ir2_lowlim, l_ir2_highlim) + if l_disp_on then DisplayTestStatus("Ir2 = ", l_ir2_data[l_i], "A", l_ir2_status[l_i], l_delay) end + + -- Perform Reverse Voltage Breakdown Test (Vr) + + l_vr_data[l_i], l_vr_test_curr[l_i] = Vfwd_Vrev(smu, l_vr_isrc_rng, l_vr_isrc_lev, l_vr_src_del, l_vr_vcmpl) + l_vr_status[l_i], l_vr_fail[l_i] = TestStatus(l_vr_data[l_i], l_vr_lowlim, l_vr_highlim) + if l_disp_on then DisplayTestStatus("Vr = ", l_vr_data[l_i], "V", l_vr_status[l_i], l_delay) end + + -- Determine cumulative part status + + l_part_status[l_i] = PartStatus(l_vf1_fail[l_i], l_vf2_fail[l_i], l_dynz_fail[l_i], l_ir1_fail[l_i], l_ir2_fail[l_i], l_vr_fail[l_i]) + + -- Bin the part + + BinPart(l_vf1_fail[l_i], l_vf2_fail[l_i], l_dynz_fail[l_i], l_ir1_fail[l_i], l_ir2_fail[l_i], l_vr_fail[l_i], l_bins) + + if l_disp_on then DisplayPartStatus(l_part_status[l_i], l_bins) end + delay(3 * l_delay) + + if l_part_status[l_i] == "GOOD" then + digio.writebit(1,1) -- Set Bit 1 HIGH + delay(l_delay) -- Delay a little + digio.writebit(1,0) -- Set Bit 1 LOW + else -- If "BAD" then ... + digio.writebit(2,1) -- Set Bit 2 HIGH + delay(l_delay) -- Delay a little + digio.writebit(2,0) -- Set Bit 2 LOW + end --if + + end --for + + smu.source.output = smu.OUTPUT_OFF + + l_stop_time = timer.measure.t() + l_elapsed_time = l_stop_time - l_start_time + + display.clear() + display.setcursor (1,1) + display.settext("Parts per sec = "..tostring(ndiodes / l_elapsed_time)) + display.setcursor(2,1) + display.settext("Bin Count: ") + for l_i = 1, 7 do + display.settext(tostring(l_bins[l_i]).." ") + end --for + delay(5) + + -- Update the front panel display and restore modified settings. + smu.source.func = l_s_func + smu.source.autorangei = l_s_autorangei + smu.source.rangei = l_s_rangei + smu.source.leveli = l_s_leveli + smu.measure.autorangev = l_m_autorangev + smu.measure.rangev = l_m_rangev + display.clear() + display.screen = l_d_screen + +end --function DiodeTest + +print("FUNCTIONS CREATED") + +display.loadmenu.add("DiodeTest_Slow", "DiodeTest(smua, nil, 'SLOW')") +display.loadmenu.add("DiodeTest_Fast", "DiodeTest(smua, nil, 'FAST')") + +print("MENU ITEMS ADDED") + +DiodeTest(smua, nil, "SLOW") + diff --git a/TSP_Examples/2602/Diode_Slow/View This First.pdf b/TSP_Examples/2602/Diode_Slow/View This First.pdf new file mode 100644 index 0000000..2630426 Binary files /dev/null and b/TSP_Examples/2602/Diode_Slow/View This First.pdf differ diff --git a/TSP_Examples/2602/Resisitor_Fast/.vscode/settings.json b/TSP_Examples/2602/Resisitor_Fast/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Fast/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Fast/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Fast/ResistorFast.tsp b/TSP_Examples/2602/Resisitor_Fast/ResistorFast.tsp new file mode 100644 index 0000000..d6f2640 --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Fast/ResistorFast.tsp @@ -0,0 +1,348 @@ +--[[ +ResistorFast(): + +This program performs a resistance test on a 10kohm part. + +Required equipment: + +(1) Keithley 2602 System Sourcemeter(c) +(1) Keithley 8101-04-TRX Test Fixture +(2) Keithley 2600-DEMO-TRX cables + +Rev1: JAC 4.7.2005 +Rev2: Added Print Data Option + JAC 4.22.2005 + +]]-- + +------------------ Keithley TSP Function ------------------ +function ResTest(smu,irange,ilevel,srcdelay,vcmpl) + +--Source current on selected smu channel and measure voltage. +--Calculate and return resistance value. + +--Pass parameters: +-- smu is the smu channel selected for the test (A or B); smua is default +-- irange is source current range; 1mA default +-- ilevel is source current value; 500 ua default +-- srcdelay is the delay after source is set before the measurement is started; 0s default +-- vcmpl is the voltage compliance limit and measurement range; 10V default + + --default to smua if no smu specified + if smu == nil then smu = smua end + + --prompt for input parameters if missing from list + + if ilevel == nil then + ilevel = display.prompt("0.000E+00", " Amps", "Enter Test Current.", 500E-6,-1E-3,1E-3) + end --end if + + if irange == nil then irange = ilevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0,0,20) + end --end if + + if vcmpl == nil then + vcmpl = display.prompt("+0.000E+00", " Volts", "Enter Voltage Compliance.", 2,-40,40) + end --end if + + --Temporary variables used by this function + local l_vmeasured,l_isourced + + + --Configure source and measure settings + smu.source.func = smu.OUTPUT_DCAMPS + smu.source.rangei = irange + smu.source.leveli = ilevel + smu.source.limitv = vcmpl + smu.measure.rangev = vcmpl + + --wait before making measurement + delay(srcdelay) + + --measure current and voltage + l_isourced, l_vmeasured = smu.measure.iv() + + return l_vmeasured/l_isourced --Return quotient = resistance calculation + +end --function res_test() + + +function TestStatus(testvalue, lolim, hilim) + + --Temporary variables used by this function. + local l_status + local l_testfail + + if (testvalue >= lolim) and (testvalue <= hilim) then + l_status = "PASS" + l_testfail = false + else + l_status = "FAIL" + l_testfail = true + end --if + + return l_status,l_testfail + +end --function test_status() + + +function PartStatus(tst1fail) + + --Temporary variables used by this function. + local l_status = "GOOD" + + if tst1fail then l_status = "BAD" end + + return l_status + +end --function part_status() + + +function BinPart(tst1fail, bins) + + if tst1fail then --if first test fails increment bin + bins[2] = bins[2] + 1 + else + bins[1] = bins[1] + 1 --part is good + end --if + +end --function bin_part() + + +function DisplayTestStatus(testname,testvalue,teststatus,disp_delay) + + --This function displays individual test results on the front panel display. + + display.clear() + display.setcursor(1,1) + display.settext(testname) + delay(disp_delay) + display.settext(tostring(testvalue)) + delay(disp_delay) + display.setcursor(2,1) + display.settext("Test Status: "..teststatus) + delay(disp_delay) + +end --function DisplayTestStatus() + + +function DisplayPartStatus(partstatus,bins) + + --Temporary variables used by this function. + local l_i + + display.clear() + display.setcursor(1,1) + display.settext("Part Status: "..partstatus) + display.setcursor(2,1) + display.settext("Bin Counts: ") + + for l_i = 1,2 do + + display.settext(tostring(bins[l_i]).." ") + + end --for + +end --function DisplayPartStatus() + +function ResistorTest(smu,nresistors,speed, returndata) + + --[[This function performs a resistor test and the measurement + is compared to defined pass/fail limits. The results are displayed on the front + panel. + ]]-- + + --Default to smua if no smu specified + if smu == nil then smu = smua end + + --Prompt user for number of resistors + if nresistors == nil then + nresistors = display.prompt("0000"," Resistors", "Enter number of devices to test", 100, 1, 9999) + end + + if speed == nil then speed = "SLOW" end + + --Save settings in temporary variables so that they can be restored. + local l_s_func = smu.source.func + local l_s_autorangei = smu.source.autorangei + local l_s_rangei = smu.source.rangei + local l_m_autorangev = smu.measure.autorangev + local l_v_rangev = smu.measure.rangev + local l_d_screen = display.screen + + --Test inspection limits + local l_res_lolimit = 10.2E+3 + local l_res_hilimit = 9.8E+3 + + --Variables used to configure source and measure in res_test() + local l_res_isource_range = 1E-3 + local l_res_isource_level = 500E-6 + local l_res_source_delay = 0.1 --"SLOW" default + if speed == "FAST" then l_res_source_delay = 0 end + local l_res_vcmpl = 40 + + + --Variable used to configure measurement time + local l_res_nplc = 1 --"Slow" default + if speed == "FAST" then l_res_nplc = 0.001 end + + --Variable used to store number of devices to test + local l_nresistors = nresistors -- + + --Boolean flag used to select Autozero state + local l_azero_on = true --"Slow" default + if speed == "FAST" then l_azero_on = false end + + --Boolen flag used for display state (true == on, false == off) + local l_disp_on = true --"SLOW" is default + if speed == "FAST" then l_disp_on = false end + + --Display delay + local l_delay = 1 --"Slow" default + if speed == "FAST" then l_delay = 0 end + + --Variable to hold Print decision + local l_return_data = returndata + + --Tables used to hold test data and pass/fail + --local l_res_isourced = {} + --local l_res_vmeasured = {} + local l_res_calc = {} + local l_res_status = {} + local l_res_fail = {} + + --Table to hold good/bad part status for cumulative results of all tests + local l_part_status = {} + + --Table used to count simulated bin entries + local l_bins = {0,0} --intialize to 0 + + --Variables to hold timing information + local l_start_time,l_stop_time,l_elapsed_time + + --Counter + local l_i + + --**Initial 2602 Setup**-- + --2 wire sensing is used as default + + smu.reset() + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.levelv = 0 + smu.sense = smu.SENSE_LOCAL + smu.measure.nplc = l_res_nplc + + if l_azero_on then + smu.measure.autozero = smu.AUTOZERO_AUTO + else + smu.measure.autozero = smu.AUTOZERO_ONCE + end --end if + + digio.writeport(0) --Set unprotected bits to 0 + + errorqueue.clear() --Clear the error queue + + --**Run Test**-- + + if speed == "FAST" then + display.clear() + display.setcursor(1,1) + display.settext("Test in Progress") + display.setcursor(2,1) + display.settext("Testing "..tostring(l_nresistors).." Parts") + end --if + + timer.reset() + l_start_time = timer.measure.t() + smu.source.output = smu.OUTPUT_ON + + for l_i = 1,l_nresistors do + +--Retreive data + l_res_calc[l_i] = ResTest(smu,l_res_isource_range, l_res_isource_level,l_res_source_delay,l_res_vcmpl) + +--Print Data + if l_return_data == "yes" then + --print(l_return_data) + PrintData(l_i, l_res_calc[l_i])--pass variable to printdata() + end --if + +--Determine Pass/fail + l_res_status[l_i],l_res_fail[l_i] = TestStatus(l_res_calc[l_i],l_res_lolimit,l_res_hilimit) + +--Determine part status + l_part_status[l_i] = PartStatus(l_res_fail[l_i]) + + if l_disp_on then DisplayTestStatus("Ohms: ", l_res_calc[l_i],l_res_status[l_i],l_delay) end + + --Bin the part + BinPart(l_res_fail,l_bins) + + + if l_disp_on then DisplayPartStatus(l_part_status[l_i],l_bins) end + delay(3*l_delay) + + if l_part_status[l_i] == "GOOD" then + digio.writebit(2,1) --Set bit 2 Hi, DUT pass + delay(l_delay) + digio.writebit(2,0) --Set bit 2 Lo + else + digio.writebit(8,1) --Set bit 8 Hi, DUT fails + delay(l_delay) + digio.writebit(8,0) --Set bit 8 Lo + end --if + + end --for + + smu.source.output = smu.OUTPUT_OFF + + l_stop_time = timer.measure.t() + l_elapsed_time = l_stop_time - l_start_time + + display.clear() + display.setcursor(1,1) + display.settext("Parts per sec = "..string.format("%d",tostring(l_nresistors/l_elapsed_time))) + display.setcursor(2,1) + display.settext("Bin Count: ") + + for l_i = 1,2 do + display.settext(tostring(l_bins[l_i].." ")) + end --for + delay(5) + + display.clear() + + --Update display and restore settings + smu.source.func = l_s_func + smu.source.autorangei = l_s_autorangei + smu.source.leveli = 0 + smu.source.rangei = l_s_rangei + smu.measure.autorangev = l_m_autorangev + smu.measure.rangev = l_v_rangev + display.screen = l_d_screen + +end --function ResistorTest() + +function PrintData(i,data) +--print data to immediate window + --Local Variable + local l_i = i --Loop count + local l_data = data + + if l_i == 1 then + print("Readings (Ohms):") + end --for + + print(l_data) + +end --function printdata() +display.loadmenu.add("ResistorTest_Slow","ResistorTest(smua,nil,'SLOW','no')") +display.loadmenu.add("ResistorTest_Fast", "ResistorTest(smua,nil,'FAST','no')") + +ResistorTest(smua, nil, 'FAST','yes') + + + --delay(disp_delay) + \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Fast/View This First.pdf b/TSP_Examples/2602/Resisitor_Fast/View This First.pdf new file mode 100644 index 0000000..04bb7c7 Binary files /dev/null and b/TSP_Examples/2602/Resisitor_Fast/View This First.pdf differ diff --git a/TSP_Examples/2602/Resisitor_Slow/.vscode/settings.json b/TSP_Examples/2602/Resisitor_Slow/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Slow/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Slow/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Slow/ResistorSlow.tsp b/TSP_Examples/2602/Resisitor_Slow/ResistorSlow.tsp new file mode 100644 index 0000000..48a6067 --- /dev/null +++ b/TSP_Examples/2602/Resisitor_Slow/ResistorSlow.tsp @@ -0,0 +1,344 @@ +--[[ +ResistorSlow(): + +This program performs a resistance test on a 10kohm part. + +Required equipment: + +(1) Keithley 2602 System Sourcemeter(c) +(1) Keithley 8101-04-TRX Test Fixture +(2) Keithley 2600-DEMO-TRX cables + +Rev1: JAC 4.7.2005 +Rev2: Added Print Data Option + JAC 4.22.2005 + +]]-- + +------------------ Keithley TSP Function ------------------ +function res_test(smu,irange,ilevel,srcdelay,vcmpl) + +--Source current on selected smu channel and measure voltage. +--Calculate and return resistance value. + +--Pass parameters: +-- smu is the smu channel selected for the test (A or B); smua is default +-- irange is source current range; 1mA default +-- ilevel is source current value; 500 ua default +-- srcdelay is the delay after source is set before the measurement is started; 0s default +-- vcmpl is the voltage compliance limit and measurement range; 10V default + + --default to smua if no smu specified + if smu == nil then smu = smua end + + --prompt for input parameters if missing from list + + if ilevel == nil then + ilevel = display.prompt("0.000E+00", " Amps", "Enter Test Current.", 500E-6,-1E-3,1E-3) + end --end if + + if irange == nil then irange = ilevel end + + if srcdelay == nil then + srcdelay = display.prompt("00.000", " Seconds", "Enter Source Delay.", 0,0,20) + end --end if + + if vcmpl == nil then + vcmpl = display.prompt("+0.000E+00", " Volts", "Enter Voltage Compliance.", 2,-40,40) + end --end if + + --Temporary variables used by this function + local l_vmeasured,l_isourced + + + --Configure source and measure settings + smu.source.func = smu.OUTPUT_DCAMPS + smu.source.rangei = irange + smu.source.leveli = ilevel + smu.source.limitv = vcmpl + smu.measure.rangev = vcmpl + + --wait before making measurement + delay(srcdelay) + + --measure current and voltage + l_isourced, l_vmeasured = smu.measure.iv() + + return l_vmeasured/l_isourced --Return quotient = resistance calculation + +end --function res_test() + + +function test_status(testvalue, lolim, hilim) + + --Temporary variables used by this function. + local l_status + local l_testfail + + if (testvalue >= lolim) and (testvalue <= hilim) then + l_status = "PASS" + l_testfail = false + else + l_status = "FAIL" + l_testfail = true + end --if + + return l_status,l_testfail + +end --function test_status() + + +function part_status(tst1fail) + + --Temporary variables used by this function. + local l_status = "GOOD" + + if tst1fail then l_status = "BAD" end + + return l_status + +end --function part_status() + + +function bin_part(tst1fail, bins) + + if tst1fail then --if first test fails increment bin + bins[2] = bins[2] + 1 + else + bins[1] = bins[1] + 1 --part is good + end --if + +end --function bin_part() + + +function DisplayTestStatus(testname,testvalue,teststatus,disp_delay) + + --This function displays individual test results on the front panel display. + + display.clear() + display.setcursor(1,1) + display.settext(testname) + delay(disp_delay) + display.settext(tostring(testvalue)) + delay(disp_delay) + display.setcursor(2,1) + display.settext("Test Status: "..teststatus) + delay(disp_delay) + +end --function DisplayTestStatus() + + +function DisplayPartStatus(partstatus,bins) + + --Temporary variables used by this function. + local l_i + + display.clear() + display.setcursor(1,1) + display.settext("Part Status: "..partstatus) + display.setcursor(2,1) + display.settext("Bin Counts: ") + + for l_i = 1,2 do + + display.settext(tostring(bins[l_i]).." ") + + end --for + +end --function DisplayPartStatus() + +function ResistorTest(smu,nresistors,speed, returndata) + + --[[This function performs a resistor test and the measurement + is compared to defined pass/fail limits. The results are displayed on the front + panel. + ]]-- + + --Default to smua if no smu specified + if smu == nil then smu = smua end + + --Prompt user for number of resistors + if nresistors == nil then + nresistors = display.prompt("0000"," Resistors", "Enter number of devices to test", 1, 1, 9999) + end + + if speed == nil then speed = "SLOW" end + + --Save settings in temporary variables so that they can be restored. + local l_s_func = smu.source.func + local l_s_autorangei = smu.source.autorangei + local l_s_rangei = smu.source.rangei + local l_m_autorangev = smu.measure.autorangev + local l_v_rangev = smu.measure.rangev + local l_d_screen = display.screen + + --Test inspection limits + local l_res_lolimit = 10.2E+3 + local l_res_hilimit = 9.8E+3 + + --Variables used to configure source and measure in res_test() + local l_res_isource_range = 1E-3 + local l_res_isource_level = 500E-6 + local l_res_source_delay = 0.1 --"SLOW" default + if speed == "FAST" then l_res_source_delay = 0 end + local l_res_vcmpl = 40 + + --Variable used to configure measurement time + local l_res_nplc = 1 --"Slow" default + if speed == "FAST" then l_res_nplc = 0.001 end + + --Variable used to store number of devices to test + local l_nresistors = nresistors -- + + --Boolean flag used to select Autozero state + local l_azero_on = true --"Slow" default + if speed == "FAST" then l_azero_on = false end + + --Boolen flag used for display state (true == on, false == off) + local l_disp_on = true --"SLOW" is default + if speed == "FAST" then l_disp_on = false end + + --Display delay + local l_delay = 1 --"Slow" default + if speed == "FAST" then l_delay = 0 end + + --Variable to hold Print decision + local l_return_data = returndata + + --Tables used to hold test data and pass/fail + --local l_res_isourced = {} + --local l_res_vmeasured = {} + local l_res_calc = {} + local l_res_status = {} + local l_res_fail = {} + + --Table to hold good/bad part status for cumulative results of all tests + local l_part_status = {} + + --Table used to count simulated bin entries + local l_bins = {0,0} --intialize to 0 + + --Variables to hold timing information + local l_start_time,l_stop_time,l_elapsed_time + + --Counter + local l_i + + --**Initial 2602 Setup**-- + --2 wire sensing is used as default + + smu.reset() + smu.source.func = smu.OUTPUT_DCVOLTS + smu.source.levelv = 0 + smu.sense = smu.SENSE_LOCAL + smu.measure.nplc = l_res_nplc + + if l_azero_on then + smu.measure.autozero = smu.AUTOZERO_AUTO + else + smu.measure.autozero = smu.AUTOZERO_ONCE + end --end if + + + digio.writeport(0) --Set unprotected bits to 0 + + errorqueue.clear() --Clear the error queue + + --**Run Test**-- + + if speed == "FAST" then + display.clear() + display.setcursor(1,1) + display.settext("Test in Progress") + display.setcursor(2,1) + display.settext("Testing "..tostring(l_nresistors).." Parts") + end --if + + timer.reset() + l_start_time = timer.measure.t() + smu.source.output = smu.OUTPUT_ON + + for l_i = 1,l_nresistors do + +--Retreive data + l_res_calc[l_i] = res_test(smu,l_res_isource_range, l_res_isource_level,l_res_source_delay,l_res_vcmpl) + +--Print Data + if l_return_data == "yes" then + --print(l_return_data) + printdata(l_i, l_res_calc[l_i])--pass variable to printdata() + end --if + +--Determine Pass/fail + l_res_status[l_i],l_res_fail[l_i] = test_status(l_res_calc[l_i],l_res_lolimit,l_res_hilimit) + +--Determine part status + l_part_status[l_i] = part_status(l_res_fail[l_i]) + + if l_disp_on then DisplayTestStatus("Ohms: ", l_res_calc[l_i],l_res_status[l_i],l_delay) end + + --Bin the part + bin_part(l_res_fail,l_bins) + + + if l_disp_on then DisplayPartStatus(l_part_status[l_i],l_bins) end + delay(3*l_delay) + + if l_part_status[l_i] == "GOOD" then + digio.writebit(2,1) --Set bit 2 Hi, DUT pass + delay(l_delay) + digio.writebit(2,0) --Set bit 2 Lo + else + digio.writebit(8,1) --Set bit 8 Hi, DUT fails + delay(l_delay) + digio.writebit(8,0) --Set bit 8 Lo + end --if + + end --for + + smu.source.output = smu.OUTPUT_OFF + + l_stop_time = timer.measure.t() + l_elapsed_time = l_stop_time - l_start_time + + for l_i = 1,2 do + display.settext(tostring(l_bins[l_i].." ")) + end --for + delay(5) + + display.clear() + + --Update display and restore settings + smu.source.func = l_s_func + smu.source.autorangei = l_s_autorangei + smu.source.leveli = 0 + smu.source.rangei = l_s_rangei + smu.measure.autorangev = l_m_autorangev + smu.measure.rangev = l_v_rangev + display.screen = l_d_screen + +end --function ResistorTest() + +function printdata(i,data) +--print data to immediate window + --Local Variable + local l_i = i --Loop count + local l_data = data + + if l_i == 1 then + print("Readings (Ohms):") + end --for + + print(l_data) + +end --function printdata() + + +display.loadmenu.add("ResistorTest_Slow","ResistorTest(smua,nil,'SLOW','no')") +display.loadmenu.add("ResistorTest_Fast", "ResistorTest(smua,nil,'FAST','no')") + +ResistorTest(smua, nil, 'SLOW','yes') + + + --delay(disp_delay) + \ No newline at end of file diff --git a/TSP_Examples/2602/Resisitor_Slow/View This First.pdf b/TSP_Examples/2602/Resisitor_Slow/View This First.pdf new file mode 100644 index 0000000..9db3190 Binary files /dev/null and b/TSP_Examples/2602/Resisitor_Slow/View This First.pdf differ diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/settings.json b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..86a404f --- /dev/null +++ b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,15 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2651A" + }, + "node2":{ + "model": "2651A" + }, + "node3":{ + "model": "2601B" + } + }, + "self": "2651A" +} \ No newline at end of file diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2651A/Combining_SMUs_for_100A/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/KE2651A_Combining_SMUs_for_100A.tsp b/TSP_Examples/2651A/Combining_SMUs_for_100A/KE2651A_Combining_SMUs_for_100A.tsp new file mode 100644 index 0000000..186183b --- /dev/null +++ b/TSP_Examples/2651A/Combining_SMUs_for_100A/KE2651A_Combining_SMUs_for_100A.tsp @@ -0,0 +1,285 @@ +--[[ + Title: Combining SMUs for 100A Example + + Description: This script is designed to perform an Rds(on) sweep + on a power MOSFET device. It combines two 2651A SMUs in parallel to + perform a current sweep up to 100A. Data collected from the sweep + is then returned in a Microsoft Excel compatible format for plotting + and analysis. + + Equipment Needed: + 2x 2651A + 1x 26xxA + 2x TSP-Link Cable + + TSP-Link Configuration: + ----------------------- + Unit | Node # + 2651A #1 | 1 + 2651A #2 | 2 + 26xxA | 3 + + Master Node (PC Interface): Node 1 +]] + +--[[ + Name: DualSmuRdson(gateLevel, dstart, dstop, dsteps, pulseWidth, pulsePeriod, pulseLimit) + Description: + This function uses two 2651A SMUs to perform a pulsed Rds(on) sweep + with currents up to 100A. + + Parameters: + gateLevel: The gate level to be used during the sweep + dstart: The starting current level of the drain sweep + dstop: The ending current level of the drain sweep + dsteps: The number of steps in the drain sweep + pulseWidth: The width of the drain pulse in seconds + pulsePeriod: The time from the start of one drain pulse to + the next in seconds + pulseLimit: The voltage limit of the drain pulse in volts + Note: Actual pulse limit will be 10% lower + than setting to protect SMUs in a compliance + condition + + Example Usage: + DualSmuRdson(10, 1, 100, 100, 500e-6, 50e-3, 10) +]] +function DualSmuRdson(gateLevel, dstart, dstop, dsteps, pulseWidth, pulsePeriod, pulseLimit) + tsplink.reset() + reset() + + -- Configure 2651A #1 (Drain SMU 1) + ----------------------------------- + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + smua.sense = smua.SENSE_REMOTE + smua.source.offmode = smua.OUTPUT_NORMAL + smua.source.offfunc = smua.OUTPUT_DCVOLTS + smua.source.offlimiti = 1e-3 -- Set off limit + -- SMU #1 will be a 0V voltage source with 1mA limit when its output + -- is turned off. SMU #2 will be a 0A current source with 10V limit + -- when the output is turned off. These settings keep the parallel + -- combination safe in case one SMU is turned off by accident. + + smua.source.rangei = math.max(math.abs(dstart / 2), + math.abs(dstop / 2)) + smua.source.leveli = 0 -- Sets the DC bias level + smua.source.limitv = 9 -- Sets the DC bias limit + -- SMU #2 will have a voltage limit of 10V. By setting the voltage + -- limit 10% lower than that of SMU #2's we can ensure that only one + -- of the two SMUs will ever go into compliance and become a voltage + -- source. This is desirable because if both SMUs went into + -- compliance, there would be two voltage sources in parallel which + -- is an unsafe condition. + + smua.measure.nplc = 0.005 + smua.measure.rangev = pulseLimit + smua.measure.autozero = smua.AUTOZERO_ONCE + smua.measure.delay = (pulseWidth - + ((1 / localnode.linefreq) * smua.measure.nplc)) - 20e-6 + -- Set the delay so that the measurement is near the end of the pulse + + -- Prepare the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 1 + + -- Configure TSP-Link Trigger 1 + tsplink.trigger[1].clear() + tsplink.trigger[1].mode = tsplink.TRIG_FALLING + tsplink.trigger[1].stimulus = trigger.timer[1].EVENT_ID + -- TSP-Link Trigger 1 is used to signal 2651A #2 to pulse + + -- Timer 1 controls the pulse period by triggering the pulse to begin + trigger.timer[1].count = dsteps - 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + trigger.timer[1].clear() + + -- Timer 2 controls the pulse width + trigger.timer[2].count = 1 + trigger.timer[2].delay = pulseWidth - 3e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = smua.trigger.SOURCE_COMPLETE_EVENT_ID + trigger.timer[2].clear() + + -- Configure SMU Trigger Model for Sweep + -- Each unit will source half the current so divide the start + -- and stop values by 2 + smua.trigger.source.lineari(dstart / 2, dstop / 2, dsteps) + smua.trigger.source.limitv = pulseLimit - (pulseLimit * 0.1) + -- Again, keep the limit SMU #1 lower than the limit of SMU #2 + -- to prevent parallel V-sources + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.measure.action = smua.ENABLE + + -- Return to the bias level at the end of the pulse/sweep + smua.trigger.endpulse.action = smua.SOURCE_IDLE + smua.trigger.endsweep.action = smua.SOURCE_IDLE + + smua.trigger.count = dsteps + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = 0 + smua.trigger.endpulse.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.source.action = smua.ENABLE + + -- Configure 2651A #2 (Drain SMU 2) + ----------------------------------- + node[2].smua.reset() + node[2].smua.source.func = node[2].smua.OUTPUT_DCAMPS + node[2].smua.sense = node[2].smua.SENSE_REMOTE + node[2].smua.source.offmode = node[2].smua.OUTPUT_NORMAL + node[2].smua.source.offfunc = node[2].smua.OUTPUT_DCAMPS + node[2].smua.source.offlimitv = 10 -- Set off limit + -- SMU will be a 0A current source with 10V limit when output + -- is turned off + node[2].smua.source.rangei = + math.max(math.abs(dstart / 2), math.abs(dstop / 2)) + node[2].smua.source.leveli = 0 -- Sets the DC bias level + node[2].smua.source.limitv = 10 -- Sets the DC bias limit + + node[2].smua.measure.nplc = 0.005 + node[2].smua.measure.rangev = pulseLimit + node[2].smua.measure.autozero = node[2].smua.AUTOZERO_ONCE + node[2].smua.measure.delay = (pulseWidth - + ((1 / node[2].linefreq) * node[2].smua.measure.nplc)) - 20e-6 + -- Set the delay so that the measurement is near the end of the pulse + + -- Prepare the reading buffers + node[2].smua.nvbuffer1.clear() + node[2].smua.nvbuffer1.collecttimestamps = 1 + node[2].smua.nvbuffer1.collectsourcevalues = 1 + node[2].smua.nvbuffer2.clear() + node[2].smua.nvbuffer2.collecttimestamps = 1 + node[2].smua.nvbuffer2.collectsourcevalues = 1 + + -- Configure TSP-Link Trigger 1 + node[2].tsplink.trigger[1].clear() + node[2].tsplink.trigger[1].mode = + node[2].tsplink.TRIG_FALLING + + -- Timer 1 controls the pulse width + node[2].trigger.timer[1].count = 1 + node[2].trigger.timer[1].delay = pulseWidth - 3e-6 + node[2].trigger.timer[1].passthrough = false + node[2].trigger.timer[1].stimulus = + node[2].smua.trigger.SOURCE_COMPLETE_EVENT_ID + node[2].trigger.timer[1].clear() + + -- Configure SMU Trigger Model for Sweep + node[2].smua.trigger.source.lineari(dstart / 2, dstop / 2, dsteps) + node[2].smua.trigger.source.limitv = pulseLimit + node[2].smua.trigger.measure.iv(node[2].smua.nvbuffer1, + node[2].smua.nvbuffer2) + node[2].smua.trigger.measure.action = node[2].smua.ENABLE + + -- Return the output to the bias level at the end of the pulse/sweep + node[2].smua.trigger.endpulse.action = node[2].smua.SOURCE_IDLE + node[2].smua.trigger.endsweep.action = node[2].smua.SOURCE_IDLE + node[2].smua.trigger.count = dsteps + node[2].smua.trigger.arm.stimulus = 0 + node[2].smua.trigger.source.stimulus = + node[2].tsplink.trigger[1].EVENT_ID + node[2].smua.trigger.measure.stimulus = 0 + node[2].smua.trigger.endpulse.stimulus = + node[2].trigger.timer[1].EVENT_ID + node[2].smua.trigger.source.action = node[2].smua.ENABLE + + -- Configure the 26xxA (Gate SMU) + --------------------------------- + node[3].smua.reset() + node[3].smua.source.func = node[3].smua.OUTPUT_DCVOLTS + node[3].smua.sense = node[3].smua.SENSE_REMOTE + node[3].smua.source.levelv = gateLevel + node[3].smua.source.highc = 1 + -- If you find your gate oscillating even with a dampening resistor + -- in place, then try enabling high-C mode to help stabilize the gate. + + -- Prepare the reading buffers + node[3].smua.nvbuffer1.clear() + node[3].smua.nvbuffer1.collectsourcevalues = 1 + node[3].smua.nvbuffer2.clear() + node[3].smua.nvbuffer2.collectsourcevalues = 1 + + -------------------------- + -- Ready to begin the test + -------------------------- + -- Outputs on + node[3].smua.source.output = 1 + node[2].smua.source.output = 1 + smua.source.output = 1 + + -- Give the Gate some time to settle before starting the sweep + delay(0.001) + node[3].smua.measure.iv(node[3].smua.nvbuffer1, + node[3].smua.nvbuffer2) + + -- Start 2651A #2's Trigger Model + node[2].smua.trigger.initiate() + -- Start 2651A #1's Trigger Model + smua.trigger.initiate() + -- Wait until test is comeplete + waitcomplete() + + -- Outputs off + node[3].smua.source.output = 0 + smua.source.output = 0 + node[2].smua.source.output = 0 + + -- Print Back Data + PrintDualSmuRdsonData() +end + + +--[[ + Function: PrintDualSmuRdsonData() + Description: + This function processes the data stored in the SMU reading buffers + by function DualSmuRdson() and prints back the individual SMU data as + well as the combined SMU data and Rds(on) readings in a format that is + copy and paste compatible with Microsoft Excel. +]] +function PrintDualSmuRdsonData() + -- Print the Gate SMU readings + print("Gate SMU\r\nSource Value\tVoltage\tCurrent") + print(string.format("%0.2f\t%g\t%g\r\n", + node[3].smua.nvbuffer1.sourcevalues[1], + node[3].smua.nvbuffer2[1], + node[3].smua.nvbuffer1[1])) + + -- Print column headers + print("Timestamp\tSource Value\tVoltage 1\tCurrent 1\tVoltage 2\tCurrent 2\tVoltage\tCurrent\tRds(on)") + -- Loop through the reading buffer printing one row at a time + for i = 1,smua.nvbuffer1.n do + -- Combined Source Level = SMU1 source level + SMU2 source level + sourceLevel = smua.nvbuffer1.sourcevalues[i] + + node[2].smua.nvbuffer1.sourcevalues[i] + + -- Combined Voltage = Average(SMU1 Voltage reading, + -- SMU2 Voltage reading) + combinedVoltage = (smua.nvbuffer2[i] + node[2].smua.nvbuffer2[i]) / 2 + + -- Combined Current = SMU1 Current reading + SMU2 Current reading + combinedCurrent = smua.nvbuffer1[i] + node[2].smua.nvbuffer1[i] + + -- Rds(on) = Combined Voltage / Combined Current + rdson = combinedVoltage / combinedCurrent + + -- Print a row of data + print(string.format("%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g\t%g", + smua.nvbuffer1.timestamps[i], + sourceLevel, + smua.nvbuffer2[i], + smua.nvbuffer1[i], + node[2].smua.nvbuffer2[i], + node[2].smua.nvbuffer1[i], + combinedVoltage, + combinedCurrent, + rdson)) + end +end diff --git a/TSP_Examples/2651A/Combining_SMUs_for_100A/View This First.pdf b/TSP_Examples/2651A/Combining_SMUs_for_100A/View This First.pdf new file mode 100644 index 0000000..e3a983c Binary files /dev/null and b/TSP_Examples/2651A/Combining_SMUs_for_100A/View This First.pdf differ diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/settings.json b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..d5c438e --- /dev/null +++ b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2651A" +} \ No newline at end of file diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2651A/Fast_ADC_Usage/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/KE2651A_Fast ADC Usage.tsp b/TSP_Examples/2651A/Fast_ADC_Usage/KE2651A_Fast ADC Usage.tsp new file mode 100644 index 0000000..1481339 --- /dev/null +++ b/TSP_Examples/2651A/Fast_ADC_Usage/KE2651A_Fast ADC Usage.tsp @@ -0,0 +1,246 @@ +--[[ + Title: Fast ADC Usage + + Description: This script is designed to output pulses and + capture both the current and the voltage of the pulse using + the fast ADC of the Model 2651A High Power System SourceMeter + instrument. + + Equipment Needed: + 1x 2651A +]] + +--[[ + Name: CapturePulseV(pulseLevel, pulseWidth, pulseLimit, + numPulses) + Description: + This function outputs voltage pulses with a 1% duty cycle and + performs measurements using the fast ADC to capture each pulse in + its entirety. At the conclusion of the pulse train, the data is + returned to the instrument console in a Microsoft Excel + compatible format. + + Parameters: + pulseLevel: The voltage level of the pulse in volts + pulseWidth: The width of the pulse in seconds + 100e-6 <= pulseWidth <= 4e-3 + pulseLimit: The current limit of the pulse in amps + numPulses: The number of pulses to output + + Example Usage: + CapturePulseV(5, 300e-6, 50, 5) +]] +function CapturePulseV(pulseLevel, pulseWidth, pulseLimit, numPulses) + if (numPulses == nil) then numPulses = 1 end + + -- Configure the SMU + reset() + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + smua.sense = smua.SENSE_REMOTE + smua.source.rangev = pulseLevel + smua.source.levelv = 0 -- The bias level + smua.source.limiti = 5 -- The DC Limit + smua.measure.autozero = smua.AUTOZERO_ONCE + + -- Use a measure range that is as large as the biggest + -- possible pulse + smua.measure.rangei = pulseLimit + smua.measure.rangev = pulseLevel + + -- Select the fast ADC for measurements + smua.measure.adc = smua.ADC_FAST + + -- Set the time between measurements. 1us is the smallest + smua.measure.interval = 1e-6 + + -- Set the measure count to be 1.25 times the width of the pulse + -- to ensure we capture the entire pulse plus falling edge. + smua.measure.count = + (pulseWidth / smua.measure.interval) * 1.25 + + -- Prepare the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 0 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 0 + -- Can't use source values with async measurements + + -- Configure the Pulsed Sweep setup + ----------------------------------- + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPulses - 1 + -- -- 1% Duty Cycle + trigger.timer[1].delay = pulseWidth / 0.01 + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + + -- Timer 2 controls the pulse width + trigger.timer[2].count = 1 + trigger.timer[2].delay = pulseWidth - 3e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = + smua.trigger.SOURCE_COMPLETE_EVENT_ID + + + -- Configure SMU Trigger Model for Sweep/Pulse Output + ----------------------------------------------------- + -- Pulses will all be the same level so set start and stop to + -- the same value and the number of points in the sweep to 2 + smua.trigger.source.linearv(pulseLevel, pulseLevel, 2) + smua.trigger.source.limiti = pulseLimit + smua.trigger.measure.action = smua.ASYNC + -- We want to start the measurements before the source action takes + -- place so we must configure the ADC to operate asynchronously of + -- the rest of the SMU trigger model actions + + -- Measure I and V during the pulse + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + + -- Return the output to the bias level at the end of the pulse/sweep + smua.trigger.endpulse.action = smua.SOURCE_IDLE + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPulses + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.endpulse.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.source.action = smua.ENABLE + + + smua.source.output = 1 + smua.trigger.initiate() + waitcomplete() + smua.source.output = 0 + + PrintPulseData() +end + +--[[ + Name: CapturePulseI(pulseLevel, pulseWidth, pulseLimit, + numPulses) + Description: + This function outputs current pulses with a 1% duty cycle and + performs measurements using the fast ADC to capture each pulse in + its entirety. At the conclusion of the pulse train, the data is + returned to the instrument console in a Microsoft Excel compatible + format. + + Parameters: + pulseLevel: The current level of the pulse in amps + pulseWidth: The width of the pulse in seconds + 100e-6 <= pulseWidth <= 4e-3 + pulseLimit: The voltage limit of the pulse in volts + numPulses: The number of pulses to output + + Example Usage: + CapturePulseI(50, 300e-6, 10, 5) +]] +function CapturePulseI(pulseLevel, pulseWidth, pulseLimit, numPulses) + if (numPulses == nil) then + numPulses = 1 + end + + -- Configure the SMU + reset() + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + smua.sense = smua.SENSE_REMOTE + smua.source.rangei = pulseLevel + smua.source.leveli = 0 -- The bias level + smua.source.limitv = 10 -- The DC Limit + smua.measure.autozero = smua.AUTOZERO_ONCE + + -- Use a measure range that is as large as the biggest + -- possible pulse + smua.measure.rangev = pulseLimit + smua.measure.rangei = pulseLevel + + -- Select the fast ADC for measurements + smua.measure.adc = smua.ADC_FAST + + -- Set the time between measurements. 1us is the smallest + smua.measure.interval = 1e-6 + + -- Set the measure count to be 1.25 times the width of the pulse + -- to ensure we capture the entire pulse plus falling edge. + smua.measure.count = + (pulseWidth / smua.measure.interval) * 1.25 + + -- Prepare the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 0 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 0 + -- Can't use source values with async measurements + + -- Configure the Pulsed Sweep setup + ----------------------------------- + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPulses - 1 + -- 1% Duty Cycle + trigger.timer[1].delay = pulseWidth / 0.01 + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + + -- Timer 2 controls the pulse width + trigger.timer[2].count = 1 + trigger.timer[2].delay = pulseWidth - 3e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = + smua.trigger.SOURCE_COMPLETE_EVENT_ID + + + -- Configure SMU Trigger Model for Sweep/Pulse Output + ----------------------------------------------------- + -- Pulses will all be the same level so set start and stop to + -- the same value and the number of points in the sweep to 2 + smua.trigger.source.lineari(pulseLevel, pulseLevel, 2) + smua.trigger.source.limitv = pulseLimit + smua.trigger.measure.action = smua.ASYNC + -- We want to start the measurements before the source action takes + -- place so we must configure the ADC to operate asynchronously of + -- the rest of the SMU trigger model actions + + -- Measure I and V during the pulse + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + + -- Return the output to the bias level at the end of the pulse + smua.trigger.endpulse.action = smua.SOURCE_IDLE + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPulses + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.endpulse.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.source.action = smua.ENABLE + + + smua.source.output = 1 + smua.trigger.initiate() + waitcomplete() + smua.source.output = 0 + + PrintPulseData() +end + +--[[ + Name: PrintPulseData() + Description; + This function prints the data contained in smua.nvbuffer1 and + smua.nvbuffer2 in an format that is copy and paste compatible with + Microsoft Excel. +]] +function PrintPulseData() + print("Timestamp\tVoltage\tCurrent") + for i=1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", + smua.nvbuffer1.timestamps[i], + smua.nvbuffer2[i], + smua.nvbuffer1[i])) + end +end diff --git a/TSP_Examples/2651A/Fast_ADC_Usage/View This First.pdf b/TSP_Examples/2651A/Fast_ADC_Usage/View This First.pdf new file mode 100644 index 0000000..e47d177 Binary files /dev/null and b/TSP_Examples/2651A/Fast_ADC_Usage/View This First.pdf differ diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/settings.json b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..4d1cb8e --- /dev/null +++ b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2651A" + }, + "node2":{ + "model": "2601B" + } + }, + "self": "2651A" +} \ No newline at end of file diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2651A/MOSFET_IV_Curves/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/KE2651A_MOSFET_IV_Curves.tsp b/TSP_Examples/2651A/MOSFET_IV_Curves/KE2651A_MOSFET_IV_Curves.tsp new file mode 100644 index 0000000..097f3f2 --- /dev/null +++ b/TSP_Examples/2651A/MOSFET_IV_Curves/KE2651A_MOSFET_IV_Curves.tsp @@ -0,0 +1,220 @@ +--[[ + Title: IV Curves Example Script + + Description: This script will perform a series of IV Curves on a + MOSFET or IGBT device and will return the data in a Microsoft Excel + compatible format for graphing and analysis. + + TSP-Link Configuration: + Node 1: 2651A + Node 2: 26xxA + + Master Node: Node 1 +]] + +--[[ + IV_Curves(gstart, gstop, gsteps, dstart, dstop, dsteps, pulseWidth, pulsePeriod, pulseLimit) + + Description: This function will perform a series of pulsed sweeps + on a MOSFET or IGBT device to generate a series of IV Curves that + characterize the device. Note: To avoid device oscillations, a + series resistor on the gate terminal of the device may be required. + + Parameters: + gstart: The starting voltage of the gate sweep + gstop: The ending voltage of the gate sweep + gsteps: The number of steps in the gate sweep + dstart: The starting voltage of the drain sweep + dstop: The ending voltage of the drain sweep + dsteps: The number of steps in the drain sweep + pulseWidth: The width of the drain pulse in seconds + pulsePeriod:The time in seconds between the start of consecutive drain pulses in the sweep + pulseLimit: The current limit in Amps of the drain pulse + + Example Usage: + IV_Curves(5, 9, 5, 0, 10, 21, 300e-6, 30e-3, 50) +--]] +function IV_Curves(gstart, gstop, gsteps, dstart, dstop, dsteps, pulseWidth, pulsePeriod, pulseLimit) + reset() + tsplink.reset() + + -- Configure the Drain SMU(2651A) + --------------------------------- + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + smua.sense = smua.SENSE_REMOTE + + smua.source.rangev = math.max(math.abs(dstart), math.abs(dstop)) + -- Select the source range that is large enough to fit all values of the sweep + smua.source.levelv = 0 -- Sets the drain bias level + smua.source.limiti = 5 + + smua.measure.rangev = smua.source.rangev + smua.measure.rangei = (pulseLimit == "off") and 50 or pulseLimit + -- Select a measure range large enough to fit pulses up to the current limit + + smua.measure.autozero = smua.AUTOZERO_ONCE + smua.measure.nplc = 0.001 + -- NPLC can be increased to improve measurement accuracy. + -- However, it should remain small enough to fit the measurement + -- within the width of the settled part of the pulse. + smua.measure.delay = (pulseWidth - ((1/localnode.linefreq) * smua.measure.nplc)) - 50e-6 + -- Set the measure delay so that the measurement is + -- taken at the end of the pulse before the falling edge + + -- Timer 1 controls the pulse period + trigger.timer[1].count = (dsteps <= 1) and 1 or (dsteps - 1) + -- If dsteps <= 1 then use 1 for the count else use dsteps - 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = tsplink.trigger[1].EVENT_ID + trigger.timer[1].clear() + + -- Timer 2 controls the pulse width + trigger.timer[2].count = 1 + trigger.timer[2].delay = pulseWidth - 3e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = smua.trigger.SOURCE_COMPLETE_EVENT_ID + trigger.timer[2].clear() + + -- Configure Drain SMU(2651A) trigger model + smua.trigger.source.linearv(dstart, dstop, dsteps) + smua.trigger.source.limiti = pulseLimit + smua.trigger.measure.action = 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.arm.count = gsteps + smua.trigger.count = dsteps + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = 0 + smua.trigger.endpulse.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.source.action = smua.ENABLE + + -- Configure TSP-Link Triggers + tsplink.trigger[1].clear() + tsplink.trigger[1].mode = tsplink.TRIG_SYNCHRONOUSM + tsplink.trigger[1].stimulus = smua.trigger.ARMED_EVENT_ID + -- TSP-Link Trigger 1 is used by the 2651A to command the 26xxA + -- to step the gate and for the 26xxA to report to the 2651A + -- that it has completed the step. + + tsplink.trigger[2].clear() + tsplink.trigger[2].mode = tsplink.TRIG_FALLING + tsplink.trigger[2].stimulus = smua.trigger.SWEEP_COMPLETE_EVENT_ID + -- TSP-Link Trigger 2 is used by the 2651A to command the 26xxA that + -- it has completed the drain sweep and that the 26xxA continue. + + -- Prepare the Drain SMU (2651A) reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collectsourcevalues = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collectsourcevalues = 1 + + + -- Configure the Gate SMU(26xxA) + -------------------------------- + node[2].smua.reset() + node[2].smua.source.func = node[2].smua.OUTPUT_DCVOLTS + node[2].smua.sense = node[2].smua.SENSE_REMOTE + node[2].smua.source.levelv = 0 + node[2].smua.source.limiti = 100e-3 + node[2].smua.measure.delay = 300e-6 -- Give gate 300us to settle + -- Do not need to configure any additional measure settings. + -- Timing is not critical on the gate so autorange will do. + + node[2].smua.source.highc = 0 + -- If you find the gate to be unstable even with a gate resistor in place + -- changing highc to 1 can improve stability. + + -- Configure Gate SMU(26xxA) Trigger Model + node[2].smua.trigger.source.linearv(gstart, gstop, gsteps) + node[2].smua.trigger.source.limiti = 100e-3 + node[2].smua.trigger.measure.action = node[2].smua.ENABLE + node[2].smua.trigger.measure.iv(node[2].smua.nvbuffer1, node[2].smua.nvbuffer2) + node[2].smua.trigger.endpulse.action = smua.SOURCE_HOLD + node[2].smua.trigger.endsweep.action = smua.SOURCE_IDLE + node[2].smua.trigger.count = gsteps + node[2].smua.trigger.arm.stimulus = 0 + node[2].smua.trigger.source.stimulus = node[2].tsplink.trigger[1].EVENT_ID + node[2].smua.trigger.measure.stimulus = 0 + node[2].smua.trigger.endpulse.stimulus = node[2].tsplink.trigger[2].EVENT_ID + node[2].smua.trigger.source.action = smua.ENABLE + + -- Configure Model 26xxA TSP-Link Triggers + node[2].tsplink.trigger[1].clear() + node[2].tsplink.trigger[1].mode = node[2].tsplink.TRIG_SYNCHRONOUSA + node[2].tsplink.trigger[1].stimulus = node[2].smua.trigger.MEASURE_COMPLETE_EVENT_ID + + node[2].tsplink.trigger[2].clear() + node[2].tsplink.trigger[2].mode = node[2].tsplink.TRIG_FALLING + + -- Prepare the Gate SMU (26xxA) reading buffers + node[2].smua.nvbuffer1.clear() + node[2].smua.nvbuffer1.collectsourcevalues = 1 + node[2].smua.nvbuffer2.clear() + node[2].smua.nvbuffer2.collectsourcevalues = 1 + + -- The SMUs are configured and ready to run the test + + -- Outputs on + node[2].smua.source.output = 1 + smua.source.output = 1 + + -- Start the 26xxA's trigger model + node[2].smua.trigger.initiate() + + -- Start the 2651A's trigger model + smua.trigger.initiate() + + waitcomplete() -- Wait until the sweeps are complete + + -- Outputs off + smua.source.output = 0 + node[2].smua.source.output = 0 + + -- Return the data + PrintIVcurveData(gsteps, dsteps) +end + + +--[[ + PrintIVcurveData(gsteps, dsteps) + + Description: This function will output the data collected by + the IV_Curves() function in a Microsoft Excel compatible format. + For each step of the gate, this function will output three + columns containing the drain sweep data as well as the gate data + in the first row. + + Parameters: + gsteps: The number of steps in the gate sweep + dsteps: The number of steps in the drain sweep + + Example Usage: + PrintIVcurveData(5, 21) +--]] +function PrintIVcurveData(gsteps, dsteps) + line1 = "" + line2 = "" + for i = 1,gsteps do + line1 = line1 .. string.format("Vgs = %0.2f\t%g\t%g\t", + node[2].smua.nvbuffer1.sourcevalues[i], + node[2].smua.nvbuffer2[i], + node[2].smua.nvbuffer1[i]) + line2 = line2 .. "Source Value\tVoltage\tCurrent\t" + end + print(line1) + print(line2) + for i = 1, dsteps do + line = "" + for j = 1, gsteps do + line = line .. string.format("%g\t%g\t%g\t", + smua.nvbuffer1.sourcevalues[(j - 1) * dsteps + i], + smua.nvbuffer2[(j - 1) * dsteps + i], + smua.nvbuffer1[(j - 1) * dsteps + i]) + end + print(line) + end +end diff --git a/TSP_Examples/2651A/MOSFET_IV_Curves/View This First.pdf b/TSP_Examples/2651A/MOSFET_IV_Curves/View This First.pdf new file mode 100644 index 0000000..cf888ad Binary files /dev/null and b/TSP_Examples/2651A/MOSFET_IV_Curves/View This First.pdf differ diff --git a/TSP_Examples/2657A/DiodeRL/.vscode/settings.json b/TSP_Examples/2657A/DiodeRL/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL/DiodeRL.tsp b/TSP_Examples/2657A/DiodeRL/DiodeRL.tsp new file mode 100644 index 0000000..869d409 --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL/DiodeRL.tsp @@ -0,0 +1,110 @@ +--[[ + DiodeRL(vstart, vstop, vstep, irange, ilimit) + + Description: This function uses a 'for' loop to configure a reverse voltage sweep on a diode + and collect leakage current measurements. + + This demonstrates a very simple method of performing a linear voltage sweep on the Model 2657A. + + Parameters: + vstart: The starting voltage of the diode reverse voltage sweep + vstop: The stopping voltage of the diode reverse voltage sweep. + vstep: The step voltage of the diode reverse voltage sweep (how much the voltage changes per step) + irange: current measurement range, set to value or set to "auto" to enable autorange + ilimit: The current limit of the voltage source. + + Additional Notes: + Source delay is automatically added to each point of this sweep because the smua.source.levelv command is used. + Source delay varies by voltage range. + If the timing of the source is critical to your application, please use the DiodeRL_Swp function instead. + + Example Usage: + DiodeRL(0, 1000, 100, 100e-9, 0.01) +--]] + +function DiodeRL(vstart,vstop,vstep,irange,ilimit) + + --Reset and initialize instrument + reset() + status.reset() + errorqueue.clear() + + --Configure source function as 2W DCVOLTS + smua.source.func = smua.OUTPUT_DCVOLTS + smua.sense = smua.SENSE_LOCAL + + --Define local variable to store the number of points in the sweep + local l_numPoints + + --Calculate the number of points based on the start and stop values of the sweep + l_numPoints = math.abs((vstop - vstart) / vstep) + 1 + + --Set up source range + if math.abs(vstart) > math.abs(vstop) then + smua.source.rangev = vstart + else + smua.source.rangev = vstop + end + + --Set up current compliance + smua.source.limiti = ilimit + + --Set up current range + if irange == "auto" then + smua.measure.autorangei = smua.AUTORANGE_ON + else + smua.measure.autorangei = smua.AUTORANGE_OFF + smua.measure.rangei = irange + end + + --Set the measurement integration time + smua.measure.nplc = 1 + smua.measure.delay = 0.05 + + --Configure the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.appendmode = 1 + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 0 + smua.nvbuffer1.fillmode = smua.FILL_ONCE + smua.nvbuffer2.clear() + smua.nvbuffer2.appendmode = 1 + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 0 + smua.nvbuffer2.fillmode = smua.FILL_ONCE + + --Turn on the output + smua.source.output = 1 + + --Use a "for" loop to run the linear voltage sweep and make current and voltage measurements + for l_i = 0, (l_numPoints - 1) do + --Update the source level + if vstop > vstart then + smua.source.levelv = vstart + (l_i * math.abs(vstep)) + else + smua.source.levelv = vstart - (l_i * math.abs(vstep)) + end + + --Make simultaneous voltage and current measurements + smua.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + end + + --Set the voltage level back to 0V + smua.source.levelv = 0 + + --Turn off the output + smua.source.output = 0 +end + + +--This function prints the data from the smua.nvbuffer1 and smua.nvbuffer2 reading buffers into three separate columns. +function printData() + if smua.nvbuffer1.n == 0 then + print("No readings in buffer") + else + print("Timestamps\tCurrent\tVoltage") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer1.readings[i], smua.nvbuffer2.readings[i])) + end + end +end \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL/View_This_First.pdf b/TSP_Examples/2657A/DiodeRL/View_This_First.pdf new file mode 100644 index 0000000..80dd6cf Binary files /dev/null and b/TSP_Examples/2657A/DiodeRL/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/DiodeRL_Swp/.vscode/settings.json b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL_Swp/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/DiodeRL_Swp/DiodeRL_Swp.tsp b/TSP_Examples/2657A/DiodeRL_Swp/DiodeRL_Swp.tsp new file mode 100644 index 0000000..d3e2887 --- /dev/null +++ b/TSP_Examples/2657A/DiodeRL_Swp/DiodeRL_Swp.tsp @@ -0,0 +1,111 @@ +--[[ + DiodeRL_Swp(vstart, vstop, vstep, irange, ilimit, sourceDelay) + + Description: This function uses the trigger model and built-in sweeping function to create a linear + voltage sweep to measure the reverse leakage of a diode. + + Using this method is useful when there is a need to send or receive external triggers from another instrument + or device handler. + + Parameters: + vstart: The starting voltage of the diode reverse voltage sweep. + vstop: The stopping voltage of the diode reverse voltage sweep. + vstep: The step voltage of the diode reverse voltage sweep (how much the voltage changes per step). + irange: current measurement range, set to value or set to "auto" to enable autorange. + ilimit: The current limit of the voltage source. + sourceDelay: The delay between the start of source and the source complete event. + + Example Usage: + DiodeRL_Swp(0, 1000, 10, 100e-9, 0.01, 0.05) +--]] + +function DiodeRL_Swp(vstart,vstop,vstep,irange,ilimit,sourceDelay) + + --Reset and initialize instrument + reset() + status.reset() + errorqueue.clear() + + --Configure source function as 2W DCVOLTS + smua.source.func = smua.OUTPUT_DCVOLTS + smua.sense = smua.SENSE_LOCAL + + --Define a local variable to store the number of points in the sweep + local l_numPoints + + --Calculate the number of points in the sweep based on the start and stop values + l_numPoints = math.abs((vstop - vstart) / vstep) + 1 + + --Set up source range + if math.abs(vstart) > math.abs(vstop) then + smua.source.rangev = vstart + else + smua.source.rangev = vstop + end + + --Set up source delay + smua.source.delay = sourceDelay + + --Set up current compliance + smua.source.limiti = ilimit + + --Set up current measurement range + if irange == "auto" then + smua.measure.autorangei = smua.AUTORANGE_ON + else + smua.measure.autorangei = smua.AUTORANGE_OFF + smua.measure.rangei = irange + end + + --Set the integration time + smua.measure.nplc = 1 + + --Configure the reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.appendmode = 0 + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 0 + smua.nvbuffer1.fillmode = smua.FILL_ONCE + smua.nvbuffer2.clear() + smua.nvbuffer2.appendmode = 0 + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 0 + smua.nvbuffer2.fillmode = smua.FILL_ONCE + + --Configure the source lsweep + smua.trigger.source.linearv(vstart, vstop, l_numPoints) + smua.trigger.source.action = smua.ENABLE + smua.trigger.source.stimulus = 0 + + --Configure measurements during the sweep + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.stimulus = 0 + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + + --Configure trigger model parameters + smua.trigger.count = l_numPoints + smua.trigger.arm.count = 1 + + --Turn on the output + smua.source.output = 1 + + --Initiate the sweep and wait until sweep is complete before proceeding to next command + smua.trigger.initiate() + waitcomplete() + + --Turn off the output + smua.source.output = 0 +end + + +--This function prints the data from the smua.nvbuffer1 and smua.nvbuffer2 reading buffers into three separate columns. +function printData() + if smua.nvbuffer1.n == 0 then + print("No readings in buffer") + else + print("Timestamps\tCurrent\tVoltage") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer1.readings[i], smua.nvbuffer2.readings[i])) + end + end +end diff --git a/TSP_Examples/2657A/DiodeRL_Swp/View_This_First.pdf b/TSP_Examples/2657A/DiodeRL_Swp/View_This_First.pdf new file mode 100644 index 0000000..80dd6cf Binary files /dev/null and b/TSP_Examples/2657A/DiodeRL_Swp/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/MOS_BVdss/.vscode/settings.json b/TSP_Examples/2657A/MOS_BVdss/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/MOS_BVdss/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/MOS_BVdss/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_BVdss/MOS_BVdss.tsp b/TSP_Examples/2657A/MOS_BVdss/MOS_BVdss.tsp new file mode 100644 index 0000000..4a2978e --- /dev/null +++ b/TSP_Examples/2657A/MOS_BVdss/MOS_BVdss.tsp @@ -0,0 +1,60 @@ +--[[ + Title: FET Drain-Source Breakdown Voltage + Description: This script measures the drain-source breakdown voltage (BVdss) of a FET. +]] + +--[[ + BVdss(gateV, drainI, measDelay, igLimit, vdLimit, numNPLC) + + Description: This function uses the Model 2657A to force a current from drain to source. The SMU + also measures the resulting voltage (Vds) with the FET channel turned off. A second System SourceMeter Instrument + applies the gate to source voltage (Vgs) to ensure that the gate is turned off. + + Parameters: + gateV: Applied gate voltage (Vgs) + drainI: Test current applied by the Model 2657A from drain to source (Id) + measDelay: Measurement delay before making the drain voltage measurement (Vgs) + igLimit: Current limit (compliance) for the SMU connected to the FET gate terminal + vdLimit: Voltage limit (compliance) for the SMU connected to the FET drain terminal + numNPlC: Integration time for the drain voltage measurement (in number of power line cycles) + + Example Usage: + BVdss(0, 0.001, 0.01, 0.01, 2000, 1) +--]] + +function BVdss(gateV, drainI, measDelay, igLimit, vdLimit, numNPLC) + + --Initialize SMU + reset() + errorqueue.clear() + status.reset() + tsplink.reset() + + --Configure source function + node[2].smua.source.func = node[2].smua.OUTPUT_DCVOLTS + node[2].smua.source.levelv = gateV + node[2].smua.source.limiti = igLimit + + smua.source.func = smua.OUTPUT_DCAMPS + smua.source.rangei = drainI + smua.source.leveli = drainI + smua.source.limitv = vdLimit + + --Configure measurement parameters + smua.measure.rangev = vdLimit + smua.measure.nplc = numNPLC + smua.measure.delay = measDelay + + --Run the test + node[2].smua.source.output = 1 + smua.source.output = 1 + + I,V = smua.measure.iv() + + smua.source.output = 0 + node[2].smua.source.output = 0 + + print("Test current:", I) + print("Measured voltage:", V) + +end \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_BVdss/View_This_First.pdf b/TSP_Examples/2657A/MOS_BVdss/View_This_First.pdf new file mode 100644 index 0000000..b2632b3 Binary files /dev/null and b/TSP_Examples/2657A/MOS_BVdss/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/MOS_Idss/.vscode/settings.json b/TSP_Examples/2657A/MOS_Idss/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/MOS_Idss/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/MOS_Idss/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/MOS_Idss/MOS_Idss.tsp b/TSP_Examples/2657A/MOS_Idss/MOS_Idss.tsp new file mode 100644 index 0000000..8583098 --- /dev/null +++ b/TSP_Examples/2657A/MOS_Idss/MOS_Idss.tsp @@ -0,0 +1,106 @@ +--[[ + Title: FET Drain-to-Source Leakage Current Measurement Sweep + Description: This script measures the drain current while the drain voltage is sweeping linearly and + under a 0 V gate bias. +]] + +--[[ + Idss(gateV, startV, stopV, numSteps, measDelay, measRange, iLimit, intNPLC) + + Description: This function uses the Model 2657A to sweep the voltage across the drain + up to the drain-source breakdown voltage and measure the drain current. A second SourceMeter + instrument is used to bias the gate. For enhancement-mode power MOSFETs, a typical gate bias + is 0 V. + + Parameters: + gateV: Applied gate voltage bias (Vgs) + startV: Starting drain voltage (Vds) + stopV: Final drain voltage (Vds) + numSteps: Number of points in the drain voltage sweep + measDelay: Measurement delay + measRange: Current measurement range for the drain current measurements + iLimit: Current limit (compliance) for the drain current + numNPLC: Integration time in the number of power line cycles + + Example Usage: + Idss(0, 10, 1760, 500, 0.05, 100e-9, 500e-6, 1) +--]] + + +function Idss(gateV, startV, stopV, numSteps, measDelay, measRange, iLimit, numNPLC) + + --Initialize SMU + reset() + errorqueue.clear() + status.reset() + + --Configure reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.appendmode = 1 + smua.nvbuffer1.collecttimestamps = 1 + + smua.nvbuffer2.clear() + smua.nvbuffer2.appendmode = 1 + smua.nvbuffer2.collecttimestamps = 1 + + --Configure source parameters for the gate SMU + node[2].smua.source.func = node[2].smua.OUTPUT_DCVOLTS + node[2].smua.source.levelv = gateV + node[2].smua.source.limiti = 0.001 + + --Configure source parameters for the drain SMU + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.levelv = 0 + smua.source.limiti = iLimit + if math.abs(startV) > math.abs(stopV) then + smua.source.rangev = startV + else + smua.source.rangev = stopV + end + + --Calculate the step voltage + stepV = (stopV - startV)/(numSteps - 1) + + --Configure measurement parameters for the drain SMU + smua.measure.rangei = measRange + smua.measure.nplc = numNPLC + smua.measure.delay = measDelay + + --Run the test + node[2].smua.source.output = 1 + smua.source.output = 1 + delay(1) + + for i = 0, (numSteps - 1) do + smua.source.levelv = startV + (i * stepV) + smua.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + --Remove the following 4 lines if you do not want to monitor for compliance + testCmpl = smua.source.compliance + if testCmpl == true then + break + end + end + + --Turn off the SMUs to complete the test + smua.source.levelv = 0 + node[2].smua.source.levelv = 0 + node[2].smua.source.output = 0 + smua.source.output = 0 + + printData() + +end + + +function printData() + + if smua.nvbuffer1.n == 0 then + print("No reading in buffer") + else + print("Timestamps\tVoltage\tCurrent") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer2.readings[i], smua.nvbuffer1.readings[i])) + end + end +end + diff --git a/TSP_Examples/2657A/MOS_Idss/View_This_First.pdf b/TSP_Examples/2657A/MOS_Idss/View_This_First.pdf new file mode 100644 index 0000000..b2632b3 Binary files /dev/null and b/TSP_Examples/2657A/MOS_Idss/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/settings.json b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..a0baf62 --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2657A" + }, + "node2":{ + "model": "2602B" + } + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_holdingCurr/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/Thyristor_holdingCurr.tsp b/TSP_Examples/2657A/Thyristor_holdingCurr/Thyristor_holdingCurr.tsp new file mode 100644 index 0000000..e4d5efb --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_holdingCurr/Thyristor_holdingCurr.tsp @@ -0,0 +1,81 @@ +--[[ + holdingCurr(gateBiasCurr, gateVoltLimit, gateOnTime, anodeBiasVolt, anodeLatchingCurr, anodeCurrStep, numNPLC) + + Description: This function can be used to determine Ih of a thyristor. Two SMUs + are required for this function. One SMU (node[2].smua) is connected to the gate terminal and is used to + trigger the device. The Model 2657A (smua) is connected to the anode and is applying a voltage bias. + After the device is turned on, the gate signal is removed and the current limit of + the Model 2657A is varied until the device turns off. The current at which the device turns + off is the holding current. + + Parameters: + gateBiasCurr = Current to apply to the gate to trigger the device on. Should be greater than or equal to the gate trigger current. + gateVoltLimit = Voltage limit for the gate SMU. Should be greater than or equal to the gate trigger voltage. + gateOnTime = Number of seconds to apply the gate trigger (single pulse event) + anodeBiasVolt = Model 2657A applies this voltage to the anode terminal + anodeLatchingCurr = Specified latching current of the device. This will be the initial current limit of the Model 2657A + anodeCurrStep = How much to vary the anode current in order to arrive at the gate current. + numNPLC = Integration time in number of power line cycles + + Example Usage: + + holdingCurr(0.05, 10e-3, 2, 12, 0.06, 0.005, 1) + +--]] + +function holdingCurr(gateBiasCurr, gateOnTime, gateVoltLimit, anodeBiasVolt, anodeLatchingCurr, anodeCurrStep, numNPLC) + + --Initialize instruments and clear errors and status registers + tsplink.reset() + reset() + errorqueue.clear() + status.reset() + + --Configure gate SMU + node[2].smua.source.func = node[2].smua.OUTPUT_DCAMPS + node[2].smua.source.rangei = gateBiasCurr + node[2].smua.source.leveli = gateBiasCurr + node[2].smua.source.limitv = gateVoltLimit + node[2].smua.source.delay = 0 + + --Configure anode SMU source parameters + smua.source.func = smua.OUTPUT_DCVOLTS + smua.sense = smua.SENSE_LOCAL + smua.source.rangev = anodeBiasVolt + smua.source.levelv = anodeBiasVolt + smua.source.limiti = anodeLatchingCurr --This is the initial current limit to ensure that the device stays on after the gate + + --Configure anode SMU measure parameters + smua.measure.rangei = anodeLatchingCurr + smua.measure.nplc = numNPLC + smua.measure.autozero = smua.AUTOZERO_ONCE + + numSteps = (anodeLatchingCurr / anodeCurrStep) + 1 + + if anodeCurrStep >= anodeLatchingCurr then + print("Wrong value: The current step cannot be greater than or equal to the expected latching current.") + else + smua.source.output = 1 + node[2].smua.source.output = 1 + delay(gateOnTime) + node[2].smua.source.output = 0 + + for i = 1, numSteps do + smua.measure.i() + cmplCheck = smua.source.compliance + + if cmplCheck == false then + break + else + smua.source.limiti = anodeLatchingCurr - (i*anodeCurrStep) + end + + end + + --Complete the test and output the result + smua.source.output = 0 + finalIh = smua.source.limiti + print("Holding Current (Amps): ", finalIh) + end + +end diff --git a/TSP_Examples/2657A/Thyristor_holdingCurr/View_This_First.pdf b/TSP_Examples/2657A/Thyristor_holdingCurr/View_This_First.pdf new file mode 100644 index 0000000..f62f283 Binary files /dev/null and b/TSP_Examples/2657A/Thyristor_holdingCurr/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/settings.json b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..a0baf62 --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1":{ + "model": "2657A" + }, + "node2":{ + "model": "2602B" + } + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_latchingCurr/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/Thyristor_latchingCurr.tsp b/TSP_Examples/2657A/Thyristor_latchingCurr/Thyristor_latchingCurr.tsp new file mode 100644 index 0000000..5bd9da3 --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_latchingCurr/Thyristor_latchingCurr.tsp @@ -0,0 +1,121 @@ +--[[ + latchingCurr(gateBiasCurr, gateVoltLimit, gateOnTime, anodeStartCurr, anodeMaxCurr, anodeStepCurr, anodeVoltLimit, numNPLC) + + Description: This function can be used to determine Ilatch of a thyristor. Two SMUs + are required for this function. One SMU (node[2].smua) is connected to the gate terminal and is used to + trigger the device. The Model 2657A (smua) is connected to the anode and is used to source the current. + The gate is triggered while a current bias is applied to the anode. The gate current is removed and + measurements are made to verify that the device is on. If the device is off, the current at the anode is increased + and the gate is re-triggered. This continues until the device remains on even after the gate signal is removed. + The current at which the device remains on is the latching current. + + In order to complete this task, custom list sweeps are configured on the gate and anode SMUs. + + Parameters: + gateBiasCurr = Current to apply to the gate to trigger the device on. Should be greater than or equal to the gate trigger current. + gateVoltLimit = Voltage limit for the gate SMU. Should be greater than or equal to the gate trigger voltage. + gateOnTime = Number of seconds to apply the gate trigger (single pulse event) + anodeStartCurr = Start value for the anode current sweep. Typically slightly less than or equal to the holding current value. + anodeMaxCurr = Stop value for the anode current sweep. May not reach this value, but this is the maximum value to source + anodeStepCurr = Step value for the anode current sweep + anodeVoltLimit = Voltage limit for the anode SMU. Should be equal to Vdrm. + numNPLC = Integration time in the number of power line cycles + + Example Usage: + + latchingCurr(0.060, 10, 1e-3, 0.020, 0.120, 0.005, 600, 0.01) + +--]] + +function latchingCurr(gateBiasCurr, gateVoltLimit, gateOnTime, anodeStartCurr, anodeMaxCurr, anodeStepCurr, anodeVoltLimit, numNPLC) + + --Initialize instruments and clear errors and status registers + tsplink.reset() + reset() + errorqueue.clear() + status.reset() + + --Configure gate SMU + node[2].smua.source.func = node[2].smua.OUTPUT_DCAMPS + node[2].smua.source.rangei = gateBiasCurr + node[2].smua.source.leveli = 0 + node[2].smua.source.limitv = gateVoltLimit + node[2].smua.source.delay = gateOnTime + + --Configure anode SMU source parameters + smua.source.func = smua.OUTPUT_DCAMPS + smua.sense = smua.SENSE_LOCAL + smua.source.rangei = anodeMaxCurr + smua.source.leveli = 0 + smua.source.limitv = anodeVoltLimit + + --Configure anode SMU measurement parameters + smua.measure.delay = 0.005 + --Must have delay if you want reasonable anode measurements + + smua.measure.rangev = anodeVoltLimit + smua.measure.nplc = numNPLC + smua.measure.autozero = smua.AUTOZERO_ONCE + + smua.nvbuffer1.clear() + smua.nvbuffer2.clear() + smua.nvbuffer1.appendmode = 1 + smua.nvbuffer2.appendmode = 1 + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.collecttimestamps = 1 + + --Create custom sweeps for anode and gate SMUs + numSwpPts = 2*((anodeMaxCurr - anodeStartCurr)/(anodeStepCurr)) + 1 + + gateSwp = {} + anodeSwp = {} + + for i = 1, numSwpPts do + if math.mod(i,2) == 0 then + gateSwp[i] = 0 + else + gateSwp[i] = gateBiasCurr + end + end + + for j = 1, numSwpPts, 2 do + anodeSwp [j] = anodeStartCurr + ((j-1)/2)*anodeStepCurr + anodeSwp[j+1] = anodeStartCurr + ((j-1)/2)*anodeStepCurr + end + + smua.source.output = 1 + node[2].smua.source.output = 1 + + for k = 1, numSwpPts, 2 do + smua.source.leveli = anodeSwp[k] + node[2].smua.source.leveli = gateSwp[k] + node[2].smua.source.leveli = gateSwp[k+1] + smua.measure.iv(smua.nvbuffer1,smua.nvbuffer2) + checkCmpl = smua.source.compliance + --If in compliance, then device is off. If out of compliance, then device is on and we've reached latching current. + + if checkCmpl == false then + finalIL = anodeSwp[k] + break + end + end + + node[2].smua.source.output = 0 + smua.source.output = 0 + print("Latching Current(Amps): ", finalIL) + print("Raw Data follows:") + printData() +end + + +function printData() + + if smua.nvbuffer1.n == 0 then + print("No reading in buffer") + else + print("Timestamps\tVoltage\tCurrent") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer2.readings[i], smua.nvbuffer1.readings[i])) + end + end +end \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_latchingCurr/View_This_First.pdf b/TSP_Examples/2657A/Thyristor_latchingCurr/View_This_First.pdf new file mode 100644 index 0000000..f62f283 Binary files /dev/null and b/TSP_Examples/2657A/Thyristor_latchingCurr/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/settings.json b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_offVoltLeakI/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/Thyristor_offVoltLeakI.tsp b/TSP_Examples/2657A/Thyristor_offVoltLeakI/Thyristor_offVoltLeakI.tsp new file mode 100644 index 0000000..a390501 --- /dev/null +++ b/TSP_Examples/2657A/Thyristor_offVoltLeakI/Thyristor_offVoltLeakI.tsp @@ -0,0 +1,99 @@ +--[[ + offVoltLeakI(startV, stopV, numSteps, measDelay, measRange, iLimit, numNPLC) + + Description: This function can be used to determine Vdrm and Idrm or + Vrrm and Irrm of a thyristor. In this function, the Model 2657A will + perform a voltage sweep on the anode and measure the corresponding + leakage current at each step. As no voltage or current bias is required + on the gate terminal of the thyristor, this function can be used with + gated and non-gated devices. + + To determine Vdrm and Idrm, connect the Model 2657A from anode to + cathode of the device, and program positive start and stop voltages + for the sweep. + + To determine Vrrm and Irrm, connect the Model 2657A from the anode to + the cathode of the device, and program negative start and stop voltages + for the sweep. + + Parameters: + startV: Starting drain voltage (Vds). + stopV: Final drain voltage (Vds). + numSteps: Number of points in the drain voltage sweep. + measDelay: Measurement delay. + measRange: Current measurement range for the drain current measurements. + iLimit: Current limit (compliance) for the drain current. + numNPLC: Integration time in number of power line cycles. + + Example usage: + + for Vdrm and Idrm: + offVoltLeakI(0, 800, 501, 0.010, 100e-6, 1e-3, 1) + + for Vrrm and Irrm: + offVoltLeakI(0, -800, 501, 0.010, 100e-6, 1e-3, 1) +--]] + +function offVoltLeakI(startV, stopV, numSteps, measDelay, measRange, iLimit, numNPLC) + + --Initialize SMU + reset() + errorqueue.clear() + status.reset() + + --Configure reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.appendmode = 1 + smua.nvbuffer1.collecttimestamps = 1 + + smua.nvbuffer2.clear() + smua.nvbuffer2.appendmode = 1 + smua.nvbuffer2.collecttimestamps = 1 + + --Configure source parameters for the drain SMU + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.levelv = 0 + smua.source.limiti = iLimit + if math.abs(startV) > math.abs(stopV) then + smua.source.rangev = startV + else + smua.source.rangev = stopV + end + + --Calculate the step voltage + stepV = (stopV - startV)/(numSteps - 1) + + --Configure measurement parameters for the drain SMU + smua.measure.rangei = measRange + smua.measure.nplc = numNPLC + smua.measure.delay = measDelay + smua.measure.autozero = smua.AUTOZERO_ONCE + + --Run the test + smua.source.output = 1 + + for i = 0, (numSteps - 1) do + smua.source.levelv = startV + (i * stepV) + smua.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + end + + --Turn off the SMU to complete the test + smua.source.levelv = 0 + smua.source.output = 0 + + printData() + +end + + +function printData() + + if smua.nvbuffer1.n == 0 then + print("No reading in buffer") + else + print("Timestamps\tVoltage\tCurrent") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer2.readings[i], smua.nvbuffer1.readings[i])) + end + end +end diff --git a/TSP_Examples/2657A/Thyristor_offVoltLeakI/View_This_First.pdf b/TSP_Examples/2657A/Thyristor_offVoltLeakI/View_This_First.pdf new file mode 100644 index 0000000..f62f283 Binary files /dev/null and b/TSP_Examples/2657A/Thyristor_offVoltLeakI/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/runCapLeak/.vscode/settings.json b/TSP_Examples/2657A/runCapLeak/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/2657A/runCapLeak/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/config.tsp.json b/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ffdd79a --- /dev/null +++ b/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2657A" +} \ No newline at end of file diff --git a/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/tspSchema.json b/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/2657A/runCapLeak/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/2657A/runCapLeak/View_This_First.pdf b/TSP_Examples/2657A/runCapLeak/View_This_First.pdf new file mode 100644 index 0000000..6fa3094 Binary files /dev/null and b/TSP_Examples/2657A/runCapLeak/View_This_First.pdf differ diff --git a/TSP_Examples/2657A/runCapLeak/runCapLeak.tsp b/TSP_Examples/2657A/runCapLeak/runCapLeak.tsp new file mode 100644 index 0000000..a2395ef --- /dev/null +++ b/TSP_Examples/2657A/runCapLeak/runCapLeak.tsp @@ -0,0 +1,74 @@ +function runCapLeak(testV, iLimit, measRange, numReadings, soakTime, numNPLC) + + --Initialize SMU + reset() + errorqueue.clear() + status.reset() + + --Configure reading buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.appendmode = 0 + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer1.collectsourcevalues = 0 + + smua.nvbuffer2.clear() + smua.nvbuffer2.appendmode = 0 + smua.nvbuffer2.collecttimestamps = 1 + smua.nvbuffer2.collectsourcevalues = 0 + + --Configure source function + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.levelv = testV + smua.source.limiti = iLimit + + --[[ + Configure measurement parameters. Each call of the measurement function + will result in the number of readings specified by smua.measure.count. + The time specified by smua.measure.delay is enforced before any + measurements are made. + --]] + smua.measure.autozero = smua.AUTOZERO_ONCE + smua.measure.rangei = measRange + smua.measure.count = numReadings + smua.measure.nplc = numNPLC + smua.measure.delay = soakTime + + --Run the test + --Turn on the output. The programmed voltage is output immediately. + smua.source.output = 1 + --Perform a set of current and voltage measurements. Measure delay is enforced before measurements are made. + smua.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + --After measurements are complete, return the voltage to 0V. Rate of discharge is limited by programmed current limit. + smua.source.levelv = 0 + --Wait until the capacitor is fully discharged before turning off the output. + delay(soakTime) + smua.source.output = 0 + +end + + +--This function prints the raw voltage and current measurements that are stored in reading buffers smua.nvbuffer1 and smua.nvbuffer2 +function printData() + --Retrieve average values of measured current and voltage + current_stats = smua.buffer.getstats(smua.nvbuffer1) + voltage_stats = smua.buffer.getstats(smua.nvbuffer2) + current_mean = current_stats.mean + voltage_mean = voltage_stats.mean + + --Calculate the insulation resistance of the capacitor + resistance = voltage_mean/current_mean + + --Print the summary of the results to the communication interface + print(string.format("Average current: %g", current_mean)) + print(string.format("Average voltage: %g", voltage_mean)) + print(string.format("Insulator Resistance: %g", resistance)) + + if smua.nvbuffer1.n == 0 then + print("No reading in buffer") + else + print("Timestamps\tCurrent\tVoltage") + for i = 1, smua.nvbuffer1.n do + print(string.format("%g\t%g\t%g", smua.nvbuffer1.timestamps[i], smua.nvbuffer1.readings[i], smua.nvbuffer2.readings[i])) + end + end +end \ No newline at end of file diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/settings.json b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/settings.json new file mode 100644 index 0000000..5b7feb0 --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2636B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2636B\\AllTspCommands", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2636B\\tspLinkSupportedCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/config.tsp.json b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..6939809 --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1": { + "model": "2636B" + }, + "node2": { + "model": "2636B" + } + }, + "self": "2636B" +} \ No newline at end of file diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..2399fd7 --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/nodeTable.tsp @@ -0,0 +1,2 @@ +node[1] = model2636B +node[2] = model2636B diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/tspSchema.json b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep.pdf b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep.pdf new file mode 100644 index 0000000..947fdec Binary files /dev/null and b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep.pdf differ diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Dual.tsp b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Dual.tsp new file mode 100644 index 0000000..c5436de --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Dual.tsp @@ -0,0 +1,360 @@ +--[[ + Title: KE26XXB Pulsed Sweep Dual + + Description: This example demonstrates how to synchronize pulsed + sweeps between two SMU channels on a dual channel Series 2600B + SourceMeter instrument. This example performs linear sweeps but + can easily be modified to perform log or list sweeps. This + example also programs both SMUs to source the same levels + however, this can also easily be modified for each SMU to output + different levels. + There are two functions contained in this example script. One + function outputs pulsed voltage sweeps while the other performs + pulsed current sweeps. + At the conclusion of the sweeps the data is returned to the + instrument console in a format that is compatible for copy and + paste into Microsoft Excel. + + Equipment Needed: + 1x Dual Channel Series 2600B SourceMeter instrument + + Script Functions: + PulsedSweepVDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + PulsedSweepIDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) +]] + +--[[ + Name: PulsedSweepVDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + + Description: + This function performs synchronized pulsed linear voltage sweeps + on dual SMU channels. + + Parameters: + start: The voltage level of the first step in the sweep in volts + stop: The voltage level of the last step in the sweep in volts + numPoints: The number of points in the sweep + pulseWidth: The width of the pulse in seconds + pulsePeriod: The time from the start of one pulse to the start of the next pulse + limitI: The current limit of the pulse in amps + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + remoteSense Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements + + Notes: + After calling this function you will need to press the TRIG button + on the instrument's front panel to trigger the sweep to start. + The code can easily be modified to trigger off other sources as + well. + + Example Usage: + PulsedSweepVDual(0, 10, 11, 1e-3, 5e-3, 0.1, 0.001, false) +]] +function PulsedSweepVDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + reset() + -- Configure Channel A Settings + --============================= + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + if remoteSense == true then + smua.sense = smua.SENSE_REMOTE + else + smua.sense = smua.SENSE_LOCAL + end + smua.source.autorangev = smua.AUTORANGE_OFF + smua.source.rangev = math.max(math.abs(start), math.abs(stop)) + smua.source.levelv = 0 + -- 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 + if remoteSense == true then + smub.sense = smub.SENSE_REMOTE + else + smub.sense = smub.SENSE_LOCAL + end + smub.source.autorangev = 0 + smub.source.rangev = math.max(math.abs(start), math.abs(stop)) + smub.source.levelv = 0 + -- 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 + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measurement + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- Configure SMUA Trigger Model for Sweep + smua.trigger.source.linearv(start, stop, numPoints) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = 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 + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.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(start, stop, numPoints) + smub.trigger.source.limiti = limitI + smub.trigger.measure.action = smub.ENABLE + smub.trigger.measure.iv(smub.nvbuffer1, smub.nvbuffer2) + smub.trigger.endpulse.action = smub.SOURCE_IDLE + smub.trigger.endsweep.action = smub.SOURCE_IDLE + smub.trigger.count = numPoints + smub.trigger.arm.stimulus = 0 + smub.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smub.trigger.measure.stimulus = trigger.timer[2].EVENT_ID + smub.trigger.endpulse.stimulus = trigger.timer[3].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 + + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + smub.source.output = smub.OUTPUT_OFF + + -- 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 + +--[[ + Name: PulsedSweepIDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) + + Description: + This function performs synchronized pulsed linear current sweeps + on dual SMU channels. + + Parameters: + start: The current level of the first step in the sweep in amps + stop: The current level of the last step in the sweep in amps + numPoints: The number of points in the sweep + pulseWidth: The width of the pulse in seconds + pulsePeriod: The time from the start of one pulse to the start of the next pulse + limitV: The voltage limit of the pulse in volts + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + remoteSense Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements + + Notes: + After calling this function you will need to press the TRIG button + on the instrument's front panel to trigger the sweep to start. + The code can easily be modified to trigger off other sources as + well. + + Example Usage: + PulsedSweepIDual(0, 10e-3, 11, 1e-3, 5e-3, 10, 0.001, false) +]] +function PulsedSweepIDual(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) + reset() + -- Configure Channel A Settings + --============================= + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + if remoteSense == true then + smua.sense = smua.SENSE_REMOTE + else + smua.sense = smua.SENSE_LOCAL + end + smua.source.autorangei = 0 + smua.source.rangei = math.max(math.abs(start), math.abs(stop)) + smua.source.leveli = 0 + -- Set the DC bias limit. This is not the limit used during the pulses. + smua.source.limitv = 10 + + -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing + smua.measure.autozero = smua.AUTOZERO_ONCE + smua.measure.autorangev = 0 + smua.measure.rangev = limitV + 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_DCAMPS + if remoteSense == true then + smub.sense = smub.SENSE_REMOTE + else + smub.sense = smub.SENSE_LOCAL + end + smub.source.autorangei = 0 + smub.source.rangei = math.max(math.abs(start), math.abs(stop)) + smub.source.leveli = 0 + -- Set the DC bias limit. This is not the limit used during the pulses. + smub.source.limitv = 10 + + -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing + smub.measure.autozero = smua.AUTOZERO_ONCE + smub.measure.autorangev = 0 + smub.measure.rangev = limitV + 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 + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measurement + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- Configure SMUA Trigger Model for Sweep + smua.trigger.source.lineari(start, stop, numPoints) + smua.trigger.source.limitv = limitV + smua.trigger.measure.action = 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 + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.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.lineari(start, stop, numPoints) + smub.trigger.source.limitv = limitV + smub.trigger.measure.action = smub.ENABLE + smub.trigger.measure.iv(smub.nvbuffer1, smub.nvbuffer2) + smub.trigger.endpulse.action = smub.SOURCE_IDLE + smub.trigger.endsweep.action = smub.SOURCE_IDLE + smub.trigger.count = numPoints + smub.trigger.arm.stimulus = 0 + smub.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smub.trigger.measure.stimulus = trigger.timer[2].EVENT_ID + smub.trigger.endpulse.stimulus = trigger.timer[3].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 + + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + smub.source.output = smub.OUTPUT_OFF + + -- 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 \ No newline at end of file diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Quad.tsp b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Quad.tsp new file mode 100644 index 0000000..08ccbac --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Quad.tsp @@ -0,0 +1,404 @@ +--[[ + Title: KE26XXB Pulsed Sweep Quad + + Description: This example demonstrates how to synchronize pulsed + sweeps between multiple SMU channels on multiple Series 2600B + SourceMeter instruments. It is written to control four SMU + channels within two dual channels Series 2600B SourceMeter + instruments and can easily be expanded to support additional + Series 2600B SourceMeter instruments. This example script + performs linear sweeps but can easily be modified to perform log + or list sweeps. It also programs all SMUs to source the same + levels however, this can also easily be modified for each SMU to + output different levels. + There are two functions contained in this script. One function + performs pulsed voltage sweeps while the other performs pulsed + current sweeps. + At the conclusion of the sweeps the data is returned to the + instrument console in a format that is compatible for copy and + paste into Microsoft Excel. + + Equipment Needed: + 2x Dual Channel Series 2600B SourceMeter instruments + + TSP-Link Configuration: + 26XXB #1: Node 1 (Master Node) + 26XXB #2: Node 2 + + Script Functions: + PulsedSweepVQuad(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + PulsedSweepIQuad(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) +]] + +---# Description: +---This function performs synchronized pulsed linear voltage sweeps +---on four SMU channels across two dual channel Series 2600B +---SourceMeter instruments. +--- +---# Parameters: +---@param start number The voltage level of the first step in the sweep in volts +---@param stop number The voltage level of the last step in the sweep in volts +---@param numPoints integer The number of points in the sweep +---@param pulseWidth number The width of the pulse in seconds +---@param pulsePeriod number The time from the start of one pulse to the start of the next pulse +---@param limitI number The current limit of the pulse in amps +---@param nplc number The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power +---@param remoteSense boolean Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements +--- +---# Notes: +---After calling this function you will need to press the TRIG button +---on the instrument's front panel to trigger the sweep to start. +---The code can easily be modified to trigger off other sources as +---well. +--- +---# Example Usage: +---```lua +---PulsedSweepVQuad(0, 10, 11, 1e-3, 5e-3, 0.1, 0.001, false) +---``` +function PulsedSweepVQuad(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + -- 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 + + reset() + + -- Configure SMUs + ConfigVSMU(node[1], node[1].smua, start, stop, numPoints, limitI, nplc, remoteSense) + ConfigVSMU(node[1], node[1].smub, start, stop, numPoints, limitI, nplc, remoteSense) + ConfigVSMU(node[2], node[2].smua, start, stop, numPoints, limitI, nplc, remoteSense) + ConfigVSMU(node[2], node[2].smub, start, stop, numPoints, limitI, nplc, remoteSense) + + -- Configure the Trigger Model + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measure delay + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- The TSP-Link triggers are used to synchronize the two instruments + ConfigTSPLinkTriggers(node[1]) + ConfigTSPLinkTriggers(node[2]) + + -- The Master Node sends out the TSP-Link triggers so its TSP-Link + -- triggers need a stimulus. + tsplink.trigger[1].stimulus = trigger.timer[1].EVENT_ID + tsplink.trigger[2].stimulus = trigger.timer[2].EVENT_ID + tsplink.trigger[3].stimulus = trigger.timer[3].EVENT_ID + + -- SMU trigger models were configured in ConfigVSMU() + + --============================== + -- End Trigger Model Configuration + + -- Turn the outputs on + smua.source.output = smua.OUTPUT_ON + smub.source.output = smub.OUTPUT_ON + node[2].smua.source.output = node[2].smua.OUTPUT_ON + node[2].smub.source.output = node[2].smub.OUTPUT_ON + + -- Start the trigger model execution + smua.trigger.initiate() + smub.trigger.initiate() + node[2].smua.trigger.initiate() + node[2].smub.trigger.initiate() + -- Sweep will not start until the TRIG button is pressed + + -- Wait until the sweep has completed + waitcomplete() + + -- Turn the output off + smua.source.output = smua.OUTPUT_OFF + smub.source.output = smub.OUTPUT_OFF + node[2].smua.source.output = node[2].smua.OUTPUT_OFF + node[2].smub.source.output = node[2].smub.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Node 1 SMUA Voltage\tNode 1 SMUA Current\tNode 1 SMUB Voltage\tNode 1 SMUB Current\tNode 2 SMUA Voltage\tNode 2 SMUA Current\tNode 2 SMUB Voltage\tNode 2 SMUB Current") + for x=1,smua.nvbuffer1.n do + -- Voltage readings are in nvbuffer2. Current readings are in nvbuffer1. + print(smua.nvbuffer2[x], smua.nvbuffer1[x], smub.nvbuffer2[x], smub.nvbuffer1[x], node[2].smua.nvbuffer2[x], node[2].smua.nvbuffer1[x], node[2].smub.nvbuffer2[x], node[2].smub.nvbuffer1[x]) + end +end + +---# Description +--- +---This function performs synchronized pulsed linear current sweeps +---on four SMU channels across two dual channel Series 2600B +---SourceMeter instruments. +--- +---# Parameters +--- +---@param start number The current level of the first step in the sweep in amps +---@param stop number The current level of the last step in the sweep in amps +---@param numPoints integer The number of points in the sweep +---@param pulseWidth number The width of the pulse in seconds +---@param pulsePeriod number The time from the start of one pulse to the start of the next pulse +---@param limitV number The voltage limit of the pulse in volts +---@param nplc number The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power +---@param remoteSense boolean Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements +--- +---# Notes +--- +---After calling this function you will need to press the TRIG button +---on the instrument's front panel to trigger the sweep to start. +---The code can easily be modified to trigger off other sources as +---well. +--- +---# Usage +--- +---```lua +---PulsedSweepIQuad(0, 10e-3, 11, 1e-3, 5e-3, 10, 0.001, false) +---``` +--- +function PulsedSweepIQuad(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) + -- Reset the TSP-Link if it is offline + if tsplink.state == "offline" then + NodesFound = tsplink.reset() + if NodesFound ~= 2 then + print(string.format("Error: Found %d Nodes. Expecting 2.", NodesFound)) + exit() + end + end + + reset() + + -- Configure SMUs + ConfigISMU(node[1], node[1].smua, start, stop, numPoints, limitV, nplc, remoteSense) + ConfigISMU(node[1], node[1].smub, start, stop, numPoints, limitV, nplc, remoteSense) + ConfigISMU(node[2], node[2].smua, start, stop, numPoints, limitV, nplc, remoteSense) + ConfigISMU(node[2], node[2].smub, start, stop, numPoints, limitV, nplc, remoteSense) + + -- Configure the Trigger Model + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measure delay + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- The TSP-Link triggers are used to synchronize the two instruments + ConfigTSPLinkTriggers(node[1]) + ConfigTSPLinkTriggers(node[2]) + + -- The Master Node sends out the TSP-Link triggers so its TSP-Link + -- triggers need a stimulus. + tsplink.trigger[1].stimulus = trigger.timer[1].EVENT_ID + tsplink.trigger[2].stimulus = trigger.timer[2].EVENT_ID + tsplink.trigger[3].stimulus = trigger.timer[3].EVENT_ID + + -- SMU trigger models were configured in ConfigVSMU() + + --============================== + -- End Trigger Model Configuration + + -- Turn the outputs on + smua.source.output = smua.OUTPUT_ON + smub.source.output = smub.OUTPUT_ON + node[2].smua.source.output = node[2].smua.OUTPUT_ON + node[2].smub.source.output = node[2].smub.OUTPUT_ON + + -- Start the trigger model execution + smua.trigger.initiate() + smub.trigger.initiate() + node[2].smua.trigger.initiate() + node[2].smub.trigger.initiate() + -- Sweep will not start until the TRIG button is pressed + + -- Wait until the sweep has completed + waitcomplete() + + -- Turn the output off + smua.source.output = smua.OUTPUT_OFF + smub.source.output = smub.OUTPUT_OFF + node[2].smua.source.output = node[2].smua.OUTPUT_OFF + node[2].smub.source.output = node[2].smub.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Node 1 SMUA Voltage\tNode 1 SMUA Current\tNode 1 SMUB Voltage\tNode 1 SMUB Current\tNode 2 SMUA Voltage\tNode 2 SMUA Current\tNode 2 SMUB Voltage\tNode 2 SMUB Current") + for x=1,smua.nvbuffer1.n do + -- Voltage readings are in nvbuffer2. Current readings are in nvbuffer1. + print(smua.nvbuffer2[x], smua.nvbuffer1[x], smub.nvbuffer2[x], smub.nvbuffer1[x], node[2].smua.nvbuffer2[x], node[2].smua.nvbuffer1[x], node[2].smub.nvbuffer2[x], node[2].smub.nvbuffer1[x]) + end +end + +-- ================= +-- Utility functions +-- ================= + +---@param trig_smu model2636B | nodeArr +---@param smu smua | smub +---@param start number +---@param stop number +---@param numPoints integer +---@param limitI number +---@param nplc number +---@param remoteSense boolean +--- +---#Usage +---```lua +---ConfigVSMU(node[1], node[1].smua, 1.0, 10.0, 100, 0.005, 0.6, true) +---``` +function ConfigVSMU(trig_smu, smu, start, stop, numPoints, limitI, nplc, remoteSense) + smu.reset() + smu.source.func = smu.OUTPUT_DCVOLTS + if (remoteSense == true) then + smu.sense = smu.SENSE_REMOTE + else + smu.sense = smu.SENSE_LOCAL + end + smu.source.autorangev = smu.AUTORANGE_OFF + smu.source.rangev = math.max(math.abs(start), math.abs(stop)) + smu.source.levelv = 0 + -- Set the DC bias limit. This is not the limit used during the pulses. + smu.source.limiti = 0.1 + + -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing + smu.measure.autozero = smu.AUTOZERO_ONCE + smu.measure.autorangei = smu.AUTORANGE_OFF + smu.measure.rangei = limitI + 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 + + -- 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 + + -- Configure SMU Trigger Model for Sweep + smu.trigger.source.linearv(start, stop, numPoints) + smu.trigger.source.limiti = limitI + 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 = numPoints + smu.trigger.arm.stimulus = 0 + smu.trigger.source.stimulus = trig_smu.tsplink.trigger[1].EVENT_ID + smu.trigger.measure.stimulus = trig_smu.tsplink.trigger[2].EVENT_ID + smu.trigger.endpulse.stimulus = trig_smu.tsplink.trigger[3].EVENT_ID + smu.trigger.source.action = smu.ENABLE +end + +---@param trig_smu model2636B | nodeArr +---@param smu smua | smub +---@param start number +---@param stop number +---@param numPoints integer +---@param limitV number +---@param nplc number +---@param remoteSense boolean +--- +---#Usage +---```lua +---ConfigVSMU(node[1], node[1].smua, 1.0, 10.0, 100, 0.005, 0.6, true) +---``` +function ConfigISMU(trig_smu, smu, start, stop, numPoints, limitV, nplc, remoteSense) + smu.reset() + 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 = math.max(math.abs(start), math.abs(stop)) + smu.source.leveli = 0 + -- Set the DC bias limit. This is not the limit used during the pulses. + smu.source.limitv = 1 + + -- 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 + + -- 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 + + -- Configure SMU Trigger Model for Sweep + smu.trigger.source.lineari(start, stop, numPoints) + 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 = numPoints + smu.trigger.arm.stimulus = 0 + smu.trigger.source.stimulus = trig_smu.tsplink.trigger[1].EVENT_ID + smu.trigger.measure.stimulus = trig_smu.tsplink.trigger[2].EVENT_ID + smu.trigger.endpulse.stimulus = trig_smu.tsplink.trigger[3].EVENT_ID + smu.trigger.source.action = smu.ENABLE +end + +---Configure the TSP-Link triggers for the given node index. +---@param triggerNode model2636B | nodeArr +--- +---*Example* +---```lua +---ConfigTSPLinkTriggers(node[1]) +---``` +function ConfigTSPLinkTriggers(triggerNode) + assert(triggerNode ~= nil, "attempt to reference a node that is a nil value") + assert(triggerNode.tsplink ~= nil, "attempt to set a tsplink trigger on a node that doesn't have tsplink triggering support") + + triggerNode.tsplink.trigger[1].clear() + triggerNode.tsplink.trigger[1].mode = tsplink.TRIG_FALLING + triggerNode.tsplink.trigger[2].clear() + triggerNode.tsplink.trigger[2].mode = tsplink.TRIG_FALLING + triggerNode.tsplink.trigger[3].clear() + triggerNode.tsplink.trigger[3].mode = tsplink.TRIG_FALLING + +end diff --git a/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Single.tsp b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Single.tsp new file mode 100644 index 0000000..4a82d9a --- /dev/null +++ b/TSP_Examples/26xxB/Pulsed_Sweep/KE26XXB_Pulsed_Sweep_Single.tsp @@ -0,0 +1,246 @@ +--[[ + Title: KE26XXB Pulsed Sweep Single + + Description: This example demonstrates how to output a pulsed sweep + on a single SMU channel. This script performs a linear sweep but + can easily be modified to perform log or list sweeps. + There are two functions contained in this script. One function + performs a pulsed voltage sweep while the other performs a pulsed + current sweep. + At the conclusion of the sweeps the data is returned to the + instrument console in a format that is compatible for copy and + paste into Microsoft Excel. + + Equipment Needed: + 1x Series 2600B SourceMeter instrument + + Script Functions: + PulsedSweepVSingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + PulsedSweepISingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) +--]] + +--[[ + Name: PulsedSweepVSingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + + Description: + This function performs a pulsed linear voltage sweep on a single SMU channel. + + Parameters: + start: The voltage level of the first step in the sweep in volts + stop: The voltage level of the last step in the sweep in volts + numPoints: The number of points in the sweep + pulseWidth: The width of the pulse in seconds + pulsePeriod: The time from the start of one pulse to the start of the next pulse + limitI: The current limit of the pulse in amps + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + remoteSense Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements + + Notes: + After calling this function you will need to press the TRIG button + on the instrument's front panel to trigger the sweep to start. + The code can easily be modified to trigger off other sources as + well. + + Example Usage: + PulsedSweepVSingle(0, 10, 11, 1e-3, 5e-3, 0.1, 0.001, false) +--]] +function PulsedSweepVSingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitI, nplc, remoteSense) + reset() + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + if remoteSense == true then + smua.sense = smua.SENSE_REMOTE + else + smua.sense = smua.SENSE_LOCAL + end + smua.source.autorangev = smua.AUTORANGE_OFF + smua.source.rangev = math.max(math.abs(start), math.abs(stop)) + smua.source.levelv = 0 + -- 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 control the measure delay 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 + + -- Configure the Trigger Model + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measure delay + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.linearv(start, stop, numPoints) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = 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 + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.endpulse.stimulus = trigger.timer[3].EVENT_ID + smua.trigger.source.action = smua.ENABLE + --============================== + -- End Trigger Model Configuration + + smua.source.output = smua.OUTPUT_ON + + -- Start the trigger model execution + smua.trigger.initiate() + -- Sweep will not start TRIG button is pressed + + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: PulsedSweepISingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) + + Description: + This function performs a pulsed linear current sweep on a single SMU channel. + + Parameters: + start: The current level of the first step in the sweep in amps + stop: The current level of the last step in the sweep in amps + numPoints: The number of points in the sweep + pulseWidth: The width of the pulse in seconds + pulsePeriod: The time from the start of one pulse to the start of the next pulse + limitI: The voltage limit of the pulse in volts + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + remoteSense Set to true to enable 4-Wire (Kelvin) measurements or to false for 2-Wire measurements + + Notes: + After calling this function you will need to press the TRIG button + on the instrument's front panel to trigger the sweep to start. + The code can easily be modified to trigger off other sources as + well. + + Example Usage: + PulsedSweepISingle(0, 10e-3, 11, 1e-3, 5e-3, 10, 0.001, false) +--]] +function PulsedSweepISingle(start, stop, numPoints, pulseWidth, pulsePeriod, limitV, nplc, remoteSense) + reset() + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + if remoteSense == true then + smua.sense = smua.SENSE_REMOTE + else + smua.sense = smua.SENSE_LOCAL + end + smua.source.autorangei = smua.AUTORANGE_OFF + smua.source.rangei = math.max(math.abs(start), math.abs(stop)) + smua.source.leveli = 0 + -- Set the DC bias limit. This is not the limit used during the pulses. + smua.source.limitv = 1 + + -- Disabling Auto-Ranging and Auto-Zero ensures accurate and consistent timing + smua.measure.autozero = smua.AUTOZERO_ONCE + smua.measure.autorangev = smua.AUTORANGE_OFF + smua.measure.rangev = limitV + smua.measure.nplc = nplc + -- A timer will be used to control the measure delay 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 + + -- Configure the Trigger Model + --============================ + -- Pressing the TRIG button on the front panel will trigger the sweep to start + display.trigger.clear() + + -- Timer 1 controls the pulse period + trigger.timer[1].count = numPoints > 1 and numPoints - 1 or 1 + trigger.timer[1].delay = pulsePeriod + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = display.trigger.EVENT_ID + + -- Timer 2 controls the measure delay + trigger.timer[2].count = 1 + -- Set the measure delay long enough so that measurements start after the pulse + -- has settled, but short enough that it fits within the width of the pulse. + trigger.timer[2].delay = pulseWidth - (1/localnode.linefreq)*nplc - 60e-6 + trigger.timer[2].passthrough = false + trigger.timer[2].stimulus = trigger.timer[1].EVENT_ID + + -- Timer 3 controls the pulse width + trigger.timer[3].count = 1 + trigger.timer[3].delay = pulseWidth + trigger.timer[3].passthrough = false + trigger.timer[3].stimulus = trigger.timer[1].EVENT_ID + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.lineari(start, stop, numPoints) + smua.trigger.source.limitv = limitV + smua.trigger.measure.action = 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 + smua.trigger.arm.stimulus = 0 + smua.trigger.source.stimulus = trigger.timer[1].EVENT_ID + smua.trigger.measure.stimulus = trigger.timer[2].EVENT_ID + smua.trigger.endpulse.stimulus = trigger.timer[3].EVENT_ID + smua.trigger.source.action = smua.ENABLE + --============================== + -- End Trigger Model Configuration + + smua.source.output = smua.OUTPUT_ON + + -- Start the trigger model execution + smua.trigger.initiate() + -- Sweep will not start until the TRIG button is pressed + + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end diff --git a/TSP_Examples/26xxB/Sweeps/.vscode/settings.json b/TSP_Examples/26xxB/Sweeps/.vscode/settings.json new file mode 100644 index 0000000..590e63d --- /dev/null +++ b/TSP_Examples/26xxB/Sweeps/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\2602B\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/config.tsp.json b/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..1188711 --- /dev/null +++ b/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "2602B" +} \ No newline at end of file diff --git a/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/tspSchema.json b/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/26xxB/Sweeps/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/26xxB/Sweeps/KE26XXB_AC_Waveform_Sweep.tsp b/TSP_Examples/26xxB/Sweeps/KE26XXB_AC_Waveform_Sweep.tsp new file mode 100644 index 0000000..3f5a469 --- /dev/null +++ b/TSP_Examples/26xxB/Sweeps/KE26XXB_AC_Waveform_Sweep.tsp @@ -0,0 +1,119 @@ +--[[ + Title: KE26XXB AC Waveform Sweep + + Description: This example demonstrates how to output an AC Waveform + with the Series 2600B System SourceMeter instruments. This + example script shows how to use the math capabilities of the TSP + scripting engine to generate a table of source values representing + a sine wave to use as the list values for a list sweep. This + script also shows how to configure the Series 2600B trigger model + to output this waveform with consistent timing. + At the conclusion of the sweeps the data is returned to the + instrument console in a format that is compatible for copy and + paste into Microsoft Excel. + + Equipment Needed: + 1x Series 2600B SourceMeter instrument + + Script Functions: + AC_Waveform_Sweep(Vrms, numCycles, frequency, limitI) +--]] + +--[[ + Name: AC_Waveform_Sweep(Vrms, numCycles, frequency, limitI) + + Description: + This function demonstrates how to configure the SMU to output a + AC waveform using the list sweep function. + At the conclusion of the sweep the collected data is printed back + to the instrument console in a format that is compatible for copy + and paste into Microsoft Excel. + + Parameters: + Vrms: The desired RMS voltage of the sinewave + numCycles: The number of sinewave cycles to output + frequency: The frequency of the sinewave + limitI: The current limit of the output + + Notes: + RMS voltage is smaller than peak voltage. RMS voltage must be set + low enough that peak voltage fits within the maximum voltage + source range of the SourceMeter instrument. + Maximum frequency is approximately 1000 Hz depending on the + quality of sine wave desired. + + Example Usage: + AC_Waveform_Sweep(12, 2, 60, 100e-3) +--]] +function AC_Waveform_Sweep(Vrms, numCycles, frequency, limitI) + reset() + + -- Generate the source values + local Vpp = Vrms * math.sqrt(2) + local sourceValues = {} + local pointsPerCycle = 7200 / frequency + local numDataPoints = pointsPerCycle * numCycles + + for i=1, numDataPoints do + sourceValues[i] = (Vpp * math.sin(i * 2 * math.pi / pointsPerCycle)) + end + + -- Configure the SMU ranges + smua.reset() + smua.source.settling = smua.SETTLE_FAST_POLARITY + smua.source.autorangev = smua.AUTORANGE_OFF + smua.source.autorangei = smua.AUTORANGE_OFF + smua.source.rangev = Vpp + smua.source.limiti = limitI + + smua.measure.autorangev = smua.AUTORANGE_OFF + smua.measure.autorangei = smua.AUTORANGE_OFF + smua.measure.autozero = smua.AUTOZERO_OFF + -- Voltage will be measured on the same range as the source range + smua.measure.rangei = limitI + smua.measure.nplc = 0.001 + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure the trigger model + --============================ + + -- Timer 1 controls the time between source points + trigger.timer[1].delay = (1 / 7200) + trigger.timer[1].passthrough = true + trigger.timer[1].stimulus = smua.trigger.ARMED_EVENT_ID + trigger.timer[1].count = numDataPoints - 1 + + -- Configure the SMU trigger model + smua.trigger.source.listv(sourceValues) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numDataPoints + 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 + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end diff --git a/TSP_Examples/26xxB/Sweeps/KE26XXB_DC_Sweeps.tsp b/TSP_Examples/26xxB/Sweeps/KE26XXB_DC_Sweeps.tsp new file mode 100644 index 0000000..4796a1e --- /dev/null +++ b/TSP_Examples/26xxB/Sweeps/KE26XXB_DC_Sweeps.tsp @@ -0,0 +1,405 @@ +--[[ + Title: KE26XXB DC Sweeps + + Description: This script demonstrates how to output simple auto- + ranged DC sweeps with the Series 2600B System SourceMeter + instruments. This script contains functions to perform linear, + log and list sweeps. + For each sweep type there are two functions. One function + performs the sweep sourcing voltage while the other performs the + sweep sourcing current. + At the conclusion of the sweeps the data is returned to the + instrument console in a format that is compatible for copy and + paste into Microsoft Excel. + + Equipment Needed: + 1x Series 2600B SourceMeter instrument + + Script Functions: + DCSweepVLinear(start, stop, numPoints, limitI, nplc) + DCSweepILinear(start, stop, numPoints, limitV, nplc) + DCSweepVLog(start, stop, numPoints, limitI, nplc) + DCSweepILog(start, stop, numPoints, limitV, nplc) + DCSweepVList(sweepList, numPoints, limitI, nplc) + DCSweepIList(sweepList, numPoints, limitV, nplc) +--]] + +--[[ + Name: DCSweepVLinear(start, stop, numPoints, limitI, nplc) + + Description: + This function performs an autoranged DC linear voltage sweep. It + demonstrates the simplest trigger model configuration to perform + this sweep. + + Parameters: + start: The voltage level of the first step in the sweep in volts + stop: The voltage level of the last step in the sweep in volts + numPoints: The number of points in the sweep + limitI: The current limit of the source in amps + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepVLinear(0, 10, 11, 0.1, 1) +--]] +function DCSweepVLinear(start, stop, numPoints, limitI, nplc) + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.limiti = limitI + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.linearv(start, stop, numPoints) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: DCSweepILinear(start, stop, numPoints, limitV, nplc) + + Description: + This function performs an autoranged DC linear current sweep. It + demonstrates the simplest trigger model configuration to perform + this sweep. + + Parameters: + start: The current level of the first step in the sweep in amps + stop: The current level of the last step in the sweep in amps + numPoints: The number of points in the sweep + limitV: The voltage limit of the source in volts + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepILinear(0, 10e-3, 11, 10, 1) +--]] +function DCSweepILinear(start, stop, numPoints, limitV, nplc) + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + smua.source.limitv = limitV + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.lineari(start, stop, numPoints) + smua.trigger.source.limitv = limitV + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: DCSweepVLog(start, stop, numPoints, limitI, nplc) + + Description: + This function performs an autoranged DC log voltage sweep. It + demonstrates the simplest trigger model configuration to perform + this sweep. + + Parameters: + start: The voltage level of the first step in the sweep in volts + stop: The voltage level of the last step in the sweep in volts + numPoints: The number of points in the sweep + limitI: The current limit of the source in amps + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepVLog(1, 10, 11, 0.1, 1) +--]] +function DCSweepVLog(start, stop, numPoints, limitI, nplc) + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.limiti = limitI + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.logv(start, stop, numPoints, 0) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: DCSweepILog(start, stop, numPoints, limitV, nplc) + + Description: + This function performs an autoranged DC log current sweep. It + demonstrates the simplest trigger model configuration to perform + this sweep. + + Parameters: + start: The current level of the first step in the sweep in amps + stop: The current level of the last step in the sweep in amps + numPoints: The number of points in the sweep + limitV: The voltage limit of the source in volts + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepILog(1e-3, 10e-3, 11, 10, 1) +--]] +function DCSweepILog(start, stop, numPoints, limitV, nplc) + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + smua.source.limitv = limitV + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.logi(start, stop, numPoints, 0) + smua.trigger.source.limitv = limitV + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: DCSweepVList(sweepList, numPoints, limitI, nplc) + + Description: + This function performs an autoranged DC list voltage sweep. It demonstrates + the simplest trigger model configuration to perform this sweep. + + Parameters: + sweeplist: A table of values to source during the sweep + numPoints: The number of points to source in the sweep + limitI: The current limit of the source in amps + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepVList({3,1,4,5,2}, 5, 0.1, 1) + DCSweepVList(nil, 12, 0.1, 1) +--]] +function DCSweepVList(sweepList, numPoints, limitI, nplc) + -- If the user does not include a table of values then generate one. + if sweepList == nil or type(sweepList) ~= "table" then + sweepList = {1, 5, 2, 6, 3, 7, 4, 8, 5, 9, 6, 10} + end + + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCVOLTS + smua.source.limiti = limitI + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.listv(sweepList) + smua.trigger.source.limiti = limitI + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end + +--[[ + Name: DCSweepIList(sweepList, numPoints, limitV, nplc) + + Description: + This function performs an autoranged DC list current sweep. It demonstrates + the simplest trigger model configuration to perform this sweep. + + Parameters: + sweeplist: A table of values to source during the sweep + numPoints: The number of points to source in the sweep + limitV: The voltage limit of the source in volts + nplc: The measurment aperture setting in PLCs where 1 PLC = 1/60 s for 60Hz power + + Example Usage: + DCSweepIList({3e-3,1e-3,4e-3,5e-3,2e-3}, 5, 10, 1) + DCSweepIList(nil, 12, 10, 1) +--]] +function DCSweepIList(sweepList, numPoints, limitV, nplc) + -- If the user does not include a table of values then generate one. + if sweepList == nil or type(sweepList) ~= "table" then + sweepList = {1e-3, 5e-3, 2e-3, 6e-3, 3e-3, 7e-3, 4e-3, 8e-3, 5e-3, 9e-3, 6e-3, 10e-3} + end + + reset() + + -- Configure the SMU + smua.reset() + smua.source.func = smua.OUTPUT_DCAMPS + smua.source.limitv = limitV + smua.measure.nplc = nplc + smua.measure.delay = smua.DELAY_AUTO + + -- Prepare the Reading Buffers + smua.nvbuffer1.clear() + smua.nvbuffer1.collecttimestamps = 1 + smua.nvbuffer2.clear() + smua.nvbuffer2.collecttimestamps = 1 + + -- Configure SMU Trigger Model for Sweep + smua.trigger.source.listi(sweepList) + smua.trigger.source.limitv = limitV + smua.trigger.measure.action = smua.ENABLE + smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2) + smua.trigger.endpulse.action = smua.SOURCE_HOLD + -- By setting the endsweep action to SOURCE_IDLE, the output will return + -- to the bias level at the end of the sweep. + smua.trigger.endsweep.action = smua.SOURCE_IDLE + smua.trigger.count = numPoints + smua.trigger.source.action = smua.ENABLE + -- Ready to begin the test + + smua.source.output = smua.OUTPUT_ON + -- Start the trigger model execution + smua.trigger.initiate() + -- Wait until the sweep has completed + waitcomplete() + smua.source.output = smua.OUTPUT_OFF + + -- Print the data back to the Console in tabular format + print("Time\tVoltage\tCurrent") + 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]) + end +end diff --git a/TSP_Examples/26xxB/Sweeps/KE26XXB_Sweeps.pdf b/TSP_Examples/26xxB/Sweeps/KE26XXB_Sweeps.pdf new file mode 100644 index 0000000..3c33553 Binary files /dev/null and b/TSP_Examples/26xxB/Sweeps/KE26XXB_Sweeps.pdf differ diff --git a/TSP_Examples/37xx/.vscode/settings.json b/TSP_Examples/37xx/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/37xx/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/37xx/.vscode/tspConfig/config.tsp.json b/TSP_Examples/37xx/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..94a577b --- /dev/null +++ b/TSP_Examples/37xx/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "3706" +} \ No newline at end of file diff --git a/TSP_Examples/37xx/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/37xx/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/37xx/.vscode/tspConfig/tspSchema.json b/TSP_Examples/37xx/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/37xx/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/37xx/DMM_Advance_Scan.tsp b/TSP_Examples/37xx/DMM_Advance_Scan.tsp new file mode 100644 index 0000000..60cdf7f --- /dev/null +++ b/TSP_Examples/37xx/DMM_Advance_Scan.tsp @@ -0,0 +1,70 @@ + + +--[[ + +This Example does different DMM Readings with scanning + + +Advance_Scan will be doing DCV, 1 NPLC and 10 V range + +Advance_Scan +Using 3706 with switching card in slot 1 + +To Run: +There are three options to run this demonstration script. + +From Test Script Builder + +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Advance_Scan() + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card + + +Rev: 1-EEB + 1.1-Update Function names-EEB +]] + +function Advance_Scan() + +reset() --Reset +-- Setup DC Volts +dmm.func = dmm.DC_VOLTS --Set dmm function to DC volts +dmm.nplc=1 --Set NPLC +dmm.range=100 --Set Range +dmm.configure.set("mydcvolts") --Save setup to mydcvolts +dmm.setconfig("1001:1005","mydcvolts") --Assign configuration to channels +-- Setup Temperature +dmm.func = dmm.TEMPERATURE --Set dmm funciton to Temperature +dmm.nplc=1 --Set NPLC +dmm.transducer=dmm.TEMP_THERMOCOUPLE --Set Temperature sensor to Thermocouple +dmm.refjunction=dmm.REF_JUNCTION_INTERNAL --Set CJC junction to internal +dmm.thermocouple=dmm.THERMOCOUPLE_J --Set to J Thermocouple +dmm.units=dmm.UNITS_FAHRENHEIT --Set units to Fahrenheit +dmm.configure.set("mytemp") --save setup to mytemp +dmm.setconfig("1006:1010","mytemp") --Assign configuration to channels +-- Setup 2 Wire ohms +dmm.func=dmm.TWO_WIRE_OHMS --Set dmm function to 2 wire ohms +dmm.nplc=1 --Set NPLC +dmm.range=100 --Set range +dmm.configure.set("my2wire") --save setup to my2wire +dmm.setconfig("1011:1015","my2wire") --Assign configuration to channels +-- Setup Scan +reading_buffer=dmm.makebuffer(10000) --Create buffer +scan.create("1001:1015") --create scan list +scan.scancount=1 --Set scan count +scan.execute(reading_buffer) --perform scan and save reading to buffer +printbuffer(1,15,reading_buffer) --Print buffer + + +end + +Advance_Scan() + + diff --git a/TSP_Examples/37xx/DMM_Basic_Scan.tsp b/TSP_Examples/37xx/DMM_Basic_Scan.tsp new file mode 100644 index 0000000..1da6481 --- /dev/null +++ b/TSP_Examples/37xx/DMM_Basic_Scan.tsp @@ -0,0 +1,107 @@ + + +--[[ + + +This Example does same DMM Readings with scanning using scripting commands +instead of the built in scan on the 3706. This method may be better suited for +some applications. + +DMM needs to be configured once then a specified number of readings + are taken. + + +Each setup will be doing DCV, 1 NPLC and 10 V range + +Basic_Scan_1() +Using 3706 with switching card in slot 1 +This setup shows using Exclusive Close Method to close a series of channels then taking +a dmm measurement. Using this method, the programmer must ensure the proper Analog +Backplanes are closed in order to take a measurement + +Basic_Scan_2() +Using a 3706 with switching card in slot 1 +This setup shows using the dmm.close method to close a series of channels then taking +dmm measurement. Using this method, the 3706 ensures proper measurement by opening and +closing all channels needed to take a good measurement. + +****************************************************************************** + NOTE: +The two different methods here achieve the same measurement. However it is important +to note that using any of the close methods associated with channel do not ensure a proper +measurement path. It is left up to the programmer to ensure the proper measurement path. +Examples: If using channel.close, it is possible to have multiple channels +closed that at connected to Analog bus #1 that can affect the accuracy of the measurement. +Another example would if using an channel.exclusiveclose or channel.exclusiveslotclose +it is possible that the proper backplanes are not closed resulting in possible improper measurements + +dmm.measure ensures a good measurement path to the dmm by opening all channels +connected to the measurement analog bus and closing all backplane relays needed. It +also writes the dmm configuration associated with the channel to the dmm. This will +error if channel is configured as no function + +The trade off is that since the dmm.close needs to check for proper measurement path +and write dmm function to the dmm, the method in setup #1 will be a little faster. + + +******************************************************************************* +To Run: +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Basic_Scan_1() or + Basic_Scan_2() + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card + + +Rev: 1-EEB + 1.1-Update Function Names-EEB + + +]] + +function Basic_Scan_1() -- Define Function +reset() -- Reset +reading_buffer=dmm.makebuffer(1000) -- Configure Buffer +reading_buffer.appendmode=1 -- Set buffer to append mode +dmm.func = dmm.DC_VOLTS -- Set measurement function +dmm.nplc=1 -- Set NPLC +dmm.range=10 -- Set Range +channel.setbackplane("1001:1010","1911") -- Set analog backplane 1 to close for each channel in the scan +-- load table with channels in scan +mem_pattern1 = {"1001", "1002", "1003", "1004", "1005", "1006", "1007", "1008", "1009", "1010"} +for i = 1, 10 do -- For, next loop with index i + channel.exclusiveclose(mem_pattern1[i]) -- Exclusive close each channel in mem_pattern1 table per index of i + dmm.measure(reading_buffer) -- do a single dmm measure and put into buffer +end -- End loop +printbuffer(1,10,reading_buffer) -- Print Buffer +end -- End Function + + + + +function Basic_Scan_2() -- Define Function +reset() -- Reset +reading_buffer=dmm.makebuffer(1000) -- Configure Buffer +reading_buffer.appendmode=1 -- Set buffer to append mode +dmm.func = dmm.DC_VOLTS -- Set measurement function +dmm.nplc=1 -- Set NPLC +dmm.range=10 -- Set Range +dmm.configure.set("mydcvolts") -- Save Configuration +dmm.setconfig("1001:1010","mydcvolts") -- Assign configuration to channels +-- load table with channels in scan +mem_pattern1 = {"1001", "1002", "1003", "1004", "1005", "1006", "1007", "1008", "1009", "1010"} +for i = 1, 10 do -- For, next loop with index i + dmm.close(mem_pattern1[i]) -- Dmm.close each channel in mem_pattern1 table per index of i + dmm.measure(reading_buffer) -- do a single dmm measure and put into buffer +end -- End loop +printbuffer(1,10,reading_buffer) -- Print Buffer +end + +Basic_Scan_1() + diff --git a/TSP_Examples/37xx/DMM_Ext_Trig_scan.tsp b/TSP_Examples/37xx/DMM_Ext_Trig_scan.tsp new file mode 100644 index 0000000..9be34ab --- /dev/null +++ b/TSP_Examples/37xx/DMM_Ext_Trig_scan.tsp @@ -0,0 +1,63 @@ + + +--[[ + +This Example does a scan with external trigger to pace an internal measure scan +An external trigger signal will also be generated when channel closed + +DMM_Ext_Trigger will run the program + +DMM_Ext_Trigger +Using 3706 with switching card with a the STP in Slot 1 + +To Run: + +From Test Script Builder + +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type DMM_Ext_Trigger(1) + -Pass the number or scans that you want to run. In the above example 1 is passed + + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card with + +Rev: 1-EEB + 1.1-Update Function Names-EEB + +]] + + + +function DMM_Ext_Trigger(Scan_count) --Function Name that is used to pass the number of scans +reset() --Reset +reading_buffer=dmm.makebuffer(1000) --Configure Buffer +dmm.func = dmm.DC_VOLTS --Set measurement function +dmm.nplc=1 --Set NPLC +dmm.range=10 --Set Range +dmm.configure.set("mydcvolts") --Save Configuration +dmm.setconfig("1001:1010","mydcvolts") --Assign configuration to channels +-- scan.bypass allows unit to fall through the channel stimulus the first time +--through the trigger model. This is useful if you have two unit in external trigger +--mode, one needs to go first to "prime the pump". +--by turning bypass off, 3706 will wait for a trigger BEFORE taking the first measurement +scan.bypass=scan.OFF --Turns scan bypass off, it is on by default +scan.trigger.channel.stimulus = digio.trigger[2].EVENT_ID --Configure Scan Channel Stimulus to Digital [2] +digio.trigger[2].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge input +digio.trigger[2].clear() --Clear Digital line 2 +digio.trigger[1].stimulus=scan.trigger.EVENT_MEASURE_COMP --Configure Digital line[1] to scan channel ready output +digio.trigger[1].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge output +digio.trigger[1].pulsewidth=.001 --Configure output width +scan.create("1001:1010") --Create Scan +scan.scancount=Scan_count --Pass scan count from function call +scan.execute(reading_buffer) --Execute Scan +printbuffer(1,10,reading_buffer) --Print reading in buffer +end --End function + +DMM_Ext_Trigger(1) + diff --git a/TSP_Examples/37xx/DMM_Simple_Scan.tsp b/TSP_Examples/37xx/DMM_Simple_Scan.tsp new file mode 100644 index 0000000..4ce46b6 --- /dev/null +++ b/TSP_Examples/37xx/DMM_Simple_Scan.tsp @@ -0,0 +1,51 @@ + +--[[ + + +This Example does same DMM Readings with scanning +DMM needs to be configured once then a specified number of readings + are taken. + + + +Each setup will be doing DCV, 1 NPLC and 10 V range + +DMM_Simple_Scan() +Using 3706 with switching card in slot 1 + +To Run: +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type DMM_Simple_Scan() + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card + + +Rev: 1-EEB + 1.1-Updated Function Names-EEB + +]] + + +function DMM_Simple_Scan() +-- Sets up 10 channel scan by saving configurations to channels +reset() -- Reset +reading_buffer=dmm.makebuffer(1000) -- Configure Buffer +dmm.func = dmm.DC_VOLTS -- Set measurement function +dmm.nplc=1 -- Set NPLC +dmm.range=10 -- Set Range +dmm.configure.set("mydcvolts") -- Save Configuration +dmm.setconfig("1001:1010","mydcvolts") -- Assign configuration to channels +scan.create("1001:1010") -- create scan +scan.scancount=1 -- Set Scan Count +scan.execute(reading_buffer) -- Execute Scan and save to buffer +printbuffer(1,10,reading_buffer) -- print buffer + +end + +DMM_Simple_Scan() diff --git a/TSP_Examples/37xx/DMM_Single_Measure.tsp b/TSP_Examples/37xx/DMM_Single_Measure.tsp new file mode 100644 index 0000000..acdb80d --- /dev/null +++ b/TSP_Examples/37xx/DMM_Single_Measure.tsp @@ -0,0 +1,67 @@ + +--[[ + +This is an example to do a single DMM Measurement +This Example does same DMM Readings with no switching +DMM needs to be configured once then a specified number of +readings are taken after being triggered + + +This will have two setups + +Each setup will be doing DCV, 1 NPLC and 10 V range + +Single_Measure_1() +Single 3706, no switch cards, reading VIA Analog Backplane, Single reading + +Single_Measure_2() +Single 3706, no switch cards, reading VIA Analog Backplane, 5 readings + + +To Run: +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Single_Measure_1() or Single_Measure_2() + + +Required equipment: +3706 System Switch and Multimeter + +Rev: 1-EEB + 1.1-Update Function Names-EEB + + + +]]-- + + +function Single_Measure_1() +reset() -- reset +dmm.func = dmm.DC_VOLTS -- Set dmm function +dmm.nplc=1 -- Set NPLC +dmm.range=100 -- Set Range +print(dmm.measure()) -- Take dmm measure and print reading +end + +function Single_Measure_2() + +reset() -- reset +reading_buffer=dmm.makebuffer(10) -- configure reading buffer +dmm.func = dmm.DC_VOLTS -- set dmm function +dmm.nplc=1 -- set nplc +dmm.range=10 -- set range +dmm.measurecount=5 -- set measure count +dmm.measure(reading_buffer) -- trigger measure and store reading in buffer +print(printbuffer(1,5, reading_buffer)) -- print buffer + +end + +--Function Copy and Paste +Single_Measure_1() +--Single_Measure_2() + + + diff --git a/TSP_Examples/37xx/DMM_Temp_Scan.tsp b/TSP_Examples/37xx/DMM_Temp_Scan.tsp new file mode 100644 index 0000000..1f33d18 --- /dev/null +++ b/TSP_Examples/37xx/DMM_Temp_Scan.tsp @@ -0,0 +1,53 @@ + +--[[ + +This Example does a Thermocouple Scan + + +Temp_Scan will be doing K T/C Scan + +Temp_Scan +Using 3706 with switching card with a CJC on the STP in Slot 1 (3720,3721) + +To Run: + +From Test Script Builder + +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Temp_Scan() + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card with CJC on STP. + + +Rev: 1-EEB + 1.1-Update Function Names-EEB + + +]] + + + +function Temp_Scan() --create function called Setup_1() +reset() --reset instrument +reading_buffer=dmm.makebuffer(1000) --create buffer +dmm.func = dmm.TEMPERATURE --set function to Temperature +dmm.nplc=1 --set NPLC +dmm.transducer=dmm.TEMP_THERMOCOUPLE -- set sensor to T/C +dmm.refjunction=dmm.REF_JUNCTION_INTERNAL --set Reference Junction to internal +dmm.thermocouple=dmm.THERMOCOUPLE_K --set T/C to K +dmm.units=dmm.UNITS_FAHRENHEIT --set units to F +dmm.configure.set("mytemp") --save DMM setting to mytemp +dmm.setconfig("1001:1005,1017:1021","mytemp") --assign mytemp setting to channels +scan.create("1001:1005,1017:1021") --create scan list +scan.execute(reading_buffer) --execute scan and save readings to buffer +printbuffer(1,10,reading_buffer) --print readings from buffer + +end --end function + +Temp_Scan() diff --git a/TSP_Examples/37xx/NoFunc_Ext_Trig_Scan.tsp b/TSP_Examples/37xx/NoFunc_Ext_Trig_Scan.tsp new file mode 100644 index 0000000..308c8d0 --- /dev/null +++ b/TSP_Examples/37xx/NoFunc_Ext_Trig_Scan.tsp @@ -0,0 +1,51 @@ + + +--[[ + +This Example does a scan with external trigger to pace a no function scan +An external trigger signal will also be generated when channel closed + +NoFunc_Ext_Trig_Scan will run the program + +NoFunc_Ext_Trig_Scan +Using 3706 or 3706-S with switching card with a the STP in Slot 1 + +To Run: + +From Test Script Builder + +1) Load TSP file to 3706 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type NoFunc_Ext_Trig_Scan(1) + -Pass the number or scans that you want to run. In the above example 1 is passed + + +Required equipment: +3706 System Switch and Multimeter +Multiplexer Switch Card with + +Rev: 1-EEB + 1.1-Update Function Names-EEB + + +]] + + + +function NoFunc_Ext_Trig_Scan(Scan_count) --Function Name that is used to pass the number of scans +reset() --Reset +scan.trigger.channel.stimulus = digio.trigger[2].EVENT_ID --Configure Scan Channel Stimulus to Digital [2] +digio.trigger[2].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge input +digio.trigger[2].clear() --Clear Digital line 2 +digio.trigger[1].stimulus=scan.trigger.EVENT_CHANNEL_READY --Configure Digital line[1] to scan channel ready output +digio.trigger[1].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge output +digio.trigger[1].pulsewidth=.001 --Configure output width +scan.create("1001:1010") --Create Scan +scan.scancount=Scan_count --Pass scan count from function call +scan.execute() --Execute Scan +end --End function + +NoFunc_Ext_Trig_Scan(1) \ No newline at end of file diff --git a/TSP_Examples/70xB/.vscode/settings.json b/TSP_Examples/70xB/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/70xB/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/70xB/.vscode/tspConfig/config.tsp.json b/TSP_Examples/70xB/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..a8633b7 --- /dev/null +++ b/TSP_Examples/70xB/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "708B" +} \ No newline at end of file diff --git a/TSP_Examples/70xB/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/70xB/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/70xB/.vscode/tspConfig/tspSchema.json b/TSP_Examples/70xB/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/70xB/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/70xB/NoFunc_Ext_Trig_Scan.tsp b/TSP_Examples/70xB/NoFunc_Ext_Trig_Scan.tsp new file mode 100644 index 0000000..90cc688 --- /dev/null +++ b/TSP_Examples/70xB/NoFunc_Ext_Trig_Scan.tsp @@ -0,0 +1,47 @@ + + +--[[ + +This Example does a scan with external trigger to pace a no function scan +An external trigger signal will also be generated when channel closed + +NoFunc_Ext_Trig_Scan will run the program + +NoFunc_Ext_Trig_Scan +Using 707B or 708B with switching card in Slot 1 + +To Run: + +From Test Script Builder + +1) Load TSP file to Instrument Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type NoFunc_Ext_Trig_Scan(1) + -Pass the number or scans that you want to run. In the above example 1 is passed + + +Required equipment: +70xB System Switch with +Multiplexer Switch Card + +]] + + + +function NoFunc_Ext_Trig_Scan(Scan_count) --Function Name that is used to pass the number of scans +reset() --Reset +scan.trigger.channel.stimulus = digio.trigger[2].EVENT_ID --Configure Scan Channel Stimulus to Digital [2] +digio.trigger[2].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge input +digio.trigger[2].clear() --Clear Digital line 2 +digio.trigger[1].stimulus=scan.trigger.EVENT_CHANNEL_READY --Configure Digital line[1] to scan channel ready output +digio.trigger[1].mode = digio.TRIG_FALLING --Configure Digital I/O line for falling edge output +digio.trigger[1].pulsewidth=.001 --Configure output width +scan.create("1A01:1A10") --Create Scan +scan.scancount=Scan_count --Pass scan count from function call +scan.execute() --Execute Scan +end --End function + +NoFunc_Ext_Trig_Scan(1) diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/settings.json b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/Mixed_Function_Scanning.tsp b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/Mixed_Function_Scanning.tsp new file mode 100644 index 0000000..20e9fb0 --- /dev/null +++ b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/Mixed_Function_Scanning.tsp @@ -0,0 +1,34 @@ +-- Reset the instrument to the default settings +reset() + +-- Establish channel settings for the scan card configuration... +channel.setdmm("101", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_AC_VOLTAGE) +channel.setdmm("101", dmm.ATTR_MEAS_DETECTBW, dmm.DETECTBW_30HZ) +channel.setdmm("102:110", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_DC_VOLTAGE) +channel.setdmm("111:114", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_TEMPERATURE) +channel.setdmm("111:114", dmm.ATTR_MEAS_TRANSDUCER, dmm.TRANS_THERMOCOUPLE) +channel.setdmm("111:114", dmm.ATTR_MEAS_THERMOCOUPLE, dmm.THERMOCOUPLE_K) +channel.setdmm("111:114", dmm.ATTR_MEAS_REF_JUNCTION, dmm.REFJUNCT_SIMULATED) +channel.setdmm("111:114", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_TEMPERATURE, dmm.ATTR_MEAS_SIM_REF_TEMP, 23) +channel.setlabel("101", "ACSource") +channel.setlabel("111", "Reg12VTemp") +channel.setlabel("112", "Reg5VTemp") +channel.setlabel("113", "LoadTemp1") +channel.setlabel("114", "LoadTemp2") +channel.setdmm("121", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_AC_CURRENT) +channel.setdmm("122", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_DC_CURRENT) + +-- Generate the scan... +scan.create("101:114,121,122") +scan.scancount = 10 + +-- Clear and size the buffer... +defbuffer1.clear() +defbuffer1.capacity = 10 * 16 + +-- Start the scan and wait... +trigger.model.initiate() +waitcomplete() + +-- Extract the data... +printbuffer(1, defbuffer1.n, defbuffer1, defbuffer1.readings, defbuffer1.channels) \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Mixed_Function_Scanning/View_this_first.pdf b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/View_this_first.pdf new file mode 100644 index 0000000..b06b76a Binary files /dev/null and b/TSP_Examples/DAQ6510/Mixed_Function_Scanning/View_this_first.pdf differ diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/settings.json b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/PreScan_Monitor/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/PreScan_Monitor.tsp b/TSP_Examples/DAQ6510/PreScan_Monitor/PreScan_Monitor.tsp new file mode 100644 index 0000000..8d811bc --- /dev/null +++ b/TSP_Examples/DAQ6510/PreScan_Monitor/PreScan_Monitor.tsp @@ -0,0 +1,18 @@ +-- monitor temperature on channel 101 +reset() +channel.setdmm("101", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_TEMPERATURE, dmm.ATTR_MEAS_TRANSDUCER, dmm.TRANS_THERMOCOUPLE, dmm.ATTR_MEAS_THERMOCOUPLE, dmm.THERMOCOUPLE_K, dmm.ATTR_MEAS_REF_JUNCTION, dmm.REFJUNCT_INTERNAL) channel.setdmm("101", dmm.ATTR_MEAS_UNIT, dmm.UNIT_CELSIUS) + +-- set limit high on monitor and trigger scan when high limit exceeds +scan.monitor.channel = "101" +scan.monitor.limit.high.value = 30 +scan.monitor.mode = scan.MODE_HIGH + +-- scan 2-wire resistance on channel 102:105 +channel.setdmm("102:105", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_RESISTANCE, dmm.ATTR_MEAS_RANGE_AUTO, dmm.ON) + +-- create scan +scan.create("101:105") +scan.scancount = 10 + +-- initiates the monitoring of channel 101 conditions, which will enable the scan when it crosses the temperature threshold. +trigger.model.initiate() \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/PreScan_Monitor/View_this_first.pdf b/TSP_Examples/DAQ6510/PreScan_Monitor/View_this_first.pdf new file mode 100644 index 0000000..8717e9c Binary files /dev/null and b/TSP_Examples/DAQ6510/PreScan_Monitor/View_this_first.pdf differ diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/settings.json b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/Scanning_4W_Resistors.tsp b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/Scanning_4W_Resistors.tsp new file mode 100644 index 0000000..ecdb319 --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/Scanning_4W_Resistors.tsp @@ -0,0 +1,18 @@ +-- Reset the instrument to the default settings +reset() +scanCount = 100 + +-- set up each channels function, range and offset compensation +channel.setdmm("101, 102", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_4W_RESISTANCE, dmm.ATTR_MEAS_RANGE, 100, dmm.ATTR_MEAS_OFFCOMP_ENABLE, dmm.OCOMP_ON) +channel.setdmm("103, 104", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_4W_RESISTANCE, dmm.ATTR_MEAS_RANGE, 10, dmm.ATTR_MEAS_OFFCOMP_ENABLE, dmm.OCOMP_ON) +channel.setdmm("105, 106", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_4W_RESISTANCE, dmm.ATTR_MEAS_RANGE, 1, dmm.ATTR_MEAS_OFFCOMP_ENABLE, dmm.OCOMP_ON) + +-- set up Scan +scan.add("101,102,103,104,105,106") +scan.scancount = 100 + +-- set up trigger model +trigger.model.initiate() + +-- wait till scan completes +waitcomplete() diff --git a/TSP_Examples/DAQ6510/Scanning_4W_Resistors/View_this_first.pdf b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/View_this_first.pdf new file mode 100644 index 0000000..fecccc0 Binary files /dev/null and b/TSP_Examples/DAQ6510/Scanning_4W_Resistors/View_this_first.pdf differ diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/settings.json b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/Scanning_Low_Level_DCV.tsp b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/Scanning_Low_Level_DCV.tsp new file mode 100644 index 0000000..5925f6a --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/Scanning_Low_Level_DCV.tsp @@ -0,0 +1,30 @@ +-- Reset the instrument to the default settings +reset() +channelCount = 6 +scanCount = 10 +bufferSize = channelCount * scanCount +defbuffer1.capacity = bufferSize + +scan.buffer = defbuffer1 -- not necessary when using the default buffer, but added to show command use case + +-- set up channels +channel.setdmm("101:106", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_DC_VOLTAGE, dmm.ATTR_MEAS_RANGE_AUTO, dmm.ON, dmm.ATTR_MEAS_AUTO_ZERO, dmm.ON, dmm.ATTR_MEAS_NPLC, 5) + +-- set up Scan +scan.add("101:106") +scan.scancount = scanCount + +-- set up trigger model +trigger.model.initiate() + +-- print measurement data to console +i = 1 +while i <= bufferSize do + delay(2) + lastIndex = defbuffer1.n + printbuffer(i, lastIndex, defbuffer1.readings) + i = lastIndex + 1 +end + +-- save buffer data from defbuffer1 to USB +buffer.save(defbuffer1, "/usb1/MyData.csv") \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/View_this_first.pdf b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/View_this_first.pdf new file mode 100644 index 0000000..449016a Binary files /dev/null and b/TSP_Examples/DAQ6510/Scanning_Low_Level_DCV/View_this_first.pdf differ diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/settings.json b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/Scanning_Temperature_with_Thermocouples.tsp b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/Scanning_Temperature_with_Thermocouples.tsp new file mode 100644 index 0000000..3e4df45 --- /dev/null +++ b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/Scanning_Temperature_with_Thermocouples.tsp @@ -0,0 +1,30 @@ +-- Reset the instrument to the default settings +reset() + +-- Set up channel settings for Slot 1 +channel.setdmm("101:110", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_TEMPERATURE) +channel.setdmm("101:110", dmm.ATTR_MEAS_TRANSDUCER, dmm.TRANS_THERMOCOUPLE) +channel.setdmm("101:110", dmm.ATTR_MEAS_THERMOCOUPLE, dmm.THERMOCOUPLE_K) +channel.setdmm("101:110", dmm.ATTR_MEAS_REF_JUNCTION, dmm.REFJUNCT_INTERNAL) +channel.setdmm("101:110", dmm.ATTR_MEAS_OPEN_DETECTOR, dmm.ON) + +-- set up Scan +scan.create("101:110") + +-- Set the scan count to 24hrs * 60min/hr = 1440 +scan.scancount = 1440 + +-- Set the time between scans to 60s +scan.scaninterval = 6.000e+01 + +-- Ensure data gets written to a connected USB drive after each scan +scan.export("/usb1/scan24hr.csv", scan.WRITE_AFTER_SCAN, buffer.SAVE_RELATIVE_TIME) + +-- Enable scan restart after power failure +scan.restart = scan.ON + +-- Trigger to start the scan... +trigger.model.initiate() + +-- Ensure that the display shows the SCAN swipe and carousel +display.changescreen(display.SCREEN_SCAN_SWIPE) \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/View_this_first.pdf b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/View_this_first.pdf new file mode 100644 index 0000000..9c467d9 Binary files /dev/null and b/TSP_Examples/DAQ6510/Scanning_Temperature_with_Thermocouples/View_this_first.pdf differ diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/settings.json b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..e983277 --- /dev/null +++ b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DAQ6510" +} \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DAQ6510/Speed_Scanning/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/Speed_Scanning.tsp b/TSP_Examples/DAQ6510/Speed_Scanning/Speed_Scanning.tsp new file mode 100644 index 0000000..a292c86 --- /dev/null +++ b/TSP_Examples/DAQ6510/Speed_Scanning/Speed_Scanning.tsp @@ -0,0 +1,59 @@ +-- Set up variables to be referenced during the scan +local scanCnt = 1000 +local sampleCnt = 0 +local chanCnt = 0 +local actualRdgs = 0 +local rcvBuffer = "" + +-- Get the initial timestamp for end-of-run comparison +local x = os.clock() + +-- Reset the instrument and clear the buffer +reset() +defbuffer1.clear() + +-- Set up reading buffer format and establish scan count +format.data = format.ASCII +scan.scancount = scanCnt +-- Configure the scan channels for the Slot 1 card +channel.setdmm("101:120", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_DC_VOLTAGE) +channel.setdmm("101:120", dmm.ATTR_MEAS_RANGE, 1) +channel.setdmm("101:120", dmm.ATTR_MEAS_RANGE_AUTO, dmm.OFF) +channel.setdmm("101:120", dmm.ATTR_MEAS_AUTO_ZERO, dmm.OFF) +channel.setdmm("101:120", dmm.ATTR_MEAS_DIGITS, dmm.DIGITS_4_5) +channel.setdmm("101:120", dmm.ATTR_MEAS_NPLC, 0.0005) +channel.setdmm("101:120", dmm.ATTR_MEAS_APERTURE, 8.33333e-06) +channel.setdmm("101:120", dmm.ATTR_MEAS_LINE_SYNC, dmm.OFF) +channel.setdmm("101:120", dmm.ATTR_MEAS_LIMIT_ENABLE_1, dmm.OFF) +channel.setdmm("101:120", dmm.ATTR_MEAS_LIMIT_ENABLE_2, dmm.OFF) + +-- Dim the display... +display.lightstate = display.STATE_LCD_OFF + +-- Generate the scan... +scan.create("101:120") +scan.scaninterval = 0.0 +chanCnt = scan.stepcount + +-- Calculate the overall sample count and use it to size the buffer +sampleCnt = scanCnt * chanCnt +defbuffer1.capacity = sampleCnt + +-- Start the scan... +trigger.model.initiate() + +-- Loop to capture and print readings +i = 1 +while i <= sampleCnt do + delay(0.5) + myCnt = defbuffer1.n + -- NOTE: Can be supplemented or replaced by writing to USB + printbuffer(i, myCnt, defbuffer1.readings) + i = myCnt + 1 +end + +-- Turn the display back on... +display.lightstate = display.STATE_LCD_50 + +-- Output the elapsed time to the user +print(string.format("Elapsed Time: %2f\n", os.clock() - x)) \ No newline at end of file diff --git a/TSP_Examples/DAQ6510/Speed_Scanning/View_this_first.pdf b/TSP_Examples/DAQ6510/Speed_Scanning/View_this_first.pdf new file mode 100644 index 0000000..b5831ba Binary files /dev/null and b/TSP_Examples/DAQ6510/Speed_Scanning/View_this_first.pdf differ diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/settings.json b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..226735f --- /dev/null +++ b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM6500" +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/Grading_and_Binning_Resistors.tsp b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/Grading_and_Binning_Resistors.tsp new file mode 100644 index 0000000..04a9a75 --- /dev/null +++ b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/Grading_and_Binning_Resistors.tsp @@ -0,0 +1,61 @@ +-- Reset the instrument to default settings +reset() + +-- Create a user-defined reading buffer that can store up to 1 million readings +local bufferVar = buffer.make(1000000) +bufferVar.clear() + +--Set the measure function to 4-wire resistance +dmm.measure.func = dmm.FUNC_4W_RESISTANCE + +-- Set the number of power line cycles 1 PLC +dmm.measure.nplc = 1 + +-- Immediately update autozero reference measurements and then disable the autozero function +dmm.measure.autozero.once() + +-- Enable offset compensation for more accurate resistance reading +dmm.measure.offsetcompensation.enable = dmm.ON + +-- Configure digital I/O lines 1 through 4 as digital outputs. These I/O lines are used to output binning code to component handler +digio.line[1].mode = digio.MODE_DIGITAL_OUT +digio.line[2].mode = digio.MODE_DIGITAL_OUT +digio.line[3].mode = digio.MODE_DIGITAL_OUT +digio.line[4].mode = digio.MODE_DIGITAL_OUT + +-- Clear digital I/O lines to 0 +digio.line[1].state = digio.STATE_LOW +digio.line[2].state = digio.STATE_LOW +digio.line[3].state = digio.STATE_LOW +digio.line[4].state = digio.STATE_LOW + +-- Configure digital I/0 line 5 as a trigger input used to detect +-- the start-of-test trigger from the component handler +digio.line[5].mode = digio.MODE_TRIGGER_IN + +-- Set trigger detector to detect falling edge +trigger.digin[5].edge = trigger.EDGE_FALLING + +-- Configure digital I/0 line 6 as a trigger output used to send +-- an end-of-test trigger to the component handler +digio.line[6].mode = digio.MODE_TRIGGER_OUT + +-- Output a falling edge trigger +trigger.digout[6].logic = trigger.LOGIC_NEGATIVE + +-- Set width of output trigger pulse to 10 us +trigger.digout[6].pulsewidth = 10E-6 + +-- Trigger pulse is output when the Notify Block generates an event +trigger.digout[6].stimulus = trigger.EVENT_NOTIFY2 + +--Load Component Binning trigger model template +trigger.model.load("GradeBinning", 100, 5, .1, .1, 120, 80, 15, 4, 110, 90, 1, 105, 95, 2, 101, 99, 3, bufferVar) + +--Initiate trigger model and wait until finished +trigger.model.initiate() +waitcomplete() + +--Display on front panel USER swipe screen after binning test completes +display.changescreen(display.SCREEN_USER_SWIPE) +display.settext(display.TEXT1, "Test Completed") \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/View_this_first.pdf b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/View_this_first.pdf new file mode 100644 index 0000000..33cfafd Binary files /dev/null and b/TSP_Examples/DMM6500/Grading_and_Binning_Resistors/View_this_first.pdf differ diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/settings.json b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..226735f --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM6500" +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/Measuring_4W_Res_with_OCOMP.tsp b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/Measuring_4W_Res_with_OCOMP.tsp new file mode 100644 index 0000000..7cb9a90 --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/Measuring_4W_Res_with_OCOMP.tsp @@ -0,0 +1,22 @@ +--Reset the Model DMM6500 to the default settings. +reset() + +--Set the measure function to 4-wire resistance. +dmm.measure.func = dmm.FUNC_4W_RESISTANCE + +--Enable autorange. +dmm.measure.autorange = dmm.ON + +--Enable autozero. +dmm.measure.autozero.enable = dmm.ON + +--Enable offset compensation. +dmm.measure.offsetcompensation.enable = dmm.ON + +--Set the number of power line cycles to 1. +dmm.measure.nplc = 1 + +--Read the resistance value. +print(dmm.measure.read()) + + diff --git a/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/View_this_first.pdf b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/View_this_first.pdf new file mode 100644 index 0000000..d28a04a Binary files /dev/null and b/TSP_Examples/DMM6500/Measuring_4W_Res_with_OCOMP/View_this_first.pdf differ diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/settings.json b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..226735f --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM6500" +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/Measuring_DCV_With_High_Accuracy.tsp b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/Measuring_DCV_With_High_Accuracy.tsp new file mode 100644 index 0000000..ed5386b --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/Measuring_DCV_With_High_Accuracy.tsp @@ -0,0 +1,29 @@ +--Reset the instrument to the default settings. +reset() + +--Set the measure function to DC voltage. +dmm.measure.func = dmm.FUNC_DC_VOLTAGE + +--Set the measurement range to 10 V. +dmm.measure.range = 10 + +--Set the number of power line cycles to 10. +dmm.measure.nplc = 10 + +--Set the input impedance to auto so it selects 10 Gohm for the 10V range. +dmm.measure.inputimpedance = dmm.IMPEDANCE_AUTO + +--Enable autozero. +dmm.measure.autozero.enable = dmm.ON + +--Set the averaging filter type to repeating. +dmm.measure.filter.type = dmm.FILTER_REPEAT_AVG + +--Set filter count to 100. +dmm.measure.filter.count = 100 + +--Enable the filter. +dmm.measure.filter.enable = dmm.ON + +--Read the voltage value. +print(dmm.measure.read()) \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/View_this_first.pdf b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/View_this_first.pdf new file mode 100644 index 0000000..3a4a7df Binary files /dev/null and b/TSP_Examples/DMM6500/Measuring_DCV_With_High_Accuracy/View_this_first.pdf differ diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/settings.json b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..ab2ece3 --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,12 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + "node1": { + "model": "DMM6500" + }, + "node2": { + "model": "DMM6500" + } + }, + "self": "DMM6500" +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/Measuring_Power_Using_Digitizing.tsp b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/Measuring_Power_Using_Digitizing.tsp new file mode 100644 index 0000000..63a951c --- /dev/null +++ b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/Measuring_Power_Using_Digitizing.tsp @@ -0,0 +1,94 @@ +-- Initiate the tsp-link network +tsplink.initialize() + +-- Set a delay of 0.5 seconds. +delay(0.5) + +-- Reset master instrument at node 1 +node[1].reset() + +-- Set up TSP-link trigger line 1 to trigger the subordinate node digitizer. +node[1].tsplink.line[1].mode = tsplink.MODE_TRIGGER_OPEN_DRAIN +node[1].trigger.tsplinkout[1].stimulus = trigger.EVENT_NOTIFY1 + +-- Set up digitize voltage function settings. +node[1].dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE +node[1].dmm.digitize.samplerate = 50000 + +-- Set up digitize voltage range based on voltage applying to the BLE device. +node[1].dmm.digitize.range = 10 + +-- Set up reading buffers. +node[1].defbuffer1.capacity = 50000 + +-- Set up trigger model. +node[1].trigger.model.setblock(1, trigger.BLOCK_NOTIFY, trigger.EVENT_NOTIFY1) +node[1].trigger.model.setblock(2, trigger.BLOCK_WAIT, trigger.EVENT_TSPLINK1) +node[1].trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE, defbuffer1, 50000) + +-- Reset instrument at node 2. +node[2].reset() + +-- Set up TSP-link trigger line 1 to receive a trigger from master node. +node[2].tsplink.line[1].mode = node[2].tsplink.MODE_TRIGGER_OPEN_DRAIN + +-- Set up digitize current function settings. +node[2].dmm.digitize.func = node[2].dmm.FUNC_DIGITIZE_CURRENT +node[2].dmm.digitize.samplerate = 50000 + +-- Set up digitize current range based on maximum current the BLE device can draw. +node[2].dmm.digitize.range = 1 + +-- Set up reading buffers. +node[2].defbuffer1.capacity = 50000 + +-- Set up trigger model. +node[2].trigger.model.setblock(1, node[2].trigger.BLOCK_WAIT, node[2].trigger.EVENT_TSPLINK1) +node[2].trigger.model.setblock(2, node[2].trigger.BLOCK_MEASURE_DIGITIZE, defbuffer1, 50000) + +-- Show graph of measurements on swipe screens. +node[1].display.changescreen(node[1].display.SCREEN_GRAPH_SWIPE) +node[2].display.changescreen(node[2].display.SCREEN_GRAPH_SWIPE) +delay(1.0) + +-- Initiate trigger model on both instruments. +node[2].trigger.model.initiate() +trigger.model.initiate() + +-- Wait for test to complete. +waitcomplete() + +-- Retrieve buffer statistics. +voltage_buffer = node[1].defbuffer1 +voltage_stats = node[1].buffer.getstats(voltage_buffer) +avgVolt = voltage_stats.mean +print(avgVolt .. " Volts") +current_buffer = node[2].defbuffer1 +current_stats = node[2].buffer.getstats(current_buffer) +avgCurr = current_stats.mean +print(avgCurr .. " Amps") + +-- Print results to the USER swipe screen. +node[1].display.changescreen(display.SCREEN_USER_SWIPE) +node[1].display.settext(display.TEXT1, "AVG V: " .. string.format("%.2e", avgVolt) .. " V") +node[1].display.settext(display.TEXT2, "Average Power: Calculating... ") +node[2].display.changescreen(display.SCREEN_USER_SWIPE) +node[2].display.settext(display.TEXT1, "AVG I: " .. string.format("%.2e", avgCurr) .. " A") +node[2].display.settext(display.TEXT2, "Average Power: Calculating... ") + +-- Calculate power using reading index-based method. +power_total = 0 +num_readings = current_buffer.n + +-- Iterate through each current and voltage reading, and calculate power. +for i = 1, num_readings do + current = current_buffer.readings[i] + voltage = voltage_buffer.readings[i] + + -- Keep track of the total power + power_total = power_total + current*voltage +end + +-- Find average power by dividing total power by the number of readings. +average_power = power_total / num_readings +print(average_power .. " Watts") \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/View_this_first.pdf b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/View_this_first.pdf new file mode 100644 index 0000000..2e6657a Binary files /dev/null and b/TSP_Examples/DMM6500/Measuring_Power_Using_Digitizing/View_this_first.pdf differ diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/settings.json b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/settings.json new file mode 100644 index 0000000..954986c --- /dev/null +++ b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [] +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..226735f --- /dev/null +++ b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM6500" +} \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/Scanning_Temperature_to_USB.tsp b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/Scanning_Temperature_to_USB.tsp new file mode 100644 index 0000000..fd606b6 --- /dev/null +++ b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/Scanning_Temperature_to_USB.tsp @@ -0,0 +1,37 @@ +--Reset the instrument to the default settings. +reset() + +--Establish variables to make a measurement every 60 seconds 1440 times (24 hours). +local scanCnt = 24 * 60 --1440 minutes = 24 hours +local chanCnt = 9 +local totalRdgs = scanCnt * chanCnt + +--Empty the buffer and set it to the capacity calculated by totalRdgs. +defbuffer1.clear() +defbuffer1.capacity = totalRdgs + +-- Set up the channels to measure temperature using type K thermocouples using internal reference junction. +channel.setdmm("2:10", dmm.ATTR_MEAS_FUNCTION, dmm.FUNC_TEMPERATURE) +channel.setdmm("2:10", dmm.ATTR_MEAS_UNIT, dmm.UNIT_CELSIUS) +channel.setdmm("2:10", dmm.ATTR_MEAS_NPLC, 1) +channel.setdmm("2:10", dmm.ATTR_MEAS_DIGITS, dmm.DIGITS_5_5) +channel.setdmm("2:10", dmm.ATTR_MEAS_TRANSDUCER, dmm.TRANS_THERMOCOUPLE) +channel.setdmm("2:10", dmm.ATTR_MEAS_THERMOCOUPLE, dmm.THERMOCOUPLE_K) +channel.setdmm("2:10", dmm.ATTR_MEAS_REF_JUNCTION, dmm.REFJUNCT_INTERNAL) + +-- Set up the scan; channel 2 is first available channel on a 2001-TCSCAN card. +scan.create("2:10") +scan.scancount = scanCnt + +-- Set the amount of time for each scan. +scan.scaninterval = 60.0 + +-- Write the data to a USB flash drive at the end of the scan. +scan.export("/usb1/TempData", scan.WRITE_AFTER_SCAN, buffer.COL_ALL) + +-- Start the scan. +trigger.model.initiate() +waitcomplete() + +-- Get the data. +printbuffer(1, defbuffer1.n, defbuffer1) \ No newline at end of file diff --git a/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/View_this_first.pdf b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/View_this_first.pdf new file mode 100644 index 0000000..440bea1 Binary files /dev/null and b/TSP_Examples/DMM6500/Scanning_Temperature_to_USB/View_this_first.pdf differ diff --git a/TSP_Examples/DMM7510/4WResistance/.vscode/settings.json b/TSP_Examples/DMM7510/4WResistance/.vscode/settings.json new file mode 100644 index 0000000..4ae846a --- /dev/null +++ b/TSP_Examples/DMM7510/4WResistance/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..30f8b0d --- /dev/null +++ b/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM7510" +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM7510/4WResistance/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM7510/4WResistance/4WResistance_OComp.tsp b/TSP_Examples/DMM7510/4WResistance/4WResistance_OComp.tsp new file mode 100644 index 0000000..cdc0891 --- /dev/null +++ b/TSP_Examples/DMM7510/4WResistance/4WResistance_OComp.tsp @@ -0,0 +1,60 @@ +--[[ + +Description: This example shows you how to do a 4W resistance measurement with offset compensation +on the Model DMM7510 Graphical Sampling Multimeter. + +The example takes either a single reading or 10 readings. Both setups will be doing a 4W Res at 1 NPLC +and with autorange enabled. + +Single_Measure() +Single DMM7510 reading + +Multi_Measure() +10 DMM7510 readings + +Further information on making accurate 4W resistance measurement, please +refer to the DMM7510 Reference Manual and the Keithley Low Level Measurements Handbook. + + +To Run: +1) Load TSP file to DMM7510 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Single_Measure() + or Multi_Measure() +]] + +function Resistance_Setup() + --Reset the instrument to the default settings. + reset() + --Set the measurement function to four-wire resistance + dmm.measure.func = dmm.FUNC_4W_RESISTANCE + --Enable autozero (set to dmm.OFF to disable) + dmm.measure.autozero.enable = dmm.ON + --Enable offset compensation (set to dmm.OFF to disable) + dmm.measure.offsetcompensation.enable = dmm.ON + --Set the number of power line cycles to 1 + dmm.measure.nplc = 1 +end + +function Single_Measure() + Resistance_Setup() + --Read the resistance value + print(dmm.measure.read()) +end + +function Multi_Measure() + Resistance_Setup() + --Set measure count to 10 for 10 readings + dmm.measure.count = 10 + --start taking measurements + dmm.measure.read() + --print the 10 readings + printbuffer(1, defbuffer1.n, defbuffer1) +end + +--Function Copy and Paste +Single_Measure() +--Multi_Measure() diff --git a/TSP_Examples/DMM7510/4WResistance/View_this_first.pdf b/TSP_Examples/DMM7510/4WResistance/View_this_first.pdf new file mode 100644 index 0000000..ee3b6ef Binary files /dev/null and b/TSP_Examples/DMM7510/4WResistance/View_this_first.pdf differ diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/settings.json b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/settings.json new file mode 100644 index 0000000..4ae846a --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..30f8b0d --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM7510" +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_PowerUp/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/DigitizeV_PowerUp.tsp b/TSP_Examples/DMM7510/DigitizeV_PowerUp/DigitizeV_PowerUp.tsp new file mode 100644 index 0000000..f38b8ff --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_PowerUp/DigitizeV_PowerUp.tsp @@ -0,0 +1,69 @@ +--[[ + +Description: This example shows you how to capture a power-up transient waveform +using the analog edge trigger feature on the Model DMM7510 Graphical Sampling Multimeter. + +This example configures the Model DMM7510 to acquire the 0 to 5V power up behavior on a +buck converter. The sampling rate is set to 1MHz. The data buffer is sized to 10000 +to cover about 10ms of the transient activity at 50% pretrigger and 50% posttrigger distribution. +The analog edge trigger level is set to 3V. This is a single trigger measurement. +The captured waveform can be viewed on the instrument touch screen display. +You can also copy and paste the data from the TSB instrument console to a spreadsheet. + +To Run: +1) Load TSP file to DMM7510 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type Single_EdgeTrigger() + - Turn on the power supply to the buck converter to power up the DUT + +]] -- + +function Single_EdgeTrigger() + --Reset the instrument to default settings + reset() + --Create a local variable to store the number of samples desired + local numofsamples = 10000 + --Set the measurement function to Digitize Voltage to capture the power-up behavior + dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE + --Voltage range must be fixed when using Digitizing Voltage + dmm.digitize.range = 10 + --Set the sample rate to 1MHz to capture any glitch + dmm.digitize.samplerate = 1e6 + --Set aperture to auto to get the highest accuracy measurement for the sampling rate configured + dmm.digitize.aperture = dmm.APERTURE_AUTO + --Changing count is optional. The reading buffer capacity is the determining factor + dmm.digitize.count = 1 + --Set the input impedance to auto so it select 10G for the 10V range + dmm.digitize.inputimpedance = dmm.IMPEDANCE_AUTO + --Set the buffer size to number of samples to capture both pre and post triggerred data + defbuffer1.capacity = numofsamples + --Clear buffer + defbuffer1.clear() + + --Select analog edge trigger to capture the power up behavior + dmm.digitize.analogtrigger.mode = dmm.MODE_EDGE + --Set edge slope to detect a rising edge + dmm.digitize.analogtrigger.edge.slope = dmm.SLOPE_RISING + --Set edge level trigger to 3V for the 5V steadystate output + dmm.digitize.analogtrigger.edge.level = 3 + + --Change to graph screen + display.changescreen(display.SCREEN_GRAPH) + + --Define a trigger model that will capture 50% pre and 50% post triggered data + trigger.model.setblock(1, trigger.BLOCK_MEASURE_DIGITIZE, defbuffer1, trigger.COUNT_INFINITE) + trigger.model.setblock(2, trigger.BLOCK_WAIT, trigger.EVENT_ANALOGTRIGGER) + trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE, defbuffer1, numofsamples / 2) + + trigger.model.initiate() + --Waits for the trigger model to finish collecting data before proceeding + waitcomplete() + + print("test ended") +end + +--Function Copy and Paste +Single_EdgeTrigger() diff --git a/TSP_Examples/DMM7510/DigitizeV_PowerUp/View_this_first.pdf b/TSP_Examples/DMM7510/DigitizeV_PowerUp/View_this_first.pdf new file mode 100644 index 0000000..f8c5f2b Binary files /dev/null and b/TSP_Examples/DMM7510/DigitizeV_PowerUp/View_this_first.pdf differ diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/settings.json b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/settings.json new file mode 100644 index 0000000..4ae846a --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..30f8b0d --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM7510" +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/DigtizeV_RippleVoltage.tsp b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/DigtizeV_RippleVoltage.tsp new file mode 100644 index 0000000..dd3186a --- /dev/null +++ b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/DigtizeV_RippleVoltage.tsp @@ -0,0 +1,63 @@ +--[[ + +Description: This example shows you how capture a repetitive voltage waveform using +the Model DMM7510 Graphical Sampling Multimeter. + +This example configures the Model DMM7510 to acquire a mV 50kHz ripple at 5V DC offset +using the Digitize Voltage function. + +This is a one-shot measurement that captures about 5 ripples at 1MSample/sec sampling rate. +The signal coupling remains at default DC coupling. The count is set to 100. The digitize +voltage range is at 10V. The waveform captured can be viewed on the instrument touch screen +display. You can also copy and paste the data from the TSB instrument console to a spreadsheet. + +To Run: +1) Load TSP file to DMM7510 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - Make sure the ripple voltage is presented on the input terminals of the DMM + - At the TSP> prompt in the Instrument Control Panel, type Single_Digitize() + +]] -- + +function Single_Digitize() + --Reset the instrument to default settings. + reset() + --Create a local variable to store the number of samples desired + local numofsamples = 100 + --Set the measurement function to Digitize Voltage to capture the ripple waveform + dmm.digitize.func = dmm.FUNC_DIGITIZE_VOLTAGE + --Voltage range must be fixed when using Digitizing Voltage + dmm.digitize.range = 10 + --Set the sample rate to 1MS/s to sample a 50kHz voltage ripple + dmm.digitize.samplerate = 1e6 + --Set the aperture to auto to get the highest accuracy measurement for the sampling rate configured + dmm.digitize.aperture = dmm.APERTURE_AUTO + --Set the sample count to the number of samples to capture about 5 ripples + dmm.digitize.count = numofsamples + --Set the input impedance to auto so it select 10G for the 10V range + dmm.digitize.inputimpedance = dmm.IMPEDANCE_AUTO + --Set the buffer to align with the number of samples. This is optional + defbuffer1.capacity = numofsamples + --Clear buffer + defbuffer1.clear() + --Make sure your signal is connected to the DMM. Digitize now... + dmm.digitize.read() + + --Print the measurement + if defbuffer1.n > 0 then + print("Ripple Voltage:") + print("Total number of readings:", defbuffer1.n) + printbuffer(1, defbuffer1.n, defbuffer1) + print("Timestamps:") + printbuffer(1, defbuffer1.n, defbuffer1.relativetimestamps) + else + print("No data collected") + end + print("Test Ended") +end + +--Function Copy and Paste +Single_Digitize() diff --git a/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/View_this_first.pdf b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/View_this_first.pdf new file mode 100644 index 0000000..30115a6 Binary files /dev/null and b/TSP_Examples/DMM7510/DigitizeV_RippleVoltage/View_this_first.pdf differ diff --git a/TSP_Examples/DMM7510/SampleTemperature/.vscode/settings.json b/TSP_Examples/DMM7510/SampleTemperature/.vscode/settings.json new file mode 100644 index 0000000..4ae846a --- /dev/null +++ b/TSP_Examples/DMM7510/SampleTemperature/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "files.associations": { + "*.tsp": "lua" + }, + "Lua.diagnostics.libraryFiles": "Disable", + "Lua.workspace.ignoreDir": [], + "Lua.workspace.library": [ + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\Helper", + "c:\\Users\\esarver1\\.vscode\\extensions\\tektronix.tsp-toolkit-0.16.1\\node_modules\\@tektronix\\keithley_instrument_libraries\\keithley_instrument_libraries\\DMM7510\\AllTspCommands" + ] +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/config.tsp.json b/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/config.tsp.json new file mode 100644 index 0000000..30f8b0d --- /dev/null +++ b/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/config.tsp.json @@ -0,0 +1,6 @@ +{ + "$schema": "./tspSchema.json", + "nodes":{ + }, + "self": "DMM7510" +} \ No newline at end of file diff --git a/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/nodeTable.tsp b/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/nodeTable.tsp new file mode 100644 index 0000000..e69de29 diff --git a/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/tspSchema.json b/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/tspSchema.json new file mode 100644 index 0000000..e23154c --- /dev/null +++ b/TSP_Examples/DMM7510/SampleTemperature/.vscode/tspConfig/tspSchema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "nodes": { + "type": "object", + "patternProperties": { + "^node\\d+$": { + "type": "object", + "properties": { + "model": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + }, + "slots": { + "type": "object", + "patternProperties": { + "^slot\\d+$": { + "type": "string" + } + }, + "minProperties": 1 + } + }, + "required": ["model"] + } + } + }, + "self": { + "type": "string", + "enum": ["2450","2460","2461","2470","2601B","2602B","2604B","2611B","2612B","2614B","2634B","2635B","2636B","DMM7510"] + } + } + + } \ No newline at end of file diff --git a/TSP_Examples/DMM7510/SampleTemperature/TempInterval.tsp b/TSP_Examples/DMM7510/SampleTemperature/TempInterval.tsp new file mode 100644 index 0000000..f512ea2 --- /dev/null +++ b/TSP_Examples/DMM7510/SampleTemperature/TempInterval.tsp @@ -0,0 +1,98 @@ +--[[ + +Description: This is example shows you how to do RTD temperature measurements at a fixed interval +on the Model DMM7510 Graphical Sampling Multimeter. + +A temperature reading will be taken every minute (60seconds) over a 24hour period. +This is equivalent to 1440 readings. The bottom half of the instrument display will change to a +graphical view of the temperature profile. If you swipe to USER swipe screen, the displayed message +shows the status of the test. +The temperature readings and the corresponding timestamps can be +printed on the TSB console at the end of the test. +This example configures the DMM to perform 4 wire RTD temperature measurement using a PT100. The +measurement is done at 1 NPLC with offsetcompensation enabled. + +To Run: +1) Load TSP file to DMM7510 Memory + - Select the .tsp file of interest + - Press the run arrow in Test Script Builder Main Menu + +2) Run Program + - At the TSP> prompt in the Instrument Control Panel, type ConfigureTemperature() + and then SetupTimer() and then press the TRIGGER key on the front panel. + Type PrintResults() at the TSP> prompt to print the temperature readings and timestamps. + +]] -- + +function ConfigureTemperature() + --Reset the instrument to default settings + reset() + + --Establish variables to take a measurement every 60 seconds for 1440 times (24 hours) + MeasCount = 1440 --24 hours + MeasInterval = 60 --60 seconds + --Set the measure function to temperature + dmm.measure.func = dmm.FUNC_TEMPERATURE + --Configure to measure 4-wire RTD + dmm.measure.transducer = dmm.TRANS_FOURRTD + --Enable the detection of open leads + dmm.measure.opendetector = dmm.ON + --Select four-wire RTD type to be a Pt100 sensor + dmm.measure.fourrtd = dmm.RTD_PT100 + --Set the number of power line cycles to 1 + dmm.measure.nplc = 1 + --Enable offset compensation for more accurate reading + dmm.measure.offsetcompensation.enable = dmm.ON + --Change to graph swipe screen + display.changescreen(display.SCREEN_GRAPH_SWIPE) +end + +function SetupTimer() + --Set up timer 1 + trigger.timer[1].reset() + --Timer delays each time the timer is triggered + trigger.timer[1].delay = MeasInterval + --Set EVENT_NOTIFY to trigger the start of timer + trigger.timer[1].start.stimulus = trigger.EVENT_NOTIFY1 + --Generate timer event once when the timer delay elapses + trigger.timer[1].start.generate = trigger.OFF + --Enables timer + trigger.timer[1].enable = trigger.ON + + --Wait for TRIGGER key from front panel to start trigger model + trigger.model.setblock(1, trigger.BLOCK_WAIT, trigger.EVENT_DISPLAY) + --Send notify to start the timer + trigger.model.setblock(2, trigger.BLOCK_NOTIFY, trigger.EVENT_NOTIFY1) + --Make a measurement and store reading in default buffer + trigger.model.setblock(3, trigger.BLOCK_MEASURE_DIGITIZE, defbuffer1) + --Wait for timer delay to elapse + trigger.model.setblock(4, trigger.BLOCK_WAIT, trigger.EVENT_TIMER1) + --Go to block 2 for set number of times + trigger.model.setblock(5, trigger.BLOCK_BRANCH_COUNTER, MeasCount, 2) + + --Initiate trigger model and wait until finished + trigger.model.initiate() + --The USER swipe screen will show the status of the test + display.clear() + --Prints a message on the user swipe screen to indicate test in progress + display.settext(display.TEXT1, "Test in progress...") + waitcomplete() + --Prints a message on the user swipe screen to indicate test completion + display.clear() + display.settext(display.TEXT1, "Test complete.") +end + +function PrintResults() + --Print the temperature readings and the corresponding timestamps + print("Temperature:") + printbuffer(1, defbuffer1.n, defbuffer1) + print("Timestamps:") + printbuffer(1, defbuffer1.n, defbuffer1.relativetimestamps) +end + +--Function +ConfigureTemperature() +SetupTimer() +--Press the TRIGGER key to start the measurement +--Upon completion +PrintResults() diff --git a/TSP_Examples/DMM7510/SampleTemperature/View_this_first.pdf b/TSP_Examples/DMM7510/SampleTemperature/View_this_first.pdf new file mode 100644 index 0000000..e052135 Binary files /dev/null and b/TSP_Examples/DMM7510/SampleTemperature/View_this_first.pdf differ