Keithley 2400 GPIB-USB-HS

Hey all,

I am wondering if it is possible to control a Keithley 2400 SMU using a GPIB-USB-HS connector and the VISA extension in Igor. I have activated the VISA extension and see no indication that Igor is communicating with the instrument when I run the VISA XOP tests. I am running Igor 6.36 on Windows 7.

Any thoughts/ideas?

Thank you in advance.
My understanding is that the GPIB-USB-HS controller allows you to control a GPIB device connected via a USB port and that it supports the NI-488.2 driver. Consequently both the VISA XOP and the NIGPIB2 XOP should be able to talk to the instrument provided that you use the right VISA resource name string (e.g., "GPIB0::1::INSTR") or GPIB address for NIGPIB2.

Quote:
see no indication that Igor is communicating with the instrument when I run the VISA XOP tests.


I'm not sure what tests you are referring to. The example code in the documentation for viFindRsrc or viStatusDesc would be a good place to start.

Thank you hrodstein! I realized I had not changed the string as you mentioned to "GPIB0::24::INSTR".

I am able to communicate to the Keithley sourcemeter now evidenced by my ability to read and write attributes. However, now I cannot figure out how I actually send SCPI commands to the sourcemeter. If I wanted to send the keithley source meter "*IDN?" and save its output to a variable, how could I do that?

Thank you again for your help.
Quote:
If I wanted to send the keithley source meter "*IDN?" and save its output to a variable, how could I do that?


Use the VISAWrite operation, and make sure to use the correct terminator - probably "\r\n".

Then use the VISARead operation to read into a string variable.

Read the documentation for VISAWrite and VISARead before proceeding.
Perfect. Thank you again.

For those looking to start with a copy-and-paste IGOR code that works, try this:

NOTE: The code just gets your instrument name and enables and disables the front panel display.

Function Test()
    Variable defaultRM, instr
   
    Variable status

    status = viOpenDefaultRM(defaultRM)
    Printf "DefaultRM=%d\r", defaultRM
   
    String resourceName = "GPIB0::24::INSTR"
   
    status = viOpen(defaultRM, resourceName, 0, 0, instr)
    Printf "instr=%d\r", instr

   
    String variableWrite, variableRead
   
    variableWrite = "*IDN?"
   
    VISAWrite instr, variableWrite
    VISARead/T="\r\n" instr, variableRead
    Print V_flag,V_status
    Print variableRead
   
    variableWrite = ":DISPlay:ENABle 0"
    VISAWrite instr, variableWrite
   
    variableWrite = ":DISPlay:ENABle?"
   
    VISAWrite instr, variableWrite
    VISARead/T="\r\n" instr, variableRead
    Print variableRead
   
    variableWrite = ":DISPlay:ENABle 1"
    VISAWrite instr, variableWrite
   
    variableWrite = ":DISPlay:ENABle?"
   
    VISAWrite instr, variableWrite
    VISARead/T="\r\n" instr, variableRead
    Print variableRead
   
    viClose(instr)
   
    viClose(defaultRM)
End
Nice example.

One note ... VISARead can read into either a numeric or string variable. If you know that the answer from the instrument is numeric, you can provide a local numeric variable as the parameter to VISARead. That way you don't need to do the string-to-number conversion yourself.
Ok, I made it pretty far, but I cannot figure out how to use VISAReadWave. The help file did not help. Here's the problem:

I am successfully sending SCPI commands to the sourcemeter to acquire 20 voltage measurements.
After taking the 20 voltage readings, I send the Query ":TRAC:DATA?", which requests the raw data in the buffer.
Now, if I store that data in a string variable, I can read up to 10 values and print those values successfully without a problem using VISARead:
String dataValues

VISAWrite instr, ":TRAC:DATA?" // Read contents of buffer, i.e. request voltage readings
VISARead/T="" instr, dataValues // Read the buffer and store in 'variableRead'

print dataValues


If I do more than 10 values, I get the "-410 Error Query Interrupted," indicating that I did not read all of the data in the buffer. The obvious solution is to store the data in a wave, but when I try VISAReadWave Igor freezes and stops responding. Here is the code I used to try and store the data in a wave:
Make/O dataValues

