Membuat filter digital di GNU Radio semudah melempar kaos oblong di bak cucian. Kalaupun meleset, ya tinggal jalan ambil trus lempar lagi :). Asal comot saja dan klak-klik muncul hasilnya hehe. Sebenarnya, urusan matematika untuk membuat filter digital ini rumit. Seruwet kisah cinta yang gak jelas tempo lalu. GNU Radio membuatnya sederhana bagi petani miskin ini.
Karena output GNU Radio berupa script Python atau C++, jika ingin menjalankan, tinggal eksekusi saja tanpa “perlu” GNU Radio. Blok diagram seperti di bawah. Anda dapat bereksperimen dengan mengubah nilai parameter yang ada. Ubah saja sample rate jadi 500MHz (tanpa throttle) dan CPU PC Anda akan kerja rodi hehe. Intinya, ubah apa yang bisa diubah dan lihat hasilnya seperti apa.

FFT (Fast Fourier Transform) Frequency Sink akan memudahkan dalam pengamatan unjuk kerja filter. Signal/noise diamati dalam lingkup amplitudo vs frekuensi. Osiloskop standar hanya bermain di arena amplitudo vs waktu.




Output Flow Graph Python saya tampilkan di bawah. Script ini dibuat otomatis oleh GNU Radio.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: Tes Filter
# GNU Radio version: 3.9.7.0
from distutils.version import StrictVersion
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print("Warning: failed to XInitThreads()")
from PyQt5 import Qt
from gnuradio import qtgui
from gnuradio.filter import firdes
import sip
from gnuradio import analog
from gnuradio import filter
from gnuradio import gr
from gnuradio.fft import window
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
from gnuradio import qtgui
class LPF1(gr.top_block, Qt.QWidget):
def __init__(self):
gr.top_block.__init__(self, "Tes Filter", catch_exceptions=True)
Qt.QWidget.__init__(self)
self.setWindowTitle("Tes Filter")
qtgui.util.check_set_qss()
try:
self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
except:
pass
self.top_scroll_layout = Qt.QVBoxLayout()
self.setLayout(self.top_scroll_layout)
self.top_scroll = Qt.QScrollArea()
self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
self.top_scroll_layout.addWidget(self.top_scroll)
self.top_scroll.setWidgetResizable(True)
self.top_widget = Qt.QWidget()
self.top_scroll.setWidget(self.top_widget)
self.top_layout = Qt.QVBoxLayout(self.top_widget)
self.top_grid_layout = Qt.QGridLayout()
self.top_layout.addLayout(self.top_grid_layout)
self.settings = Qt.QSettings("GNU Radio", "LPF1")
try:
if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
self.restoreGeometry(self.settings.value("geometry").toByteArray())
else:
self.restoreGeometry(self.settings.value("geometry"))
except:
pass
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 64e3
##################################################
# Blocks
##################################################
self.qtgui_freq_sink_x_0_0_1 = qtgui.freq_sink_c(
1024, #size
window.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1,
None # parent
)
self.qtgui_freq_sink_x_0_0_1.set_update_time(0.10)
self.qtgui_freq_sink_x_0_0_1.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0_0_1.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0_0_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0_0_1.enable_autoscale(False)
self.qtgui_freq_sink_x_0_0_1.enable_grid(False)
self.qtgui_freq_sink_x_0_0_1.set_fft_average(1.0)
self.qtgui_freq_sink_x_0_0_1.enable_axis_labels(True)
self.qtgui_freq_sink_x_0_0_1.enable_control_panel(False)
self.qtgui_freq_sink_x_0_0_1.set_fft_window_normalized(False)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0_0_1.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0_0_1.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0_0_1.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0_0_1.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0_0_1.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_0_1_win = sip.wrapinstance(self.qtgui_freq_sink_x_0_0_1.qwidget(), Qt.QWidget)
self.top_layout.addWidget(self._qtgui_freq_sink_x_0_0_1_win)
self.qtgui_freq_sink_x_0_0_0 = qtgui.freq_sink_c(
1024, #size
window.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1,
None # parent
)
self.qtgui_freq_sink_x_0_0_0.set_update_time(0.10)
self.qtgui_freq_sink_x_0_0_0.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0_0_0.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0_0_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0_0_0.enable_autoscale(False)
self.qtgui_freq_sink_x_0_0_0.enable_grid(False)
self.qtgui_freq_sink_x_0_0_0.set_fft_average(1.0)
self.qtgui_freq_sink_x_0_0_0.enable_axis_labels(True)
self.qtgui_freq_sink_x_0_0_0.enable_control_panel(False)
self.qtgui_freq_sink_x_0_0_0.set_fft_window_normalized(False)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0_0_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0_0_0.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0_0_0.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0_0_0.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0_0_0.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_0_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0_0_0.qwidget(), Qt.QWidget)
self.top_layout.addWidget(self._qtgui_freq_sink_x_0_0_0_win)
self.qtgui_freq_sink_x_0_0 = qtgui.freq_sink_c(
1024, #size
window.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1,
None # parent
)
self.qtgui_freq_sink_x_0_0.set_update_time(0.10)
self.qtgui_freq_sink_x_0_0.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0_0.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0_0.enable_autoscale(False)
self.qtgui_freq_sink_x_0_0.enable_grid(False)
self.qtgui_freq_sink_x_0_0.set_fft_average(1.0)
self.qtgui_freq_sink_x_0_0.enable_axis_labels(True)
self.qtgui_freq_sink_x_0_0.enable_control_panel(False)
self.qtgui_freq_sink_x_0_0.set_fft_window_normalized(False)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0_0.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0_0.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0_0.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0_0.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0_0.qwidget(), Qt.QWidget)
self.top_layout.addWidget(self._qtgui_freq_sink_x_0_0_win)
self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c(
1024, #size
window.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1,
None # parent
)
self.qtgui_freq_sink_x_0.set_update_time(0.10)
self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0.enable_autoscale(False)
self.qtgui_freq_sink_x_0.enable_grid(False)
self.qtgui_freq_sink_x_0.set_fft_average(1.0)
self.qtgui_freq_sink_x_0.enable_axis_labels(True)
self.qtgui_freq_sink_x_0.enable_control_panel(False)
self.qtgui_freq_sink_x_0.set_fft_window_normalized(False)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.qwidget(), Qt.QWidget)
self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win)
self.low_pass_filter_0 = filter.fir_filter_ccf(
1,
firdes.low_pass(
1,
samp_rate,
7e3,
1e2,
window.WIN_HAMMING,
6.76))
self.high_pass_filter_0 = filter.fir_filter_ccf(
1,
firdes.high_pass(
1,
samp_rate,
20e3,
100,
window.WIN_HAMMING,
6.76))
self.band_pass_filter_0 = filter.fir_filter_ccf(
1,
firdes.band_pass(
1,
samp_rate,
7e3,
15e3,
100,
window.WIN_HAMMING,
6.76))
self.analog_noise_source_x_0 = analog.noise_source_c(analog.GR_GAUSSIAN, 1, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_noise_source_x_0, 0), (self.band_pass_filter_0, 0))
self.connect((self.analog_noise_source_x_0, 0), (self.high_pass_filter_0, 0))
self.connect((self.analog_noise_source_x_0, 0), (self.low_pass_filter_0, 0))
self.connect((self.analog_noise_source_x_0, 0), (self.qtgui_freq_sink_x_0, 0))
self.connect((self.band_pass_filter_0, 0), (self.qtgui_freq_sink_x_0_0_1, 0))
self.connect((self.high_pass_filter_0, 0), (self.qtgui_freq_sink_x_0_0_0, 0))
self.connect((self.low_pass_filter_0, 0), (self.qtgui_freq_sink_x_0_0, 0))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "LPF1")
self.settings.setValue("geometry", self.saveGeometry())
self.stop()
self.wait()
event.accept()
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.band_pass_filter_0.set_taps(firdes.band_pass(1, self.samp_rate, 7e3, 15e3, 100, window.WIN_HAMMING, 6.76))
self.high_pass_filter_0.set_taps(firdes.high_pass(1, self.samp_rate, 20e3, 100, window.WIN_HAMMING, 6.76))
self.low_pass_filter_0.set_taps(firdes.low_pass(1, self.samp_rate, 7e3, 1e2, window.WIN_HAMMING, 6.76))
self.qtgui_freq_sink_x_0.set_frequency_range(0, self.samp_rate)
self.qtgui_freq_sink_x_0_0.set_frequency_range(0, self.samp_rate)
self.qtgui_freq_sink_x_0_0_0.set_frequency_range(0, self.samp_rate)
self.qtgui_freq_sink_x_0_0_1.set_frequency_range(0, self.samp_rate)
def main(top_block_cls=LPF1, options=None):
if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
style = gr.prefs().get_string('qtgui', 'style', 'raster')
Qt.QApplication.setGraphicsSystem(style)
qapp = Qt.QApplication(sys.argv)
tb = top_block_cls()
tb.start()
tb.show()
def sig_handler(sig=None, frame=None):
tb.stop()
tb.wait()
Qt.QApplication.quit()
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
timer = Qt.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
qapp.exec_()
if __name__ == '__main__':
main()