Λίγα λόγια:
Το RTL-SDR είναι ένα πολύ φτηνό dongle αξίας $ 25 USB το οποίο μπορεί να χρησιμοποιηθεί ως ραδιοφωνικός σαρωτής με βάση τον υπολογιστή για λήψη ζωντανών ραδιοφωνικών σημάτων στην περιοχή σας.
Code explanation:
Κάνουμε import τα παρακάτω packages.- tkinter για το gui
- matplotlib για graph plotting
- numpy για αναπαράσταση των δεδομένων ως 64bit complex
- rtlsdr για να χρησιμοποιήσουμε την rtlsdr κεραία
import matplotlib; matplotlib.use("TkAgg") import tkinter as tk import matplotlib.animation as anim import numpy as np from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2TkAgg) from matplotlib.figure import Figure from rtlsdr import RtlSdr LARGE_FONT = ("Verdana", 12)
Κατασκευάζουμε τα widgets στο application
class FrequencyGraph(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) tk.Tk.wm_title(self, "rtlsdr-qui") container = tk.Frame(self) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) container.grid(row=0, column=0) f_station_label = tk.Label(container, text="Frequency Station", font=LARGE_FONT) f_station_label.grid(row=0, column=0) self.f_station_entry = tk.Entry(container) self.f_station_entry.grid(row=0, column=1) f_offset_label = tk.Label(container, text="Frequency Offset", font=LARGE_FONT) f_offset_label.grid(row=1, column=0) self.f_offset_entry = tk.Entry(container) self.f_offset_entry.grid(row=1, column=1) sample_rate_label = tk.Label(container, text="Sample Rate", font=LARGE_FONT) sample_rate_label.grid(row=2, column=0) self.sample_rate_entry = tk.Entry(container) self.sample_rate_entry.grid(row=2, column=1) sample_count_label = tk.Label(container, text="Sample count", font=LARGE_FONT) sample_count_label.grid(row=3, column=0) self.sample_count_entry = tk.Entry(container) self.sample_count_entry.grid(row=3, column=1) b = tk.Button(container, text="Change Settings", command=self.change_settings) b.grid(row=4, column=1) f = Figure(figsize=(5, 5), dpi=100)
Κάνουμε initialize το RtlSdr object για να αρχίσουμε να καταγράφουμε δεδομένα από την κεραία
και αρχικοποιούμε τις τιμές. Στην συνέχεια κατασκευάζουμε ένα figure canvas το οποίο το κάνουμε
associate με μια function update_plot η οποία θα ευθύνεται για να κρατάει το plot up to date.
self.sdr = RtlSdr() self.ax1 = f.add_subplot(111) self.F_station = int(96.9e6) # Rutgers Radio self.F_offset = 300000 # Offset to capture at # We capture at an offset to avoid DC spike self.Fc = self.F_station - self.F_offset # Capture center frequency self.Fs = int(1140000) # Sample rate self.N = int(262144) # Samples to capture int() 8192000 # configure device self.sdr.sample_rate = self.Fs # Hz self.sdr.center_freq = self.Fc # Hz self.sdr.gain = 'auto' self.f_station_entry.insert(0, "96.9") self.f_offset_entry.insert(0, "300000") self.sample_rate_entry.insert(0, "1140000") self.sample_count_entry.insert(0, "262144") samples = self.sdr.read_samples(self.N) x1 = np.array(samples).astype("complex64") self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc) canvas = FigureCanvasTkAgg(f, self) anim_void = anim.FuncAnimation(f, self.update_plot, interval=1000, blit=False) canvas.show() canvas.get_tk_widget().grid(row=0, column=1) canvas._tkcanvas.grid(row=0, column=1)
Η update_plot διαβάζει samples από την κεραία και κάνει update το διάγραμμα
def update_plot(self, i): samples = self.sdr.read_samples(self.N) x1 = np.array(samples).astype("complex64") self.ax1.clear() self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc)
To change settings διαβάζει τα values από τα entry widgets και τα αναθέτει ως attributes
def change_settings(self): self.F_station = float(self.f_station_entry.get()) * 10e5 # Rutgers Radio self.F_offset = int(self.f_offset_entry.get()) # Offset to capture at # We capture at an offset to avoid DC spike self.Fc = self.F_station - self.F_offset # Capture center frequency self.Fs = int(self.sample_rate_entry.get()) # Sample rate self.N = int(self.sample_count_entry.get()) # Samples to capture int() 8192000 # configure device self.sdr.sample_rate = self.Fs # Hz self.sdr.center_freq = self.Fc # Hz self.sdr.gain = 'auto'
Tέλος κάνουμε αρχικοποιούμε το graphical user interface
if __name__ == '__main__': app = FrequencyGraph() app.mainloop()
Useful links: https://www.rtl-sdr.com/about-rtl-sdr/