Page 1 of 1

Help on matlab and IQ samples FFT processing

Posted: Thu Mar 08, 2018 3:12 am
by Geo89
Greetings,

I'm having a lot of trouble to plot the spectrum of the samples produced by the bladeRF-cli.

I'm using matlab 2015b. I used the info provided on a topic for OCTAVE, but it doesn't seem to work fine.

However, blade_rx_gui example displays the spectrum of the given bandwidth as expected.

My settings to get the samples are the following:

Code: Select all

bladeRF> set frequency rx 810M

bladeRF> set samplerate rx 40M

bladeRF> set bandwidth rx 20M

bladeRF> set lnagain 6

bladeRF> set rxvga1 10

bladeRF> set rxvga2 0

bladeRF> rx config file=test.csv format=csv n=5000

bladeRF> rx start

bladeRF> rx
Here's my code:
I'm experiencing some high spikes on the IQ data plot and on FFT I'm getting a 0 magnitude for about 2500 samples in a row out of 5000 samples in total.
I didn't proceed to plot a proper graph of the spectrum,because I don't know if the data I'm receiving are good.

Code: Select all

function iq_spectrum_test(filename)

    csv = load(filename);
 
    signal_i = csv(:, 1);
    signal_q = csv(:, 2);
    signal = signal_i + signal_q*1i;
    
 
Fs=40000000;           


L = 5000;       
Y = fft(signal);

close all;

figure;
plot(1:L,abs(signal))
title('IQ Data Test')
xlabel('Samples')
ylabel('')

figure;
plot(1:L,abs(Y))
title('FFT Data Test')
xlabel('Samples')
ylabel('')

end
I know that I'm doing something wrong, but I don't know where to start.

Can anyone help me out?

Thanks for your time

Re: Help on matlab and IQ samples FFT processing

Posted: Wed Mar 21, 2018 12:03 pm
by bglod
If you have a bunch of leading zero samples, that sounds strange to me if you are using the official libbladeRF, bladeRF-cli, FX3 firmware, and FPGA. Are the raw sample values actually zero, or do they just look like zero on the chart? Some things of note:
  1. Normalize your samples (divide all samples by 2**11). See load_csv.m for details.
  2. Plot needs a "20*log10", i.e.:

    Code: Select all

    20*log10(abs(fft(signal)))
  3. Capture more samples, like 100k or 1M, or more (the more the better ... 1M is pretty good)
  4. The MATLAB `pwelch` function is pretty cool if you know your sample rate:

    Code: Select all

    pwelch(signal,[],[],[],samplerate,'centered')
Edit:

If you see some strange anomalies in your FFT plot, it sometimes helps to plot signal_i and signal_q over time. If you see some craziness at the start or end of your samples in the time-domain plots, you can typically just ignore those samples for the purposes of analysis, but it could be indicative of something you need to adjust. The I vs. Q plot can be useful too.

Code: Select all

figure; plot(signal_i);
figure; plot(signal_q);
figure; scatterplot(signal [, samples_per_symbol]);

Re: Help on matlab and IQ samples FFT processing

Posted: Wed Apr 04, 2018 8:56 am
by adlofts
Hello,
I have been working on something similar and was hoping you could help me out as well @bglod.
I would like to convert my RX units to dBuV then to V/m since many exposure projects are expressed this way.
I have done as you recommended:

y = (y(:,1)./ 2048.0) + (y(:,2)./ 2048.0)*1i; % similar to the csvread function, normalizes
y = y - mean(y); %To remove DC spike that shows up
y = 20*log10(abs(fftshift(fft(y))));

Can you explain the following:
1. What is the physical units of the values from -1 to 1? Seems to imply volts but on what scale?
2. Why is fftshift needed/not needed here. Without it when I TX and RX, the RX doesn't look right
3. How does the RX,TX,LNA gains effect the dB values, do i simply subtract the these + or - to get the real dB values.

I am working on a spectrum scanner that scans the full 0.3-3.8GHz range in 20MHz BWs and then pieces them together to form the full spectrum.
Thank you,
Andrew

Re: Help on matlab and IQ samples FFT processing

Posted: Thu Apr 05, 2018 11:52 am
by bglod
adlofts wrote: Wed Apr 04, 2018 8:56 am Hello,
I have been working on something similar and was hoping you could help me out as well @bglod.
I would like to convert my RX units to dBuV then to V/m since many exposure projects are expressed this way.
The I/Q samples are uncalibrated ADC LSB counts from the ADCs in the LMS6, so they are essentially Volts. Tektronix has this really good derivation going from I/Q samples to Volts and power. This conversion is super inaccurate if you try to do it without having a calibration table for your specific board. Calibration is a somewhat lengthy process involving the use of test equipment to inject CWs at known frequencies and power levels. At each frequency being tested, the LMS gain stages are swept across their operating range. The resulting I/Q samples are converted to power, and because you know the actual input power, you can build a conversion function/look-up table. Sensitivity changes quite a bit over frequency, and gain stages can be imprecise and non-linear, so a good cal table requires lots of data points.
adlofts wrote: Wed Apr 04, 2018 8:56 am I have done as you recommended:

