Forum Replies Created
My own experience is limited for now to BB60C, and we have used quite a few. So far I have not touched the SM200A.
If “shared clock” implies getting the clock from one BB60C to the other BB60C, some special API functions must be called in order for the API to use the same reference clock frequency. The 10MHz built into the BB60C is not quite 10MHz, but slightly off. When set to external reference, the API considers exactly 10MHz.
The end result of this issue is a tuned frequency mismatch and slight sampling rate difference.
I’m using twin BB60Cs in something similar. And I’ve been through the same issues roughly two years ago.
(1) If you pass reference clock from one receiver to the other you need to properly set the reference clock frequency in both. When you will get proper time alignment you will see the drift. Discuss with Andrew about the special, kind of “dangerous”, API calls for properly setting the timebase information.
(2) Use IQ streaming instead of sweeping.
(3) Use an external trigger! A simple controller that can issue the sync pulses whenever you need and then align the samples in software. But be aware that there is a 4 samples pulse position imprecision at widest streaming bandwidth, as far as I recall. In my case the upper level algorithm automatically compensates it.
So I need to check the peak value of the samples in the IQ buffer for zero-span mode and the peak spectrum data in sweep mode. With the calibrated samples that should be quite easy.
Many thanks, Catalin
I’m probably one of the guys that Andrew mentioned by “several customers”! I’ve just seen your question, so sorry for the delay in my reply!
Briefly said, we currently have a platform involving 2 BB60Cs and a simple (FTDI serial port basically!) device that we operate through a 10m USB3 active cable and a 4-port USB3 hub and we saw no major issues. But in order to get to the current structure, that can be connected to several PCs and shows no significant performance differences, we ended up with a box of useless USB3 hubs!
With two BB60Cs there is a rather small performance regression with latest APIs. At some point in the past it was terrible but Andrew sorted it out! And for 7 BB60Cs you need to consider a pretty powerful CPU.
I will do some tests with even more BB60Cs connected at once to the same PC as I am involved in a project where I need 14 units. Clearly I won’t go that far, as the project doesn’t require them in just one place, but I will certainly do some tests with as many as possible connected to the same PC.
Just as a warning, depending on the motherboard chipset and/or USB hub, you might see periodic errors while streaming, with the end result of missing samples. With similar structures I testes on several platforms and so far I could not find a general rule. But, on the platform where I see it happening, it tends to happen also when only a single BB60C is connected directly to the PC.
Anyway, our “nightmare” is that we need those two BB60Cs to be in sync!
Catalincatalin_ro October 11, 2016 at 12:26 am in reply to: BB60C–external trigger–bbFetchRaw(buffer, triggers)
I might reply to this one!
First of all, the buffer length is in I/Q samples, not in 32-bit floating point values. So, the 16384 I/Q samples in each buffer actually means 32768 (2*16384) 32-bit floating point values. Considering that, the index that you reported in the example, 26666, is mostly correct.
But there is a well hidden problem in how you determined it. The API manual states that the trigger position is in I/Q samples number. So you must first convert the trigger position to the I/Q sample number before multiplying it by 2.
So you have SamplePos=TrigPos/DecimRatio (integer math!) and then go at 2*SamplePos in the received buffer to get the samples after the trigger.
The way you estimated the sample position is not correct because for many trigger position values, when using integer math, 2*Pos/Decim is different from 2*(Pos/Decim) and you end up accessing the Q1/I2 instead of I1/Q1 (the samples are considered I1/Q1, I2/Q2 etc.).
Catalincatalin_ro October 9, 2016 at 4:32 am in reply to: BB60C–external trigger–bbFetchRaw(buffer, triggers)
I 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).
- This reply was modified 6 years, 11 months ago by catalin_ro.
More 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
bbDeviceInvalidErrerror 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.
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?