Author Topic: Problems Writing code for GPIB Py VISA  (Read 18759 times)

0 Members and 1 Guest are viewing this topic.

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Problems Writing code for GPIB Py VISA
« on: December 20, 2023, 09:52:54 pm »
Hi
I have assembled Xyphro's excellent USB:GPIB adapter at this link https://www.eevblog.com/forum/testgear/open-source-gpib-adapter/
I now have the problem of writing code to make use of the adapters.  I have decided to use Python and PyVISA.  I am new to Python and GPIB. 

My target test equipment includes:
  • WaveTek 2520 RF signal generator 200kHz-2.2GHz
  • HP 3478A Multimeter
  • HP 54645D 100MHz DSO
  • Electro-Metrics EMC30 - an obsolete Mil-Spec emc receiver

All of these are notably ancient so for at least two of them, there is no point in asking questions like: "How do I program for my WaveTek 2520" when there is probably me and no-one else on the planet that want to run such an antique instrument over GPIB. 

I plan to use this thread as the place I ask generalised questions about specific problems I am, or likely, to have.  I anticipate others like me will have questions of their own.  I searched the internet for an active PYVISA forum, but none found.

Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #1 on: December 20, 2023, 10:16:56 pm »
I have started to program a test program in Python for my WaveTek 2520 RF Sig Gen.
The first problem I have hit is buffering.  The WaveTek includes a FIFO message buffer. 

The problem I have is aligning the GPIB commands with the buffer content.  If I issue a command to read the ID string, the ID is loaded into the buffer.  If anything is already in the buffer, that comes out ahead of the ID string.
The code looks like this:
Code: [Select]
print("ID ")
print(SigGen.write('ID ?'))
print(SigGen.read())

Note I have chosen not to use the query command.

The first time I run this code after power up I get:
Code: [Select]
ID                                                                                                                                                               
5                                                                                                                                                               
D:\darren\My Documents\Electronics\GPIB USB Adapter\dazz\gpib_test_2_WvTk2520.py:24: UserWarning: read string doesn't end with termination characters             
print(SigGen.read())                                                                                                                                           
101-COMMAND HEADER 

In this case, the "101-COMMAND HEADER is printed out.  The contents of the buffer is not aligned with the read ID string command.
The next time I ran the same code I got:

Code: [Select]
ID                                                                                                                                                               
5                                                                                                                                                               
WVTK/2520A,V81.1,F5.1                                                                                                                                           

Now the ID string is printed out because there is nothing ahead of it in the buffer.  The read ID command is aligned with the ID string in the buffer.

The WaveTek does not have a command to clear the buffer.    The issue is further complicated by the STR function that allows a user to press a key on the front panel that generates a service request.  Potentially messages can be randomly inserted into the buffer.

Is there a recommended method of aligning buffered strings with the command that called for them?







Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline alm

  • Super Contributor
  • ***
  • Posts: 2903
  • Country: 00
Re: Problems Writing code for GPIB Py VISA
« Reply #2 on: December 20, 2023, 10:19:34 pm »
My solution for this was to develop python-ivi drivers, for example this driver for the HP 3456A which might be kind of similar to the HP 3478A. But if you're new to Python, I would not recommend it. It makes the code a lot more complicated and requires some familiarity with the IVI specification which is not worth it for a beginner.

I would start by sending simple commands to the meter or signal gen (probably the simplest to program), and write functions like this:

Code: [Select]
def set_3478a_to_3v_dc(instr):
  instr.write("F1R0")

def read_from_3478a(instr):
  response = instr.read()
  return float(response)

rm = ...
instr = rm....
set_3478a(instr)
while True:
  print(read_from_3478a(instr))

In this case, the "101-COMMAND HEADER is printed out.
I'm not familiar with this signal gen, but this reads like an error message to me. Should there be a space between 'ID' and '?'?

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #3 on: December 20, 2023, 10:51:14 pm »
Hi
I have been doing exactly as you suggested, writing small test programs to try things out.  The code sample provided above is a snippet from the test program.
I wouldn't expect you, or anyone else, to be familiar with a dinosaur like the 2520.  It dates back to late 1980s, so doesn't conform with the later standards on command format.  In this case "ID ?" is correct.  I know that from the manual, but the manual doesn't cover query and buffer alignment.

The starting assumption was that issuing a read command would always return the desired string message.  The 101-COMMAND HEADER message was something left in the message buffer from previous testing.  It is not related to the ID command, and that is the problem.  I issued a read ID command and got back a random message.  I am thinking this is likely to be a problem on any instrument with a message buffer.

Note that in response to any read command, I receive a digit and then the message.  I have not figured out the purpose/significance of this yet.  This appears to be the length of the string sent to the 2520, including the termination symbol ('\n')

« Last Edit: December 20, 2023, 11:47:03 pm by dazz1 »
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline alm

  • Super Contributor
  • ***
  • Posts: 2903
  • Country: 00
Re: Problems Writing code for GPIB Py VISA
« Reply #4 on: December 20, 2023, 11:56:30 pm »
I'd start with the HP 3478A. DMMs are simpler than scopes and in my experience HP equipment has been the most well behaved with GPIB, with Datron pretty close, but Keithley as more finicky. Sounds like Wavetek might be similar to Keithley.

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #5 on: December 21, 2023, 02:38:30 am »
The first time I run this code after power up I get:
Code: [Select]
ID                                                                                                                                                               
5                                                                                                                                                               
D:\darren\My Documents\Electronics\GPIB USB Adapter\dazz\gpib_test_2_WvTk2520.py:24: UserWarning: read string doesn't end with termination characters             
print(SigGen.read())                                                                                                                                           
101-COMMAND HEADER 

