Posted 7 months ago by Cole, Shae
I have attempted to use PYVISA package with Python to communicate with SCIP commands with a Keithley 2602B instrument. I get error codes -285 where there seems to be syntax issues. 
When running the following code in python I get an error code -285 unexpected symbol near ':' : 
import pyvisa
# Initialize the VISA resource manager
    rm = pyvisa.ResourceManager()

# Connect to the Keithley 2600
    instrument = rm.open_resource('USB0::0x05E6::0x2602::4422867::INSTR')

# Initialize the instrument
        instrument.write('*RST')  # Reset the instrument to default settings
        
# Select channel A
        instrument.write(':INST:NSEL 1')  # Selects the source meter channel (channel A)
After this issue I noticed that for my Keithley instrument 2602B there are no SCPI commands for this instrument in the manual or at least the one I have. 

I have sense then installed Keithley Test Script Builder and I have connected the instrument but when I run this pre-made script I get a -286 error code -286 with a run time error attempting to index global 'debuffer1' (a nil value): 
--[[
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()
defbuffer1.clear()

--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.
voltage = defbuffer1.sourcevalues
current = defbuffer1
isc = current[1]
mincurr = current[1]
imax = current[1]
voc = voltage[1]
vmax = voltage[1]
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))

Any help would be greatly appreciated! 
Posted 7 months ago by C, Andrea
In Test Script Builder, look for the samples in folders labeled with 2600 such as KE26XXB_Example_Scripts.

In your post, you are attempting to use commands related to different products/different model numbers which have different command set from what the 2602B understands.

