- AuthorSearch Results
Found in Replies
catalin_ro posted on October 9, 2016 at 4:32 am View this postIn reply to: BB60C–external trigger–bbFetchRaw(buffer, triggers)
catalin_roParticipantI decided not to start another thread because the problem I have just discovered is related. The setup is 100% identical.
There is spurious trigger event occurring on the first ever call of bbInitiate with trigger input enabled, after opening the receiver, even if the trigger input is hardwired to ground. Subsequent bbInitiate calls do not cause spurious trigger events.
If the first ever bbInitiate call is with trigger input disabled there is no spurious event when later enabling the input.
The spurious event is always in the first ever received buffer at sample 572 with 64-bit APIs and at sample 1144 with 32-bit APIs. Tested with 32-bit and 64-bit API 3.0.11 (bbFetchRaw) and 64-bit API 3.0.14 (bbGetIQ).
Catalin
Found in Replies
- This reply was modified 8 years, 6 months ago by
catalin_ro.
catalin_ro posted on October 8, 2016 at 1:55 am View this postIn reply to: Two BB60C IQ streaming in the same process
catalin_roParticipantMore to my reply…
I have been able to get it running in my application as well. In the end, after playing around connecting/disconnecting the receivers, I got it going as expected.
But, in the process, I have also seen the undocumented
bbDeviceInvalidErr
error code for the second receiver. While all other error codes have pretty meaningful names, this error code isn’t even documented as possible result by the API manual.More to that, while that happened, I decided to see if the second receiver could still be used by another application instance. So I released if from the application instance that gave me the error and I had no problems starting it in a different instance of the same application.
To better understand what the application does, simply think of a radio monitoring software that allows defining hand-off receivers for the detected transmissions. I can dynamically define/undefine the hand-off receivers and I only have issues starting them. By undefining the application, I can start separate application instances for them and they always work as expected.
Catalin
Found in Replies
catalin_ro posted on October 7, 2016 at 11:51 pm View this postIn reply to: Two BB60C IQ streaming in the same process
catalin_roParticipantHello Andrew,
Based on your reply, I have re-checked the API manual (completely re-reading the first pages!) and came across the multi-threading related comment. That paragraph states that the API functions calls are not thread-safe and that they must be protected in the application.
Briefly said, my application has a C++ class that wraps all the required API functionality and provides all the multi-threading protection for one receiver. bbGetIQ/bbFetchRaw (depending on the API version!) is called from another thread that does only that.
When using two receivers, all management functions are called from the main application thread and the IQ buffers retrieving is done in two independent threads, one for each receiver. Do I have to add complete protection around bbGetIQ/bbFetchRaw so they are not called from different threads for different receivers?
Regards,
CatalinFound in Replies
Andrew posted on October 7, 2016 at 1:11 pm View this postIn reply to: Performance regression for APIs newer than 3.0.11
AndrewModeratorHello Catalin,
Check out your other thread for my response to the 2 streaming receiver question.
As for performance regressions. I am re-visiting this issue for a short time. As we have discussed in earlier emails, the bbGetIQ function adds a small amount of additional overhead. At this point I have only seen a marginal regression on one Win10 laptop in our office. All other PCs I have tested exhibit a non-observable CPU increase by switching to the bbGetIQ functionality. In the latest 3.0.14 API, the bbFetchRaw function is simply routed to the bbGetIQ function, and will incur the small overhead.
I will use the Win10 laptop as a test bed for some potential optimizations.
In the mean-time, as we previously discussed, you can continue to use the 3.0.11 API version and the bbFetchRaw functionality.
Regards,
A.J.Found in Replies
subscr posted on October 7, 2016 at 1:02 am View this postIn reply to: Two BB60C IQ streaming in the same process
subscrParticipantHi catalin_ro,
I am facing the same issues too with the new API and BB60C in a multi-instrument configuration. The older API has been more well behaved.
Infact, we had almost placed an order for several pairs of BB60C for a similar requirement. But now I think it will be worthwhile to wait and see if “multiple BB60C on the same host” issue can be resolved by Signal Hound.
To me it looks like an minor API issue. I hope it is taken care of soon.
rgds
Found in Topics
catalin_ro posted on October 7, 2016 at 12:09 am View this postHello,
With the APIs that came after v3.0.11 there is a serious performance hit in zero-span mode, especially when using two BB60C simultaneously (Spike used for both of them). The test PCs are roughly equivalent – i7-2600/16GB/Radeon HD6850 and i7-4710HQ/16GB/nVidia.
Spike 3.0.21 (with API 3.0.11) shows about 10% CPU usage per receiver (so 20% total CPU usage when using both of them) when not decimating (27MHz BW/40MHz sampling rate).
Starting with Spike 3.0.22 (API 3.0.12 and newer) shows about 15% CPU usage for the same settings, but the total CPU usage jumps to 60% when using both receivers. Those 60% are equally split between the two Spike instances.
The test PCs are running Windows 10 Home, 64-bit, fully updated, including the newest drivers.
Regards, Catalin
Found in Topics
catalin_ro posted on October 7, 2016 at 12:00 am View this postTopic: Two BB60C IQ streaming in the same process
in forum BB Series DiscussionsHello,
While trying to use two BB60C in the same Windows application, in IQ streaming mode, only the samples from the first started device are received. bbInitiate returns no error code, but neither bbGetIQ nor bbFetchRaw return any data or any error code for the second started device.
The test was done using API versions 3.0.11 and 3.0.14.The same test on Linux, with API version 3.0.11, has the same end result. Even worse, on Linux even if used in separate applications the second started BB60C returns no IQ samples.
Any chance to get this fixed?
Regards, Catalin
Found in Replies
Andrew posted on September 21, 2016 at 8:54 am View this postIn reply to: How To Find Old BB60C API For Windows
AndrewModeratorHello sszqdz,
If you are happy with version API 3.0.6, you can get this by installing version 3.0.11 of Spike from the link below.
https://signalhound.com/sigdownloads/Spike/Spike(x64)_3011.zip
Once installed you can find the API in the installation directory.
If you have a newer version of Spike installed, you will need to manually uninstall it before 3.0.11 will install.Hope this helps,
Regards,
A.J.Found in Topics
Anonymous
Anonymous posted on September 21, 2016 at 2:37 am View this postTopic: How To Find Old BB60C API For Windows
in forum BB Series DiscussionsHello,everyone
I wrote a program which use bb_api.dll.
My program crashed when I use the bb_api.dll of v3.0.13/3.0.14,but it ran well with v3.0.5.
So I want old dll between 3.0.6 to 3.0.12 to test.
So …can you help me ? Thanks~Found in Replies
Anonymous
Anonymous posted on September 21, 2016 at 2:19 am View this postIn reply to: Get IQ by labview
AnonymousInactiveHi Art!
The example in the folder you download has no problem.
The problem I met is I want to get IQ data.
There is no this example.
So we have to build the VI our self with the getIQ data API.
I already wrote it, but I think something wrong.
It crash all the time when the API getIQ was called.
Do you need my VI? I can send to you.Found in Replies
Andrew posted on September 20, 2016 at 9:39 am View this postIn reply to: Error when getting sweep results with API
AndrewModeratorHello akarthikeyan,
I apologize, I don’t have much experience with ctypes or Python but I can try to help.
It doesn’t look like you are creating a proper array to pass to our API. This line right here
min = ct.c_double(swlen.value)
It looks like you are simply create a single double, whereas you need an array of doubles. (This is an educated guess on my part)
Also, if you are calling GetSweep, you do not need to call GetPartialSweep. Unless you have specific reason to, you will only need GetSweep. GetPartialSweep is a method for retrieving a very long sweep as it is updating. You should start with simply GetSweep for now until you need this functionality.
There might be others who can be of further assistance.
Regards,
A.J.Found in Topics
akarthikeyan posted on September 19, 2016 at 5:11 pm View this postTopic: Error when getting sweep results with API
in forum SA Series DiscussionsHi,
I am trying to do a sweep using sa_api.dll and python & ctypes and I am getting an error and python is getting killed when I call ‘saGetSweep’ function. Following is my program and error.
+++++++
Snippet
+++++++
import os
import sys
import ctypes as ctclass SA124B():
def __init__(self):
self.dllpath = os.path.join(os.getcwd(), ‘x64/sa_api.dll’)
self.sa = 0
self.deviceHandle = 0# Initialize
self.sa = ct.CDLL(self.dllpath)
print “Successfuly Initialized”# Open Device
def openDevice(self):
self.deviceHandle = ct.c_int(0)
deviceHandlePnt = ct.pointer(self.deviceHandle)
res = self.sa.saOpenDevice(deviceHandlePnt)
if res == 0:
print ‘Opened Device Successfully’
else:
print “Opening Device Failed”
sys.exit(0)# Get Serial Number
def getSerialNumber(self):
serialNo = ct.c_uint(0)
serialNoPnt = ct.pointer(serialNo)
self.sa.saGetSerialNumber(self.deviceHandle, serialNoPnt)
print ‘Serial Number: %s’ % str(serialNo.value)# Get Firmware Vesion
def getFirmwareVersion(self):
firmwareRev = ct.c_uint(0)
firmwareRevPnt = ct.pointer(firmwareRev)
self.sa.saGetFirmwareString(self.deviceHandle, firmwareRevPnt)
print ‘Firmware Revision: %s’ % str(firmwareRev.value)# Get Device Type
def getDeviceType(self):
devType = ct.c_uint(0)
devTypePnt = ct.pointer(devType)
self.sa.saGetDeviceType(self.deviceHandle, devTypePnt)
print ‘Device Type: %s’ % str(devType.value)# Get API Version
def getAPIVersion(self):
self.sa.saGetAPIVersion.restype = ct.c_char_p # Tell ctypes this function returns a pointer to a string
apiRevStr = self.sa.saGetAPIVersion(self.deviceHandle)
ret = ct.c_char_p(apiRevStr).value # Dereference pointer, extract string
print ‘API Version: %s’ % str(ret)# Configure Center Span
def cfgCeterSpan(self):
center = ct.c_double(915.0e6)
span = ct.c_double(1.0e6)
res = self.sa.saConfigCenterSpan(self.deviceHandle, center, span)
if res == 0:
print ‘Configured Center Span’
else:
print ‘Configuring Center Span Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Acquisition
def cfgAcquisition(self):
detector = ct.c_uint(0)
scale = ct.c_uint(0)
res = self.sa.saConfigAcquisition(self.deviceHandle, detector, scale)
if res == 0:
print ‘Configured Acquisition’
else:
print ‘Configuring Acquisition Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Level
def cfgLevel(self):
ref = ct.c_double(-10.0)
atten = ct.c_double(-1)
res = self.sa.saConfigLevel(self.deviceHandle, ref, atten)
if res == 0:
print ‘Configured Level’
else:
print ‘Configuring Level Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Sweep Coupling
def cfgSweepCoupling(self):
rbw = ct.c_double(1.0e3)
vbw = ct.c_double(1.0e3)
rejection = ct.c_bool(True)
res = self.sa.saConfigSweepCoupling(self.deviceHandle, rbw, vbw, rejection)
if res == 0:
print ‘Configured Sweep Coupling’
else:
print ‘Configuring Sweep Coupling Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Initiate
def startSweep(self):
mode = ct.c_int(0)
flag = ct.c_uint(0)
res = self.sa.saInitiate(self.deviceHandle, mode, flag)
if res == 0:
print ‘Started Sweep’
else:
print ‘Start Sweep Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Get Sweep and Frame Characteristics
def getSweepInfo(self):
swlen = ct.c_int()
swlenPnt = ct.pointer(swlen)
sfreq = ct.c_double()
sfreqPnt = ct.pointer(sfreq)
binsz = ct.c_double()
binszPnt = ct.pointer(binsz)
res = self.sa.saQuerySweepInfo(self.deviceHandle, swlenPnt, sfreqPnt, binszPnt)
if res == 0:
print ‘Got Sweep Info’
print ‘Sweep Length: %s’ % str(swlen.value)
print ‘Start Frequency: %s’ % str(sfreq.value)
print ‘Bin Size: %s’ % str(binsz.value)min = ct.c_double(swlen.value)
minPnt = ct.pointer(min)
max = ct.c_double(swlen.value)
maxPnt = ct.pointer(max)
# res = self.sa.saGetSweep_64f(self.deviceHandle, minPnt, maxPnt)
start = ct.c_int32(500)
startPnt = ct.pointer(start)
stop = ct.c_int32(1000)
stopPnt = ct.pointer(stop)
res = self.sa.saGetPartialSweep_64f(self.deviceHandle, minPnt, maxPnt, startPnt, stopPnt)
print ‘result: %s’ % str(res)
if res == 0:
print ‘Got Sweep Results’
#print minPnt
#print min.value
#print ‘Minimum Point: %s’ % str(min.value)
#print ‘Maximum Point: %s’ % str(max.value)
else:
print ‘Get Sweep Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)
else:
print ‘Querying Sweep Info Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)def Abort(self):
res = self.sa.saAbort(self.deviceHandle)
if res == 0:
print ‘Aborted’
else:
print ‘Abort Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)def closeDevice(self):
res = self.sa.saCloseDevice(self.deviceHandle)
if res == 0:
print ‘Closed Device Successfully’
else:
print ‘Closing Device Failed: %s’ % str(res)
sys.exit(0)if __name__ == “__main__”:
sa = SA124B()
sa.openDevice()
#sa.getSerialNumber()
#sa.getFirmwareVersion()
#sa.getDeviceType()
#sa.getAPIVersion()
sa.cfgCeterSpan()
sa.cfgAcquisition()
sa.cfgLevel()
sa.cfgSweepCoupling()
sa.startSweep()
sa.getSweepInfo()
sa.getSweep()
sa.Abort()
sa.closeDevice()+++++++++
+++++++++
ERROR
+++++++++
Please find attached Error1.png and Error2.png.
+++++++++Attachments:
You must be logged in to view attached files.Found in Topics
akarthikeyan posted on September 19, 2016 at 4:59 pm View this postHi,
I am trying to do a sweep using sa_api.dll and python & ctypes and I am getting an error and python is getting killed when I call ‘saGetSweep’ function. Following is my program and error.
+++++++
Snippet
+++++++
import os
import sys
import ctypes as ctclass SA124B():
def __init__(self):
self.dllpath = os.path.join(os.getcwd(), ‘x64/sa_api.dll’)
self.sa = 0
self.deviceHandle = 0# Initialize
self.sa = ct.CDLL(self.dllpath)
print “Successfuly Initialized”# Open Device
def openDevice(self):
self.deviceHandle = ct.c_int(0)
deviceHandlePnt = ct.pointer(self.deviceHandle)
res = self.sa.saOpenDevice(deviceHandlePnt)
if res == 0:
print ‘Opened Device Successfully’
else:
print “Opening Device Failed”
sys.exit(0)# Get Serial Number
def getSerialNumber(self):
serialNo = ct.c_uint(0)
serialNoPnt = ct.pointer(serialNo)
self.sa.saGetSerialNumber(self.deviceHandle, serialNoPnt)
print ‘Serial Number: %s’ % str(serialNo.value)# Get Firmware Vesion
def getFirmwareVersion(self):
firmwareRev = ct.c_uint(0)
firmwareRevPnt = ct.pointer(firmwareRev)
self.sa.saGetFirmwareString(self.deviceHandle, firmwareRevPnt)
print ‘Firmware Revision: %s’ % str(firmwareRev.value)# Get Device Type
def getDeviceType(self):
devType = ct.c_uint(0)
devTypePnt = ct.pointer(devType)
self.sa.saGetDeviceType(self.deviceHandle, devTypePnt)
print ‘Device Type: %s’ % str(devType.value)# Get API Version
def getAPIVersion(self):
self.sa.saGetAPIVersion.restype = ct.c_char_p # Tell ctypes this function returns a pointer to a string
apiRevStr = self.sa.saGetAPIVersion(self.deviceHandle)
ret = ct.c_char_p(apiRevStr).value # Dereference pointer, extract string
print ‘API Version: %s’ % str(ret)# Configure Center Span
def cfgCeterSpan(self):
center = ct.c_double(915.0e6)
span = ct.c_double(1.0e6)
res = self.sa.saConfigCenterSpan(self.deviceHandle, center, span)
if res == 0:
print ‘Configured Center Span’
else:
print ‘Configuring Center Span Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Acquisition
def cfgAcquisition(self):
detector = ct.c_uint(0)
scale = ct.c_uint(0)
res = self.sa.saConfigAcquisition(self.deviceHandle, detector, scale)
if res == 0:
print ‘Configured Acquisition’
else:
print ‘Configuring Acquisition Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Level
def cfgLevel(self):
ref = ct.c_double(-10.0)
atten = ct.c_double(-1)
res = self.sa.saConfigLevel(self.deviceHandle, ref, atten)
if res == 0:
print ‘Configured Level’
else:
print ‘Configuring Level Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Configure Sweep Coupling
def cfgSweepCoupling(self):
rbw = ct.c_double(1.0e3)
vbw = ct.c_double(1.0e3)
rejection = ct.c_bool(True)
res = self.sa.saConfigSweepCoupling(self.deviceHandle, rbw, vbw, rejection)
if res == 0:
print ‘Configured Sweep Coupling’
else:
print ‘Configuring Sweep Coupling Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Initiate
def startSweep(self):
mode = ct.c_int(0)
flag = ct.c_uint(0)
res = self.sa.saInitiate(self.deviceHandle, mode, flag)
if res == 0:
print ‘Started Sweep’
else:
print ‘Start Sweep Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)# Get Sweep and Frame Characteristics
def getSweepInfo(self):
swlen = ct.c_int()
swlenPnt = ct.pointer(swlen)
sfreq = ct.c_double()
sfreqPnt = ct.pointer(sfreq)
binsz = ct.c_double()
binszPnt = ct.pointer(binsz)
res = self.sa.saQuerySweepInfo(self.deviceHandle, swlenPnt, sfreqPnt, binszPnt)
if res == 0:
print ‘Got Sweep Info’
print ‘Sweep Length: %s’ % str(swlen.value)
print ‘Start Frequency: %s’ % str(sfreq.value)
print ‘Bin Size: %s’ % str(binsz.value)min = ct.c_double(swlen.value)
minPnt = ct.pointer(min)
max = ct.c_double(swlen.value)
maxPnt = ct.pointer(max)
# res = self.sa.saGetSweep_64f(self.deviceHandle, minPnt, maxPnt)
start = ct.c_int32(500)
startPnt = ct.pointer(start)
stop = ct.c_int32(1000)
stopPnt = ct.pointer(stop)
res = self.sa.saGetPartialSweep_64f(self.deviceHandle, minPnt, maxPnt, startPnt, stopPnt)
print ‘result: %s’ % str(res)
if res == 0:
print ‘Got Sweep Results’
#print minPnt
#print min.value
#print ‘Minimum Point: %s’ % str(min.value)
#print ‘Maximum Point: %s’ % str(max.value)
else:
print ‘Get Sweep Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)
else:
print ‘Querying Sweep Info Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)def Abort(self):
res = self.sa.saAbort(self.deviceHandle)
if res == 0:
print ‘Aborted’
else:
print ‘Abort Failed: %s’ % str(res)
self.closeDevice()
sys.exit(0)def closeDevice(self):
res = self.sa.saCloseDevice(self.deviceHandle)
if res == 0:
print ‘Closed Device Successfully’
else:
print ‘Closing Device Failed: %s’ % str(res)
sys.exit(0)if __name__ == “__main__”:
sa = SA124B()
sa.openDevice()
#sa.getSerialNumber()
#sa.getFirmwareVersion()
#sa.getDeviceType()
#sa.getAPIVersion()
sa.cfgCeterSpan()
sa.cfgAcquisition()
sa.cfgLevel()
sa.cfgSweepCoupling()
sa.startSweep()
sa.getSweepInfo()
sa.getSweep()
sa.Abort()
sa.closeDevice()+++++++++
+++++++++
ERROR
+++++++++
Please find attached Error1.png and Error2.png.
+++++++++Attachments:
You must be logged in to view attached files.Found in Replies
Anonymous
Anonymous posted on September 18, 2016 at 1:02 pm View this postIn reply to: Get IQ by labview
AnonymousInactiveI downloaded sa_api.dll from https://signalhound.com/support/product-downloads/sa44b-sa124b-downloads/
No error occurred when I run VI.What error occurred? Could you show me screenshot? Sorry for my bad English
Found in Replies
Anonymous
Anonymous posted on September 18, 2016 at 9:40 am View this postIn reply to: Get IQ by labview
AnonymousInactiveHi Art.
I don’t have your e-mail.
I attach the sa_api.dll here, thank you so much for trying to help me.Found in Replies
Anonymous
Anonymous posted on September 9, 2016 at 10:20 am View this postIn reply to: Get IQ by labview
AnonymousInactivePlease, send me sa_api.dll. I’ll try to help you.
Found in Replies
Andrew posted on September 6, 2016 at 10:41 am View this post
AndrewModeratorHello Randy,
Have you taken a look at the IQ examples we provide in the C programming language? They are freely available in the API download folder. These examples will show you all the functions required to configure IQ acquisition. I suggest getting the functionality to work in C before moving to Labview.
The download link for the API files is on the downloads page at,
https://signalhound.com/support/product-downloads/sa44b-sa124b-downloads/The download also includes the API manual which will help with any questions you have while looking over the API examples.
Regards,
A.J.Found in Replies
Anonymous
Anonymous posted on September 6, 2016 at 9:25 am View this post
AnonymousInactiveDear Andrew
Thank you for your reply!
Could you tell me how to make the API GetIQ work?
It seems doesn’t work.Regard,
RandyFound in Replies
Andrew posted on September 6, 2016 at 8:45 am View this post
AndrewModeratorHello Randy,
I apologize, we do not have any examples for IQ acquisition in Labview. We only have the sweep example found in the API download folder and there are some sweep examples developed by customers on our forums.
Regards,
A.J.Found in Replies
Andrew posted on September 6, 2016 at 8:40 am View this postIn reply to: Spectrum recording
AndrewModeratorHi Tom,
If you need time stamping from a GPS, you can accomplish this but will need to utilize the C programming interface to accomplish this. Our desktop software does not expose this functionality. If it is interesting to you, a future update to our software will allow long IQ recordings with system time stamping (non GPS). I would expect this in the coming weeks to months.
Using an external GPS and our programming interface, you can expect time stamping with a resolution of around 50ns at the highest sample rates (40MS/s IQ). There is a code example of performing this on page 45 of our programming manual, which you can find linked here,
https://signalhound.com/sigdownloads/BB60C/BB60-API-Manual.pdf
It uses a deprecated function (bbFetchRaw) which has been replaced with bbGetIQ, but otherwise would remain the same if you decided to implement this.If you have any additional questions let me know.
Regards,
A.J.- This reply was modified 8 years, 6 months ago by
- AuthorSearch Results