This is almost certainly an artifact of the xyphro firmware's Auto ID feature. If you have an older instrument, such as this WaveTek, that does not respond to the *IDN? query, and this WaveTek doesn't, an error will be generated on the instrument when the adapter automatically sends *IDN? at power up in an attempt to make a "pretty" VISA resource string. According to my reading of the Wavetek's manual, 101-COMMAND HEADER means "I don't recognize the command that was sent", which is as expected since it doesn't support *IDN?.

You have three choices to get around this:
1. Disable the Auto ID feature of the adapter using the method xyphro describes near the end of his GitHub README
2. Throw in an extra read at the start of the program to read out the error message and just ignore it
3. My personal preference: Use the VISA clear function to reset the instrument at the beginning of the program. This is preferred because it should reset the instrument to its power-on state, clear all buffers, etc.

Also, since this an old, possibly quirky instrument, it may be necessary to change the default read termination behavior of the xyphro firmware. I have to do this for my HP 5385A frequency counter or else I can't read properly from it.

Below is my attempt at a script to read the ID of the WaveTek 2520 that incorporates my recommendations from above. Please note: the sleep delays ARE necessary, especially after a VISA clear. I speak from experience...

Code: [Select]
import pyvisa
from sys import platform
from time import sleep

if platform == "linux" or platform == "linux2":
   # Linux
   rm = pyvisa.ResourceManager("/usr/lib/librsvisa.so@ivi")
elif platform == "darwin":
   # macOS
   rm = pyvisa.ResourceManager("/Library/Frameworks/RsVisa.framework/RsVisa@ivi")
elif platform == "win32":
   # Windows
   rm = pyvisa.ResourceManager()

SigGen = rm.open_resource('YOUR_RESOURCE_STRING_HERE')

# xyphro UsbGpib configuration
# Configure read termination as Option 1 (EOI and \n)
SigGen.control_in(0xa1, 0x40, 0, 0, 1)
SigGen.write('!0101')
# Wait to make sure configuration took effect
sleep(1)
# end xyphro UsbGpib configuration

SigGen.timeout = 5000
SigGen.write_termination = '\r'
SigGen.read_termination = '\n'

# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)

print('Instrument ID:', SigGen.query('ID?'))

# xyphro UsbGpib configuration
# Configure read termination as Option 0 (EOI only)
SigGen.control_in(0xa1, 0x40, 0, 0, 1)
SigGen.write('!0100')
# Wait to make sure configuration took effect
sleep(1)
# end xyphro UsbGpib configuration

# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)

# Return front panel to local control
SigGen.control_ren(pyvisa.constants.VI_GPIB_REN_ADDRESS_GTL)
SigGen.close()
rm.close()
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #6 on: December 21, 2023, 06:44:48 am »
The first time I run this code after power up I get:
Code: [Select]
ID                                                                                                                                                               
5                                                                                                                                                               
D:\darren\My Documents\Electronics\GPIB USB Adapter\dazz\gpib_test_2_WvTk2520.py:24: UserWarning: read string doesn't end with termination characters             
print(SigGen.read())                                                                                                                                           
101-COMMAND HEADER 

This is almost certainly an artifact of the xyphro firmware's Auto ID feature. If you have an older instrument, such as this WaveTek, that does not respond to the *IDN? query, and this WaveTek doesn't, an error will be generated on the instrument when the adapter automatically sends *IDN? at power up in an attempt to make a "pretty" VISA resource string. According to my reading of the Wavetek's manual, 101-COMMAND HEADER means "I don't recognize the command that was sent", which is as expected since it doesn't support *IDN?.

That makes perfect sense but my assertion that any dregs in the buffer get pulled out ahead of the expected string remain extant, until I find another cause.
On closer reading the 2520 command should be "ID?", but "ID ?" also works.   I am still skimming along the surface of GPIB and Python so simple things are not yet simple for me.

Quote from: caiser01
You have three choices to get around this:
1. Disable the Auto ID feature of the adapter using the method xyphro describes near the end of his GitHub README
2. Throw in an extra read at the start of the program to read out the error message and just ignore it
3. My personal preference: Use the VISA clear function to reset the instrument at the beginning of the program. This is preferred because it should reset the instrument to its power-on state, clear all buffers, etc.
I haven't found a clear/reset type command for the 2520 yet but I will keep looking.  It does allow me to set/recall settings, so I can put the 2520 into a defined state.  A sample output is:
Code: [Select]
FREQUENCY 222.222 MHz                                                                                                                                           
FREQ STEP 50.0 kHz                                                                                                                                               
AMPLITUDE -10.0 dBm                                                                                                                                             
INTERNAL AM 100.0 %                                                                                                                                             
INTERNAL FM 80.0 kHz                                                                                                                                           
 EXTERNAL AM 100.0 %                                                                                                                                             
EXTERNAL FM 235.0 kHz                                                                                                                                           
RF OUTPUT OFF                                                                                                                                                   
MOD RATE 1000 Hz                                                                                                                                                 
MODULATION OFF                                                                                                                                                   
AMP STEP 0.10 dB                                                                                                                                                 
EXT PHASE 5.9 rads                                                                                                                                               
350-STORED SETTINGS ERROR 

The recalled settings have an error, but I don't know which setting is faulty.

Quote from: caiser01
Also, since this an old, possibly quirky instrument, it may be necessary to change the default read termination behavior of the xyphro firmware. I have to do this for my HP 5385A frequency counter or else I can't read properly from it.
The termination is programmable.  I can and have changed the termination to /n.  That seems to work OK.  I don't see corrupted output.

Quote from: caiser01
Below is my attempt at a script to read the ID of the WaveTek 2520 that incorporates my recommendations from above. Please note: the sleep delays ARE necessary, especially after a VISA clear. I speak from experience...
[/code]
I started adding sleeps, but I have been removing them without ill effect.
Quote from: caiser01
Code: [Select]
import pyvisa
from sys import platform
from time import sleep