VISAWrite instr, ":TRAC:DATA?" // Read contents of buffer, i.e. request raw buffer readings
VISAReadWave/T="" instr, dataValues // Read the buffer and store in 'variableRead'

print dataValues


This just makes Igor freeze and I have to force close it. I suspect it has something to do with the termination character or the data type. I have termination character disabled and "Send End on Writes" enabled, if that helps. Unless I need to use the RQS or EOI from the status byte, but I really have no idea how to implement that.

Thanks for your help. My full code is below:
Function runExp()
    Variable defaultRM, instr

    Variable status
    String variableRead
    Make/D/O dataValues

    status = viOpenDefaultRM(defaultRM)
   
    String resourceName = "GPIB0::24::INSTR"
   
    status = viOpen(defaultRM, resourceName, 0, 0, instr)
   
    VISAWrite instr, "*IDN?"
    VISARead/T="\r\n" instr, variableRead
    Print variableRead

    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*ESE 0" // Program the Standard Event Enable Register
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
    VISAWrite instr, ":FORM:SREG BIN" // Format register to binary
   
    VISAWrite instr, ":STAT:MEAS:ENAB 512" // Enable BFL (Buffer full)
    VISAWrite instr, ":*SRE 1"   // Program the Service Request Enable Register
   
    VISAWrite instr, ":TRAC:FEED:CONT NEVER" // Disable any residual data collection in buffer
    VISAWrite instr, ":TRAC:CLE" // Clear buffer
    VISAWrite instr, ":TRAC:POIN 30" // Specify buffer size, i.e. number of sweep points
   
    VISAWrite instr, ":SOUR:FUNC:MODE CURR" // Select current source mode
    VISAWrite instr, ":SOUR:CURR:STAR 0.001" // Specify start current value
    VISAWrite instr, ":SOUR:CURR:STOP 0.1"  // Specify stop current value
    VISAWrite instr, ":SOUR:CURR:STEP 0.001"  // Specify step current value
    VISAWrite instr, ":SOUR:CLE:AUTO ON" // Automatically turn output off after measurements
    VISAWrite instr, ":SOUR:CURR:MODE SWE" // Select current source sweep mode
    VISAWrite instr, ":SOUR:SWE:SPAC LIN" // Select linear staircase sweep
    VISAWrite instr, ":SOUR:DEL:AUTO OFF" // Source auto delay off
    VISAWrite instr, ":SOUR:DEL 0" // No source delay
   
    VISAWrite instr, ":SENS:FUNC 'VOLT'" // Voltage measure function
    VISAWrite instr, ":SENS:FUNC:CONC ON" // Turn on concurrent functions, allows more than one function to be measured simultaneously
    VISAWrite instr, ":SENS:VOLT:RANG:AUTO OFF" // Disable autovolts range
   
    VISAWrite instr, ":SENS:VOLT:PROT:LEV 20" // Set voltage compliance level
    VISAWrite instr, ":SENS:VOLT:RANG 20" // Set voltage range
   
    VISAWrite instr, ":SENS:VOLT:NPLC 1" // Set volts speed
    VISAWrite instr, ":FORM:ELEM:SENS VOLT" // Format measured elements separated by a comma
    VISAWrite instr, ":TRIG:COUN 30" // Set trigger count
    VISAWrite instr, ":TRIG:DEL 0" // Set trigger delay to zero
    VISAWrite instr, ":SYST:AZER:STAT OFF" // Disable auto-zero
    VISAWrite instr, ":SYST:TIME:RES:AUTO ON"
    VISAWrite instr, ":TRAC:TST:FORM ABS" // Select timestamp format

    VISAWrite instr, ":TRAC:FEED:CONT NEXT" // Fill buffer and stop
    VISAWrite instr, ":OUTP ON" // Turn source output on
    VISAWrite instr, ":INIT" // Trigger readings

    VISAWrite instr, ":TRAC:DATA?" // Read contents of buffer, i.e. request raw buffer readings
    VISAReadWave/T="" instr, dataValues // Read the buffer and store in 'variableRead'
    Print dataValues
   
    VISAWrite instr, "*SRE 0" // Program the Service Request Enable Register
    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
   
    viClose(instr)
    viClose(defaultRM)
   