y = (y(:,1)./ 2048.0) + (y(:,2)./ 2048.0)*1i; % similar to the csvread function, normalizes
y = y - mean(y); %To remove DC spike that shows up
y = 20*log10(abs(fftshift(fft(y))));

Can you explain the following:
1. What is the physical units of the values from -1 to 1? Seems to imply volts but on what scale?
2. Why is fftshift needed/not needed here. Without it when I TX and RX, the RX doesn't look right
3. How does the RX,TX,LNA gains effect the dB values, do i simply subtract the these + or - to get the real dB values.
  1. When the samples are scaled to +/- 1, they go from ADC LSB counts to a percentage of ADC full scale, which takes the ADC resolution out of the equation. This can be helpful when dealing with MATLAB functions that require things to be on a +/- 1 scale, or if you want the same code to work with samples from other ADCs with different resolutions. The scaled values maintain a relationship back to Volts.
  2. fftshift() doesn't do anything to the data, it just rearranges them so that DC is at the center of the FFT plot with the negative and positive frequencies to the left and right of center. It's not necessary, but it's a more common representation and makes the plot much easier to interpret.
  3. The short answer is yes, just subtract them from the relative power computed from your samples. The long answer is that the gain settings of the LNA/VGA1/VGA2 will have some variance, and at least VGA1 is not log-linear. There are losses between these components within the die, as well as everything outside of the LMS6 (e.g., DC blocking capacitors, baluns, filters, RF switches, PCB traces, etc.). These losses vary over frequency and gain, which is why the cal table is so important.

Re: Help on matlab and IQ samples FFT processing

Posted: Fri Apr 06, 2018 7:50 am
by adlofts
Hello,
Thanks for your help. If i understand:
1. The %ADC scale from -1 to 1 matches with the 0.2 to 3.3V is from the LMS6 data sheet Vpp? Or is the ADC reference scale a different parameter?
2. The tektronix implies we should be doing 20log10(signal(:,1)^2 + signal(:,2)^2) rather than 20log10(abs(y)). These give me different results in matlab?
3. How does doing a calibration like you suggest compare to running the cal lms + cal table dc rx commands?

Thanks,
Andrew

Re: Help on matlab and IQ samples FFT processing

Posted: Tue Apr 10, 2018 3:44 pm
by bglod
adlofts wrote: Fri Apr 06, 2018 7:50 am 1. The %ADC scale from -1 to 1 matches with the 0.2 to 3.3V is from the LMS6 data sheet Vpp? Or is the ADC reference scale a different parameter?
Those voltages are for the synthesizer, not the ADC. Table 8 has the ADC specs. :)

If we look at the "input amplitude" row, the "max" column says 1.8 Vpp. The inputs are differential and they give a common mode voltage spec of 0.9 VDC, meaning each input can have a signal that is up to 1.8 Vpp centered around 0.9 VDC. There are operating conditions for the values given in the table. Of interest is the -1 dBFS input signal (so an I/Q value of about +/-1825), which appears to correspond to an analog voltage of 1 Vpp (typ). This tells me that either I'm terribly misguided, or the ADC is not very linear and/or has a lot of error because: 1825*(1.8/2**12) = 0.8 V, which is pretty far from 1 V! If anything, this exemplifies the importance of calibration!
adlofts wrote: Fri Apr 06, 2018 7:50 am 2. The tektronix implies we should be doing 20log10(signal(:,1)^2 + signal(:,2)^2) rather than 20log10(abs(y)). These give me different results in matlab?
It would be 10*log10(abs(fftshift(fft(real(sig).^2 + imag(sig).^2)))) because the sum of squares is power (use 10*log10()), whereas voltage is (20*log10()). (It stems from squaring the voltage when computing power.) At any rate, the two plots are slightly different -- I'm not sure why off hand -- I'd have to sit down and think about it -- however, notice that the sum of squares version mirrors around DC. The magnitudes being different is just scaling.
adlofts wrote: Fri Apr 06, 2018 7:50 am 3. How does doing a calibration like you suggest compare to running the cal lms + cal table dc rx commands?
The LMS calibrations only (sort of) remove things like DC offsets, tune LPF bandwidths, and figure out the VCO capacitor selection. The calibration with external test equipment that I'm referring to is how you associate I/Q values with actual power measurements. There's a ton of stuff that goes on within the LMS6 internally, as well as all kinds of losses between the LMS6 and the SMA port. Calibration with known input power levels across gain and frequencies eliminates all of those variables and it becomes a fairly trivial look-up table or equation you run your received signal through. Without doing this, there are just too many variables and unknowns to try to figure it out mathematically -- you're almost better off throwing darts. :D