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

0 Members and 1 Guest are viewing this topic.

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #25 on: December 26, 2023, 02:23:08 am »
Nice job on the script and thanks for sharing.

A few thoughts:

1. I did not know of the existence of the timeit library so that's something to file away for later use. I've always used perf_counter from the time library for timing execution.
2. 12ms response time is pretty good and typical of an instrument of this vintage.
3. I wonder if changing just the write termination to '\r' in the script (no changes to the instrument's DIP switches, etc.) would eliminate the 350 errors. For my Fluke 6060B RF signal generator, I had to change the write termination to ';' to keep it from occasionally hiccuping.
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Test script for Query Commands
« Reply #26 on: December 26, 2023, 09:29:27 am »
Hi
I have been looking for / testing methods to get a reliable response from gpib queries sent to my WaveTek2520 RF signal generator.
The script I have come up with does this by ignoring any initial null responses, then it keeps reading until at least two adjacent nulls are returned.

I have no idea if this is best practice, or any practice, but it appears to work.
The instruction set and other key parameters are easily adjusted, so this script could be readily adapted to other instruments with simple query commands. That is why I have posted the script here:
Code: [Select]
# Wavetek 2520 RF Signal Generator simple read test
# The purpose of this script is to test a method to obtain reliable
# responses from the instrument.  This script is designed to reliably
# read the responses to query type commands only.
#
# Reads fail because:
# the script runs too fast (pauses need to be inserted)
# the first read returns a null response and,
# responses are initially from a FIFO buffer.
#
# This script:
# discards an initial single null response.
# keeps reading until the responses are at least two nulls.
# This script will read multi-line responses. 
# This script executes all query type gpib commands in a loop.
# The commands are stored in a 2xn matrix. 
# The columns are a:
# query command
# description of the command
#
# 0:  cmd      SET?
# 1:  description List all internal settings

# The instructions are in a user defined loop count. 
# The commands are in an editable array to allow this script to
# be used with any simple query command, including multi-line responses.
# Edit "pause" to adjust the inserted delay periods. 

import pyvisa
import time
from timeit import default_timer as timer
import sys
import array as arr
import numpy as np


# 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 = 5      # The number of times to loop through a set of queries

pause = .05  # 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.

############ Query Commands Arrays
# Edit this array to define all of the query commands. 
# Array:  "command", No. of response lines to read, description

arrayCmds = np.array([
["ID?" ,"ID"],
["FRQ?","Frequency"],
["FST?","Frequency Step"],
["LVL?","Amplitude"],
["LST?","Amp Step"],
["RF? ","RF Output on/off"],
["IAM?","Internal AM "],
["IFM?","Internal FM "],
["XAM?","External AM "],
["XFM?","External FM "],
["RTE?","Internal modulation tone 400/1000Hz"],
["MOD?","Modulation Mode"],
["ERR?","Error message"],
["OPT?","Installed Options"],
["SET?","List all settings:"]])



# The function to execute a GPIB query command.  The command is executed and the results
# are printed. 
def exec_query():
try:
for row in arrayCmds:
print("#   Query : ", row[0],"  =  ",row[1])
start = timer()
end = start
# Write, Read same as query
SigGen.write(row[0])          # send command to instrument
RdNull = False           # Count the number of nulls received
while True:
time.sleep(pause)
ans = SigGen.read()
end = timer()
duration = round((end - start) * 1000,2)
if ans == "" : # if read = null
#print("Null 1", RdNull)
if RdNull == True:
#print("Null 2", RdNull)
break
RdNull = True
else:
RdNull = False
print("#   Returned : ", str( ans ),"   Duration : ", duration )

except pyvisa.VisaIOError:
print("########### WARNING : Time Out exception has occurred")
return "#   Cmd Execution time: ", duration,"ms"

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


print("###### Simple GPIB test for WaveTek 2520 SigGen")
print("# Executes a list of query commands")
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
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("# Run all query commands ...")
try:
for x in range (0,read_cnt):
print("# Loop Count :", x, exec_query()) # The gpib command under test
time.sleep(pause)
except KeyboardInterrupt:
print("################ Interrupted by keyboard !")
SigGen.clear()
SigGen.close()
rm.close()

# RESULTS
# Reading the responses (multiple reads) until nulls are sensed is a reliable method of
# reading data from a WaveTek 2520 RF signal generator.  This may work with other
# instruments by modifying the command array.

A sample output is shown below:

Code: [Select]
# Loop Count : 3 ('#   Cmd Execution time: ', 884.63, 'ms')
#   Query :  ID?   =   ID
#   Returned :  WVTK/2520A,V81.1,F5.1             Duration :  59.91
#   Query :  FRQ?   =   Frequency
#   Returned :  FREQUENCY 222.222 MHz             Duration :  60.2
#   Query :  FST?   =   Frequency Step
#   Returned :  FREQ STEP 50.0 kHz                Duration :  62.51
#   Query :  LVL?   =   Amplitude
#   Returned :  AMPLITUDE -10.0 dBm               Duration :  61.86
#   Query :  LST?   =   Amp Step
#   Returned :  AMP STEP 0.10 dB                  Duration :  113.0
#   Query :  RF?    =   RF Output on/off
#   Returned :  RF OUTPUT OFF                     Duration :  60.41
#   Query :  IAM?   =   Internal AM
#   Returned :  INTERNAL AM 100.0 %               Duration :  61.69
#   Query :  IFM?   =   Internal FM
#   Returned :  INTERNAL FM 80.0 kHz              Duration :  62.06
#   Query :  XAM?   =   External AM
#   Returned :  EXTERNAL AM 60.0 %                Duration :  62.13
#   Query :  XFM?   =   External FM
#   Returned :  EXTERNAL FM 235.0 kHz             Duration :  111.9
#   Query :  RTE?   =   Internal modulation tone 400/1000Hz
#   Returned :  499-SYSTEM OPERATIONAL            Duration :  60.57
#   Query :  MOD?   =   Modulation Mode
#   Returned :  MODULATION EXT PM                 Duration :  60.55
#   Query :  ERR?   =   Error message
#   Returned :  499-SYSTEM OPERATIONAL            Duration :  60.66
#   Query :  OPT?   =   Installed Options
#   Returned :  OPT 75:Level Step                 Duration :  60.07
#   Returned :  OPT 7A:External Phase Mod         Duration :  121.1
#   Query :  SET?   =   List all settings:
#   Returned :  FREQUENCY 222.222 MHz             Duration :  112.46
#   Returned :  FREQ STEP 50.0 kHz                Duration :  172.73
#   Returned :  AMPLITUDE -10.0 dBm               Duration :  233.66
#   Returned :  INTERNAL AM 100.0 %               Duration :  293.71
#   Returned :  INTERNAL FM 80.0 kHz              Duration :  353.74
#   Returned :  EXTERNAL AM 60.0 %                Duration :  414.08
#   Returned :  EXTERNAL FM 235.0 kHz             Duration :  475.76
#   Returned :  RF OUTPUT OFF                     Duration :  536.76
#   Returned :  499-SYSTEM OPERATIONAL            Duration :  596.77
#   Returned :  MODULATION EXT PM                 Duration :  657.02
#   Returned :  AMP STEP 0.10 dB                  Duration :  717.81
#   Returned :  EXT PHASE 0.30 rads               Duration :  778.42
# Loop Count : 4 ('#   Cmd Execution time: ', 882.73, 'ms')
« Last Edit: December 26, 2023, 10:21:30 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
PyMeasure
« Reply #27 on: December 26, 2023, 10:15:49 am »
Hi
I found PyMeasure here:  https://pymeasure.readthedocs.io/en/latest/index.html

I am looking at this a fast track way to write pymeasure.instruments for my own instruments.
I can use existing similar instruments and their code, as a template for mine. 

Anyone have experience with this? 
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 #28 on: December 26, 2023, 10:19:38 am »
Nice job on the script and thanks for sharing.

A few thoughts:

...
3. I wonder if changing just the write termination to '\r' in the script (no changes to the instrument's DIP switches, etc.) would eliminate the 350 errors. For my Fluke 6060B RF signal generator, I had to change the write termination to ';' to keep it from occasionally hiccuping.

I can set the termination from the front panel for testing.  Haven't really done that yet.
The manual says read/write terminations need to be the same.
Dazz

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

Online bson

  • Supporter
  • ****
  • Posts: 2778
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #29 on: December 27, 2023, 09:24:47 pm »
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.
NI VISA is also full of bugs.  It might be worth trying usbtmc directly to the instrument without the bloated VISA stuff.
https://github.com/python-ivi/python-usbtmc
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #30 on: December 29, 2023, 12:23:26 am »
Quote from: bson

NI VISA is also full of bugs.  It might be worth trying usbtmc directly to the instrument without the bloated VISA stuff.
https://github.com/python-ivi/python-usbtmc

I am using the R&S GPIB driver which I understand is a lot lighter than NI-VISA.
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 GPIB locking up
« Reply #31 on: December 29, 2023, 12:39:41 am »
Hi
I have a problem where the 2520 GPIB interface becomes unresponsive after being left alone for a few minutes.    The fix is to unplug/plug-in the USB-GPIB adapter.  This suggest the possibility that it might be possible for the adapter firmware to be modified to recover the 2520

There is no evidence of indication of a bug in the usb-gpib adapter firmware.  This looks like a problem with the 2520 firmware.

The timeout appears to be entirely within the 2520.
The code looks like this:
Code: [Select]
# Wavetek 2520 RF Signal Generator simple read test
# CMD commands to run
# D:
# cd \darren\My Documents\Electronics\Wavetek SigGen\GPIB_test\
#  python WvTk2520_gpib_RTE.py
import pyvisa
import time

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')
SigGen.timeout = 2000         #sets 2s timeout for the meter after the read

print("# Clear")
SigGen.clear()
...

and this generate a time out error message as follows:

Code: [Select]
Simple GPIB test for WaveTek 2520 SigGen
Show the list of Resources
('USB0::0x03EB::0x2065::GPIB_02_24238323232351C01171::INSTR', 'ASRL1::INSTR')
# Opening the SigGen
# Clear
Traceback (most recent call last):
  File "D:\darren\My Documents\Electronics\Wavetek SigGen\GPIB_test\WvTk2520_gpib_RTE.py", line 32, 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_TMO (-1073807339): Timeout expired before operation completed.

It is important to note that this code will run OK if it is run frequently.  The lock out happens if things are left alone for a few minutes.

It seems that cycling the power to the USB adapter does something that "clear" does not.  Just wondering if others have exprienced and solved this problem?

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 #32 on: December 29, 2023, 09:39:18 am »
Done some searching around the Internet.  I ran this command to get info on my system setup.

Code: [Select]
>pyvisa-info
Machine Details:
   Platform ID:    Windows-10-10.0.19045-SP0
   Processor:      Intel64 Family 6 Model 94 Stepping 3, GenuineIntel

Python:
   Implementation: CPython
   Executable:     G:\Programs\Python310\python.exe
   Version:        3.12.1
   Compiler:       MSC v.1937 64 bit (AMD64)
   Architecture:   AMD64
   Build:          Dec  7 2023 22:03:25 (#tags/v3.12.1:2305ca5)
   Unicode:        UCS4

PyVISA Version: 1.14.1

Backends:
   ivi:
      Version: 1.14.1 (bundled with PyVISA)
      #1: C:\WINDOWS\system32\visa32.dll:
         found by: auto
         architecture:
            ('x86', 64)
         Vendor: Rohde & Schwarz GmbH
         Impl. Version: 7340546
         Spec. Version: 7340544
      #2: C:\WINDOWS\system32\visa64.dll:
         found by: auto
         architecture:
            ('x86', 64)
         Vendor: Rohde & Schwarz GmbH
         Impl. Version: 7340546
         Spec. Version: 7340544

None of this has helped my diagnose the problem, but it does show that what I have appears to be working.
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 #33 on: December 29, 2023, 03:43:13 pm »
It seems that cycling the power to the USB adapter does something that "clear" does not.

Try adding this at the very end of the script.

Code: [Select]
SigGen.clear()
sleep(1)
SigGen.control_ren(pyvisa.constants.VI_GPIB_REN_ADDRESS_GTL)
SigGen.close()
rm.close()

The control_ren() function does just what it says, controls the REN (remote enable) signal on the GPIB according to a constant you pass it. Passing VI_GPIB_REN_ADDRESS_GTL puts the instrument back into local mode (equivalent to pressing the Local key on the front panel). The REN signal naturally goes away when you unplug the USB adapter. Having this function at the end of the script does the same thing programmatically.
 

Online coromonadalix

  • Super Contributor
  • ***
  • Posts: 8811
  • Country: ca
Re: Problems Writing code for GPIB Py VISA
« Reply #34 on: December 29, 2023, 04:13:08 pm »
but it the other case, is there a "keep alive" communication, or maybe do some status polling ?? who would help prevent the disconnection from the 2520 ??

 

Offline caiser01

  • Regular Contributor
  • *
  • Posts: 66
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #35 on: December 29, 2023, 10:09:21 pm »
but it the other case, is there a "keep alive" communication, or maybe do some status polling ?? who would help prevent the disconnection from the 2520 ??

Never heard of a GPIB instrument that needed a communication heartbeat. That's not to say one couldn't exist.

I'm more inclined to say the Wavetek 2520 may just have a poor GPIB implementation. I have seen that multiple times.

If your program completes running cleanly and you want to run it again after some arbitrary length of time, the instrument should communicate again without issue. It sounds as though this instrument may get into a weird state if held in remote without interaction, which should not happen.

Apart from the script additions I suggested earlier, another thing to try is:
1. Run the script to completion
2. Press the Local key on the front panel
3. Leave it for a few minutes
4. Try running the script again

That will tell you if the issue indeed lies with the instrument being too long in remote mode without communication.
 
The following users thanked this post: coromonadalix

Offline rcjoy

  • Regular Contributor
  • *
  • Posts: 65
  • Country: us
Re: Problems Writing code for GPIB Py VISA
« Reply #36 on: December 30, 2023, 07:42:27 am »
You could try increasing the timeout time.  Try 10 or 30 seconds.  Just a guess.

 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA : writing bytes
« Reply #37 on: January 06, 2025, 07:54:03 am »
Hi
I am trying to write code for an Electro-Metrics EMC30 EMC test receiver.https://www.eevblog.com/forum/testgear/electro-metrics-em-30-emc-receiver/

I am writing pyvisa code to write a command that sets the receiver frequency.  The command is 3 bytes of binary data.  I will write the numbers here in decimal for clarity, but the data sent is binary bytes.  The frequency control values are in the range 0-255. 
I am a python noob but I have been programming for 45 years.

The command format is:    255 xx yy
where:
xx = frequency course control byte
yy = frequency fine control byte.

So an actual command sent might look like:    255  102 47
The second two bytes are stored as decimal variables:  FreqCse and FreqFine.

My question is how do I write these 3 bytes to the gpib interface devices with pyVISA ??

I have tried a few different commands and variants.

The one that almost works is:

emc30.write(bin(255))
emc30.write(bin(FreqCse))
emc30.write(bin(FreqFine))

It doesn't matter what values I put in the two variable, the frequency always goes to zero  zero.

I have tried: emc30.write_binary_values(255), but that doesn't work.  I get an error message that says:  TypeError: ... missing 1 required positional argument: "values"
That looks like operator error. 

What is the correct way of writing 3x bytes to my device with PyVISA?





Dazz

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

Offline Kean

  • Supporter
  • ****
  • Posts: 3542
  • Country: au
    • Kean Electronics
Re: Problems Writing code for GPIB Py VISA
« Reply #38 on: January 06, 2025, 09:49:25 am »
What is the correct way of writing 3x bytes to my device with PyVISA?

I don't use PyVISA, but I believe you would want to encode the data in a bytearray (or bytes object).

Try this:
emc30.write(bytearray([255, 102, 47]))
or
emc30.write(bytes([255, FreqCse, FreqFine]))
 

Offline dazz1Topic starter

  • Super Contributor
  • ***
  • Posts: 1142
  • Country: nz
Re: Problems Writing code for GPIB Py VISA
« Reply #39 on: January 06, 2025, 10:21:01 am »
What is the correct way of writing 3x bytes to my device with PyVISA?

I don't use PyVISA, but I believe you would want to encode the data in a bytearray (or bytes object).

Try this:
emc30.write(bytearray([255, 102, 47]))
or
emc30.write(bytes([255, FreqCse, FreqFine]))

In a moment of desperation, resorted to reading the instructions found here:  https://pyvisa.readthedocs.io/en/latest/introduction/rvalues.html
I tried using a list of decimal values (as you have done), typed as 'd', but that didn't work.  I think both a list of bytearray should work, but don't.

I have raised this as an issue here:  https://github.com/pyvisa/pyvisa/issues/883    It shouldn't be this difficult to figure out.
Dazz

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

Offline Kean

  • Supporter
  • ****
  • Posts: 3542
  • Country: au
    • Kean Electronics
Re: Problems Writing code for GPIB Py VISA
« Reply #40 on: January 06, 2025, 10:35:51 am »
It looks like the write function only accepts a string.

Similar to the suggestion on your issue, you can try write_raw but with a byte array
Code: [Select]
emc30.write_raw(bytes([255, FreqCse, FreqFine]))
But based on the description of that function, you could hit an issue with certain byte values, like the XON/XOFF or even NUL ASCII codes.
https://pyvisa.readthedocs.io/en/latest/api/resources.html#pyvisa.resources.SerialInstrument.write_raw

Edit: I'm guessing you are using the PyVisa SerialInstrument for a USB serial to an Arduino for the GPIB interface.  In that case it appears that flow_control defaults to none...
https://pyvisa.readthedocs.io/en/latest/api/resources.html#pyvisa.resources.SerialInstrument
« Last Edit: January 06, 2025, 10:39:52 am by Kean »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->