End

Quote:
I send the Query ":TRAC:DATA?", which requests the raw data in the buffer.


To really know what you are doing, you need to know the precise format of the data being sent by the device, including any separators and terminators. By default VISAReadWave expects either a comma, tab, or carriage return after each number (see /T flag documentation). If the instrument is using something else, for example, linefeeds, you would need to use the /T flag to accommodate that (e.g., /T=",\t\r\n" for comma, tab, CR or LF).

Quote:
Make/D/O dataValues


This makes a 128-point wave. This means that VISAReadWave will try to read 128 numbers with a terminator, as specified by /T, after each one. You should use the Make/N flag to set the number of points in the wave which also controls the number of reads done by VISAReadWave.

Quote:
This just makes Igor freeze and I have to force close it.


Try setting the timeout for a read. According to viRead in http://www.ni.com/pdf/manuals/370132c.pdf, you set this by calling viSetAttribute with the attribute VI_ATTR_TMO_VALUE. See the VISA XOP viSetAttribute documentation for an example of setting an attribute. You can also use viGetAttribute to see what the default timeout is.

You'll find some useful discussion of timeouts and terminators by searching for "Keithley VI_ATTR_TMO_VALUE". This is the first hit and provides some useful information: http://www.keithley.com/data?asset=14711

hrodstein, you are a godsend. I actually got it working perfectly with no errors. HOWEVER, I changed something, and now it won't work again! The VISAReadWave command works and puts the values in one per a row, but for some reason it won't read more than 10 values! If I have 11 values to read, the VISAReadWave command pauses for a long time, and then just puts a 0 for the 11th value, and 12th value, etc. if I add more values. I cannot see where I have made a mistake. The raw string that Igor receives from the instrument is separated by commas as follows:

"+2.000031E+01,+2.000031E+01,+2.000031E+01,+2.000031E+01,+2.000031E+01,+2.000031E+01,+2.000031E+01,+2.000030E+01,+2.000030E+01,+2.000029E+01,+2.000029E+01"

The output in my wave is this:

dataValues[0]= {20.0003,20.0003,20.0003,20.0003,20.0003,20.0003,20.0003,20.0003,20.0003,20.0003,3.47032e-308}

I don't know why Igor would have a problem with anything greater than 10 values. I can even do multiple columns for other data, but more than 10 rows is a problem. I set my timeout to 10 seconds, which is more than enough time.
I greatly appreciate the help; this is causing me a lot of frustration and wasted time. Here is my code:

Function cSweep()
    Variable defaultRM, instr

    Variable status
    String variableRead

    status = viOpenDefaultRM(defaultRM)
   
    String resourceName = "GPIB0::24::INSTR"
   
    status = viOpen(defaultRM, resourceName, 0, 0, instr)
    viSetAttribute(instr, VI_ATTR_TMO_VALUE, 10000)
   
    VISAWrite instr, "*IDN?"
    VISARead/T="\r" instr, variableRead
    Print variableRead

    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*ESE 0" // Program the Standard Event Enable Register
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
    VISAWrite instr, ":FORM:SREG BIN" // Format register to binary
   
    VISAWrite instr, ":STAT:MEAS:ENAB 512" // Enable BFL (Buffer full)
    VISAWrite instr, ":*SRE 1"   // Program the Service Request Enable Register
   
    VISAWrite instr, ":TRAC:FEED:CONT NEVER" // Disable any residual data collection in buffer
    VISAWrite instr, ":TRAC:CLE" // Clear buffer
    VISAWrite instr, ":TRAC:POIN 11" // Specify buffer size, i.e. number of sweep points
   
    VISAWrite instr, ":SOUR:FUNC:MODE CURR" // Select current source mode
    VISAWrite instr, ":SOUR:CURR:STAR 0.001" // Specify start current value
    VISAWrite instr, ":SOUR:CURR:STOP 0.1"  // Specify stop current value
    VISAWrite instr, ":SOUR:CURR:STEP 0.001"  // Specify step current value
    VISAWrite instr, ":SOUR:CLE:AUTO ON" // Automatically turn output off after measurements
    VISAWrite instr, ":SOUR:CURR:MODE SWE" // Select current source sweep mode
    VISAWrite instr, ":SOUR:SWE:SPAC LIN" // Select linear staircase sweep
    VISAWrite instr, ":SOUR:DEL:AUTO OFF" // Source auto delay off
    VISAWrite instr, ":SOUR:DEL 0" // No source delay
   
    VISAWrite instr, ":SENS:FUNC 'VOLT'" // Voltage measure function
    VISAWrite instr, ":SENS:FUNC:CONC ON" // Turn on concurrent functions, allows more than one function to be measured simultaneously
    VISAWrite instr, ":SENS:VOLT:RANG:AUTO OFF" // Disable autovolts range
   
    VISAWrite instr, ":SENS:VOLT:PROT:LEV 20" // Set voltage compliance level
    VISAWrite instr, ":SENS:VOLT:RANG 20" // Set voltage range

    VISAWrite instr, ":SENS:VOLT:NPLC 1" // Set volts speed
   
    VISAWrite instr, ":TRIG:COUN 11" // Set trigger count
    VISAWrite instr, ":TRIG:DEL 0" // Set trigger delay to zero
    VISAWrite instr, ":SYST:AZER:STAT OFF" // Disable auto-zero
    VISAWrite instr, ":SYST:TIME:RES:AUTO ON"
    VISAWrite instr, ":TRAC:TST:FORM ABS" // Select timestamp format
   
    VISAWrite instr, ":TRAC:FEED:CONT NEXT" // Fill buffer and stop
    VISAWrite instr, ":OUTP ON" // Turn source output on
    VISAWrite instr, ":INIT" // Trigger readings
    VISAWrite instr, ":FORM:ELEM:SENS VOLT" // Format measured elements separated by a comma
    VISAWrite instr, ":TRAC:DATA?" // Read contents of buffer, i.e. request raw buffer readings
   
    Make/D/N=(11) dataValues
    Wave dataValues
   
    VISAReadWave instr, dataValues // Read the buffer and store in 'variableRead'
   
    print dataValues
   

    VISAWrite instr, "*SRE 0" // Program the Service Request Enable Register
    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
   
    viClose(instr)
    viClose(defaultRM)

End
Quote:
I actually got it working perfectly with no errors. HOWEVER, I changed something, and now it won't work again!


I presume that you don't know what change preceded the problem. It may be something in the instrument itself rather than in your procedure.

It might be that you changed some setting in the instrument which allowed it to work and then changed the setting back or reset the instrument causing the setting to revert to default.

Give some thought to when the instrument produces a new reading, at what rate, and if there is something you need to do to trigger it.

Quote:
but for some reason it won't read more than 10 values


I don't have a good idea on this. You may be able to use NI-MAX to debug it.

You can try to write a test function that uses VISARead in a loop instead of VISAReadWave.

You can try to write a test function that uses viRead in a loop to read one byte at a time to see if it hangs after so many bytes. viRead just calls the VISA driver viRead function so it is the simplest thing you can do.
INSTRUMENT: Using NI-MAX, I can see that all of the data is correctly obtained from the instrument without an issue (even for more than 10 measurements). This eliminates the possibility that the instrument is not sending the computer all of the data.

IGOR: The instrument outputs 5 values for every measurement (Voltage, Current, Resistance, Time, Status).
I wanted to see if igor could store 50 values in a wave from the 10 datapoints by removing the line in my code that only asks for Voltage.
So, I created a wave with 2 columns and 25 rows and obtained the following:

