Salta ai contenuti

GNU Radio

GNU Radio is a free and open-source software development toolkit that provides signal processing blocks to implement software radios. It is used with readily-available low-cost external RF (radio frequency) hardware to create software-defined radios, or without hardware in a simulation-like environment.

GNU Radio is widely used in education, research, industry, and amateur radio communities for rapid prototyping, experimentation, and signal analysis without expensive hardware.

sudo apt-get update
sudo apt-get install gnuradio gnuradio-dev
sudo apt-get install libuhd-dev uhd-host  # For USRP hardware support
sudo apt-get install gr-osmosdr             # For RTL-SDR and other SDRs
git clone https://github.com/gnuradio/gnuradio.git
cd gnuradio
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig
pip install gnuradio
pip install gnuradio-osmosdr  # RTL-SDR support

The graphical tool for building radio applications.

gnuradio-companion
# or shorter
grcc
  1. Open GNU Radio Companion
  2. Drag and drop signal processing blocks
  3. Connect input/output ports
  4. Configure block parameters
  5. Generate Python code or run directly
  6. Test and refine
CommandPurpose
gnuradio-companionLaunch GUI block editor
grcc file.grcCompile GRC file to Python script
python3 file.pyRun generated flowgraph
gr_filter_designGUI filter design tool
gr_plot_qtPlot signal data with Qt
gr_plot_fftFFT visualization tool
import gnuradio
from gnuradio import gr, blocks, analog, filter
import math

# Create a top-level block
class SimpleFlowgraph(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self, "Simple FM Example")
        
        # Signal source: 440 Hz sine wave
        self.signal_source = analog.sig_source_f(
            sample_rate=48000,
            waveform=analog.GR_SIN_WAVE,
            frequency=440,
            amplitude=1
        )
        
        # Sink to print samples
        self.null_sink = blocks.null_sink(gr.sizeof_float)
        
        # Connect source to sink
        self.connect(self.signal_source, self.null_sink)

if __name__ == '__main__':
    tb = SimpleFlowgraph()
    tb.start()
    input('Press Enter to quit')
    tb.stop()
    tb.wait()
import numpy as np
from gnuradio import gr, blocks, fft

class FFTFlowgraph(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self, "FFT Example")
        
        # Create test signal
        sample_rate = 1e6
        freq = 10e3  # 10 kHz
        duration = 1  # 1 second
        samples = int(sample_rate * duration)
        
        t = np.arange(samples) / sample_rate
        signal = np.exp(2j * np.pi * freq * t).astype(np.complex64)
        
        # Vector source with signal
        self.vector_source = blocks.vector_source_c(signal)
        
        # FFT block
        self.fft = fft.fft_vcc(1024, True, ())
        
        # Null sink
        self.null_sink = blocks.null_sink(gr.sizeof_gr_complex * 1024)
        
        self.connect(self.vector_source, self.fft, self.null_sink)

if __name__ == '__main__':
    tb = FFTFlowgraph()
    tb.start()
    tb.wait()
BlockDescription
analog.sig_source_*Generate sine, cosine, square, sawtooth waveforms
blocks.vector_source_*Provide pre-defined data samples
blocks.file_sourceRead samples from file
blocks.udp_sourceReceive samples via UDP
osmosdr.sourceReceive from RTL-SDR or USRP
BlockDescription
filter.fir_filter_*FIR filtering
filter.iir_filter_*IIR filtering
fft.fft_vccFFT computation
analog.nbfm_rxNarrow-band FM demodulation
analog.fm_deemphFM de-emphasis filter
digital.gmsk_modGMSK modulation
BlockDescription
blocks.null_sinkDiscard samples
blocks.file_sinkWrite to file
blocks.udp_sinkSend via UDP
osmosdr.sinkTransmit via USRP/SDR
qtgui.time_sink_fTime-domain plot
qtgui.freq_sink_cFrequency-domain plot
from gnuradio import gr, blocks, analog, filter, digital
import osmosdr

class FMDemod(gr.top_block):
    def __init__(self, freq=99.5e6, sample_rate=1e6):
        gr.top_block.__init__(self, "FM Demodulation")
        
        # SDR source
        self.sdr = osmosdr.source(args="numchan=1")
        self.sdr.set_sample_rate(sample_rate)
        self.sdr.set_center_freq(freq)
        self.sdr.set_freq_corr(0)
        self.sdr.set_gain(25)
        
        # Low-pass filter
        self.lpf = filter.fir_filter_ccf(
            1, filter.firdes.low_pass(1, sample_rate, 75e3, 25e3)
        )
        
        # Decimate by 10
        self.decim = digital.rational_resampler_ccf(1, 10)
        
        # FM demodulator
        self.demod = analog.fm_demod_cf(
            channel_rate=sample_rate/10,
            audio_decim=1,
            deviation=75e3,
            audio_pass=15e3,
            audio_stop=16e3,
            gain=1,
            tau=75e-6
        )
        
        # Audio sink
        self.audio_sink = blocks.null_sink(gr.sizeof_float)
        
        # Connect
        self.connect(self.sdr, self.lpf, self.decim, self.demod, self.audio_sink)

