data_table = "GateV DrainI TimeT" -------------------------- Setup based on model number --------------------------- local l_model = localnode.model local l_min_amps local l_min_volts local l_max_amps local l_max_volts local l_volts_fmt if l_model=='2601' or l_model=='2602' then l_min_amps = 1e-12 l_min_volts = 1e-6 l_max_amps = 3 l_max_volts = 40 l_volts_fmt = "+00.0000" end if l_model=='2611' or l_model=='2612' then l_min_amps = 1e-12 l_min_volts = 1e-6 l_max_amps = 1.5 l_max_volts = 200 l_volts_fmt = "+000.000" end if l_model=='2635' or l_model=='2636' then l_min_amps = 10e-15 l_min_volts = 1e-6 l_max_amps = 1.5 l_max_volts = 200 l_volts_fmt = "+000.000" end ------------------------------ Sumit Lua Function ------------------------------ function PulseDualSweepVMeasureI(smu_i, smu_v, bias, start_1, stop_1, ton, toff, points, flush_v, flush_t) --Set level to starting gate voltage level = start_1 --Figure out what the delta V should be based on the number of points and --stop_1 delta_vg = (2 * (stop_1 - start_1)) / (points - 1) -- Default to smua if no smu is specified. if (smu_i == nil) then smu_i = smua end -- Default to smub if no smu is specified. if (smu_v == nil) then smu_v = smub end -- Save settings in temporary variables so they can be restored at the end. local l_s_levelv = smu_v.source.levelv local l_s_rangev = smu_v.source.rangev local l_s_autorangev = smu_v.source.autorangev local l_s_func = smu_v.source.func local l_m_autozero = smu_v.measure.autozero local l_m_filter = smu_v.measure.filter.enable local l_d_screen = display.screen -- Temporary variables used by this function. local l_j, l_tonwm -- Clear the front panel display then prompt for input parameters if missing. -- Do this later inside the conditional loops if (bias == nil) then display.clear() bias = display.prompt(l_volts_fmt, " Volts", "Enter BIAS Voltage.", 0, -l_max_volts, l_max_volts) if (bias == nil) then --Abort if Exit key pressed AbortScript(l_d_screen) end end if (level == nil) then display.clear() level = display.prompt(l_volts_fmt, " Volts", "Enter PULSE Voltage.", 1, -l_max_volts, l_max_volts) if (level == nil) then --Abort if Exit key pressed AbortScript(l_d_screen) end end if (ton == nil) then display.clear() ton = display.prompt("00.000E+00", " Seconds", "Enter pulse ON time.", 20E-3, 0, 20) if (ton == nil) then --Abort if Exit key pressed AbortScript(l_d_screen) end end if (toff == nil) then display.clear() toff = display.prompt("00.000E+00", " Seconds", "Enter pulse OFF time.", 20E-3, 0, 20) if (toff == nil) then --Abort if Exit key pressed AbortScript(l_d_screen) end end if (points == nil) then display.clear() points = display.prompt("0000", " Pulses", "Enter number of pulses", 10, 1, 1000) if points == nil then --Abort if Exit key pressed AbortScript(l_d_screen) end end -- Update display with test info. --display.settext("PulseDualSweepIMeasV") -- Line 1 (20 characters max) -- Configure source and measure settings. --Gate voltage sweeper smu_v.source.output = smu_v.OUTPUT_OFF smu_v.source.rangev = level --smu_v.source.levelv = bias --bias used to mean what is meant in this line smu_v.source.levelv = 0 smu_v.source.func = smu_v.OUTPUT_DCVOLTS smu_v.measure.autozero = smu_v.AUTOZERO_OFF smu_v.measure.filter.enable = smu_v.FILTER_OFF smu_v.source.limiti = 0.0001 --Drain bias step --set source mode to DC VOLTS smu_i.source.func = smu_i.OUTPUT_DCVOLTS --set source to a fixed range - turn autorange off, then set best FIXED smu_i.source.autorangev = smu_i.AUTORANGE_OFF --Default behavior, for without flushed drain voltage: --fixedrange = math.max(math.abs(bias),math.abs(bias)) fixedrange = math.max(math.abs(bias),math.abs(flush_v)) smu_i.source.rangev = fixedrange -- Bias set here smu_i.source.levelv = bias smu_i.source.limiti = 0.001 l_tonwm = 250E-6 -- Setup a buffer to store the result(s) in and start testing. --First buffer smu_v.nvbuffer1.clear() smu_v.nvbuffer1.appendmode = 1 smu_v.nvbuffer1.collecttimestamps = 1 smu_v.nvbuffer1.collectsourcevalues = 1 --Second (and probably last available) buffer smu_i.nvbuffer1.clear() smu_i.nvbuffer1.appendmode = 1 smu_i.nvbuffer1.collecttimestamps = 1 smu_i.nvbuffer1.collectsourcevalues = 1 smu_v.source.output = smu_v.OUTPUT_ON smu_i.source.output = smu_i.OUTPUT_ON for l_j = 1,points do -- Added by Sumit to reduce other possible delays smu_v.measure.delay = 0 smu_i.measure.delay = 0 --smu_v.source.levelv = bias -- Program source to bias level. (old code) smu_v.source.levelv = level -- Program source to Vg bias level. delay(ton) -- Wait for initial bias time, ton. smu_v.source.levelv = level -- Program source to pulse level. delay(l_tonwm) -- Wait pulse time - measurement & overhead time. smu_v.measure.v(smu_v.nvbuffer1) -- Measure gate voltage and store in reading buffer. smu_i.measure.i(smu_i.nvbuffer1) -- Measure current and store in reading buffer. smu_v.source.levelv = 0 -- Return source to bias level. if (flush_t > 0) then delay(toff-flush_t) -- Wait pulse off time. -- original_drain_voltage = smu_i.source.levelv -- Gate-source voltage turned on for flush --smu_v.source.levelv = level -- Drain-source voltage from bias voltage to flush voltage smu_i.source.levelv = flush_v delay(flush_t) -- Gate-source voltage off again --smu_v.source.levelv = 0 -- Return drain-source voltage from flush voltage to bias voltage smu_i.source.levelv = bias else delay(toff) end --Raise/decrease the level if (l_j > points / 2) then level = level - delta_vg else level = level + delta_vg end end smu_v.source.output = smu_v.OUTPUT_OFF smu_i.source.output = smu_i.OUTPUT_OFF -- Update the front panel display and restore modified settings. --display.setcursor(2,1) --display.settext("Test complete.") -- Line 2 (32 characters max) smu_v.source.levelv = 0 smu_v.source.rangev = l_s_rangev smu_v.source.autorangev = l_s_autorangev smu_v.source.func = l_s_func smu_v.source.levelv = l_s_levelv smu_v.measure.autozero = l_m_autozero smu_v.measure.filter.enable = l_m_filter delay(2) display.clear() display.screen = l_d_screen end function AbortScript(screen) --Abort script on nil (typically exit keypress) display.clear() --clear display display.settext("Script Aborted") delay(2) display.clear() --clear display display.screen = screen --show default screen exit() --abort script end --function AbortScript() --Run the desired function --Modified pulsing to make an upward and downward pulse dual sweep --PulseDualSweepVMeasureI(drain current, gate voltage, drain bias, start_vg, stop_vg, t_on, t_off, points, flush voltage, flush time) PulseDualSweepVMeasureI(smua, smub, 50E-3, -10, 10, 1E-3, 100E-3, 202, 6, 0) --Print output data from buffer to screen --Start by defining where the measurement tables used below come from Vdata_1 = smub.nvbuffer1; Idata_1 = smua.nvbuffer1; Tdata_1 = smua.nvbuffer1.timestamps; --Sumit's way of exporting the data --Ideally all measurements have same number of data points counter = 1 datapoints = table.getn(Idata_1) if (datapoints <= 0E0) then datapoints = Idata_1.n end condition = (counter <= datapoints) while (condition) do --Previously: for write_num_2 = 0,read_len_2, 30000 do buf = '' buf_items = 0 --Start: Channel 2 --if voltage requested: collect data table with header - may require multiple READS so first we check the string length if (0 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Vdata_2[counter]) buf_items = buf_items + 1 end --if current requested: collect data table with header - may require multiple READS so first we check the string length if (0 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Idata_2[counter]) buf_items = buf_items + 1 end --if TIME requested: collect data table with header - may require multiple READS so first we check the string length if (0 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Tdata_2[counter]) buf_items = buf_items + 1 end --End: Channel 2 --Start: Channel 1 --if voltage requested: collect data table with header - may require multiple READS so first we check the string length if (1 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Vdata_1[counter]) buf_items = buf_items + 1 end --if current requested: collect data table with header - may require multiple READS so first we check the string length if (1 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Idata_1[counter]) buf_items = buf_items + 1 end --if TIME requested: collect data table with header - may require multiple READS so first we check the string length if (1 == 1) then if (buf_items > 0) then buf = buf .. " " end buf = buf .. tostring(Tdata_1[counter]) buf_items = buf_items + 1 end --End: Channel 1 data_table = data_table .. "\n" .. buf counter = counter + 1 condition = (counter <= datapoints) end print(data_table)