dataValues[0][0]= {20.0003,9.02712e-05,9.91e+37,0,39948,20.0003,8.97944e-05,9.91e+37,0.0361328,39948,20.0003,9.17167e-05,9.91e+37,0.0722656,39948,20.0003,9.1806e-05,9.91e+37,0.108398,39948,20.0003,9.22084e-05}
dataValues[22][0]= {9.91e+37,0.144531,39948}
dataValues[0][1]= {20.0003,9.26256e-05,9.91e+37,0.180664,39948,20.0003,9.22978e-05,9.91e+37,0.216797,39948,20.0003,9.22978e-05,9.91e+37,0.25293,39948,20.0003,9.26703e-05,9.91e+37,0.289062,39948,20.0003}
dataValues[21][1]= {9.25958e-05,9.91e+37,0.325195,39948}

So, that worked; all the correct values are in proper sequence for the 10 measurements. This eliminated the possibility that igor was having trouble storing more than 10 values in a wave. HOWEVER, I did obtain an error saying: "While executing VISAReadWave, the following error occurred: An invalid index was used to access a wave."

Am I just not sizing my wave correctly?
Your last example contained this:
Make/O/D/N=(11) dataValues
VISAReadWave instr, dataValues


This would read 11 numbers, not 11 sets of 5 numbers.

Quote:
The instrument outputs 5 values for every measurement (Voltage, Current, Resistance, Time, Status).


If I understand correctly, you would want to do this:
Make/O/D/N=(11) voltage, current, resistance, measurementTime, status
VISAReadWave instr, voltage, current, resistance, measurementTime, status


This will read 5 numbers 11 times.

Quote:
So, I created a wave with 2 columns and 25 rows


VISA XOP is not multi-dimensional-aware so it treats this the same as one wave with 50 rows.
Mmmm yes yes, but I was not clear enough. So, there are 5 values you can specify in the query for each measurement as I mentioned. But, here's the interesting thing that I poorly explained.

Initially, I was only sending a query for voltage. I could read and store 10 voltage measurements into a wave no problem, but 11 measurements failed. In summary:
- 1 value query for 10 measurements, 10x1 wave SUCCESS
- 1 value query for 10 measurements, 11x1 wave FAIL (igor freezes, presumably b/c index our of range)
- 1 value query for 11 measurements, 11x1 wave FAIL (igor freezes for a little, then fills in last value with a zero)

With the 10 measurements working at least, I tried to query all 5 values from the 10 measurements:
- 5 value query for 10 measurements, 50x1 wave SUCCESS
- 5 value query for 10 measurements, 25x2 wave SUCCESS (although it gives index out of range error)
- 5 value query for 11 measurements, 55x1 wave FAIL (igor freezes for a little, then fills in last 5 values with zeroes)
- 5 value query for 12 measurements, 30x2 wave FAIL (igor DOES NOT freeze, but it fills in last 10 values with zeroes and gives index out of range error)

I am not sure how I ever got it to work with 30 values (I accidentally deleted a copy of the code, arg), but this has to be an igor problem/mistake since the NI-MAX is showing exactly what it should for the same query. You're probably right, it has something to do with the way it is reading the 11th measurement, but I just don't see how it should be any different than the 9th or 10th measurement. I don't want to bother you anymore; I'll keep at it. Thank you very much for your time.

Hello again,

The code shown below works perfectly. I obtain a wave containing 10 voltage values that I specified in my sweep. I can also specify if I want the 10 corresponding current values as well, in which case I just make my wave size 20 instead of 10; that works too. But, let's just say I am reading these 10 voltage values for simplicity. If I make my TRAC:POIN = 20, and TRIG:COUN = 20, and specify 10 additional voltages to my list, and increase the size of 'datavalues1' = 20, then it crashes, however it runs perfectly if I set 'datavalues1' back to a size of 10 and leave TRAC:POIN and TRIG:COUN = 20..

Igor crashes if:
1.) 'datavlaues1' wave is greater than 10
2.) TRAC:POIN is greater than 20
3.) TRIG:COUN is greater than 20

For some reason, Igor just can't read more than 10 data points. NI MAX shows that all 20 data points are indeed contained in the buffer, but if Igor tries to read beyond 10 of those data points, it either crashes or the additional values show up as zero.

