Nachbau von Frequenzregler/-anzeige und Spektrumdarstellung des
USB-Sprachempfängers in Kivy — siehe
homepage/src/projekte/ssb-usb-frontpanel/index.md für den Hintergrund
(native GRC-Widgets vs. Alternativen).
Trennt Signalverarbeitung und Darstellung bewusst:
spectrum_source.grc / .py — reiner GNU-Radio-Flowgraph (kein GUI), die
echte Empfänger-Kette aus ssb-usb-empfaenger/ssb_usb_144300_file_test.grc
(IQ-Testdatei → Freq-Xlating-USB-Filter → Realteil → AGC). Liefert drei
unabhängig abfragbare Signale über je einen Probe Signal Vector-Block:
blocks_probe_signal_vx_0 — Original-IQ-Spektrum (vor der Demodulation)blocks_probe_signal_vx_1 — demoduliertes NF-Spektrumblocks_probe_signal_vx_2 — demoduliertes NF-Zeitsignal (1024 Samples)Wird von der Kivy-App importiert, nicht eigenständig ausgeführt.
spectrum_widget.py — SpectrumWidget: matplotlib-basiertes Kivy-Widget
(kivy_garden.matplotlib) mit drei Achsen (Original-Spektrum,
demoduliertes Spektrum, demoduliertes Zeitsignal), beschriftete
Frequenz-/Sample-Achsen. Kennt GNU Radio nicht, nur die Kivy-Properties
orig_spectrum / demod_spectrum / demod_time.
frequency_display.py — FrequencyDisplay: wiederverwendbares
Digitalanzeige-Widget, formatiert frequency_hz als „xxx.xxxx MHz".
main.py — App: startet den Flowgraph, pollt alle drei Probes per
Clock.schedule_interval und schreibt die Werte in SpectrumWidget.
Zwei Buttons (- 1 kHz / + 1 kHz) verstimmen die Empfangsfrequenz live
über tb.set_carrier_freq().
pip install kivy kivy_garden.matplotlib
python3 main.py
pip install kivy kivy_garden.matplotlib
python3 main.py
Voraussetzung: ../ssb-usb-sender/ssb_usb_144300_testsignal.iq muss
existieren (mit ssb-usb-sender/ssb_usb_sender_testsignal.grc erzeugt).
Jeder Probe Signal Vector-Block liefert bei .level() immer einen
kompletten Vektor auf einmal, nicht sequenziell:
_0, _1): fft_size (512) Float-Werte in dB, dasLog Power FFT-Frames. shift=True sorgt dafür, dass_0: -iq_samp_rate/2,_1: -audio_rate/2) und Index fft_size-1 der höchsten — die(i - N/2) * samp_rate / N._2): time_len (1024) Float-Werte in linearer Amplitude,time_len aufeinanderfolgende NF-Samples nach der Demodulation (perStream to Vector gruppiert). Die Sample-Achse n = 0 … time_len-1n / audio_rate Sekunden.carrier_freq ist eine normale GRC-Variable, die als center_freq des
Freq Xlating FIR Filter verwendet wird. GRC generiert dafür automatisch
set_carrier_freq(), das intern freq_xlating_fir_filter_xxx_0.set_center_freq()
aufruft — ein Kivy-Button kann diese Methode direkt aufrufen, um den
Empfänger live umzustimmen (siehe main.py:_step_frequency).
Tatsächlich ausgeführt (GNU Radio 3.10.12.0, Kivy 2.3.1, matplotlib 3.10.1)
und per Widget.export_to_png() geprüft — screenshot.png zeigt die
laufende App bei 500 kHz (Original-Spektrum mit deutlichem Träger,
demoduliertes Spektrum und sauberes Zeitsignal). Ein zweiter Test mit
+15 kHz Verstimmung zeigt, wie der Träger aus dem USB-Filter herausläuft:
die demodulierte Amplitude bricht um zwei Größenordnungen ein (0,4 → 0,008),
und das demodulierte Spektrum zeigt nur noch die Filterflanken statt eines
sauberen Tons.
Weitere QT-Elemente aus dem Empfänger, die sich nach demselben Muster
nachbauen ließen: Lautstärke-/Squelch-Regler (Kivy Slider), LED-Indikator
für Squelch-Status, S-Meter (analog.probe_avg_mag_sqrd_f statt
probe_signal_vf, aggregierter Einzelwert statt eines Vektors).