Last night Mark and I were working on a 115 kbit/s FSK modem link for balloons that uses SDR receivers and FSK modem software.
We connected the transmitter to the SDR rx via a switched attenuator, calibrated with the spec-an, and measured a Minimum Detectable Signal (MDS) of about -75dBm. Based on an Eb/No of 15dB for 2FSK (to get a BER of 1E-5) I was expecting:
MDS = Eb/No + 10*log10(B) - 174 + NF MDS = 15 + 10*log10(115E3) - 174 + NF MDS = -108.4 + NF
So we are way off expected performance at the moment, and are testing the various components one by one.
One number I wanted to know was the Noise Figure (NF) of the SDR. Mark has a bunch of SDRs so we got on a roll and checked out the NF on all of them.
Now there are a lot of people playing with SDRs, but very few tutorials on HowTo engineer radio systems. For example, how to answer questions like “can I send this many bit/s over X km with SDR hardware Y?” So I thought it might be useful to explain how we measured Noise Figure (NF) and present the results for a bunch of SDRs.
From the Wikipedia article on Noise Figure:
The Noise Figure is the difference in decibels (dB) between the noise output of the actual receiver to the noise output of an “ideal” receiver.
An ideal receiver has an output noise power of:
Nout_dB = 10log10(B) - 174 + G_dB
The -174 dBm/Hz figure is the thermal noise density at 25C. For every 1Hz of bandwidth you will get -174dBm of noise power. It’s the lower limit set by the laws of physics. G_dB is the Rx gain. The 10log10(B) term takes into account the bandwidth of the Rx. A wider bandwidth means more total noise power.
So if you have a 1Hz bandwidth, and a gain of 100dB, you would expect Nout_NdB = 0 – 174 + 100 = -74dBm at the Rx output with no signal. If you have a 1000Hz bandwidth receiver you would have NdB_out = 10*log10(1000) – 174 + 100 = 30 – 174 + 100 = -44dBm of noise power at the output.
That’s for an ideal receiver. A real receiver has an output noise power of:
Nout_dB = 10log10(B) - 174 + G_dB + NF_dB
It’s NF_dB worse than an ideal receiver.
To determine Noise Figure we compare the output noise for our receiver (Rx) to an ideal receiver using these steps:
- Sample the Rx output first with an input test signal of known power and then with noise only.
- Find the Rx gain by comparing the Rx output power to the test signal input power.
- Find the noise output power, then using the gain we can find the noise input power.
- Normalise the noise input power to 1Hz noise bandwidth (so it’s units are also dBm/Hz) and compare to the thermal noise floor.
Here is the GNU Octave script nf_from_gr.m we used, and here are the results we obtained:
octave:17> nf_from_gr HackRF: Pin: -100.0 Pout: 38.1 G: 138.1 NF: 8.9 dB RTL-SDR: Pin: -100.0 Pout: 45.8 G: 145.8 NF: 6.7 dB AirSpy: Pin: -100.0 Pout: 42.0 G: 142.0 NF: 7.3 dB FunCube PP: Pin: -100.0 Pout: 31.0 G: 131.0 NF: 3.9 dB
GNU Radio was used to collect a few seconds of samples and save them to a file for processing by Octave. For the test signal I used a calibrated signal generator set to -100dBm. All tests were performed on a chunk of spectrum around 440MHz.
These results are not definitive – there are so many “knobs and sliders” on the SDRs it’s hard to say if we had them adjusted right. More gain in front of the ADC tends to reduce NF. The results seem reasonable though, no huge or negative NFs.
A good way to check our script would be to use a pre-amp with a known NF in front of the SDR, but we haven’t tried that yet.
It’s important to sample a chunk of noise without too many birdies (and SDRs seem full of them!). So the script asks you for a start “st” and end “en” range of frequencies. Here is a sample spectrum of the SDR output with the test signal (top) and just noise (bottom):
At the end of SM2000 Part 1 there is a section on measuring Noise Figure using a spectrum analyser.
SNR and Eb/No Worked Example explains how I work between SNR and Eb/No.