Is there a buffer size or something that I need to edit in Igor? You had mentioned looping my Read function, but I do not know the best way of doing that. Thank you again for your help.

 Function cSweep()
    Variable defaultRM, instr

    Variable status
    String variableRead

    status = viOpenDefaultRM(defaultRM)
   
    String resourceName = "GPIB0::24::INSTR"
   
    status = viOpen(defaultRM, resourceName, 0, 0, instr)
    viSetAttribute(instr, VI_ATTR_TMO_VALUE, 10000)
   
    VISAWrite instr, "*IDN?"
    VISARead/T="\r\n" instr, variableRead
    Print variableRead

    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*ESE 0" // Program the Standard Event Enable Register
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
    VISAWrite instr, ":FORM:SREG BIN" // Format register to binary
   
    VISAWrite instr, ":STAT:MEAS:ENAB 512" // Enable BFL (Buffer full)
    VISAWrite instr, ":*SRE 1"   // Program the Service Request Enable Register
   
    VISAWrite instr, ":TRAC:FEED:CONT NEVER" // Disable any residual data collection in buffer
    VISAWrite instr, ":TRAC:CLE" // Clear buffer
    VISAWrite instr, ":TRAC:POIN 10" // Specify buffer size, i.e. number of sweep points
   
    VISAWrite instr, ":SENS:FUNC:CONC OFF" // Turn on concurrent functions, allows more than one function to be measured simultaneously
    VISAWrite instr, ":SOUR:FUNC VOLT" // Select current source mode
    VISAWrite instr, ":SENS:FUNC 'CURR:DC'" // Voltage measure function
    VISAWrite instr, ":SENS:CURR:PROT 0.2" // Set voltage compliance level
    VISAWrite instr, ":SOUR:VOLT:MODE LIST" // Select current source sweep mode
    VISAWrite instr, ":SOUR:LIST:VOLT 0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0" // Select current source sweep mode
    VISAWrite instr, ":FORM:ELEM:SENS VOLT" // Format measured elements separated by a comma
    VISAWrite instr, ":TRIG:COUN 10" // Set trigger count
    VISAWrite instr, ":TRIG:DEL 0" // Set trigger delay to zero
    VISAWrite instr, "ARM:COUN 1" // Set number of sweeps to perform
    VISAWrite instr, ":SOUR:DEL:AUTO OFF" // Source auto delay off
    VISAWrite instr, ":SOUR:DEL 0" // No source delay


    VISAWrite instr, ":SOUR:CLE:AUTO ON" // Automatically turn output off after measurements

    VISAWrite instr, ":SENS:CURR:NPLC 1" // Set volts speed
   
    VISAWrite instr, ":SYST:AZER:STAT OFF" // Disable auto-zero
    VISAWrite instr, ":SYST:TIME:RES:AUTO ON"
    VISAWrite instr, ":TRAC:TST:FORM ABS" // Select timestamp format
   
    VISAWrite instr, ":TRAC:FEED:CONT NEXT" // Fill buffer and stop
    VISAWrite instr, ":OUTP ON" // Turn source output on
    VISAWrite instr, ":INIT" // Trigger readings

    VISAWrite instr, ":TRAC:DATA?" // Read contents of buffer, i.e. request raw buffer readings
   
    Make/O/D/N=(10,1) dataValues1
    VISAReadWave instr, dataValues1
    Print dataValues1
    Edit dataValues1
   
    VISAWrite instr, ":TRAC:FREE?" // Read contents of buffer, i.e. request raw buffer readings
    VISARead/T="\r\n" instr, variableRead
    Printf "FREE: %s\r", variableRead
    VISAWrite instr, ":TRAC:POIN?" // Read contents of buffer, i.e. request raw buffer readings
    VISARead/T="\r\n" instr, variableRead
    Printf "POIN: %s\r", variableRead
    VISAWrite instr, ":TRAC:FEED:CONT?" // Read contents of buffer, i.e. request raw buffer readings
    VISARead/T="\r\n" instr, variableRead
    Printf "FEED:CONT: %s\r", variableRead
   
    VISAWrite instr, "*SRE 0" // Program the Service Request Enable Register
    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
   
    viClose(instr)
    viClose(defaultRM)

    Print "Done"
   

