1

I am trying to control a Tektronix RSA306 Spectrum Analyzer by using the API. The program finds the RSA300API.dll file but throws an error when searching and connecting to the device. The program I am running is an example from Tektronix. The setup I am currently using is Python 2.7.12 x64(Anaconda 4.1.1) on 64 bit Windows 7.

from ctypes import *
import numpy as np
import matplotlib.pyplot as plt

I am locating the .dll file with:

rsa300 = WinDLL("RSA300API.dll")

The error occurs when executing the search function:

longArray = c_long*10
deviceIDs = longArray()
deviceSerial = c_wchar_p('')
numFound = c_int(0)
serialNum = c_char_p('')
nomenclature = c_char_p('')
header = IQHeader()

rsa300.Search(byref(deviceIDs), byref(deviceSerial), byref(numFound))
if numFound.value == 1:
   rsa300.Connect(deviceIDs[0])
else:
   print('Unexpected number of instruments found.')
   exit()

When running the following error messages appear:

C:\Anaconda2\python.exe C:/Tektronix/RSA_API/lib/x64/trial
<WinDLL 'RSA300API.dll', handle e47b0000 at 3ae4e80>
Traceback (most recent call last):
  File "C:/Tektronix/RSA_API/lib/x64/trial", line 44, in <module>
    rsa300.Search(byref(deviceIDs), byref(deviceSerial), byref(numFound))
  File "C:\Anaconda2\lib\ctypes\__init__.py", line 376, in __getattr__
    func = self.__getitem__(name)
  File "C:\Anaconda2\lib\ctypes\__init__.py", line 381, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'Search' not found

The issue that I am having is that the 'Search' function is not found. What would be the solution to this problem?

richar8086
  • 177
  • 4
  • 13
Rwinder
  • 11
  • 3
  • 1
    Are you sure of the way you open the dll ? Maybe you should try this way: http://stackoverflow.com/a/3173926/5920310 Are you sure that there is a `Search` function inside the dll ? – Xavier C. Sep 07 '16 at 18:24
  • I would assume that there is a 'Search' function inside the dll. The dll was downloaded straight from the Tektronix website and the example program is from there as well. @XavierC. – Rwinder Sep 07 '16 at 18:40
  • Can you provide the output of: `dir(rsa300)` and `help(rsa300)` ? It will help. – richar8086 Sep 09 '16 at 18:57

1 Answers1

0

Tektronix application engineer here.

The problem here is a mismatch of API versions. Your code is referencing an old version of the API (RSA300API.dll) and the error message is referencing a newer version of the API (RSA_API.dll). Make sure you have installed the most current version of the API and that you reference the correct dll in your code.

Here is a link to download the latest version of the RSA API (as of 11/1/16): http://www.tek.com/model/rsa306-software

Here is a link to download the API documentation (as of 11/1/16). There is an Excel spreadsheet attached to this document that outlines the differences between old functions and new functions: http://www.tek.com/spectrum-analyzer/rsa306-manual-6

Function names were changed in the new version using for the sake of clarity and consistency. The old version of the API didn't have prefixes for most functions, and it was unclear which functions were grouped together just from reading the function names. The new version of the API applies prefixes to all functions and it is now much easier to tell what functional group a given function is in just by reading its declaration. For example the old search and connect functions were simply called Search() and Connect(), and the new version of the functions are called DEVICE_Search() and DEVICE_Connect().

Note: I use cdll.LoadLibrary("RSA_API.dll") to load the dll rather than WinDLL().

DEVICE_Search() has slightly different arguments than Search(). Due to different argument data types, the new DEVICE_Search() function doesn't play as well with ctypes as the old Search() function does, but I've found a method that works (see code below).

Here is the search_connect() function I use at the beginning of my RSA control scripts:

from ctypes import *
import os

"""
################################################################
C:\Tektronix\RSA306 API\lib\x64 needs to be added to the 
PATH system environment variable
################################################################
"""
os.chdir("C:\\Tektronix\\RSA_API\\lib\\x64")
rsa = cdll.LoadLibrary("RSA_API.dll")


"""#################CLASSES AND FUNCTIONS#################"""
def search_connect():
    #search/connect variables
    numFound = c_int(0)
    intArray = c_int*10
    deviceIDs = intArray()
    #this is absolutely asinine, but it works
    deviceSerial = c_char_p('longer than the longest serial number')
    deviceType = c_char_p('longer than the longest device type')
    apiVersion = c_char_p('api')

    #get API version
    rsa.DEVICE_GetAPIVersion(apiVersion)
    print('API Version {}'.format(apiVersion.value))

    #search
    ret = rsa.DEVICE_Search(byref(numFound), deviceIDs, 
        deviceSerial, deviceType)

    if ret != 0:
        print('Error in Search: ' + str(ret))
        exit()
    if numFound.value < 1:
        print('No instruments found. Exiting script.')
        exit()
    elif numFound.value == 1:
        print('One device found.')
        print('Device type: {}'.format(deviceType.value))
        print('Device serial number: {}'.format(deviceSerial.value))
        ret = rsa.DEVICE_Connect(deviceIDs[0])
        if ret != 0:
            print('Error in Connect: ' + str(ret))
            exit()
    else:
        print('Unexpected number of devices found, exiting script.')
        exit()