Here is some Python code for use with 2600B to carry out a voltage sweep and measure current.
  1. import pyvisa as visa
  2. import time
  3. import sys
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6.  
  7. resource_mgr = visa.ResourceManager()
  8.  
  9. try:
  10.      #get a session/handle for one resource
  11.      #change the instrument_resource_string for YOUR INSTRUMENT  
  12.      #instrument_resource_string = "USB0::0x05E6::0x2602::4566591::INSTR"
  13.      instrument_resource_string = "USB0::0x05E6::0x2636::4597212::INSTR"
  14.      #instrument_resource_string = "TCPIP0::192.168.1.208::INSTR"
  15.      my_instr = resource_mgr.open_resource(instrument_resource_string)
  16. except visa.VisaIOError as e:
  17.      #did not connect.....
  18.      print("Whoops, something went wrong")
  19.      #print(e.args)
  20.      #print(resource_mgr.last_status)
  21.      print(resource_mgr.visalib.last_status)
  22.      sys.exit(1)
  23.  
  24.  
  25. # set some parameters for our session
  26. my_instr.timeout = 25000   #timeout in msec
  27. #my_instr.write_termination = '\n'
  28. my_instr.VI_ATTR_TCPIP_KEEPALIVE = True
  29.     
  30. my_instr.write("*IDN?\n")
  31. print("*****")
  32. print(my_instr.read())
  33.  
  34. # set commands to setup a trigger model linear sweep
  35. num_sweep_pts = 151
  36. cmd_list = ["reset()",
  37.             "errorqueue.clear()",
  38.             "smua.source.func = smua.OUTPUT_DCVOLTS",
  39.             "smua.source.limiti = 100e-3",
  40.             "smua.source.rangev = 2",
  41.             "smua.measure.nplc = 1",
  42.             "smua.measure.delay = smua.DELAY_AUTO",
  43.             "smua.measure.delayfactor = 1.0",
  44.             "smua.measure.lowrangei = 100e-9",
  45.             "smua.nvbuffer1.clear()",
  46.             "smua.nvbuffer1.collecttimestamps = 1",
  47.             "smua.nvbuffer2.clear()",
  48.             "smua.nvbuffer2.collecttimestamps = 1",
  49.             "smua.trigger.source.linearv(-1.0, 1.0, " + str(num_sweep_pts) + ")",
  50.             "smua.trigger.source.limiti = 0.1",
  51.             "smua.trigger.measure.action = smua.ENABLE",
  52.             "smua.trigger.measure.iv(smua.nvbuffer1, smua.nvbuffer2)",
  53.             "smua.trigger.endpulse.action = smua.SOURCE_HOLD",
  54.             "smua.trigger.endsweep.action = smua.SOURCE_IDLE",
  55.             "smua.trigger.count = " + str(num_sweep_pts),
  56.             "smua.trigger.source.action = smua.ENABLE"]    
  57.  
  58. for cmd in cmd_list:
  59.     my_instr.write(cmd)    
  60.     
  61.  
  62. #commands to configure SRQ when SWEEPING bit goes 1 to 0 = sweep is finished
  63. # see Chapter 12 in 2600B Reference Manual
  64. cmd_list2 = ["status.reset()",
  65.              "status.operation.enable = status.operation.SWEEPING",
  66.              "status.operation.sweeping.enable = status.operation.sweeping.SMUA",
  67.              "status.operation.sweeping.ptr = 0",
  68.              "status.operation.sweeping.ntr = status.operation.sweeping.SMUA",
  69.              "status.request_enable = status.OSB"]    
  70.  
  71. for cmd in cmd_list2:
  72.     my_instr.write(cmd)
  73.  
  74.  
  75. #turn output on and run the sweep
  76. my_instr.write("smua.source.output = smua.OUTPUT_ON")
  77.  
  78. t1 = time.perf_counter()
  79.  
  80. # important to read stb once before starting trigger model
  81. print("First status byte polling value: " + str(int(my_instr.read_stb())))   
  82.  
  83. #start the trigger model operation
  84. my_instr.write("smua.trigger.initiate()")  
  85.  
  86. # ********************************************
  87. # setup a polling loop to detect Sweep is finished
  88. #repeat until the MSS (SRQ) bit is set
  89. still_running = True
  90. status_byte = 0
  91. debug = 1
  92.  
  93. # attempts to my_instr.query("print(status.condition)") will be blocked by active trigger model task
  94. # instead use my_instr.read_stb() to obtain status.condition register
  95.  
  96. while still_running:
  97.     status_byte = int(my_instr.read_stb())  #read status byte (status.condition register)
  98.     if debug: print(str(status_byte) + ' - ' + str(bin(status_byte)))    
  99.     if (status_byte & 64) == 64:
  100.          still_running = False
  101.     time.sleep(0.25)  #250msec pause before asking again
  102.  
  103.  
  104. #turn output off
  105. my_instr.write("smua.source.output = smua.OUTPUT_OFF")
  106.  
  107. t2 = time.perf_counter()
  108. print('Test time: {}'.format(t2 - t1))
  109. print("Number of actual smua buffer pts: " + str(my_instr.query('print(smua.nvbuffer1.n)')))   
  110.  
  111. print("Polling loop done, status byte: " + str(int(my_instr.read_stb())))     
  112.  
  113. print('Go get the data.')
  114.  
  115. # retrieve data and graph it
  116.  
  117. #ask for voltage and current; buffer2=voltage
  118. my_instr.write("printbuffer(1, smua.nvbuffer1.n, smua.nvbuffer2.readings,smua.nvbuffer1.readings)")
  119. raw_data = my_instr.read()            #one long comma delimited string
  120.  
  121. print("After data downloaded, status byte: " + str(int(my_instr.read_stb())))   
  122. my_instr.write("status.reset()")
  123. print("Post reset, status byte value: " + str(int(my_instr.read_stb())))  
  124.  
  125. # split yields an array of strings alternating voltage, current, voltage, current
  126. raw_data_array = raw_data.split(",")  
  127.  
  128. volts = []
  129. current = []
  130. abs_current = []
  131.  
  132. # step through the array of strings, step size 2
  133. # place the V and I into their own array of floats
  134. for i in range(0, len(raw_data_array),2):
  135.     volts.append(float(raw_data_array[i]))
  136.     current.append(float(raw_data_array[i+1]))
  137.     abs_current.append(abs(float(raw_data_array[i+1])))   #absolute value of currents for log scale
  138.     
  139. #plot the absolute value of current vs. voltage    
  140. plt.plot(volts, abs_current, 'o-g')
  141.  
  142. x_min = min(volts) * 1.1
  143. x_max = max(volts) * 1.1
  144. y_min = abs(min(abs_current)) / 10
  145. y_max = abs(max(abs_current)) * 10
  146. plt.axis([x_min,x_max,y_min,y_max])
  147. plt.yscale('log')
  148. plt.xscale('linear')
  149. plt.title('Sweep V, Measure I, 1MOhm')
  150. plt.margins(x=0.1, y=0.1)
  151. plt.grid(True)
  152.  
  153. plt.show()
  154.  
  155. save_image = 0
  156. if save_image:
  157.     plt.savefig('alc_plot.png')
Posted 7 months ago by C, Andrea
When running the above code, the following output occurs:
*****
KEITHLEY INSTRUMENTS INC.,MODEL 2636B,4597212,4.0.4

First status byte polling value: 0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
0 - 0b0
192 - 0b11000000
Test time: 3.765706600010162
Number of actual smua buffer pts: 1.51000e+02

Polling loop done, status byte: 128
Go get the data.
After data downloaded, status byte: 128
Post reset, status byte value: 0


 

You must be signed in to post in this forum.