End
Quote:

Make/O/D/N=(10,1) dataValues1
VISAReadWave instr, dataValues1



This is telling VISAReadWave to read 10 values into a 2D wave. Try /N=(10) to make a 1D wave. If you want to read 20, use /N=(20). Don't use /N=(20,1).

Using /N=(10,1) should not cause Igor to crash. It would be helpful if you could create the simplest possible function that demonstrates the crash. This will allow me to focus on the source code that might be responsible for the crash.





See, the thing is that the instrument is working fine. All the data I need is being stored in the buffer; the problem is just reading that data into igor. When I use NI MAX and manually query the data using :TRAC:FEED:CONT?, all the data points are there whether there are 10 data points or 2500 data points. Igor reads in 10 data points fine, but when I go beyond 10 data points, it still only returns the correct first 10 values.

Instead of using:
Make/O/D/N=(10) dataValues
VISAReadWave instr, dataValues
Print dataValues
Edit dataValues


I simplified it and used:
VISARead/T="\r\n" instr, variableRead
Printf variableRead


Here, I measure 12 voltage values with the instrument and store them into the buffer. When I use VISARead in Igor, I obtain this:
+1.000000E-01,+2.000000E-01,+3.000000E-01,+4.000000E-01,+5.000000E-01,+6.000000E-01,+7.000000E-01,+8.000000E-01,+9.000000E-01,+1.000000E+00

Immediately after that, I manually query the buffer using NI MAX and obtain this:
+1.000000E-01,+2.000000E-01,+3.000000E-01,+4.000000E-01,+5.000000E-01,+6.000000E-01,+7.000000E-01,+8.000000E-01,+9.000000E-01,+1.000000E+00,+1.100000E+00,+1.200000E+00

So, the values are in the buffer ready to be read, but igor cannot read in more than the 10 values, only less than 10 values. Also note that Igor does not timeout or give me any errors, it just truncates the buffer after 10 values. Is there a character limit or a delimiter limit?

Thanks again for your help.
Quote:
Is there a character limit or a delimiter limit?

As far as I know, there is no limit to the number of bytes that you can read using VISARead.

Quote:

Instead of using:
Make/O/D/N=(10) dataValues
VISAReadWave instr, dataValues
Print dataValues
Edit dataValues



I would expect this to read 10 numbers. VISAReadWave attempts to read as many numbers as there are points in the output wave. If you want to read 12 numbers, you need to use /N=(12) with Make.

Also, print V_flag after calling VISAReadWave. This tells you the number of individual numbers read.

Quote:

Instead of using:
VISARead/T="\r\n" instr, variableRead
Printf variableRead



Assuming that variableRead is a string variable, this should read until it hits a carriage return or a linefeed. If variableRead is a string variable, then VISARead does not treat the input as numeric text but rather as just a stream of bytes. It does not parse the string. It just reads bytes until it reads a byte that is a terminator.

I don't know what is causing the trouble you are having. To debug it, I would need the instrument.

Here is a test function that does not require any instrument. It works correctly on my machine:
Function VISAReadWriteTest()
    VISAControl testMode=1
    VISAControl clearTestBuffer
    String writeStr = "+1.000000E-01,+2.000000E-01,+3.000000E-01,+4.000000E-01,+5.000000E-01,+6.000000E-01,+7.000000E-01,+8.000000E-01,+9.000000E-01,+1.000000E+00"
    writeStr = "+1.000000E-01,+2.000000E-01,+3.000000E-01,+4.000000E-01,+5.000000E-01,+6.000000E-01,+7.000000E-01,+8.000000E-01,+9.000000E-01,+1.000000E+00,+1.100000E+00,+1.200000E+00,The End"
    VISAWrite 0, writeStr + "\r"
    String readStr
    VISARead /T="\r" 0, readStr
    Print V_Flag
    Print strlen(readStr)
    Print readStr
    VISAControl testMode=0
End