if platform == "linux" or platform == "linux2":
   # Linux
   rm = pyvisa.ResourceManager("/usr/lib/librsvisa.so@ivi")
elif platform == "darwin":
   # macOS
   rm = pyvisa.ResourceManager("/Library/Frameworks/RsVisa.framework/RsVisa@ivi")
elif platform == "win32":
   # Windows
   rm = pyvisa.ResourceManager()

SigGen = rm.open_resource('YOUR_RESOURCE_STRING_HERE')

# xyphro UsbGpib configuration
# Configure read termination as Option 1 (EOI and \n)
SigGen.control_in(0xa1, 0x40, 0, 0, 1)
SigGen.write('!0101')
# Wait to make sure configuration took effect
sleep(1)
# end xyphro UsbGpib configuration

SigGen.timeout = 5000
SigGen.write_termination = '\r'
SigGen.read_termination = '\n'

# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)

print('Instrument ID:', SigGen.query('ID?'))

# xyphro UsbGpib configuration
# Configure read termination as Option 0 (EOI only)
SigGen.control_in(0xa1, 0x40, 0, 0, 1)
SigGen.write('!0100')
# Wait to make sure configuration took effect
sleep(1)
# end xyphro UsbGpib configuration

# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)

# Return front panel to local control
SigGen.control_ren(pyvisa.constants.VI_GPIB_REN_ADDRESS_GTL)
SigGen.close()
rm.close()
There are definitely some code snippets I can plagiarize from your code sample.
Looking at the circuit design and the manuals, I think there is a high risk of finding querks.  I have found the 2520 manual difficult to use as a look-up reference.  I am writing a summary version.
I am also writing a sample / test script that exercises all commands (there aren't too many of them) to seek out the querks and learn a bit about Python. 
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline ch_scr

  • Frequent Contributor
  • **
  • Posts: 942
  • Country: de
Re: Problems Writing code for GPIB Py VISA
« Reply #7 on: December 21, 2023, 12:24:52 pm »
To get a grip on the behaviour of an instrument, I find it a lot easier to use the interactive "pyVISA Shell" first, then write the script (knowing what the instrument expects).
Here's a script that is about the absolute minimum to log data from a DMM, with ample comments. Even though it's written for a different instrument, you might find parts of it helpfull.
 

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #8 on: December 21, 2023, 02:05:14 pm »
I haven't found a clear/reset type command for the 2520 yet

There's not a clear command for the WaveTek 2520 and most very old instruments don't have one.

I was suggesting using the VISA clear() function. That will execute a GPIB Device Clear (DC1) which is explicitly supported by the 2520 as stated on page 6-1 of the manual. That should clear the "dregs in the buffer" when executed at the beginning of the script before attempting any reads from or writes to the instrument.

Code: [Select]
# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)

This is exactly what I do for my HP 5385A, which throws an error when powered on with the xyphro adapter connected because of the Auto ID feature. I run clear() which makes it reset and boot cleanly.
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #9 on: December 22, 2023, 06:52:24 am »
To get a grip on the behaviour of an instrument, I find it a lot easier to use the interactive "pyVISA Shell" first, then write the script (knowing what the instrument expects).
Here's a script that is about the absolute minimum to log data from a DMM, with ample comments. Even though it's written for a different instrument, you might find parts of it helpfull.

Thanks for the script.  My test script is similar but less sophisticated. 
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #10 on: December 22, 2023, 07:34:47 am »
I haven't found a clear/reset type command for the 2520 yet

There's not a clear command for the WaveTek 2520 and most very old instruments don't have one.

I was suggesting using the VISA clear() function. That will execute a GPIB Device Clear (DC1) which is explicitly supported by the 2520 as stated on page 6-1 of the manual. That should clear the "dregs in the buffer" when executed at the beginning of the script before attempting any reads from or writes to the instrument.
Yes that is listed in the chapter intro, but not further on.  If it does work, there is a good chance it will change the termination. 
The 2520 provides 3x ways of changing the termination and the termination can include 1,2 or 3 chars.  The DIP switches are set to CR/LF/EOI, but I have set the termination to CR (/n) in software, so a DCI instruction, if it works, might change the termination to the DIP switch settings.   The current setting survives power cycling but may revert to the DIP SW settings to a DCI instruction.    I need to test for it.

Is there a preferred termination in the GPIB world?

Quote from: caiser01
[code
# Reset the instrument, wait for reset to complete
SigGen.clear()
sleep(1)[/code]

This is exactly what I do for my HP 5385A, which throws an error when powered on with the xyphro adapter connected because of the Auto ID feature. I run clear() which makes it reset and boot cleanly.
Wondering if it might be practical to use the eeprom on the adapter to store adjustable settings to manage the Auto ID feature. Something Xyphro could consider doing.
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline ch_scr

  • Frequent Contributor
  • **
  • Posts: 942
  • Country: de
Re: Problems Writing code for GPIB Py VISA
« Reply #11 on: December 22, 2023, 10:08:16 am »
Wondering if it might be practical to use the eeprom on the adapter to store adjustable settings to manage the Auto ID feature. Something Xyphro could consider doing.
AFAIK, it does just that? You can turn off the Auto-ID and it remembers that setting?

Here's what he writes about it:
Quote from: xyphro github repo
[...]
All parameters are applied immediately after setting them and are stored in a non voltatile way in the EEProm of the microcontroller.
[...]
Automatic instrument identification readout

To turn off the automatic instrument ID readout after power up, execute: VM.control_in(0xa1, 0x40, 0, 0) VM.write('!0001')

To turn on the automatic instrument ID readout (this is the default behaviour of GPIBUSB), execute: VM.control_in(0xa1, 0x40, 0, 0) VM.write('!0000')

After a power cycle the USB device VISA ressource name and USB serial number string will change, based on this setting
Seems like it would be good to have a ready-made script to switch that, instead of every user having to fend for themself?
« Last Edit: December 22, 2023, 10:12:31 am by ch_scr »
 

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #12 on: December 22, 2023, 07:44:56 pm »
If it does work, there is a good chance it will change the termination.

It is indeed possible but I would not automatically assume that because...

The current setting survives power cycling

Device Clear (at least on old instruments) is generally about putting the instrument back to its power-on state and clearing all GPIB buffers, status, and flags. But since this WaveTek is a bit of an oddball, who knows?

I need to test for it.

Yes, definitely, and if you find the 2520 termination setting is volatile, you could still make 'TRM' the first command you send following the call to VISA clear() to put it back the way you want it. It is generally good practice when writing code to communicate with instruments to never assume any settings or configurations carry over from one use to the next. That should all be in the initialization code for each instrument.

Is there a preferred termination in the GPIB world?

 :-DD

...but seriously, the inconsistency of expected termination sequences, especially with older instruments can be one of the most frustrating things about working with GPIB. An otherwise perfectly written program will cause the instrument to sit there angrily beeping and blinking annunciators at you for the sake of an incorrect termination sequence.

My experience has been that since the 90s at least, instrument makers seem to have settled on newline (LF) as the most common terminator. With older instruments, it's down to reading the manual and experimenting. Some instruments want CR, some want LF, some want both. It's a mess and it's telling that WaveTek included *multiple* ways to change the termination sequence for the 2520.

This is more of an issue when you have a single, traditional GPIB controller with multiple instruments hooked up. In that case, you need all the instruments to have at least compatible termination sequences. Since the xyphro adapter is one adapter per instrument, it's pretty easy to set unique termination sequences for each instrument. In object-oriented terms, each instrument can be its own object with its own properties, including termination.

Briefly, for using an instrument with the xyphro adapter, just set the termination to whatever works best for that instrument. Don't worry too much over whether it's the same as other instruments or not.

Wondering if it might be practical to use the eeprom on the adapter to store adjustable settings to manage the Auto ID feature. Something Xyphro could consider doing.

In my conversations with xyphro, he expressed a love/hate relationship with his Auto ID feature. I think he's open to ideas for changes and improvements. Why not flesh out your suggestion and submit an issue at GitHub?
 
The following users thanked this post: Roehrenonkel

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #13 on: December 22, 2023, 08:42:42 pm »
I took a look at Xyphro instructions:
Quote
read termination method

The following read termination method options are available:

    Option 0: (default): EOI only (the normal way GPIB works)
    Option 1: EOI + \n (LF / line feed)
    Option 2: EOI + \r (CR / carriage return)

If your device terminates with \r\n, select Option #2.

To set these options execute (Pyvisa example): VM.control_in(0xa1, 0x40, 0, 0) VM.write('!01XX')

for XX enter either:

    00 for Option 0 (EOI only) => VM.write('!0100')
    01 for Option 1 (EOI and \n) => VM.write('!0101')
    02 for Option 2 (EOI and \r) => VM.write('!0102')

Automatic instrument identification readout

To turn off the automatic instrument ID readout after power up, execute: VM.control_in(0xa1, 0x40, 0, 0) VM.write('!0001')

To turn on the automatic instrument ID readout (this is the default behaviour of GPIBUSB), execute: VM.control_in(0xa1, 0x40, 0, 0) VM.write('!0000')

After a power cycle the USB device VISA resource name and USB serial number string will change, based on this setting



I am on the bottom of the learning curve of,  starting to learn, three things:
  • Python
  • GPIB protocol and,
  • GPIB WaveTek 2520 command set

So I wasn't expecting the adapter to care about terminations.  Based on advice at this link:  https://forums.ni.com/t5/Instrument-Control-GPIB-Serial/Default-GPIB-termination-character/td-p/242545  EOI should be the default terminator.  Given that is a hardwired control line, the adapter needs to know this.

I am looking at all of this and thinking the adapters should be transparent and instrument agnostic.  The GPIB controlling software should write/select the correct terminator at start-up.  This will ensure that no matter which equipment the adapter is plugged into, it will be correctly configured by the controller for the instrument being controlled.  eePROM has limited write cycles so what is needed is a method of reading the terminator setting, and only writing if it needs changing.  This will significantly extend the life of the adapter.

I have opened up the 2520 and set the termination to LF with DIP switches but I think I need to change that to EOI.  I can still change the termination from the front panel or via GPIB but at least one command reverts to the DIP switch setting. 
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #14 on: December 22, 2023, 08:50:30 pm »
Quote from: caiser01
In my conversations with xyphro, he expressed a love/hate relationship with his Auto ID feature. I think he's open to ideas for changes and improvements. Why not flesh out your suggestion and submit an issue at GitHub?

Done that :  https://github.com/xyphro/UsbGpib/issues/48

Being able to read back the settings from the adapter will eliminate a potential source of trouble.
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: WaveTek 2520 SigGen : Aligning commands with the buffer
« Reply #15 on: December 22, 2023, 08:58:27 pm »
Quote from: caiser01

Briefly, for using an instrument with the xyphro adapter, just set the termination to whatever works best for that instrument. Don't worry too much over whether it's the same as other instruments or not.


OK I am going to go with EOI as my default termination.  If that doesn't work for a specific instrument, use LF or whatever works. 
My instruments include a scope and EMC receiver with a scope-like output.  Hopefully using EOI will avoid issues with byte data streams.
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #16 on: December 22, 2023, 09:19:57 pm »
So I wasn't expecting the adapter to care about terminations.  Based on advice at this link:  https://forums.ni.com/t5/Instrument-Control-GPIB-Serial/Default-GPIB-termination-character/td-p/242545  EOI should be the default terminator.  Given that is a hardwired control line, the adapter needs to know this.

A "normal" GPIB controller (like an NI or HP USB adapter or PCI card) doesn't care about read termination. Only the read termination setting in your application would matter. The xyhpro adapter cares about read termination (if I understand correctly) because of the mechanics of the translation from GPIB to USBTMC.

Yes, EOI is the only termination that should be needed for newer (488.2 compliant) instruments. Keep in mind though that just because the updated 488.2 GPIB spec was published in 1987, there was nothing to say that instrument makers *had* to comply with it. Many legacy 488.1 instruments remained in production (in fact a few oddball 488.1 instruments may still be in limited production, I have stories from my job...). So it's possible to have a post-1987 instrument that is only 488.1 compliant (and/or not SCPI-compliant for that matter). This is all part of the fun of GPIB  :rant:

I am looking at all of this and thinking the adapters should be transparent and instrument agnostic.  The GPIB controlling software should write/select the correct terminator at start-up.  This will ensure that no matter which equipment the adapter is plugged into, it will be correctly configured by the controller for the instrument being controlled.

Yep, yep. Configuring in the application software every time is the smart way.

OK I am going to go with EOI as my default termination.  If that doesn't work for a specific instrument, use LF or whatever works. 
My instruments include a scope and EMC receiver with a scope-like output.  Hopefully using EOI will avoid issues with byte data streams.

Good plan  :-+
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #17 on: December 23, 2023, 07:45:04 am »
Hi am trying to try the DCL command.
I have figured out I need to write hex value 0x14, but all I can find is confusion and error messages.  An example being this: 
https://github.com/pyvisa/pyvisa/issues/491 
and here:
https://pyvisa.readthedocs.io/en/latest/introduction/rvalues.html

Also I haven't figured out how to send an EOI terminator to the 2520.  I need to be able to tell pyVISA the terminator is "EOI".
I also need to send the 2520 a string that sets the terminator to EOI.  The manuals are silent.

[EDIT]  I still have the 2520 terminator DIP switch set to /n. I want to test the software command to set EOI before I change the DIP switches.
« Last Edit: December 23, 2023, 07:55:02 am by dazz1 »
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #18 on: December 23, 2023, 08:08:33 am »
I tried this:
Code: [Select]
D:\GPIB USB Adapter\dazz>python                                                                                                                     
Python 3.12.1 (tags/v3.12.1:2305ca5, Dec  7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32                                                                                   
Type "help", "copyright", "credits" or "license" for more information.                                                                                                             
>>> import pyvisa                                                                                                                                                                   
>>> rm = pyvisa.ResourceManager()                                                                                                                                                   
>>> print(rm.list_resources())                                                                                                                                                     
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')                                                                                                       
>>> SigGen = rm.open_resource('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR')                                                                                         
>>> cmd = bytes([0x14, ])                                                                                                                                                                                                     
>>> SigGen.send_command(data=cmd)                                                                                                                                                 
 Traceback (most recent call last):                                                                                                                                                   
File "<stdin>", line 1, in <module>                                                                                                                                             
 AttributeError: 'USBInstrument' object has no attribute 'send_command'                                                                                                             
>>>         

So wondering if the adapter has a method to write command bytes to the instrument?
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #19 on: December 23, 2023, 04:12:43 pm »
Hi am trying to try the DCL command.
I have figured out I need to write hex value 0x14, but all I can find is confusion and error messages.  An example being this: 
https://github.com/pyvisa/pyvisa/issues/491

In the issue you link to, the person is clearly using a "real" GPIB adapter or card because they refer to the pyVISA GPIBInstrument class. The xyphro adapter presents itself as a USBTMC device and therefore pyVISA can only talk to the instrument using its USBInstrument class, and therefore, the only valid VISA functions are those listed here: https://pyvisa.readthedocs.io/en/latest/api/resources.html#pyvisa.resources.USBInstrument

That's why you got this error message:
Code: [Select]
AttributeError: 'USBInstrument' object has no attribute 'send_command'Because send_command() is valid for a GPIBInstrument object but not a USBInstrument object.

With xyphro adapter, you don't need to (and in fact can't) send low-level commands to the instrument in the manner you're attempting.

If you just run:

Code: [Select]
SigGen.clear()
..and the adapter firmware will do all the low-level stuff for you.

If you want to prove to yourself what's really happening, you can follow the logic through the various specs and xyphro's firmware:

You run SigGen.clear() and pyVISA will send INITIATE_CLEAR to the xyphro adapter. Since the adapter is a USBTMC device and is USB488 compliant, it will behave as described in 4.2.1 of that specification (http://sdpha2.ucsd.edu/lab_equip_manuals/usbtmc_usb488_subclass_1_00.pdf), which is to say it will send Selected Device Clear (SDC) (hex 0x04) to the instrument. Note: The result of sending a DCL (0x14, clear all instruments on the bus) and a SDC (0x04, clear only the addressed instrument) would be the same in our case since only one instrument can be connected to the xyhpro adapter.

Now, we can follow what's happening in xyphro's firmware. In TestAndMeasurement.c (https://github.com/xyphro/UsbGpib/blob/master/SW/TestAndMeasurement/TestAndMeasurement.c), there is a switch-case starting at line 566

Code: [Select]
switch (USB_ControlRequest.bRequest)
Because we got INITIATE_CLEAR from pyVISA, that will kick us down to line 703

Code: [Select]
case Req_InitiateClear:
The important thing that happens here is that the handleSDC flag is set true. Next we jump down to line 1099

Code: [Select]
if (handleSDC)
{
gpib_ren(1); /* ensure that remote control is enabled */
timeout_start(50000); /* 0.5s timeout*/
gpib_sdc(gpib_addr, is_timedout);

handleSDC = false;
}

gpib_sdc is called and now we have to jump over to gpib.c (https://github.com/xyphro/UsbGpib/blob/master/SW/TestAndMeasurement/gpib.c) to see that function starting at line 269. Inside gpib_sdc, one more function is called and that's gpib_cmd_SDC, which is very straightforward:

Code: [Select]
static bool gpib_cmd_SDC(gpibtimeout_t ptimeoutfunc) // selective device clear
{
return gpib_tx(0x04, true, ptimeoutfunc);
}

The command byte 0x04 is sent to the instrument to perform SDC, which as we noted above is equivalent to DCL for our single connected instrument.

So to finally summarize, executing SigGen.clear() in your python script will send SDC (0x14) to your instrument.

I need to be able to tell pyVISA the terminator is "EOI".

No, you don't. The firmware on the adapter again takes care of setting EOI for you and you can follow your way through the code to prove that to yourself as above.
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #20 on: December 24, 2023, 03:49:34 am »
My first paddle into the sea of Python is a script that tests the time to execute and reliability of query commands.
It does this simply by executing the same query command (ID?) 10x in quick succession, and measuring the execution time to complete each query.  The purpose of posting this is to make it available to others.  It should probably run with any and all GPIB instruments.

With very little modification, this script could read a command line argument and execute that.  One script to run many different query commands.  I have chosen not to do that.
My plan is to copy/paste/modify this script for each query command, run the tests, and record a summary of the results in the script.

I have already found that the WaveTek 2520 is not a reliable responder.  The pyVISA exception handling is not handling the occasional errors I see.

Code: [Select]
# Wavetek 2520 RF Signal Generator simple read test
# The purpose of this script is to gauge gpib command reliability, and to measure the
# execution time. 
# This repeats the same gpib query command 10 times and measures the execution time
# for each query.

import pyvisa
import time
from timeit import default_timer as timer

# Define a function that measures the execution time of the argument.
# The argument is a gpib command.

# User Editable Variables
pause = 0.02  # Edit this.  This is the pause from the end of one query to the next. 
# It is the time taken for the instrument to be ready for the next query.
gpib_query = "ID? " # Edit this.  This is the gpib query command under test.

# ID string for adapter 0:  'USB0::0x03EB::0x2065::GPIB_23_24238323232351C01171::INSTR'
def exec_query(cmd):
try:
start = timer()
ans = SigGen.query(cmd)
end = timer()
print("Query : ", cmd,"         Returned : ", str( ans ) )
ExTm = round((end - start) * 1000,2) # milliseconds
except pyvisa.VisaIOError:
print("########### WARNING : Time Out exception has occurred")
SigGen.clear()
return "   Cmd Execution time: ", ExTm,"ms"
 

print("###### Simple GPIB test for WaveTek 2520 SigGen")
print("# Executes read ID 10x")
print()
print("# Show the list of Resources")
rm = pyvisa.ResourceManager()
print(rm.list_resources())


print("# Opening the SigGen")
# Resource = GPIB-usb adapter 0.  Different for each adapter.

SigGen = rm.open_resource('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR')
print()
# Reset the instrument, wait for reset to complete
SigGen.clear()  # Doesn't appear to have any effect on the Signal Generator.

######  Run this once to turn off auto ID.  AutoID is not supported by the WaveTek 2520.
#SigGen.control_in(0xa1, 0x40, 0, 0)
#SigGen.write('!0001')

SigGen.write_termination = '\n'
SigGen.read_termination = '\n'
SigGen.timeout = 1000         #sets 1s timeout for the meter after the read

#print("Read the ID")
try:
for x in range (1,10):
print("# Loop Count :", x, exec_query(gpib_query)) # Edit the gpib
time.sleep(pause)
except KeyboardInterrupt:
SigGen.clear()
SigGen.close()
rm.close()

# RESULTS
# typical execution time of print(SigGen.query('ID? ')) is <12ms
# delay 20ms before next ID? read.

I usually get an output that looks like this:
Code: [Select]
GPIB_test>python WvTk2520_gpib_rd_ID.py\
###### Simple GPIB test for WaveTek 2520 SigGen
# Executes read ID 10x

# Show the list of Resources
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')
# Opening the SigGen

Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  1 ('   Cmd Execution time: ', 11.91, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  2 ('   Cmd Execution time: ', 11.75, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  3 ('   Cmd Execution time: ', 11.74, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  4 ('   Cmd Execution time: ', 11.78, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  5 ('   Cmd Execution time: ', 11.89, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  6 ('   Cmd Execution time: ', 11.92, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  7 ('   Cmd Execution time: ', 11.73, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  8 ('   Cmd Execution time: ', 11.95, 'ms')
Query :  ID?           Returned :  WVTK/2520A,V81.1,F5.1
# Loop Count :  9 ('   Cmd Execution time: ', 11.74, 'ms')

when it doesn't work, I get an output that looks like this:
Code: [Select]
D:\darren\My Documents\Electronics\Wavetek SigGen\GPIB_test>python WvTk2520_gpib_rd_ID.py\
###### Simple GPIB test for WaveTek 2520 SigGen
# Executes read ID 10x

# Show the list of Resources
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')
# Opening the SigGen

Traceback (most recent call last):
  File "D:\darren\My Documents\Electronics\Wavetek SigGen\GPIB_test\WvTk2520_gpib_rd_ID.py\", line 51, in <module>
    SigGen.clear()
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\resources\resource.py", line 381, in clear
    self.visalib.clear(self.session)
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\ctwrapper\functions.py", line 616, in clear
    return library.viClear(session)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\ctwrapper\highlevel.py", line 226, in _return_handler
    return self.handle_return_value(session, ret_value)  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "G:\Programs\Python310\Lib\site-packages\pyvisa\highlevel.py", line 251, in handle_return_value
    raise errors.VisaIOError(rv)
pyvisa.errors.VisaIOError: VI_ERROR_SYSTEM_ERROR (-1073807360): Unknown system error (miscellaneous error).
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #21 on: December 24, 2023, 04:03:13 am »
Quote from: caiser01

If you just run:

Code: [Select]
SigGen.clear()
..and the adapter firmware will do all the low-level stuff for you.

OK now I know.   :-+
The gem has avoided a very deep dive into a rabbit hole.

FYI:  The
Code: [Select]
clear() command has no observable effect on the 2520.   I could write a function that simply sets the 13 user variable settings to known defaults.
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #22 on: December 24, 2023, 08:16:35 am »

So below is the result of a test where the only query command executed is the current RF output LVL.
The previous tests were  for Frequency and for ID.

The output shows the query was "LVL" but the response is Frequency, ID and lastly Level.
The "350-Stored Settings Error" appears to signal that the 2520 knows something is wrong.

I think it is safe to say the 2520 is probably full of bugs.

Code: [Select]
###### Simple GPIB test for WaveTek 2520 SigGen                                                                                       
# Executes read ID 10x                                                                                                                                                                                                                                                       
# Show the list of Resources                                                                                                           
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')                                                         
# Opening the SigGen                                                                                                                                                                                                                                                         
Clear the instrument                                                                                                                   
Query :  LVL?           Returned :  FREQUENCY 222.222 MHz                                                                             
# Loop Count : 1 ('   Cmd Execution time: ', 12.29, 'ms')                                                                             
Query :  LVL?           Returned :  FREQUENCY 222.222 MHz                                                                             
# Loop Count : 2 ('   Cmd Execution time: ', 12.16, 'ms')                                                                             
Query :  LVL?           Returned :  FREQUENCY 222.222 MHz                                                                             
# Loop Count : 3 ('   Cmd Execution time: ', 12.39, 'ms')                                                                             
Query :  LVL?           Returned :  350-STORED SETTINGS ERROR                                                                         
# Loop Count : 4 ('   Cmd Execution time: ', 12.3, 'ms')                                                                               
Query :  LVL?           Returned :  350-STORED SETTINGS ERROR                                                                         
# Loop Count : 5 ('   Cmd Execution time: ', 12.35, 'ms')                                                                             
Query :  LVL?           Returned :  350-STORED SETTINGS ERROR                                                                         
 # Loop Count : 6 ('   Cmd Execution time: ', 12.38, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 7 ('   Cmd Execution time: ', 12.27, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 8 ('   Cmd Execution time: ', 12.28, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 9 ('   Cmd Execution time: ', 12.35, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 10 ('   Cmd Execution time: ', 12.38, 'ms')                                                                           
 Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 11 ('   Cmd Execution time: ', 12.3, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 12 ('   Cmd Execution time: ', 12.23, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 13 ('   Cmd Execution time: ', 12.2, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 14 ('   Cmd Execution time: ', 12.38, 'ms')                                                                             
Query :  LVL?           Returned :  WVTK/2520A,V81.1,F5.1                                                                             
# Loop Count : 15 ('   Cmd Execution time: ', 12.33, 'ms')                                                                           
 Query :  LVL?           Returned :  350-STORED SETTINGS ERROR                                                                         
# Loop Count : 16 ('   Cmd Execution time: ', 12.35, 'ms')                                                                             
Query :  LVL?           Returned :  AMPLITUDE -10.0 dBm                                                                               
# Loop Count : 17 ('   Cmd Execution time: ', 12.24, 'ms')                                                                             
Query :  LVL?           Returned :  AMPLITUDE -10.0 dBm                                                                               
# Loop Count : 18 ('   Cmd Execution time: ', 12.37, 'ms')                                                                           
 Query :  LVL?           Returned :  AMPLITUDE -10.0 dBm                                                                               
# Loop Count : 19 ('   Cmd Execution time: ', 12.25, 'ms')       

I tested the hypothesis that the commands were issued too quickly with not enough time for the 2520 to finish.  I extended times, especially after .clear for up to 60 seconds.
The test script had dynamic fatal errors. 

So when I program gpib, I will need to keep sending commands until I get a valid response. 
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #23 on: December 24, 2023, 09:24:46 am »
I am getting error messages when a gpib command generates and exception. 

Code: [Select]
  File "D:\My Documents\Electronics\Wavetek SigGen\GPIB_test\WvTk2520_gpib_rd_LVL.py\", line 32, in exec_query
    return "   Cmd Execution time: ", ExTm,"ms"
                                      ^^^^
UnboundLocalError: cannot access local variable 'ExTm' where it is not associated with a value

I think the problem is that when the gpib command fails within a defined function the variable ExTm is not assigned a value.

Code: [Select]
...
ans = SigGen.query(cmd)                                                             # query fails generating an exception.
end = timer()
print("Query : ", cmd,"         Returned : ", str( ans ) )
ExTm = round((end - start) * 1000,2) # milliseconds           # Extm never gets assigned a value
except pyvisa.VisaIOError:
print("########### WARNING : Time Out exception has occurred") 
return "   Cmd Execution time: ", ExTm,"ms"                                                   # on return, ExTm is unassigned
...

Not sure how to fix this yet. Looking into it.


Edit:  Fixed this by moving the execution time calculation to the return(...) statement.
Code: [Select]
print("Query : ", cmd,"         Returned : ", str( ans ) )
#ExTm = round((end - start) * 1000,2) # milliseconds
except pyvisa.VisaIOError:
print("########### WARNING : Time Out exception has occurred")
return "   Cmd Execution time: ", round((end - start) * 1000,2),"ms"
« Last Edit: December 24, 2023, 09:30:11 am by dazz1 »
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #24 on: December 25, 2023, 11:38:31 pm »
Having said I wouldn't do something, I have done it. 
I have written a python script that takes a gpib query command (eg.  "ID?") as a argument.
That command is then executed in a loop.

The output includes the response to the command and measures the time taken for the instrument to execute and response to the command.  This measured time is end-to-end and includes the duration of communications to send the command and receive the response.

This script is designed for commands where something is written to the instrument, and then a response is read back.  This script does not attempt to cover all types if instructions. 


This script should run with any instrument.      It allows a user to test the response of any instrument to gpib query commands.

Code: [Select]
# Wavetek 2520 RF Signal Generator simple read test
# The purpose of this script is to gauge gpib command reliability, and to measure the
# execution time. 
# This repeats the same gpib query command 10 times and measures the execution time
# for each query.

import pyvisa
import time
import sys
from timeit import default_timer as timer
# CMD commands to run
# D:
# D:\My Documents\Electronics\Wavetek SigGen\GPIB_test\

# Define a function that measures the execution time of the argument.
# The argument is a gpib command.

# User Editable Variables
read_cnt = 20      # The number of queries looped through

pause = 1  # Edit this.  This is the pause from the end of one query to the next. 
# It is the added delay to allow the instrument to be ready for the next query.

# The function to execute a GPIB query command.  The command is executed and the results
# are printed. 
def exec_query(cmd):
try:
start = timer()
end = start
ans = SigGen.query(cmd)
end = timer()
print("Query : ", cmd,"         Returned : ", str( ans ) )
except pyvisa.VisaIOError:
print("########### WARNING : Time Out exception has occurred")
return "   Cmd Execution time: ", round((end - start) * 1000,2),"ms"

 
# ID string for adapter 0:  'USB0::0x03EB::0x2065::GPIB_23_24238323232351C01171::INSTR'

if len(sys.argv) > 0 :
gpib_cmd = str(sys.argv[1])
else:
gpib_cmd = "ID?"  # in the absence of a command, default to ID?

print("The entered query command is : ", gpib_cmd)



print("###### Simple GPIB test for WaveTek 2520 SigGen")
print("# Executes read ID 10x")
print()
print("# Show the list of Resources")
rm = pyvisa.ResourceManager()
print(rm.list_resources())

print("# Opening the SigGen")
# Resource = GPIB-usb adapter 0.  Different for each adapter.

SigGen = rm.open_resource('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR')
print()
# Reset the instrument, wait for reset to complete
#time.sleep(pause)
print("Clear the instrument")
SigGen.clear()
time.sleep(0.1)

######  Run this once to turn off auto ID.  AutoID is not supported by WvTk2520.
#SigGen.control_in(0xa1, 0x40, 0, 0)
#SigGen.write('!0001')

SigGen.write_termination = '\n'
SigGen.read_termination = '\n'
SigGen.timeout = 500        #sets timeout (ms) for the instrument to respond.

#print("Read the ID")
try:
for x in range (0,read_cnt):
print("# Loop Count :", x, exec_query(gpib_cmd)) # The gpib command under test
time.sleep(pause)
except KeyboardInterrupt:
print("################ Interrupted by keyboard !")
SigGen.clear()
SigGen.close()
rm.close()

# RESULTS
# typical execution time of print(SigGen.query('ID? ')) is <13ms
# delay 20ms before next ID? read.
# Randomly returns : Query :  FRQ?           Returned :  350-STORED SETTINGS ERROR

This is a development of the first python script I have written, so for all those that know what they are doing, be gentle on me.
This is a test program so it is unpolished and simple. 

The output shows the command, the response and the execution time (duration).
A sample output is:

Code: [Select]
# Show the list of Resources                                                                                           
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')                                           
# Opening the SigGen                                                                                                                                                                                                                           
Clear the instrument                                                                                                   
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 0 ('   Cmd Execution time: ', 11.99, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 1 ('   Cmd Execution time: ', 11.94, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 2 ('   Cmd Execution time: ', 12.27, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 3 ('   Cmd Execution time: ', 12.07, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 4 ('   Cmd Execution time: ', 12.08, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 5 ('   Cmd Execution time: ', 11.98, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 6 ('   Cmd Execution time: ', 12.15, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 7 ('   Cmd Execution time: ', 12.12, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 8 ('   Cmd Execution time: ', 12.02, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 9 ('   Cmd Execution time: ', 12.82, 'ms')                                                               
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 10 ('   Cmd Execution time: ', 12.16, 'ms')                                                             
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 11 ('   Cmd Execution time: ', 12.27, 'ms')                                                             
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 12 ('   Cmd Execution time: ', 11.97, 'ms')                                                             
Query :  lst?          Returned :  AMPLITUDE -10.0 dBm                                                                 
# Loop Count : 13 ('   Cmd Execution time: ', 12.16, 'ms')                                                             
Query :  lst?          Returned :  350-STORED SETTINGS ERROR                                                           
# Loop Count : 14 ('   Cmd Execution time: ', 12.2, 'ms')                                                               
Query :  lst?          Returned :  350-STORED SETTINGS ERROR                                                           
 # Loop Count : 15 ('   Cmd Execution time: ', 11.99, 'ms')                                                             
Query :  lst?          Returned :  AMP STEP 0.10 dB                                                                     
# Loop Count : 16 ('   Cmd Execution time: ', 12.12, 'ms')                                                             
Query :  lst?          Returned :  AMP STEP 0.10 dB                                                                     
# Loop Count : 17 ('   Cmd Execution time: ', 11.96, 'ms')                                                             
Query :  lst?          Returned :  AMP STEP 0.10 dB                                                                     
# Loop Count : 18 ('   Cmd Execution time: ', 12.37, 'ms')

The sample shows that the WaveTek 2520 is unreliable.  At face value, the sample output looks like a timing issue.  Increasing the pause durations between instructions does not change the output.  It also looks like a FIFO buffer needs to be cleared before the correct response is received.

I tested the hypothesis that  .clear() would flush any buffers.  The gpib command: SigGen.clear() has no observable effect on the WaveTek2520, but it takes 125ms to complete, so it is doing something.
« Last Edit: December 26, 2023, 09:23:26 am by dazz1 »
Dazz

Over Engineering: Why make something simple when you can make it really complicated AND get it to work?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->