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

Can 2450 (Non EC Model) Output a low frequency Square-wave while Measuring Current

Post Reply
Faraday303
Posts: 1
Joined: March 7th, 2020, 12:48 pm
Country: United States

Can 2450 (Non EC Model) Output a low frequency Square-wave while Measuring Current

Post by Faraday303 » March 7th, 2020, 12:56 pm

Hello All,

I have a 2450 and we are trying to use it to output a low frequency (1-5Hz) square wave while measuring current on our FAPI sample while taking XPS measurements. I was wondering if this is even possible using TPS or Lua, I know there are no default AC functions on the machines GUI. I have found things here and there about the 2450 EC model, but not the regular 2450.

Any kind of help is much appreciated

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

Re: Can 2450 (Non EC Model) Output a low frequency Square-wave while Measuring Current

Post by Andrea C » March 8th, 2020, 11:11 am

Yes, it can.
Before you embark, check your firmware level and consider updating. I used 1.7.1e

Here is some code run from JupyterLab. It uses pyVISA to an NI-VISA backend on Windows 10.
I used a LAN connection, but you can use USB or GPIB too. Just update the resource descriptor.

To have good timing control, use of trigger blocks is best.
Trigger Model also gives you timers; program one of those to raise an event at twice your desired square wave freq; use those events to toggle between two voltage levels.
Generally range changes interfere with good timing control. However your slow waveform freq goals could allow for range changes.

Code: Select all


import visa
import time


resource_mgr = visa.ResourceManager()
#optional print available VISA resources on this computer
print (resource_mgr.list_resources())


#get a session/handle for one resource
instrument_resource_string = "TCPIP0::192.168.1.55::inst0::INSTR"
my_instr = resource_mgr.open_resource(instrument_resource_string)

my_instr.write("*IDN?\n")
print("*****")
print(my_instr.read())

src_cmd_list = ["smu.source.configlist.create('"'MY_SOURCE_LIST'"')" ,
                "smu.source.func = smu.FUNC_DC_VOLTAGE",
                "smu.source.range = 2",
                "smu.source.ilimit.level = 0.1",
                "smu.source.readback = smu.OFF",
                "smu.source.level = 0",
                "smu.source.configlist.store('"'MY_SOURCE_LIST'"')",
                "smu.source.level = 0.8",
                "smu.source.configlist.store('"'MY_SOURCE_LIST'"')"]    

for cmd in src_cmd_list:
    my_instr.write(cmd)

#meas config list of one value - using same measure settings for all source levels
meas_cmd_list = ["smu.measure.configlist.create('"'MY_MEAS_LIST'"')",
                "smu.measure.func = smu.FUNC_DC_CURRENT",
                "smu.measure.range = 0.1",
                "smu.measure.nplc = 1",
                "smu.measure.configlist.store('"'MY_MEAS_LIST'"')"]
#consider also auto zero, use of limited auto ranginging, 4W Remote Sense, Front/Rear Terminals, etc.

for cmd in meas_cmd_list:
    my_instr.write(cmd)



#config a timer object for our square wave freq;  timer event_id will be used to control timing of sourcing
my_instr.write("trigger.timer[1].enable = 0")
my_instr.write("trigger.timer[1].reset()")
my_instr.write("trigger.timer[1].clear()")
my_instr.write("trigger.timer[1].delay = 0.5")  #squarewave freq = 2 * this delay
my_instr.write("trigger.timer[1].count = 20")  #squarewave cycles = 0.5 * this count
my_instr.write("trigger.timer[1].start.stimulus = trigger.EVENT_NOTIFY1")
my_instr.write("trigger.timer[1].start.generate = trigger.OFF")
my_instr.write("trigger.timer[1].enable = 1")

#setup trigger blocks
my_instr.write("trigger.model.setblock(1, trigger.BLOCK_BUFFER_CLEAR, defbuffer1)")
my_instr.write("trigger.model.setblock(2, trigger.BLOCK_SOURCE_OUTPUT, smu.ON)")
my_instr.write("trigger.model.setblock(3, trigger.BLOCK_CONFIG_RECALL, '"'MY_SOURCE_LIST'"', 1, '"'MY_MEAS_LIST'"', 1)")
my_instr.write("trigger.model.setblock(4, trigger.BLOCK_NOTIFY, trigger.EVENT_NOTIFY1)")  #start timer
my_instr.write("trigger.model.setblock(5, trigger.BLOCK_WAIT, trigger.EVENT_TIMER1)")
my_instr.write("trigger.model.setblock(6, trigger.BLOCK_CONFIG_NEXT, '"'MY_SOURCE_LIST'"')")
my_instr.write("trigger.model.setblock(7, trigger.BLOCK_MEASURE, defbuffer1, 10)")  #reading count and measure times needs to be managed
my_instr.write("trigger.model.setblock(8, trigger.BLOCK_BRANCH_COUNTER, 20, 5)")  #branch back to block_wait N times
my_instr.write("trigger.model.setblock(9, trigger.BLOCK_SOURCE_OUTPUT, smu.OFF)")

print("TSP commands Loaded")

When ready to run it, do this:

Code: Select all

#run the trigger blocks code
my_instr.write("trigger.model.initiate()")


time.sleep(10)   #TODO:  interrogate instrument for done state
print("done sleeping")
To retrieve the data and plot it:

Code: Select all

import matplotlib.pyplot as plt # http://matplotlib.org/
import numpy as np # http://www.numpy.org/

#retrieve data from the buffer into arrays of floats

current_values = my_instr.query_ascii_values("printbuffer(1, defbuffer1.n, defbuffer1.readings)", container=np.array, separator=',', converter='f')

src_values = my_instr.query_ascii_values("printbuffer(1, defbuffer1.n, defbuffer1.sourcevalues)", container=np.array, separator=',', converter='f')

time_values = my_instr.query_ascii_values("printbuffer(1, defbuffer1.n, defbuffer1.relativetimestamps)", container=np.array, separator=',', converter='f')

debug = 0
if debug == 1:
   print("**** Time Stamps: *******")
   print(time_values)
   print("****")
   print("**** Current: *******")
   print(current_values)
   print("****")
   print("**** Source Values: *******")
   print(src_values)
   print("****")

#plot the data

fig, axs = plt.subplots(1, 2)   #one row, two columns
fig.suptitle('Slow Square Wave from 2450 SMU')

axs[0].plot(time_values, current_values, color='green', marker='o', linestyle='None', linewidth=1, markersize=3)

plt.grid(True)
axs[0].set_title('SMU Current vs. Time')
plt.title('SMU Current vs. Time') # plot label
axs[0].set(xlabel='time (seconds)', ylabel='measured current (amps)')

plt.autoscale(True, True, True)

axs[1].plot(time_values, src_values, color='blue', marker='x', linestyle='None', linewidth=1, markersize=3)   #'rs')
axs[1].set_title('SMU Voltage vs. Time')
axs[1].set(xlabel='time (seconds)', ylabel='source voltage (volts)')

plt.show()
Here is the outcome for a 0v-0.8V squarewave into 100Ω DUT:
2450_slow_squarewave_outcome.PNG
0.8V square wave into 100 ohms
2450_slow_squarewave_outcome.PNG (17.01 KiB) Viewed 440 times

Post Reply

Return to “Solar Cell Measurements”

Who is online

Users browsing this forum: No registered users and 0 guests