I got it working!! However, I do not understand exactly why it works, but it does. The major change I made is that I added a random query (in this case, :TRAC:FREE?) inline and immediately after the :TRAC:DATA? query. For some reason, this makes it work (i.e. no query interrupt error when reading more than 10 data points). Thanks again for your help. Here's the final code:


Function IV()
    Variable defaultRM, instr

    Variable status
    String variableRead

    status = viOpenDefaultRM(defaultRM)
   
    String resourceName = "GPIB0::24::INSTR"
   
    status = viOpen(defaultRM, resourceName, 0, 0, instr)
    viSetAttribute(instr, VI_ATTR_TMO_VALUE, 100000)
   
    VISAWrite instr, "*IDN?"
    VISARead/T="\r\n" instr, variableRead
    Print variableRead

    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*ESE 0" // Program the Standard Event Enable Register
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
    VISAWrite instr, ":FORM:SREG BIN" // Format register to binary
   
    VISAWrite instr, ":STAT:MEAS:ENAB 512" // Enable BFL (Buffer full)
    VISAWrite instr, ":*SRE 1"   // Program the Service Request Enable Register
   
    VISAWrite instr, ":TRAC:FEED:CONT NEVER" // Disable any residual data collection in buffer
    VISAWrite instr, ":TRAC:CLE" // Clear buffer
    VISAWrite instr, ":TRAC:POIN 41" // Specify buffer size, i.e. number of sweep points
   
    VISAWrite instr, ":SENS:FUNC:CONC OFF" // Turn on concurrent functions, allows more than one function to be measured simultaneously
    VISAWrite instr, ":SOUR:FUNC VOLT" // Select current source mode
    VISAWrite instr, ":SENS:FUNC 'CURR:DC'" // Voltage measure function
    VISAWrite instr, ":SENS:CURR:PROT 0.2" // Set voltage compliance level
    VISAWrite instr, ":SOUR:VOLT:MODE LIST" // Select current source sweep mode
    VISAWrite instr, ":SOUR:LIST:VOLT -1.0,-0.9,-0.8,-0.7,-0.6,-0.5,-0.4,-0.3,-0.2,-0.1,0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1,0,-0.1,-0.2,-0.3,-0.4,-0.5,-0.6,-0.7,-0.8,-0.9,-1.0" // Specifies voltage points in sweep
    VISAWrite instr, ":FORM:ELEM:SENS VOLT,CURR" // Format measured elements separated by a comma
    VISAWrite instr, ":TRIG:COUN 41" // Set trigger count
    VISAWrite instr, ":TRIG:DEL 0" // Set trigger delay to zero
    VISAWrite instr, "ARM:COUN 1" // Set number of sweeps to perform
    VISAWrite instr, ":SOUR:DEL:AUTO OFF" // Source auto delay off
    VISAWrite instr, ":SOUR:DEL 0" // No source delay


    VISAWrite instr, ":SOUR:CLE:AUTO ON" // Automatically turn output off after measurements

    VISAWrite instr, ":SENS:CURR:NPLC 1" // Set volts speed
   
    VISAWrite instr, ":SYST:AZER:STAT OFF" // Disable auto-zero
   
    VISAWrite instr, ":TRAC:FEED:CONT NEXT" // Fill buffer and stop
    VISAWrite instr, ":OUTP ON" // Turn source output on
    VISAWrite instr, ":INIT" // Trigger readings

    VISAWrite instr, ":TRAC:DATA?;:TRAC:FREE?" // Read contents of buffer, i.e. request raw buffer readings
   
    Make/O/D/N=(41) dataValuesV,dataValuesI
    VISAReadWave instr, dataValuesV,dataValuesI
    Print dataValuesV,dataValuesI
   
    VISAWrite instr, "*SRE 0" // Program the Service Request Enable Register
    VISAWrite instr, ":*RST" // Restore GPIB default conditions
    VISAWrite instr, ":*CLS" // Clears all event registers and Error Queue
   
    viClose(instr)
    viClose(defaultRM)

    Print "Done"

End
Quote:
I got it working!! However, I do not understand exactly why it works, but it does.


Thanks for the update. I'm glad you got it working. I too do not understand why.