Since I’m just a noob when it comes to spectrum analyzers, I have a question when grabbing real-time IQ data from the BB60C.
In the example MATLAB code in bbgetiq.m provided in the SDK:
iqlen = 1024;
% Flush IQ data filter ramp up time
[status, iqdata] = bbgetiq(handle, iqlen, true);
% Get actual data
[status, iqdata] = bbgetiq(handle, iqlen, true);
If I’m passing true as the purge argument, then why does the example call the bbgetiq function twice? According to the BB API manual, specifying purge = TRUE discards “any samples acquired by the API since the last time and(sic) bbGetIQ function was called.
It seems that if it were set to false you’d have to call it twice, but if true wouldn’t that accomplish the intent here?
This is a good question. The reason this is called twice has less to do with the purge parameter, and more to do with wanting to discard the first chunk of I/Q samples in the stream. Your assumptions about the purge parameter are correct. There are potentially several FIR filters (depending on settings) that are in the signal processing chain when I/Q streaming. These filters take hundreds/thousands of samples to ‘charge’ and until they do, the I/Q samples will not be amplitude accurate. By calling the function once with the purge parameter, this ensures that the first large segment of I/Q samples subject to this charge time are discarded. This is not necessary, but if you do this, doing this only once after each configure is adequate.
Another interesting component of this, the first call to GetIQ might not purge any samples, as there may not be any samples collected yet on the PC. So the worst case scenario is that the first call is just waiting until some samples arrive on the PC, and the second call is the one that actually purges that first chunk of I/Q to arrive.
Feel free to try just 1 call and see if that affects your application.
Also, waiting some small amount of time (100ms) before calling getIQ after configuring the receiver would ensure that the first call to GetIQ purges the first samples.
We chose to give these samples to the user instead of discard them in the API as they could still contain information just at a reduced amplitude.
If you are using any sort of triggering to acquire your waveform, calling the function twice is probably not necessary.
Regards, Andrew
This reply was modified 6 months, 1 week ago by Andrew.
This reply was modified 6 months, 1 week ago by Andrew.
Thanks! Is there any example MATLAB code to collect IQ data upon a trigger input from the VSG60 to the BB60? Going through the SDK, all I find on triggers is in the API, not any of the sample code. I.e, do I have to add to VSG60.m to get trigger output status, or should I write a dedicated function for that?
You will need to write a dedicated function for that. A wrapper function around the GetIQ functionality should be adequate for performing any triggering on the I/Q data. You could perform video or external triggering with this function. (you didn’t specify trigger type in your message) If external triggering, there is a C++ example showing you how to detect an external trigger event, you would need to then align your capture on the trigger position and collect any additional samples required (with purge disabled to ensure continuity)
The API does not perform any triggering for the user, only provides the facilities for triggering to be performed.
Let me know if you have specific questions as you work through this.
I guess I wasn’t specific enough. I want the step the VSG60 output of a simple CW waveform, stepping from a begin frequency to an ending frequency, and to output a trigger to the BB60 so it can grab IQ samples at each step when it sees the trigger input…
I hadn’t seen the iq_external_trigger.cpp example – that certainly helps!
Yes, you would need to call the vsgSubmitTrigger function from Matlab which you should find easy if you glance at the other wrapper code in VSG60 matlab class.
I’m getting there, but having problems with MATLAB.
I started with the bbgetiq.m in the SDK, and modified it by trying to redefine the array triggers and the size of it triggerCount as specified in the API manual for bbGetIQUnpacked.
I realized I was calling libpointer with the wrong parameters, so I changed it to:
triggerCount = int32(70); % size of the trigger array (32-bit int)
% from SDK example "iq_external_trigger.cpp"
triggerArray = 0:0:triggerCount; % array where we'll store trigger events...
triggers = libpointer('int32', triggerArray); % pointer to array of 32-bit ints
...
status = calllib('bb_api','bbGetIQUnpacked',handle,iqarrayptr,iqcountint,triggers,triggerCount,purgearg,nullptr,nullptr,nullptr,nullptr);
I still get an error, but it’s
Parameter must be scalar.
Error in libpointer (line 21)
ptr=lib.pointer(varargin{:});
Error in bbgetiq (line 67)
triggers = libpointer('int32', triggerArray); % pointer to array of 32-bit ints
Are there any working examples of calling that C-library function from MATLAB? I’m stumped.
The best time to call this would be right after opening the device and only once. The 64 is taken from the header, it is the value for BB_PORT2_IN_TRIGGER_RISING_EDGE (0x40).
Then you will want to create a trigger array and count just like the iq data.
In this instance I am creating an array of 4 integers to store trigger positions. If I am only expecting 1 trigger, then an array of one will work fine.
Now I need to call bbGetIQ with these new parameters.
vsgSubmitTrigger vsgSubmitIQ vsg.transmit(waveform, mode) which calls vsgOutputWaveform or vsgRepeatWaveform then later call vsg.stop (which does a vsgAbort)
If I call vsg.transmit again, will it still output a trigger, or do I have to submit trigger again?
vsgSubmitTrigger and vsgSubmitIQ are part of the VSG60s streaming interface. If you call those functions it will push those actions into the queue to transmit ASAP. For example, if you wanted to transmit a single short waveform synchronized with a trigger, you would call in sequence
The vsgOutputWaveform/vsgRepeatWaveform functions are just convenience functions that cannot be combined with others. vsgOutputWaveform transmits your waveform exactly once. It simply calls vsgSubmitIQ and vsgFlushAndWait for you. No triggering is possible with this function. vsgRepeatWaveform is simply a convenience over calling vsgSubmitIQ in a loop. It spins off a thread to do this for you and returns control to your application. If you perform any other action, the waveform being transmitted by vsgRepeatWaveform is interrupted.
If you want to re-transmit a waveform with thg trigger, you will need to recall the submitTrigger/IQ/flush sequence again.
I hope this helps. Regards
This reply was modified 5 months, 2 weeks ago by Andrew.
*I’m collecting at the highest resolution: decimation = 1 and bandwidth = 27MHz. *The VSG60’s signal output is connected directly to the BB60 signal input (with a physical cable and 10dB attenuator).
I’ve tried varying iqlen from 4096 [2^12] to 1048576 [2^20] with no real difference – I don’t see a trigger event. I’ve checked to make sure I have the VSG port2 (trigger out) connected to BB60 port 2, and the BB60 is set to trigger on the pulse leading edge…
I have the trigger length set to the default of 10 usec.
I’ll have to check and see if the PC’s SSD can sustain writes of 250MB/sec…
JonG
This reply was modified 5 months, 1 week ago by jgauthier.
This reply was modified 5 months, 1 week ago by jgauthier.
Are you setting purge to true in that example? Effectively flushing any data and triggers that have accumulated?
I see only one GetIQData function call. The BB60C is a streaming device, so how much data do you have accumulated before the actual trigger occurs? Are you sure the trigger isn’t buffered in the API and you just haven’t polled it yet through the getIQ function?
The BB60C API only stores about 1/2 second of I/Q data. If this buffer fills, it will be forced to wrap it’s internal circular buffer. If it takes you 1/2 second to call getIQ after configuring you might have discarded that I/Q data.
Ideally, you would be polling the BB60C in another thread and waiting for the trigger to occur or transmitting the VSG60 waveform and trigger in another thread while you poll the BB60C in your main thread. That way there is no worries about any I/Q accumulation buffers overflowing. If your VSG60 waveform is short, that is probably not the case here, but worth noting.
The VSG waveform for now is short – it’s the simple CW waveform (iq = complex(1, 0) ) from the MATLAB examples in the SDK. The elapsed time from the start of transmitting the waveform from the VSG to returning from the GetIQData function (calling bbGetIQUnpacked and converting the returned array to complex) is < 0.20 seconds, so I’d think I wouldn’t need a separate thread just yet… But I’ll investigate doing it if I have to.
I’ve made the attached script just about as simple as I can get it. I’ve allowed for up to 4 triggers when grabbing I/Q data.
This reply was modified 5 months, 1 week ago by jgauthier.
So, you would want to set purge to false. Purge tells the API to throw away any accumulated data in the API, which would include your waveform and trigger location. Once you set purge to false, you will also need to poll the API until you see the trigger position.
Regards
Author
Posts
Viewing 19 posts - 1 through 19 (of 19 total)
You must be logged in to reply to this topic.
Sign up for our newsletter
We email about once a month with product and/or company updates. Fill out the form if you'd like to receive the newsletter. Oh, and we NEVER sell or give away your email address.