Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

PyVISA with Keithley 2400 SCPI

Hi, I'm trying to ask a Keithley 2440 to loop through relatively fast sets of 4 wire measurements, report the data, and repeat.  I have tried RS232 serial communications with pyserial, which worked alright but was not able to communicate quickly and therefore had a low duty cycle of time collecting data vs. not, so I switched to GPIB (NI GPIB-USB-HS with PyVISA in Python 2.7).  Now I have managed to get the Keithley set up for the right current for the 4 wire measurement, but often have errors of the output not turning off after a given period of time and the Keithley has not successfully reported any values back to my computer with my recent attempts at these controls.  I got most of the SCPI commands from a coworker who was using a LabVIEW program to control his Keithley a couple of years ago.  Current code looks like this:

 

import visa
import numpy as np
from pylab import *
import matplotlib.pyplot as plt
import time

number_loops = 20
count = 10
DIVoutput = np.zeros((count*number_loops,5)) # make sure this is at least larger than loops*trig count!!!!
NPLC = 6
COUNT = 10

rm = visa.ResourceManager()
rm.list_resources()
('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::24::INSTR')
inst = rm.open_resource('GPIB0::24::INSTR')
inst.timeout = 25000 # in milliseconds

time.sleep(0.001)

print(inst.query("*IDN?"))
print(inst.query(':ROUT:TERM?'))

inst.write(':ROUT:TERM FRON')
print(inst.query(':ROUT:TERM?'))

inst.write('*RST')

inst.write(':FORM:ELEM VOLT,CURR,TIME;DATA SREAL;BORD NORM')
inst.write(':SENSE:AVER:TCON MOV OFF')
inst.write(':SYSTEM:AZERO:STAT OFF')
inst.write(':TRIG:DEL 0.0')
inst.write(':SOURCE:DELAY 0.0')
inst.write(':SYST:AZERO OFF')
inst.write(':DISP:ENAB OFF')
inst.write(':SYST:BEEP:STAT OFF')
inst.write(':AVER OFF')
inst.write(':SYST:RSEN ON')
inst.write(':SYST:AZERO ONCE')


for i in range(number_loops):
#START OF LOOP

inst.write(':CURR:NPLC '+str(NPLC)+';')
inst.write(':SOUR:FUNC CURR')
inst.write(':SOUR:CURR 1e-3')
inst.write(":SENS:FUNC 'VOLT:DC'")
inst.write(':VOLT:PROT 5')
inst.write(':OUTP ON')
inst.write(':ARM:COUN 1;:TRIG:COUN '+str(count)+';:SOUR:CURR:MODE FIX;')
inst.write(':ARM:SOUR IMM;:ARM:TIME 0.01;:TRIG:SOUR IMM;:TRIG:DEL 0')
inst.write(':TRIG:CLE;:INIT')
inst.write(':OUTP OFF')

b=inst.query_ascii_values('FETC?')
a=(inst.read())

inst.close()

 

I get errors like "UnicodeDecodeError: 'ascii' codec can't decode byte 0xb3 in position 3: ordinal not in range(128)" when I do this.  

 

 

Does anyone have an example of code that effectively gets 4 wire measurements out of a Keithley at faster than 1 Hz?  I'd be happy with anything that pretty much works and has a higher than 50% "up" time of actually taking measurements.  

 

Thanks in advance for any help.  

0 Kudos
Message 1 of 5
(9,277 Views)

I'm not as familiar with Python, but still wanted to provide some online documentation that might be of some help! Most specifically with the error you are receiving.

 

How to fix: “UnicodeDecodeError: 'ascii' codec can't decode byte”

http://stackoverflow.com/questions/21129020/how-to-fix-unicodedecodeerror-ascii-codec-cant-decode-by...

 

Pragmatic Unicode

http://nedbatchelder.com/text/unipain.html

 

PyVISA Keithley Example

http://pyvisa.readthedocs.io/en/stable/example.html

 

Let me know if this gets you in a good enough spot to move forward!

 

Best,

Chris D. | Applications Engineer | National Instruments

0 Kudos
Message 2 of 5
(9,243 Views)

This line is the culprite - I think:
inst.write(':FORM:ELEM VOLT,CURR,TIME;DATA SREAL;BORD NORM')

"data sreal" is putting the data into binary format when you do a fetc?. Need to set 'data asc' instead. Then you will return ascii data.

 

Binary data is more effcient transfer from the instrument but you have to assemble the raw bytes in to doubles (or char). No idea how to do that in Python. C or C# yes.

0 Kudos
Message 3 of 5
(9,235 Views)

Great, thanks!  I'll try that later today.  I've tried serial and GPIB communications with this tool and, while I can occasionally get some data out of the tool, it has not been fast enough (waits entire length of timeout in serial communications) or enough data (only got 30 points back on GPIB) to meet my needs.  I'll look through this change and Chris's advice and see if I can get it to work.  Thank you for your help!!!

0 Kudos
Message 4 of 5
(9,229 Views)

Not quite sure what you are getting at but this line controls how many readings you will get.

inst.write(':ARM:COUN 1;:TRIG:COUN '+str(count)+';Smiley FrustratedOUR:CURR:MODE FIX;')

 

arm count = 1 is the outer loop of the trigger model

trig count is the number of readings to take. So what ever 'count' is.

0 Kudos
Message 5 of 5
(9,221 Views)