if __name__ == '__main__':
    tb = FMDemod()
    tb.start()
    try:
        input("Press Ctrl+C to stop")
    except KeyboardInterrupt:
        pass
    tb.stop()
    tb.wait()
from gnuradio import gr, blocks
import numpy as np

# Create and save test signal
sample_rate = 1e6
num_samples = 1000000
duration = num_samples / sample_rate

# Generate complex sine
t = np.arange(num_samples) / sample_rate
freq = 100e3
signal = np.exp(2j * np.pi * freq * t).astype(np.complex64)

# Save to file
signal.tofile('test_signal.cfile')

# Read from file in GNU Radio
class FileReadFlowgraph(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self)
        
        # Read from file
        self.file_source = blocks.file_source(
            gr.sizeof_gr_complex, 'test_signal.cfile', False
        )
        
        # Analysis sink
        self.null_sink = blocks.null_sink(gr.sizeof_gr_complex)
        
        self.connect(self.file_source, self.null_sink)
gr_filter_design

Then in Python, apply the generated filter:

from gnuradio import filter

# Low-pass filter at 100 kHz cutoff, 25 kHz transition
taps = filter.firdes.low_pass(
    gain=1.0,
    sample_rate=1e6,
    cutoff_freq=100e3,
    transition_width=25e3,
    window=filter.firdes.WIN_HAMMING
)

lpf = filter.fir_filter_ccf(1, taps)
# Band-pass filter
taps = filter.firdes.band_pass(
    gain=1.0,
    sample_rate=1e6,
    low_cutoff_freq=100e3,
    high_cutoff_freq=200e3,
    transition_width=10e3
)

# Band-stop (notch)
taps = filter.firdes.band_reject(
    gain=1.0,
    sample_rate=1e6,
    low_cutoff_freq=100e3,
    high_cutoff_freq=200e3,
    transition_width=10e3
)

# High-pass
taps = filter.firdes.high_pass(
    gain=1.0,
    sample_rate=1e6,
    cutoff_freq=100e3,
    transition_width=10e3
)
# Install RTL-SDR drivers
sudo apt-get install rtl-sdr
sudo apt-get install gr-osmosdr

# Check device
rtl_test -t
from gnuradio import gr, blocks, qtgui
import osmosdr
import sys

class RTLSDRReceiver(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self, "RTL-SDR Receiver")
        
        # Create SDR source
        self.rtl = osmosdr.source(args="numchan=1 rtl=0")
        self.rtl.set_sample_rate(2.4e6)
        self.rtl.set_center_freq(100e6)  # 100 MHz
        self.rtl.set_gain(40)
        
        # Time sink for visualization
        self.ts = qtgui.time_sink_c(
            1024,  # size
            2.4e6,  # sample rate
            "RTL-SDR Time",  # title
            1  # number of channels
        )
        
        # Frequency sink
        self.fs = qtgui.freq_sink_c(
            1024,
            2.4e6,
            "RTL-SDR Frequency",
            1
        )
        
        # Connect
        self.connect(self.rtl, self.ts)
        self.connect(self.rtl, self.fs)

if __name__ == '__main__':
    tb = RTLSDRReceiver()
    tb.start()
    try:
        input("Press Ctrl+C to stop")
    except KeyboardInterrupt:
        pass
    tb.stop()
    tb.wait()
# 1. Use decimation to reduce sample rate
decimation = 10  # Reduce rate by factor of 10

# 2. Use integer arithmetic where possible
# 3. Minimize copying with in-place operations
# 4. Profile code with gr-perf-monitorx

# 4. Use hardware acceleration (SIMD) when available
ProblemSolution
Segmentation faultUpdate GNU Radio: pip install --upgrade gnuradio
Module not foundInstall missing module: sudo apt-get install gr-<module>
SDR not detectedCheck USB connection, run rtl_test
Poor performanceReduce sample rate, increase decimation
No audio outputCheck sink configuration and volume settings
# Enable verbose logging
grcc -v flowgraph.grc

# Run with GDB
gdb --args python3 flowgraph.py