class Rtl_threading(threading.Thread): def __init__(self, addr, fc, fs, size, corr): '''Add one more augument, corr''' threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs; # Hz self.sdr.center_freq = fc; # Hz # self.freq_correction = corr; # PPM if addr==1: self.sdr.gain = 32.8 else: #0 self.sdr.gain = 32.8 # init param self.addr = addr; self.size = size self.counter = 0; #0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 def run(self): # start lock to avoid reading the same data global event, output; #init the synchronization if event.isSet(): event.clear() event.wait() else: event.set() output[self.addr] = self.sdr.read_samples(self.size); def close(self): self.sdr.close();
def main(): sdr = RtlSdr() print 'Configuring SDR...' sdr.rs = 2.4e6 sdr.fc = 100e6 sdr.gain = 10 print ' sample rate: %0.6f MHz' % (sdr.rs/1e6) print ' center frequency %0.6f MHz' % (sdr.fc/1e6) print ' gain: %d dB' % sdr.gain print 'Reading samples...' samples = sdr.read_samples(256*1024) print ' signal mean:', sum(samples)/len(samples) print 'Testing callback...' sdr.read_samples_async(test_callback, 256*1024) try: import pylab as mpl print 'Testing spectrum plotting...' mpl.figure() mpl.psd(samples, NFFT=1024, Fc=sdr.fc/1e6, Fs=sdr.rs/1e6) mpl.show() except: # matplotlib not installed/working pass print 'Done\n' sdr.close()
async def main(): import math sdr = RtlSdr() print('Configuring SDR...') sdr.rs = 2.4e6 sdr.fc = 100e6 sdr.gain = 10 print(' sample rate: %0.6f MHz' % (sdr.rs/1e6)) print(' center frequency %0.6f MHz' % (sdr.fc/1e6)) print(' gain: %d dB' % sdr.gain) print('Streaming samples...') i = 0 async for samples in sdr.stream(): power = sum(abs(s)**2 for s in samples) / len(samples) print('Relative power:', 10*math.log10(power), 'dB') i += 1 if i > 100: sdr.stop() break print('Done') sdr.close()
def get_sdr(): sdr = RtlSdr() #configure device #sdr.sample_rate = 2.048e6 #Hz #sdr.center_freq = 70e6 #Hz #sdr.freq_correction = 60 # PPM #sdr.gain = 'auto' sdr.sample_rate = 200000 sdr.center_freq = 907 * 1000 * 1000 sdr.freq_correction = 60 # PPM sdr.gain = 'auto' return sdr
class SDR: def __init__(self,freq): self.sample_rate = 1e6 self.center_freq = freq self.gain = 36 self.sdr = RtlSdr() self.sdr.direct_sampling = 1 self.sdr.sample_rate = self.sample_rate self.sdr.center_freq = self.center_freq self.sdr.gain = self.gain def __del__(self): self.sdr.close()
class Rtl_threading(threading.Thread): def __init__(self, addr, fc, fs, size, times, corr): threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs # Hz self.sdr.center_freq = fc # Hz # self.freq_correction = corr; # PPM self.gain_index = 21 # self.sdr.gain='auto' # 36.4 the stdev=0.04 # init param self.addr = addr self.size = size self.times = times self.counter = 0 self.output = np.array(maxn * [0.0], dtype=np.float64) self.keep = True def run(self): # start lock to avoid reading the same data # self.tlock.acquire() while self.keep: self.sdr.gain = gain_list[self.gain_index] output = self.sdr.read_samples(self.size) self.output = output time.sleep(0.05)
def __init__(self,freq,N_samples): self.sample_rate = 1e6 self.decim_r1 = 1e6/2e5 # for wideband fm self.decim_r2 = 2e5/44100 # for baseband recovery self.center_freq = freq+250e3 self.gain = 36 self.N_samples = N_samples self.sdr = RtlSdr() self.sdr.direct_sampling = 1 self.sdr.sample_rate = self.sample_rate self.sdr.center_freq = self.center_freq self.sdr.gain = 'auto' #self.gain self.pa = pyaudio.PyAudio() self.stream = self.pa.open( format = pyaudio.paFloat32, channels = 2, rate = 44100, output = True) adj = 0 hamming = 10*signal.hamming(self.N_samples*.10 + adj) lpf = np.append( np.zeros(self.N_samples*.45),hamming) self.lpf = np.roll(np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*.45))),int(-.25*self.N_samples))
def transmit_and_capture(data, outfile, length, title='Captured Data', verbose=False, fs_audio=48000, fs_sdr=240000, fc0=443.650e6, plot=False): """Transmit and receive a signal. length seconds """ sdr = RtlSdr() # Create an RtlSdr object p = pyaudio.PyAudio() # Create a PyAudio object Nsamples=256000*length fc = fc0*(1.0-85e-6) # Get device numbers din, dout, dusb = audio_dev_numbers(p, in_name='USB', out_name='default', debug=verbose) # Create SDR capture thread as daemon capture = threading.Thread(target=sdr_record, args=(sdr, outfile, Nsamples, fc, fs_sdr)) capture.daemon = True # Create play thread as daemon play = threading.Thread(target=play_audio, args=(data, p, fs_audio, dusb)) play.daemon = True # Start both threads capture.start() play.start() time.sleep(length+2) try: if plot: print 'Loading data...' y = np.load(outfile) print 'Generating plot...' tt,ff,xmf = myspectrogram_hann_ovlp(y, 256, fs_sdr, fc) plt.title(title) plt.show() else: print 'Captured data saved to ' + outfile except IOError: type, value, traceback = sys.exc_info() print('Error loading %s: %s' % (value.filename, value.strerror)) except Exception as e: print 'Error: '+str(e) finally: print 'Cleaning up...' sdr.close() p.terminate() print 'Closed SDR and PyAudio'
def __init__(self): self.sdr = RtlSdr() # Sampling rate self.sdr.rs = Demod.SAMP_RATE # Pins 1 and 2 self.sdr.set_direct_sampling(1) # I don't think this is used? self.sdr.gain = 1
def __init__(self,freq,N_samples): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.createQtConnections() self.sample_rate = 2.4e5 ###1e6 #self.decim_r1 = 1e6/2e5 # for wideband fm self.decim_r2 = 2.4e5/48000 # for baseband recovery self.center_freq = freq #+250e3 self.gain = 38 self.N_samples = N_samples self.is_sampling = False self.spectrogram = np.zeros((328,200)) self.chspectrogram = np.zeros((328,200)) self.plspectrogram = np.zeros((164,200)) self.sdr = RtlSdr() #self.sdr.direct_sampling = 1 self.sdr.sample_rate = self.sample_rate self.sdr.center_freq = self.center_freq self.sdr.gain = self.gain self.pa = pyaudio.PyAudio() self.stream = self.pa.open( format = pyaudio.paFloat32, channels = 2, rate = 48000, output = True) adj = 0 hamming = np.kaiser(self.N_samples/4 + adj,1) lpf = np.append( np.zeros(self.N_samples*3/8),hamming) self.lpf = np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*3/8))) #,int(-.25*self.N_samples)) hamming = 10*signal.hamming(self.N_samples/16) lpf = np.append(np.zeros(self.N_samples*15/32),hamming) self.lpf_s1 = (np.append(lpf,np.zeros(int(self.N_samples*15/32)))) #self.lpf_s1 = np.roll(temp,int(.5*self.N_samples*67/120)) #self.lpf_s1 += np.roll(temp,int(-.5*self.N_samples*67/120)) self.lpf_s1 = np.fft.fftshift(self.lpf_s1) #self.lpf_s1 += np.fft.fftshift(self.lpf_s1) # fig = plt.figure() # ax = fig.add_subplot(111) # ax.plot(range(self.lpf_s1.size),self.lpf_s1) # fig.show() hamming = 10*signal.hamming(self.N_samples/32) lpf = np.append(np.zeros(self.N_samples*31/64),hamming) self.lpf_s2 = (np.append(lpf,np.zeros(int(self.N_samples*31/64)))) #self.lpf_s2 = np.roll(temp,int(.5*self.N_samples*92/120)) #self.lpf_s2 += np.roll(temp,int(-.5*self.N_samples*92/120)) self.lpf_s2 = np.fft.fftshift(self.lpf_s2)
def device_index(self): i = getattr(self, '_device_index', None) if i is None: serial_number = self.device_config.serial_number if serial_number is None: i = 0 else: i = RtlSdr.get_device_index_by_serial(serial_number) self._device_index = i return i
def main(): sdr = RtlSdr() print 'Configuring SDR...' sdr.rs = 2.4e6 sdr.fc = 70e6 sdr.gain = 4 print ' sample rate: %0.6f MHz' % (sdr.rs/1e6) print ' center frequency %0.6f MHz' % (sdr.fc/1e6) print ' gain: %d dB' % sdr.gain print 'Reading samples...' samples = sdr.read_samples(1024) print ' signal mean:', sum(samples)/len(samples) print 'Testing callback...' sdr.read_samples_async(test_callback) sdr.close()
def main(): sdr = RtlSdr() wf = Waterfall(sdr) # some defaults # Sample rate sdr.rs = 1e6 sdr.set_direct_sampling('q') sdr.fc = 0 sdr.gain = 10 wf.start() # cleanup sdr.close()
class Rtl_threading(threading.Thread): def __init__(self, addr, fc, fs, size, times, corr): threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs; # Hz self.sdr.center_freq = fc; # Hz # self.freq_correction = corr; # PPM if addr==1: self.sdr.gain = 32.8 # 36.4 the stdev=0.04 else: #0 self.sdr.gain = 32.8 #15.7 0.725 # init param self.addr = addr; self.size = size self.times = times self.counter = 0; #0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 def run(self): # start lock to avoid reading the same data # self.tlock.acquire() for x in range(0, self.times): timestamp = int(time.time()); global event; #init the synchronization if event.isSet(): event.clear() event.wait() else: event.set() #read time_str_read = int(time.time()); output = self.sdr.read_samples(self.size); i=0 for value in output: if self.addr == 0: rsamples[i] = value.real; isamples[i] = value.imag; else: rsamples1[i] = value.real; isamples1[i] = value.imag; i+=1;
def __init__(self, addr, fc, fs, size, corr): '''Add one more augument, corr''' threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs; # Hz self.sdr.center_freq = fc; # Hz # self.freq_correction = corr; # PPM if addr==1: self.sdr.gain = 32.8 else: #0 self.sdr.gain = 32.8 # init param self.addr = addr; self.size = size self.counter = 0;
class Rtl_threading(threading.Thread): def __init__(self, addr): global params threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = params.fs # Hz self.sdr.center_freq = params.fc # Hz self.is_ref = addr == params.ref_addr # self.freq_correction = corr; # PPM if self.is_ref: self.sdr.gain = params.ref_gain else: # 0 self.sdr.gain = params.ech_gain # init param self.addr = addr self.size = params.size # loop self.loop_sw = True def run(self): global event, wf_ech, wf_ref, dsp # init the synchronization # start lock to avoid reading the same data if event.isSet(): event.clear() event.wait() else: event.set() while self.loop_sw: # read print "reading new data~~~" output = self.sdr.read_samples(self.size) if self.is_ref: # ref wf_ref = np.array(output, dtype=np.complex128) else: wf_ech = np.array(output, dtype=np.complex128) if event.isSet(): event.clear() event.wait() else: dsp.new_data() event.set() self.loop_sw = False
def run(self): # Read 128ms of data at a time (must be a multiple of a power of two) blkSize = SAMPLE_RATE_KHZ()*128; blockLoc = np.zeros(1,dtype=np.uint64); sdr = RtlSdr(); # configure device sdr.sample_rate = SAMPLE_RATE_KHZ()*1e3 # Hz sdr.center_freq = 1575420000 # Hz sdr.gain = 29; sdrQueue.put((sdr,blockLoc,blkSize/SAMPLE_RATE_KHZ(),1)); sdr.read_samples_async(sdrCallback, blkSize, context=sdrQueue);
def main(): sdr = RtlSdr() wf = Waterfall(sdr) # some defaults sdr.rs = 2.4e6 sdr.fc = 100e6 sdr.gain = 10 wf.start() # cleanup sdr.close()
def __init__(self, addr): global params threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = params.fs # Hz self.sdr.center_freq = params.fc # Hz self.is_ref = addr == params.ref_addr # self.freq_correction = corr; # PPM if self.is_ref: self.sdr.gain = params.ref_gain else: # 0 self.sdr.gain = params.ech_gain # init param self.addr = addr self.size = params.size # loop self.loop_sw = True
def main(): from rtlsdr import RtlSdr sdr = RtlSdr() print 'Configuring SDR...' sdr.rs = 1e6 sdr.fc = 70e6 sdr.gain = 5 print ' sample rate: %0.6f MHz' % (sdr.rs/1e6) print ' center ferquency %0.6f MHz' % (sdr.fc/1e6) print ' gain: %d dB' % sdr.gain print 'Testing callback...' sdr.read_samples_async(test_callback)
def storing_stream_with_windows(l, device_number, folder, subfolders, center_frequency, samplerate, gain, nsamples, freq_correction, user_hash): l.acquire() print(device_number, center_frequency, samplerate, gain, nsamples, freq_correction) # configure device sdr = RtlSdr(device_index=device_number) sdr.center_freq = center_frequency sdr.sample_rate = samplerate if freq_correction: sdr.freq_correction = freq_correction # PPM sdr.gain = gain print('hello world') timestamp = time.mktime(time.gmtime()) samples = sdr.read_bytes(nsamples*2) sdr.close() l.release() print("save") basename = "{hash}_{freq}_{time:0.0f}".format(hash=user_hash, freq=center_frequency, time=timestamp) filename = path.join(folder, subfolders[0], "tmp_" + basename) # np.savez_compressed(filename, samples) # storing by numpy and copressing it '''np.save(filename, samples) os.rename(filename + ".npy", path.join(folder, subfolders[0], basename + ".npy"))''' f = open(filename, 'wb') f.write(samples) f.close() os.rename(filename, path.join(folder, subfolders[0], basename + ".dat")) del samples filename = path.join(folder, subfolders[1], basename + ".npy") sdrmeta(filename, device_number, folder, subfolders, center_frequency, samplerate, gain, nsamples, freq_correction, user_hash) return filename
def __init__(self, addr, fc, fs, size, times, corr): threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs; # Hz self.sdr.center_freq = fc; # Hz # self.freq_correction = corr; # PPM if addr==1: self.sdr.gain = 32.8 # 36.4 the stdev=0.04 else: #0 self.sdr.gain = 32.8 #15.7 0.725 # init param self.addr = addr; self.size = size self.times = times self.counter = 0;
def __init__(self, addr, fc, fs, size, times, corr): threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs # Hz self.sdr.center_freq = fc # Hz # self.freq_correction = corr; # PPM self.gain_index = 21 # self.sdr.gain='auto' # 36.4 the stdev=0.04 # init param self.addr = addr self.size = size self.times = times self.counter = 0 self.output = np.array(maxn * [0.0], dtype=np.float64) self.keep = True
def main(): gin=sys.argv[1] ppm=sys.argv[2] chn=sys.argv[3] if ppm=='0': ppm='1' if chn=='a': frc=161.975e6 if chn=='b': frc=162.025e6 sdr = RtlSdr() wf = Waterfall(sdr) # some defaults sdr.rs = 1e6 sdr.fc = frc sdr.gain = float(gin) sdr.freq_correction = int(float(ppm)) wf.start() # cleanup sdr.close()
def __init__(self, gain, sampRate, freqs, numSamples, parent=None): super(Sampler, self).__init__(parent) self.gain = gain self.sampRate = sampRate self.freqs = freqs self.numSamples = numSamples self.offset = 0 self.sdr = None self.errorMsg = None self.WORKING = True self.BREAK = False self.MEASURE = False try: self.sdr = RtlSdr() self.sdr.set_manual_gain_enabled(1) self.sdr.gain = self.gain self.sdr.sample_rate = self.sampRate except IOError: self.WORKING = False print "Failed to initiate device. Please reconnect." self.errorMsg = "Failed to initiate device. Please reconnect." self.samplerError.emit(self.errorMsg)
def get_data(freq): sdr = RtlSdr() sdr.sample_rate = 2.048e6 sdr.center_freq = int(decimal.Decimal(str(freq) + 'e6')) sdr.freq_correction = 60 sdr.gain = 'auto' data = sdr.read_samples(512) if not data.any(): app.abort(404, 'No data!') d = [] for item in data: d.append(str(item)) js = json.dumps(d) return js
def main(): @limit_time(0.01) @limit_calls(20) def read_callback(buffer, rtlsdr_obj): print('In callback') print(' signal mean:', sum(buffer)/len(buffer)) from rtlsdr import RtlSdr sdr = RtlSdr() print('Configuring SDR...') sdr.rs = 1e6 sdr.fc = 70e6 sdr.gain = 5 print(' sample rate: %0.6f MHz' % (sdr.rs/1e6)) print(' center ferquency %0.6f MHz' % (sdr.fc/1e6)) print(' gain: %d dB' % sdr.gain) print('Testing callback...') sdr.read_samples_async(read_callback)
def rt_flight_radar(fs, center_freq, gain, N_samples, pos_ref, functions): #clear_output() #time.sleep(1) # create an input output FIFO queues Qin = queue.Queue() # create a pyaudio object sdr = RtlSdr() sdr.sample_rate = fs # sampling rate sdr.center_freq = center_freq # 1090MhZ center frequency sdr.gain = gain # initialize map # Berkeley (lat, lon) = (37.871853, -122.258423) (mx_d, my_d) = LatLonToMeters(pos_ref[0] - 0.2, pos_ref[1] - 0.2) (mx_u, my_u) = LatLonToMeters(pos_ref[0] + 0.2, pos_ref[1] + 0.2) plot = figure(x_range=(mx_d, mx_u), y_range=(my_d, my_u), x_axis_type="mercator", y_axis_type="mercator") plot.add_tile(get_provider('CARTODBPOSITRON')) plot.title.text = "Flight Radar" # create lat, longitude source source = ColumnDataSource( data=dict(lat=[], lon=[], heading=[], flightnum=[])) # create plane figure oval1 = Oval(x="lon", y="lat", width=3000, height=700, angle="heading", fill_color="blue", line_color="blue") oval2 = Oval(x="lon", y="lat", width=1000, height=7000, angle="heading", fill_color="blue", line_color="blue") text = Text(x="lon", y="lat", text_font_size="10pt", text="flightnum", angle="heading", text_color="red") plot.add_glyph(source, oval1) plot.add_glyph(source, oval2) plot.add_glyph(source, text) output_notebook() handle = show(plot, notebook_handle=True) # initialize write file log = open('rtadsb_log', 'a') # initialize stop_flag stop_flag = threading.Event() # initialize threads t_sdr_read = threading.Thread(target=sdr_read, args=(Qin, sdr, N_samples, stop_flag)) t_signal_process = threading.Thread(target=signal_process, args=(Qin, source, functions, plot, log, stop_flag)) # start threads t_sdr_read.start() t_signal_process.start() return stop_flag
from rtlsdr import RtlSdr import numpy as np import scipy.signal as signal import matplotlib matplotlib.use('Agg') # necessary for headless mode # see http://stackoverflow.com/a/3054314/3524528 import matplotlib.pyplot as plt sdr = RtlSdr() F_station = int(100.4e6) # F_offset = 250000 # Offset to capture at # We capture at an offset to avoid DC spike Fc = F_station - F_offset # Capture center frequency Fs = int(1140000) # Sample rate N = int(8192000) # Samples to capture # configure device sdr.sample_rate = Fs # Hz sdr.center_freq = Fc # Hz sdr.gain = 'auto' # Read samples samples = sdr.read_samples(N) # Clean up the SDR device sdr.close() del(sdr)
def run_spectrum_int(num_samp, nbins, gain, rate, fc, t_int): ''' Inputs: num_samp: Number of elements to sample from the SDR IQ per call; use powers of 2 nbins: Number of frequency bins in the resulting power spectrum; powers of 2 are most efficient, and smaller numbers are faster on CPU. gain: Requested SDR gain (dB) rate: SDR sample rate, intrinsically tied to bandwidth in SDRs (Hz) fc: Base center frequency (Hz) t_int: Total effective integration time (s) Returns: freqs: Frequencies of the resulting spectrum, centered at fc (Hz), numpy array p_avg_db_hz: Power spectral density (dB/Hz) numpy array ''' # Force a choice of window to allow converting to PSD after averaging # power spectra WINDOW = 'hann' # Force a default nperseg for welch() because we need to get a window # of this size later. Use the scipy default 256, but enforce scipy # conditions on nbins vs. nperseg when nbins gets small. if nbins < 256: nperseg = nbins else: nperseg = 256 print('Initializing rtl-sdr with pyrtlsdr:') sdr = RtlSdr() try: sdr.rs = rate # Rate of Sampling (intrinsically tied to bandwidth with SDR dongles) sdr.fc = fc sdr.gain = gain print(' sample rate: %0.6f MHz' % (sdr.rs / 1e6)) print(' center frequency %0.6f MHz' % (sdr.fc / 1e6)) print(' gain: %d dB' % sdr.gain) print(' num samples per call: {}'.format(num_samp)) print(' PSD binning: {} bins'.format(nbins)) print(' requested integration time: {}s'.format(t_int)) N = int(sdr.rs * t_int) num_loops = int(N / num_samp) + 1 print(' => num samples to collect: {}'.format(N)) print(' => est. num of calls: {}'.format(num_loops - 1)) # Set up arrays to store power spectrum calculated from I-Q samples freqs = np.zeros(nbins) p_xx_tot = np.zeros(nbins) cnt = 0 # Set the baseline time start_time = time.time() print('Integration began at {}'.format( time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime(start_time)))) # Estimate the power spectrum by Bartlett's method. # Following https://en.wikipedia.org/wiki/Bartlett%27s_method: # Use scipy.signal.welch to compute one spectrum for each timeseries # of samples from a call to the SDR. # The scipy.signal.welch() method with noverlap=0 is equivalent to # Bartlett's method, which estimates the spectral content of a time- # series by splitting our num_samp array into K segments of length # nperseg and averaging the K periodograms. # The idea here is to average many calls to welch() across the # requested integration time; this means we can call welch() on each # set of samples from the SDR, accumulate the binned power estimates, # and average later by the number of spectra taken to reduce the # noise while still following Barlett's method, and without keeping # huge arrays of iq samples around in RAM. # Time integration loop for cnt in range(num_loops): iq = sdr.read_samples(num_samp) freqs, p_xx = welch(iq, fs=rate, nperseg=nperseg, nfft=nbins, noverlap=0, scaling='spectrum', window=WINDOW, detrend=False, return_onesided=False) p_xx_tot += p_xx end_time = time.time() print('Integration ended at {} after {} seconds.'.format( time.strftime('%a, %d %b %Y %H:%M:%S'), end_time - start_time)) print('{} spectra were measured at {}.'.format(cnt, fc)) print('for an effective integration time of {:.2f}s'.format( num_samp * cnt / rate)) # Unfortunately, welch() with return_onesided=False does a sloppy job # of returning the arrays in what we'd consider the "right" order, # so we have to swap the first and last halves to avoid an artifact # in the plot. half_len = len(freqs) // 2 freqs = np.fft.fftshift(freqs) p_xx_tot = np.fft.fftshift(p_xx_tot) # Compute the average power spectrum based on the number of spectra read p_avg = p_xx_tot / cnt # Convert to power spectral density # A great resource that helped me understand the difference: # https://community.sw.siemens.com/s/article/what-is-a-power-spectral-density-psd # We could just divide by the bandwidth, but welch() applies a # windowing correction to the spectrum, and does it differently to # power spectra and PSDs. We multiply by the power spectrum correction # factor to remove it and divide by the PSD correction to apply it # instead. Then divide by the bandwidth to get the power per unit # frequency. # See the scipy docs for _spectral_helper(). win = get_window(WINDOW, nperseg) p_avg_hz = p_avg * ((win.sum()**2) / (win * win).sum()) / rate p_avg_db_hz = 10. * np.log10(p_avg_hz) # Shift frequency spectra back to the intended range freqs = freqs + fc # nice and tidy sdr.close() except OSError as err: print("OS error: {0}".format(err)) raise (err) except: print('Unexpected error:', sys.exc_info()[0]) raise finally: sdr.close() return freqs, p_avg_db_hz
from matplotlib import pyplot as plt from matplotlib import mlab as mlab import matplotlib.animation as animation from rtlsdr import RtlSdr sdr = RtlSdr() # configure device sdr.sample_rate = 2.4e6 # Hz sdr.center_freq = 94.7e6 # Hz sdr.freq_correction = 60 # PPM sdr.gain = 'auto' fig = plt.figure() graph_out = fig.add_subplot(1, 1, 1) def animate(i): graph_out.clear() samples = sdr.read_samples(16 * 1024) power, psd_freq = mlab.psd(samples, NFFT=1024, Fs=sdr.sample_rate / 1e6) psd_freq = psd_freq + sdr.center_freq / 1e6 graph_out.semilogy(psd_freq, power) try: ani = animation.FuncAnimation(fig, animate, interval=10) plt.show() except KeyboardInterrupt: pass finally: sdr.close()
import pyaudio import wave import time import sys import struct from rtlsdr import RtlSdr import matplotlib.pyplot as plt import numpy as np sdr = RtlSdr() # configure device sdr.sample_rate = 2.048e6 # Hz sdr.center_freq = 102.5e6 # Hz 101.3 had osmething interesteing sdr.freq_correction = 60 # PPM sdr.gain = 'auto' p = pyaudio.PyAudio() def callback(in_data, frame_count, time_info, status): sample = np.fft.fft(sdr.read_samples(2048*4)) #plt.plot( sample[1024*32:1024*32+256]) val = struct.pack( 'h' , np.argmax(np.abs(sample)) - 4150) print val return (val,pyaudio.paContinue)
def run_fswitch_int(num_samp, nbins, gain, rate, fc, fthrow, t_int, fswitch=10): ''' Note: Because a significant time penalty is introduced for each retuning, a maximum frequency switching rate of 10 Hz is adopted to help reduce the fraction of observation time spent retuning the SDR for a given effective integration time. As a consequence, the minimum integration time is 2*(1/fswitch) to ensure the user gets at least one spectrum taken on each frequency of interest. Inputs: num_samp: Number of elements to sample from the SDR IQ timeseries: powers of 2 are most efficient nbins: Number of frequency bins in the resulting power spectrum; powers of 2 are most efficient, and smaller numbers are faster on CPU. gain: Requested SDR gain (dB) rate: SDR sample rate, intrinsically tied to bandwidth in SDRs (Hz) fc: Base center frequency (Hz) fthrow: Alternate frequency (Hz) t_int: Total effective integration time (s) Kwargs: fswitch: Frequency of switching between fc and fthrow (Hz) Returns: freqs_fold: Frequencies of the spectrum resulting from folding according to the folding method implemented in the f_throw_fold (post_process module) p_fold: Folded frequency-switched power, centered at fc,(uncalibrated V^2) numpy array. ''' from .post_process import f_throw_fold import rtlsdr.helpers as helpers # Check inputs: assert t_int >= 2.0 * ( 1.0 / fswitch ), '''At t_int={} s, frequency switching at fswitch={} Hz means the switching period is longer than integration time. Please choose a longer integration time or shorter switching frequency to ensure enough integration time to dwell on each frequency.'''.format( t_int, fswitch) if fswitch > 10: print( '''Warning: high frequency switching values mean more SDR retunings. A greater fraction of observation time will be spent retuning the SDR, resulting in longer wait times to reach the requested effective integration time.''' ) print('Initializing rtl-sdr with pyrtlsdr:') sdr = RtlSdr() try: sdr.rs = rate # Rate of Sampling (intrinsically tied to bandwidth with SDR dongles) sdr.fc = fc sdr.gain = gain print(' sample rate: %0.6f MHz' % (sdr.rs / 1e6)) print(' center frequency %0.6f MHz' % (sdr.fc / 1e6)) print(' gain: %d dB' % sdr.gain) print(' num samples per call: {}'.format(num_samp)) print(' requested integration time: {}s'.format(t_int)) # Total number of samples to collect N = int(sdr.rs * t_int) # Number of samples on each frequency dwell N_dwell = int(sdr.rs * (1.0 / fswitch)) # Number of calls to SDR on each frequency num_loops = N_dwell // num_samp # Number of dwells on each frequency num_dwells = N // N_dwell print(' => num samples to collect: {}'.format(N)) print(' => est. num of calls: {}'.format(N // num_samp)) print(' => num samples on each dwell: {}'.format(N_dwell)) print(' => est. num of calls on each dwell: {}'.format(num_loops)) print(' => num dwells total: {}'.format(num_dwells)) # Set up arrays to store power spectrum calculated from I-Q samples freqs_on = np.zeros(nbins) freqs_off = np.zeros(nbins) p_xx_on = np.zeros(nbins) p_xx_off = np.zeros(nbins) cnt = 0 # Set the baseline time start_time = time.time() print('Integration began at {}'.format( time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime(start_time)))) # Swap between the two specified frequencies, integrating signal. # Time integration loop for i in range(num_dwells): tick = (i % 2 == 0) if tick: sdr.fc = fc else: sdr.fc = fthrow for j in range(num_loops): iq = sdr.read_samples(num_samp) if tick: freqs_on, p_xx = welch(iq, fs=rate, nperseg=nbins, noverlap=0, scaling='spectrum', detrend=False, return_onesided=False) p_xx_on += p_xx else: freqs_off, p_xx = welch(iq, fs=rate, nperseg=nbins, noverlap=0, scaling='spectrum', detrend=False, return_onesided=False) p_xx_off += p_xx cnt += 1 end_time = time.time() print('Integration ended at {} after {} seconds.'.format( time.strftime('%a, %d %b %Y %H:%M:%S'), end_time - start_time)) print('{} spectra were measured, split between {} and {}.'.format( cnt, fc, fthrow)) print('for an effective integration time of {:.2f}s'.format( num_samp * cnt / rate)) half_len = len(freqs_on) // 2 freqs_on = np.fft.fftshift(freqs_on) freqs_off = np.fft.fftshift(freqs_off) p_xx_on = np.fft.fftshift(p_xx_on) p_xx_off = np.fft.fftshift(p_xx_off) # Compute the average power spectrum based on the number of spectra read p_avg_on = p_xx_on / cnt p_avg_off = p_xx_off / cnt # Shift frequency spectra back to the intended range freqs_on = freqs_on + fc freqs_off = freqs_off + fthrow # Fold switched power spectra freqs_fold, p_fold = f_throw_fold(freqs_on, freqs_off, p_avg_on, p_avg_off) # nice and tidy sdr.close() except OSError as err: print("OS error: {0}".format(err)) raise (err) except: print('Unexpected error:', sys.exc_info()[0]) raise finally: sdr.close() return freqs_fold, p_fold
from rtlsdr import RtlSdr import numpy as np import matplotlib.pyplot as plt import timeit sdr = RtlSdr() # configure device sdr.sample_rate = 2.3e5 # Hz sdr.center_freq = 433e6 # Hz sdr.freq_correction = 1 # PPM sdr.gain = 80 N = 2 ** 18 M = 24 y = np.zeros(N * M, dtype=np.complex_) print(N * M / sdr.sample_rate) def listen(y): for i in range(M): idx = np.arange(N) + i * N x = np.array(sdr.read_samples(N)) y[idx] = x return y y = listen(y) fig, ax = plt.subplots()
from matplotlib.mlab import psd import pylab as pyl import numpy as np from rtlsdr import RtlSdr sdr = RtlSdr() # configure device sdr.sample_rate = 3.2e6 sdr.center_freq = 433e6 NFFT = 1024 NUM_ROWS = 1024 SKIP_ROWS = 8 # let AGC to settle MIN_ROWS = 64 ZOOM_STEP = .9 SCROLL_STEP = .1 FREQ_ZOOM = 4 SAMPLES_PER_ROW = NFFT / FREQ_ZOOM image_buffer = -100*np.ones((NUM_ROWS, SAMPLES_PER_ROW)) fig = pyl.figure() ax = fig.add_subplot(1,1,1) ax.set_xlabel('Current frequency (MHz)') ax.set_ylabel('Time (sec)') top_row = 0 num_row = NUM_ROWS def read_buffer(): samples = sdr.read_samples((SKIP_ROWS+NUM_ROWS)*NFFT)
def __init__(self): sdr = RtlSdr() CA = np.loadtxt('CA.txt', dtype=np.int16, unpack=True)
def OnRefreshButton(self, event=0): from rtlsdr import RtlSdr serial_numbers = RtlSdr.get_device_serial_addresses() self.listApps.DeleteAllItems() for i in self.appsDict: item = self.listApps.InsertItem(0, i['name']) if i['name'] == 'AIS': self.listApps.SetItem(item, 1, _('installed')) sdraisdeviceindex = self.conf.get('SDR-VHF', 'sdraisdeviceindex') if sdraisdeviceindex: self.listApps.SetItem(item, 2, sdraisdeviceindex) for ii in serial_numbers: if sdraisdeviceindex == str(RtlSdr.get_device_index_by_serial(ii)): self.listApps.SetItem(item, 3, ii) sdraisppm = self.conf.get('SDR-VHF', 'sdraisppm') if sdraisppm: self.listApps.SetItem(item, 4, sdraisppm) elif i['name'] == 'GQRX': if not os.path.isdir(self.conf.home+'/.config/gqrx'): self.listApps.SetItem(item, 1, _('not installed')) self.listApps.SetItemBackgroundColour(item,(200,200,200)) else: self.listApps.SetItem(item, 1, _('installed')) try: device = '' gqrx_conf = configparser.ConfigParser() gqrx_conf.read(self.conf.home+'/.config/gqrx/default.conf') inputDevice = gqrx_conf.get('input', 'device') inputDevice = inputDevice.replace('"','') inputDevice = inputDevice.split('=') if inputDevice[0] == 'rtl': device = inputDevice[1] if device: self.listApps.SetItem(item, 2, device) for ii in serial_numbers: if device == str(RtlSdr.get_device_index_by_serial(ii)): self.listApps.SetItem(item, 3, ii) gqrxppm = gqrx_conf.get('input', 'corr_freq') if gqrxppm: self.listApps.SetItem(item, 4, str(int(gqrxppm)/1000000)) except Exception as e: print('error getting gqrx settings: '+str(e)) elif i['name'] == 'ADS-B': if not self.platform.isInstalled('piaware'): self.listApps.SetItem(item, 1, _('not installed')) self.listApps.SetItemBackgroundColour(item,(200,200,200)) else: self.listApps.SetItem(item, 1, _('installed')) try: with open('/etc/default/dump1090-fa', 'r') as f: for line in f: if 'RECEIVER_OPTIONS=' in line: line = line.replace('\n', '') line = line.strip() items = line.split('=') item1 = items[1].replace('"', '') item1 = item1.strip() options = item1.split(' ') #--device-index 1 --gain -10 --ppm 0 device = options[1] ppm = options[5] self.listApps.SetItem(item, 2, device) self.listApps.SetItem(item, 4, ppm) for ii in serial_numbers: if device == str(RtlSdr.get_device_index_by_serial(ii)): self.listApps.SetItem(item, 3, ii) except Exception as e: print(str(e)) elif i['name'] == 'DAB': if not self.platform.isInstalled('welle.io'): self.listApps.SetItem(item, 1, _('not installed')) self.listApps.SetItemBackgroundColour(item,(200,200,200)) else: self.listApps.SetItem(item, 1, _('installed')) self.listApps.SetItem(item, 2, _('First available')) elif i['name'] == 'DVB-T': if not self.platform.isInstalled('w-scan'): self.listApps.SetItem(item, 1, _('not installed')) self.listApps.SetItemBackgroundColour(item,(200,200,200)) else: self.listApps.SetItem(item, 1, _('installed')) self.listApps.SetItem(item, 2, _('First available')) self.onListAppsDeselected() if self.started: self.started = False self.statusUpdate() self.started = True indexAis = self.listApps.GetItemText(0, 2) indexAdsb = self.listApps.GetItemText(1, 2) if indexAis == indexAdsb: try: subprocess.check_output(['systemctl', 'is-enabled', 'openplotter-rtl_ais']).decode(sys.stdin.encoding) worksAis = True except: worksAis = False try: subprocess.check_output(['systemctl', 'is-enabled', 'dump1090-fa']).decode(sys.stdin.encoding) worksAdsb = True except: worksAdsb = False if worksAis and worksAdsb: self.listApps.SetItemBackgroundColour(0,(255,0,0)) self.listApps.SetItemBackgroundColour(1,(255,0,0))
loss='categorical_crossentropy', metrics=['accuracy']) # model.summary() model.fit(Xtrain, Ytrain, epochs=50, batch_size=128, shuffle=True, validation_data=(Xtest, Ytest)) # ============================================== # print("") sdr = RtlSdr() sdr.sample_rate = sample_rate = 2400000 sdr.err_ppm = 56 sdr.gain = 'auto' correct_predictions = 0 def read_samples(freq): f_offset = 250000 # shifted tune to avoid DC sdr.center_freq = freq - f_offset time.sleep(0.06) iq_samples = sdr.read_samples(sample_rate * 0.25) # sample 1/4 sec fc1 = np.exp(-1.0j * 2.0 * np.pi * f_offset / sample_rate * np.arange(len(iq_samples))) # shift down 250kHz iq_samples = iq_samples * fc1
def main(input): print("let's find your SDR's oscillator precision") show_graph = input["graph"] verbose = input["verbose"] samplerate = input["rs"] mode = input["m"] if input["f"] is not None: print("loading file...") filename = input["f"] if os.path.exists(filename): data = cali.utils.load_data(filename, offset=44) if mode == "dab": print("starting mode: dab") ppm = cali.dabplus.dab.get_ppm(data, samplerate=samplerate, show_graph=show_graph, verbose=verbose) print("your sdr's precision is", ppm, "ppm") elif mode == "dvbt": print("starting mode: dvbt") cali.dvbt.dvbt.main() elif mode == "gsm": print("starting mode: gsm") cali.gsm.gsm.main() else: print("ending") else: print("sorry, file not found. try again.") elif input["s"] is not None: # scanning with your sdr print("scanning...") if mode == "dab": print("starting mode: dab") from rtlsdr import RtlSdr filename = "tmp.dat" device = input["rd"] sdr = RtlSdr(device_index=device) rs = input["rs"] rg = input["rg"] ns = rs * input["nsec"] #seconds c = input["c"] result = [] dabchannels = cali.dabplus.dab.channels() if c == "all": print("Scanning all channels") for channel in tqdm(range(len(dabchannels["dab"])), desc="Scanning…", ascii=False, ncols=75): channel, block, cf, dab_snr, dab_block_detected, dab_ppm = \ cali.utils.scan_one_dab_channel(dabchannels, channel, sdr, rs, ns, rg, filename, samplerate, show_graph, verbose) result.append([channel, block, cf, dab_snr, dab_block_detected, dab_ppm]) else: print("Scanning only channel #", c) channel = int(c) channel, block, cf, dab_snr, dab_block_detected, dab_ppm = \ cali.utils.scan_one_dab_channel(dabchannels, channel, sdr, rs, ns, rg, filename, samplerate, show_graph, verbose) result.append([channel, block, cf, dab_snr, dab_block_detected, dab_ppm]) # output dab_snr_max = 0 for i in range(len(result)): if i == 0 or dab_snr_max < result[i][3]: dab_snr_max = result[i][3] print("") print("____Results_______________________________________________________________________________________") print("# , block, freq [Hz], SNR [dB] , Prec. [ppm], offset [Hz], block [x][o][ ] & signal strength") print("--------------------------------------------------------------------------------------------------") for i in range(len(result)): channel = result[i][0] block = result[i][1] cf = result[i][2] dab_snr = result[i][3] dab_block_detected = "[ ]" if result[i][4] == 1: dab_block_detected = "[o]" elif result[i][4] == 2: dab_block_detected = "[x]" dab_ppm = result[i][5] bar = cali.utils.signal_bar(dab_snr, dab_snr_max) f_offset = 0.0 if dab_ppm != None: f_offset = cf / 1000000.0 * dab_ppm print("# {0:2d}, {1:5s}, {2:9.0f}, {3:+9.5f}, {4:+10.4f}, {5:+11.1f}, {6:4s} {7}". format(channel, block, cf, dab_snr, dab_ppm, f_offset, dab_block_detected, bar)) else: print("# {0:2d}, {1:5s}, {2:9.0f}, {3:+9.5f}, None, {5:+11.1f}, {6:4s} {7}". format(channel, block, cf, dab_snr, dab_ppm, f_offset, dab_block_detected, bar)) sdr.close() elif mode == "dvbt": print("starting mode: dvbt") cali.dvbt.dvbt.main() elif mode == "gsm": print("starting mode: gsm") cali.gsm.gsm.main() else: print("ending")
def __init__(self, sdr=None, fig=None): self.fig = fig if fig else pyl.figure() self.sdr = sdr if sdr else RtlSdr() self.init_plot()
distmin = 25 distmax = 35 elif (SNR < 37.455 and SNR > 30.5): distmin = 35 distmax = 45 elif (SNR < 30.5 and SNR > 25): distmin = 45 distmax = 100 return distmin, distmax #print(len(sys.argv)) #print(sys.argv[0]) #configuring the device sdr = RtlSdr(serial_number='0000103') sdr.sample_rate = 1.024e6 sdr.bandwidth = 512e3 if len(sys.argv) == 2: sdr.center_freq = sys.argv[1] else: sdr.center_freq = 462562500 print("Current Frequency: ", sdr.center_freq) sdr.freq_correction = 1 sdr.gain = 6 #time = 21 snr_vals = [] #num_samples = int(sdr.sample_rate*time) #print("Collecting ", num_samples, " samples")
def saveSignal(freq, file_path): # Define function for writing signal data into file def write_data(data_points, magnitudeData, frequencyData, mag_file, freq_file): i = 0 mag_file.write('[') freq_file.write('[') while i < data_points - 1: mag_file.write("%s, " % magnitudeData[i]) freq_file.write("%s, " % frequencyData[i]) i += 1 mag_file.write('%s]\n' % magnitudeData[i]) freq_file.write('%s]\n' % frequencyData[i]) sdr = RtlSdr() # Configure SDR sdr.sample_rate = 2.4e6 # Hz sdr.center_freq = freq # Hz sdr.freq_correction = 60 # PPM sdr.gain = 4 # 'auto' # Initialize data_points = 1024 samples = sdr.read_samples(256 * data_points) mag_file_path = file_path + "/magdata.txt" freq_file_path = file_path + "/freqdata.txt" ### *** IMPORTANT *** (for later, when optimizing) ### I'm not sure if we should leave this outside of the function ### and move it to the end of the main code, after the flight path ### ends. Idk the impact of leaving the SDR open/on for an extended ### period of time. If we move sdr.close() outside, we have to ### remember to also move the above code outside as well. ### Leaving this line within this function should be fine for now. sdr.close() # PSD plot data psddata = psd(samples, NFFT=data_points, Fs=sdr.sample_rate / 1e6, Fc=sdr.center_freq / 1e6) # Extracting pertinent information from the PSD plot calculation magnitudeData = psddata[0] frequencyData = psddata[1] # Check for .txt file and write data # For Ron: Magnitude has not been converted to dB yet. To convert, 10*log(magnitude). if Path(mag_file_path).is_file() and Path(freq_file_path).is_file(): with open(mag_file_path, 'a') as mag_file, open(freq_file_path, 'a') as freq_file: write_data(data_points, magnitudeData, frequencyData, mag_file, freq_file) else: with open(mag_file_path, 'w') as mag_file, open(freq_file_path, 'w') as freq_file: write_data(data_points, magnitudeData, frequencyData, mag_file, freq_file) print("Data saved successfully.")
pozadi_volba = raw_input("Odecist sumove pozadi : a = ano // n = ne :") print("volba =", pozadi_volba) if sirka_volba is 'a': pocet_vzorku = 8 * 512 if sirka_volba is 'b': pocet_vzorku = 32 * 512 if sirka_volba == 'c': pocet_vzorku = 128 * 512 if sirka_volba == 'd': pocet_vzorku = 1024 * 1024 sdr = RtlSdr() pocet_oken = f_stop - f_start f_start = f_start * 1e6 f_stop = f_stop * 1e6 sdr.sample_rate = 1.2e6 # Hz sdr.freq_correction = +30 # korekce ochylky hodin, v PPM sdr.gain = 12 sdr.center_freq = f_start + 0.5e6 # Hz x = np.linspace(f_start, f_stop, pocet_oken * (int(round(pocet_vzorku * (1 / 1.2)))) ) # definice velikosti pole pro vyslednou FFT - jen pro indexy data = sdr.read_samples( pocet_vzorku) # testovaci aktivace prijimace, prvni vzorky nejsou kvalitni provede_mereni = 1
parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--ppm', type=int, default=0, help='ppm error correction') parser.add_argument('--gain', type=int, default=20, help='RF gain level') parser.add_argument('--freq', type=int, default=92900000, help='frequency to listen to, in Hertz') parser.add_argument( '--lang', type=str, default='en-US', help='language to recognize, en-US, ru-RU, fi-FI or any other supported') parser.add_argument('--buf', type=int, default=100, help='buffer size to recognize, 100 = 6.25 seconds') parser.add_argument('--verbose', action='store_true', help='mute audio output') args = parser.parse_args() sdr = RtlSdr() sdr.rs = 1024000 sdr.fc = args.freq sdr.gain = args.gain sdr.err_ppm = args.ppm sdr.read_samples_async(read_callback, int(sdr.get_sample_rate()) // 16)
ps_real=sp.real ps_imag=sp.imag sq=np.power(ps_real,2)+np.power(ps_imag,2) sqrt=np.sqrt(sq) psd=sqrt/1024 max=np.max(psd) log=10*math.log10(max) object.close() freq=object.get_center_freq() return log, freq if __name__ == '__main__': # Find the device index for a given serial number sdr = RtlSdr(serial_number='00000001') sdr2 = RtlSdr(serial_number='00000002') #Set Center Frequency cntr_freq1=sdr.set_center_freq(88200000) cntr_freq2=sdr2.set_center_freq(103500000) #Set Gain sdr.gain = 15 sdr2.gain = 15 #Set sample rate sdr.rs = 2.4e6 sdr2.rs = 2.4e6
def _open_sdr_local(self): try: sdr = RtlSdr() except IOError: sdr = None return sdr
sat = ephem.readtle(sat_line0, sat_line1, sat_line2) active_orbcomm_satellites[name]['sat_obj'] = sat active_orbcomm_satellites[name]['tles'] = [sat_line0, sat_line1, sat_line2] # PyEphem observer # set lat/long/alt in the CONFIG file obs = ephem.Observer() obs.lat, obs.lon = '{}'.format(lat), '{}'.format(lon) obs.elevation = alt # Technically is the altitude of observer # Set RTLSDR parameters and initialize sample_rate = 1.2288e6 center_freq = 137.5e6 gain = 'auto' # Use AGC sdr = RtlSdr() sdr.rs = sample_rate sdr.gain = gain sdr.fc = center_freq # Set recording parameters record_length = 2.0 # seconds record_interval = 5.0 # seconds # receive samples that are an integer multiple of 1024 from the RTLSDR num_samples_per_recording = int( (floor(record_length * sample_rate / 1024) + 1) * 1024) file_count = 100 while 1: try:
#!/usr/bin/python from azure.servicebus import ServiceBusService from rtlsdr import RtlSdr sdr = RtlSdr() # sdr sdr.sample_rate = 2.048e6 sdr.center_freq = 70e6 sdr.freq_correction = 60 sdr.gain = 'auto' # Azure key_name = 'RootManageSharedAccessKey' key_value = '6RS3yrdYH3Ds/+rQPKQjiG56VpzghffyCDNbxGTiivo=' service_namespace = 'hyperfineml' x = 512 i = 0 samples = sdr.read_samples(x) sbs = ServiceBusService(service_namespace, shared_access_key_name=key_name, shared_access_key_value=key_value) if (sbs.create_event_hub('sdrhub')): while (i < x): sbs.send_event('sdr', '{"signalval": "' + str(samples[i]) + '"}') i = i + 1 sbs.delete_event_hub('sdrhub')
def run_total_power_int(num_samp, gain, rate, fc, t_int): ''' Implement a total-power radiometer. Raw, uncalibrated power values. Inputs: num_samp: Number of elements to sample from the SDR IQ timeseries per call gain: Requested SDR gain (dB) rate: SDR sample rate, intrinsically tied to bandwidth in SDRs (Hz) fc: Bandpass center frequency (Hz) t_int: Total integration time (s) Returns: p_tot: Time-averaged power in the signal from the sdr, in uncalibrated units ''' import rtlsdr.helpers as helpers # Start the RtlSdr instance print('Initializing rtl-sdr with pyrtlsdr:') sdr = RtlSdr() try: sdr.rs = rate sdr.fc = fc sdr.gain = gain print(' sample rate: {} MHz'.format(sdr.rs / 1e6)) print(' center frequency {} MHz'.format(sdr.fc / 1e6)) print(' gain: {} dB'.format(sdr.gain)) print(' num samples per call: {}'.format(num_samp)) print(' requested integration time: {}s'.format(t_int)) # For Nyquist sampling of the passband dv over an integration time # tau, we must collect N = 2 * dv * tau real samples. # https://www.cv.nrao.edu/~sransom/web/A1.html#S3 # Because the SDR collects complex samples at a rate rs = dv, we can # Nyquist sample a signal of band-limited noise dv with only rs * tau # complex samples. # The phase content of IQ samples allows the bandlimited signal to be # Nyquist sampled at a data rate of rs = dv complex samples per second # rather than the 2* dv required of real samples. N = int(sdr.rs * t_int) print(' => num samples to collect: {}'.format(N)) print(' => est. num of calls: {}'.format(int(N / num_samp))) global p_tot global cnt p_tot = 0.0 cnt = 0 # Set the baseline time start_time = time.time() print('Integration began at {}'.format( time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime(start_time)))) # Time integration loop @helpers.limit_calls(N / num_samp) def p_tot_callback(iq, context): # The below is a total power measurement equivalent to summing # P = V^2 / R = (sqrt(I^2 + Q^2))^2 = (I^2 + Q^2) global p_tot p_tot += np.sum(np.real(iq * np.conj(iq))) global cnt cnt += 1 sdr.read_samples_async(p_tot_callback, num_samples=num_samp) end_time = time.time() print('Integration ended at {} after {} seconds.'.format( time.strftime('%a, %d %b %Y %H:%M:%S'), end_time - start_time)) print('{} calls were made to SDR.'.format(cnt)) print('{} samples were measured at {} MHz'.format( cnt * num_samp, fc / 1e6)) print('for an effective integration time of {:.2f}s'.format( (num_samp * cnt) / rate)) # Compute the average power value based on the number of measurements # we actually did p_avg = p_tot / (num_samp * cnt) # nice and tidy sdr.close() except OSError as err: print("OS error: {0}".format(err)) raise (err) except: print('Unexpected error:', sys.exc_info()[0]) raise finally: sdr.close() return p_avg
mpl.use('TkAgg') from tkinter import * from numpy import * import matplotlib matplotlib.use('TkAgg') import matplotlib.pyplot as plt from rtlsdr import RtlSdr import time from SSN_modul.Received_power import received_power from SSN_modul.Received_power import received_power2 from SSN_modul.self_psd import selfpsd # Get a list of detected device serial numbers (str) serial_numbers = RtlSdr.get_device_serial_addresses() #---------------------------------------------------------first sensor # Find the device index for a given serial number device_index0 = RtlSdr.get_device_index_by_serial(serial_numbers[0]) sdr0 = RtlSdr(device_index0) sdr0.sample_rate = 3.2e6 sdr0.center_freq = 1600 * 1e6 sdr0.gain = 4 #---------------------------------------------------------second sensor device_index1 = RtlSdr.get_device_index_by_serial(serial_numbers[1]) sdr1 = RtlSdr(device_index1) sdr1.sample_rate = 3.2e6 sdr1.center_freq = 1600 * 1e6 sdr1.gain = 4 N = 1
class Demod: SAMP_RATE = 256000. SAMP_WINDOW = 1024*40 def __init__(self): self.sdr = RtlSdr() # Sampling rate self.sdr.rs = Demod.SAMP_RATE # Pins 1 and 2 self.sdr.set_direct_sampling(1) # I don't think this is used? self.sdr.gain = 1 def run(self, limit=None, callback=lambda x: print(x), carrier=32000, bw=1000, sps=8, codes=manchester, mod=Mods.MAGNITUDE, header=HEADER, footer=FOOTER, pktlen=PKTBYTES): # Center frequency self.sdr.fc = carrier self.mod = mod self.header = header self.footer = footer self.pktlen = 8*pktlen + len(footer) self.rxcallback = callback decim = Demod.SAMP_RATE/bw/sps assert decim == int(decim) self.decim = int(decim) assert Demod.SAMP_WINDOW % self.decim == 0 self.sampchips = Demod.SAMP_WINDOW / self.decim self.corr = codes2corr(codes, sps) self.codelen = len(self.corr[0]) self.last = np.zeros(Demod.SAMP_WINDOW) self.index = 0 self.tocheck = [None] * self.codelen for i in range(self.codelen): self.tocheck[i] = dict() self.tocheck[i]['last'] = ''.join(range(0)) self.tocheck[i]['pkts'] = range(0) if limit is None: def byte_callback(samp, sdr): if select.select([sys.stdin], [], [], 0)[0]: sdr.cancel_read_async() self.ddc(samp, sdr) else: @limit_calls(limit) def byte_callback(samp, sdr): if select.select([sys.stdin], [], [], 0)[0]: sdr.cancel_read_async() self.ddc(samp, sdr) self.sdr.read_bytes_async(byte_callback, Demod.SAMP_WINDOW*2) print (self.index, "samples read") sys.stdout.flush() sys.stdin.readline() def bb2c(self, baseband): mag = np.abs(baseband) phase = np.angle(baseband) dp = np.mod(np.ediff1d(phase)+np.pi, 2*np.pi)-np.pi return mag[1:], phase[1:], dp def decode(self, chips): corrs = [] for c in self.corr: corrs.append(np.correlate(chips, c)) # Vector correlations if np.iscomplex(corrs).any(): corrs = np.abs(corrs) maxes = np.max(np.array(corrs), 0) codes = np.argmax(np.array(corrs), 0) return maxes, codes def debounce(self, i, l, rxstr): try: if i != self.debounce_i or abs(l - self.debounce_l) > 1: self.rxcallback(rxstr) except AttributeError: self.rxcallback(rxstr) self.debounce_i = i self.debounce_l = l def extract(self, nc): for codeoffset in range(self.codelen): pkts = [] codestr = "".join(map(repr, map(int, nc[codeoffset::self.codelen]))) for p in self.tocheck[codeoffset]['pkts']: pkt = p + codestr[0:self.pktlen-len(p)] if len(pkt) < self.pktlen: pkts.append(pkt) elif len(self.footer) == 0 or pkt[-len(self.footer):] == self.footer: str = "" for j in range(0,len(pkt)-1,8): str += chr(int(pkt[j:j+8][::-1], 2)) self.debounce(self.index, -len(p), str) sys.stdout.flush() codestr = self.tocheck[codeoffset]['last'] + codestr for ind in find_all(codestr, self.header): pkt = codestr[ind+len(self.header):ind+len(self.header)+self.pktlen] if len(pkt) < self.pktlen: pkts.append(pkt) elif len(self.footer) == 0 or pkt[-len(self.footer):] == self.footer: str = "" for j in range(0,len(pkt)-1,8): str += chr(int(pkt[j:j+8][::-1], 2)) self.debounce(self.index, ind, str) sys.stdout.flush() self.tocheck[codeoffset]['pkts'] = [] + pkts self.tocheck[codeoffset]['last'] = "" + codestr[-len(self.header)+1:] def ddc(self, samp, sdr): s = np.asarray(samp) i, q = s[::2], s[1::2] i = np.mean(i.reshape(-1,self.decim), 1) # poor man's decimation q = np.mean(q.reshape(-1,self.decim), 1) # poor man's decimation iq = np.empty(len(i), 'complex') iq.real, iq.imag = i, q iq /= (255/2) iq -= (1 + 1j) baseband = np.concatenate((self.last, iq)) self.last = iq mag, phase, dp = self.bb2c(baseband) if self.mod == Mods.MAGNITUDE: sig = mag elif self.mod == Mods.PHASE: sig = phase elif self.mod == Mods.DPHASE: sig = dp else: sig = baseband corrs, codes = self.decode(sig) nc = codes[self.codelen:self.codelen+self.sampchips] self.extract(nc) self.index += 1 def end(self): self.sdr.close() def plot(self): plt.ion() fig = plt.figure() ax1 = fig.add_subplot(311) ax1.plot(self.chips) ax2 = fig.add_subplot(312, sharex=ax1) ax2.plot(self.corrs) ax3 = fig.add_subplot(313, sharex=ax1) ax3.plot(self.demod) plt.show() def checkdemod(self, index, demod=None, packetlen=5): if demod is None: demod = self.demod l = packetlen*8+6+7 b = self.demod[index:index+l*self.codelen:self.codelen] return chipsToString(np.concatenate(([1,0], b, [0]))) def findstring(self, demod = None, packetlen=5): if demod is None: demod = self.demod find = [] for i in range(len(demod)): s, c = self.checkdemod(i, demod, packetlen) if len(s) and s[0] == 'a' and s[-1] == 'x': find.append((i, s[1:-1])) return find
def __loadDevice(self): try: self.radio = RtlSdr() return True except: return False
class FMRadio: # num samplesmust be multiple of 256 def __init__(self,freq,N_samples): self.sample_rate = 1e6 self.decim_r1 = 1e6/2e5 # for wideband fm self.decim_r2 = 2e5/44100 # for baseband recovery self.center_freq = freq+250e3 self.gain = 36 self.N_samples = N_samples self.sdr = RtlSdr() self.sdr.direct_sampling = 1 self.sdr.sample_rate = self.sample_rate self.sdr.center_freq = self.center_freq self.sdr.gain = 'auto' #self.gain self.pa = pyaudio.PyAudio() self.stream = self.pa.open( format = pyaudio.paFloat32, channels = 2, rate = 44100, output = True) adj = 0 hamming = 10*signal.hamming(self.N_samples*.10 + adj) lpf = np.append( np.zeros(self.N_samples*.45),hamming) self.lpf = np.roll(np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*.45))),int(-.25*self.N_samples)) def __del__(self): print "sdr closed" self.sdr.close() print "pyaudio terminated" self.pa.terminate() def getSamples(self): #N_samples = self.N_samples # 1/24.4 seconds ~46336 #approximately a blocksize amount's time return self.sdr.read_samples(self.N_samples) # def demodulate_threaded(self,samples): # async_demodulation = self.pool.apply_async(self.demodulate, samples, callback=self.play) def demodulate(self,samples): # DEMODULATION CODE #samples = #self.sample_buffer.get() # LIMITER goes here # low pass & down sampling via fft spectrum = np.fft.fft(samples)*self.lpf toplot = False if(toplot): fig = plt.figure() plt.plot(np.abs(spectrum)) plt.show() # Decimate in two rounds. One to 200k, another to 44.1k # DECIMATE HERE. Note that we're looking at 1MHz bandwidth. n_s = spectrum.size channel_spectrum = spectrum[int(n_s*.75-.5*n_s/self.decim_r1):int(.75*n_s+.5*n_s/self.decim_r1)] #np.append(spectrum[0:int(n_s/self.decim_r1*.5)],spectrum[n_s-int(n_s/self.decim_r1*.5):n_s]) #radio_spectrum -= np.mean(radio_spectrum) #attempt to remove dc bias #print channel_spectrum.size toplot = False if(toplot): fig = plt.figure() plt.plot(np.abs(np.fft.ifftshift(channel_spectrum))) plt.show() lp_samples = np.fft.ifft(np.fft.ifftshift(channel_spectrum)) power = np.abs(self.rms(lp_samples)) lp_samples /= power #lp_samples = self.lowpass_filter(lp_samples,4) # polar discriminator A = lp_samples[1:lp_samples.size] B = lp_samples[0:lp_samples.size-1] dphase = ( A * np.conj(B) ) #dpm = np.mean(np.abs(dphase)) # normalize # dphase /= dpm dphase.resize(dphase.size+1) dphase[dphase.size-1] = dphase[dphase.size-2] rebuilt = signal.medfilt(np.angle(dphase)/np.pi,21) # np.cos(dphase) #phase = np.sin(rebuilt) #phase = self.lowpass_filter(phase,8) #rebuilt= self.lowpass_filter(rebuilt,8) toplot = False if toplot: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(rebuilt) plt.show() modulated = rebuilt * np.sin(2*np.pi*38000/2e5*np.r_[0:rebuilt.size]) spectrum = np.fft.fft(rebuilt) mod_spectrum = np.fft.fft(modulated) #* self.lpf2 n_z = spectrum.size #base_spectrum = np.append(spectrum[0:1024],spectrum[n_z-1024:n_z]) base_spectrum = np.append(spectrum[0:int(n_z/self.decim_r2*.5)],spectrum[n_z-int(n_z/self.decim_r2*.5):n_s]) stereo_spectrum = np.append(mod_spectrum[0:int(n_z/self.decim_r2*.5)],mod_spectrum[n_z-int(n_z/self.decim_r2*.5):n_s]) stereo_spectrum *= np.fft.ifftshift(np.hamming(stereo_spectrum.size)) toplot = False if(toplot): fig = plt.figure() plt.plot(np.linspace(-22050,22050,stereo_spectrum.size),np.abs(np.fft.fftshift(stereo_spectrum)), np.linspace(-22050,22050,base_spectrum.size),.05*np.abs(np.fft.fftshift(base_spectrum))) plt.show() output = np.fft.ifft(base_spectrum) diff =np.fft.ifft(stereo_spectrum) #check: should be 1807 or very close to it. it is!! #output = self.lowpass_filter(np.real(output),8) #[12:8204] stereo = np.zeros(output.size*2,dtype='complex') left = output + 10*diff right = output - 10* diff stereo[0:stereo.size:2] = left stereo[1:stereo.size:2] = right #print 1e6/n_s / 44100 * output.size return np.real(stereo) def demodulate2(self,samples): # DEMODULATION CODE # LIMITER goes here # low pass & down sampling lp_samples = signal.decimate(self.lowpass_filter(samples,16),int(self.decim_r1)) # polar discriminator A = lp_samples[1:lp_samples.size] B = lp_samples[0:lp_samples.size-1] dphase = ( A * np.conj(B) ) dphase.resize(dphase.size+1) dphase[dphase.size-1] = dphase[dphase.size-2] rebuilt = signal.medfilt(np.angle(dphase)/np.pi,15) # np.cos(dphase) output = signal.decimate(rebuilt,int(self.decim_r2)) return np.real(output) def lowpass_filter(self,x,width): #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi wndw = np.kaiser(width,6) wndw /= np.sum(wndw) new_array = signal.fftconvolve(x, wndw) return new_array[int(width/2):x.size+int(width/2)] # calculate rms for power # def rms(self,samples): meansq = np.mean(np.square(samples)) return np.sqrt(meansq) def play(self,samples): self.stream.write( samples.astype(np.float32).tostring() ) def start(self): while True: self.play(self.demodulate(self.getSamples()))
from rtlsdr import RtlSdr import dmrutils reciever = RtlSdr() reciever.sample_rate = 2.048e6 #hz reciever.center_freq = 70e6 #hz reciever.freq_correcetion = 60 #PPM reciever.gain = 'auto' print(reciever.read.samples(1024))
class Rtl_threading(threading.Thread): def __init__(self, addr, fc, fs, size, times, corr): threading.Thread.__init__(self) self.sdr = RtlSdr(addr) # configure device self.sdr.sample_rate = fs; # Hz self.sdr.center_freq = fc; # Hz # self.freq_correction = corr; # PPM if addr==1: self.sdr.gain = 15.7; else: #0 self.sdr.gain = 32.8; #15.7 0.725 # init param self.alive = True self.addr = addr; self.size = size self.times = times self.counter = 0; self.timestamp = int(time.time()); #0.0 0self.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 def run(self): global event, samples0, samples1; #init the synchronization # start lock to avoid reading the same data if event.isSet(): event.clear() event.wait() else: self.timestamp = int(time.time()); event.set() for x in range(0, self.times): #read output = self.sdr.read_samples(self.size); if self.addr == 0: #ref samples0 = np.array(output, dtype = np.complex128); else: samples1 = np.array(output, dtype = np.complex128); if event.isSet(): event.clear() if not self.alive: break; event.wait() else: self.save2mat(x) self.timestamp = int(time.time()); print '*'*3+' '+str(x)+' done: '+time.asctime( time.localtime(time.time()) ); if not self.alive: break; event.set() def save2mat(self, i): global samples0, samples1; std0 = np.around(np.std(samples0), 5); std1 = np.around(np.std(samples1), 5); print 'std0:', std0, 'std1', std1; scipy.io.savemat('./data/'+folder_name+'/'+filename+'_'+str(i)+'.mat', mdict={'s0':samples0, 's1':samples1, 'timestamp': self.timestamp, 'fs':self.sdr.sample_rate, 'ref_addr':ref_addr});
def collect_samples(freq, classname): os.makedirs("training_data/" + classname, exist_ok=True) os.makedirs("testing_data/" + classname, exist_ok=True) for i in range(0, 1000): iq_samples = read_samples(sdr, freq) iq_samples = signal.decimate(iq_samples, decimation_rate, zero_phase=True) if (i < 750): # 75% train, 25% test filename = "training_data/" + classname + "/samples-" + randomword(16) + ".npy" else: filename = "testing_data/" + classname + "/samples-" + randomword(16) + ".npy" np.save(filename, iq_samples) if not (i % 10): print(i / 10, "%", classname) sdr = RtlSdr() sdr.sample_rate = sample_rate = 2400000 decimation_rate = 48 sdr.err_ppm = 56 # change it to yours sdr.gain = 'auto' # collect_samples(422600000, "tetra") collect_samples(95000000, "wfm") collect_samples(104000000, "wfm") collect_samples(942200000, "gsm") collect_samples(147337500, "dmr") collect_samples(49250000, "tv") # collect "other" class training data for freq in range(112000000, 174000000, 50000): print('Sampling at', freq)
def main(): # Setup cli arguments parser = argparse.ArgumentParser( description= '''Listen for ADS-B signals using an RTL-SDR and watch the air traffic on local Dash webserver! Default location is http://localhost:8050''' ) parser.add_argument( '--rtl_device', '-d', type=int, default=0, metavar='device_index', help='Select the RTL-SDR device index to use. Defaults to device 0.') parser.add_argument( '--location', '-l', type=float, nargs=2, metavar=('Lat', 'Lon'), default=(None, None), help= 'Set the latitude and longitude of your ground station; usually your current location. If unset, attempts to determine your location using your IP address.' ) parser.add_argument( '--TTL', '-t', type=int, default=100, help= "Delete a tracked object if we haven't heard from it for TTL seconds. Default to 100 seconds." ) parser.add_argument( '--port', '-p', type=int, default=8050, help= 'The local port to run the Dash webserver on. Default to port 8050.') parser.add_argument( '--log', type=str, default=None, help= 'Where to log information on detected ADS-B packets. Does not log if unset.' ) parser.add_argument( '--fix-single-bit-errors', type=str, default='No', metavar='[Y/N]', dest='fix_single_bit_errors', help= 'Have the decoder attempt to fix single bit errors in packets. VERY RESOURCE INTENSIVE AT THIS TIME!!!' ) args = parser.parse_args() # Variable initialization fs = 2000000 # 2MHz sampling frequency center_freq = 1090e6 # 1090 MHz center frequency gain = 49.6 # Gain N_samples = 2048000 # SDR samples for each chunk of data ( Approx 1.024 seconds per chunk ) TTL = args.TTL # How long to store ADS-B object information log = args.log # Where to log packets # Determine ground station location using IP address or manual input if args.location[0] == None or args.location[1] == None: try: url = 'https://ipinfo.io' loc_request = requests.get(url) lat_lon = loc_request.json()['loc'].split(',') pos_ref = [float(lat_lon[0]), float(lat_lon[1])] except Exception: print(f'Error requesting location information from {url}') exit() else: pos_ref = [args.location[0], args.location[1]] # Determine whether to fix 1-bit errors FIX_1BIT_ERRORS = (args.fix_single_bit_errors[0] == 'Y' or args.fix_single_bit_errors[0] == 'y' or args.fix_single_bit_errors[0] == '1' or args.fix_single_bit_errors[0] == 'T' or args.fix_single_bit_errors[0] == 't') # Setup Dash server app.server(pos_ref, planes, packets) # Create a queue for communication between the reading and processing threads Qin = queue.Queue() # Setup the RTL-SDR reader sdr = RtlSdr(args.rtl_device) sdr.sample_rate = fs # sampling rate sdr.center_freq = center_freq # 1090MhZ center frequency sdr.gain = gain stop_flag = threading.Event() # Setup the reading and processing threads t_sdr_read = threading.Thread(target=sdr_read, args=(Qin, sdr, N_samples, stop_flag)) t_signal_process = threading.Thread(target=signal_process, args=(Qin, source, stop_flag, log, pos_ref, FIX_1BIT_ERRORS)) t_sdr_read.start() t_signal_process.start() # Run the Dash web server app.app.run_server(port=args.port) # Run until the threads stop while threading.active_count() > 0: try: time.sleep(0.1) except: print("Stopping threads...") stop_flag.set() raise exit()
def listen(self, sdr): try: loop = asyncio.get_event_loop() loop.run_until_complete(client.streaming(sdr)) except KeyboardInterrupt: raise SystemExit("Stopped Listening for the Remote Signal!") # Added a Proper Entry Point I Guess if __name__ == "__main__": # Start SDR try: device = 0 # Get a list of detected device serial numbers (str) devices = RtlSdr.get_device_serial_addresses() print("Devices: " + str(devices)) if len(devices) is 0: raise Exception("No Detected RTLSDR Devices!!!") # Find the device index for a given serial number device_index = RtlSdr.get_device_index_by_serial( devices[device] ) # You can insert your Serial Address (as a string) directly here sdr = RtlSdr(device_index) #sdr = RtlSdr() # If you don't have more than 1 device, this will work fine. except OSError: print("Could Not Find RTLSDR!!! Is It Locked???") sys.exit(2) except IndexError: print("Choose a Valid Device ID!!!") sys.exit(2) except Exception as error:
Fs = 2.048e6 Fo = 101.723e6 if len(sys.argv) > 1: print(sys.argv[1]) Fo = float(sys.argv[1] + 'e6') fm = Demodulador(Fs, Fo) output_Fs = fm.outputFs() p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=output_Fs, output=True) sdr = RtlSdr() sdr.sample_rate = Fs # Hz sdr.center_freq = Fo # Hz sdr.freq_correction = 60 # PPM sdr.gain = 'auto' STOP_FLAG = False async def streaming(): elapsed_time = time.time() async for samples in sdr.stream(num_samples_or_bytes=10240000): audio = np.int16(fm.demodular(samples) * 32767) stream.write(audio) if STOP_FLAG: await sdr.stop()
class RTLSdr: def __init__(self, **args): self.logcl = LogCL() self.import_rtlsdr() self.import_pylab() self.set_static_dir() self.set_args(args) self.dev = None self.dev_open = False self.sensivity = 3 self.stop_func = None def set_static_dir(self): full_path = os.path.realpath(__file__) self.static_dir = os.path.split(full_path)[0] + '/static/' def set_args(self, args): try: self.dev_id = int(args['dev']) self.sample_rate = int(args['samprate']) self.gain = args['gain'] self.center_freq = args['freq'] self.num_read = int(args['n']) self.interval = int(args['i']) self.args = args except Exception as e: self.logcl.log("Invalid argument detected.\n" + str(e), 'error') sys.exit() def import_rtlsdr(self): try: self.logcl.log("Importing rtlsdr module...") global RtlSdr from rtlsdr import RtlSdr except: self.logcl.log("rtlsdr module not found.", "error") def import_pylab(self): try: global plt, np, peakutils import pylab as plt import numpy as np import peakutils except Exception as e: if 'peak' in str(e): self.logcl.log("peakutils module not found.\n" + str(e), 'error') else: self.logcl.log("matplotlib module not found.\n" + str(e), 'error') sys.exit() def init_device(self, init_dev=True, show_log=True): try: if show_log: self.logcl.log("Trying to open & initialize device #" + str(self.dev_id)) self.dev = RtlSdr(self.dev_id) self.dev_open = True if init_dev: self.dev.center_freq = self.center_freq self.dev.sample_rate = self.sample_rate self.dev.gain = self.gain except IOError as e: self.dev_open = False if init_dev: self.logcl.log("Failed to open RTL-SDR device!\n" + str(e), 'error') except Exception as e: self.logcl.log("Failed to initialize RTL-SDR device.\n" + str(e), 'fatal') return self.dev_open def read_samples(self, n_read=512*512): try: if not self.dev.device_opened: if not self.stop_func == None: self.dev_open = False self.stop_func() else: return self.dev.read_samples(n_read) except Exception as e: self.logcl.log("Failed to read samples from RTL-SDR.\n" + str(e), 'error') def close(self, show_log=False): try: if show_log: self.logcl.log("Closing RTL-SDR device #" + str(self.dev_id)) if self.dev != None: self.dev.close() self.dev_open = False except Exception as e: self.logcl.log("Failed to close RTL-SDR device.\n" + str(e), 'error') def find_peaks(self, plt, Y, F, n): try: freqs = [] dbs = [] indexes = peakutils.indexes(Y, thres=abs(11-(n))/10, min_dist=20) for index in indexes: freq = F[index] db = 10 * math.log10(Y[index]) freqs.append(freq) dbs.append(db) plt.plot(freq, db, color='k', marker='x', markersize=6, linestyle='None') return [freqs, dbs] except: self.logcl.log("Failed to find peaks on graph.\n" + str(e), 'error') def get_fft_data(self, scan=False): try: [Y, F] = plt.psd(self.read_samples(), NFFT=1024, Fs=int(self.sample_rate)/1e6, \ Fc=int(self.center_freq)/1e6, color='k') if scan: max_freqs = self.find_peaks(plt, Y, F, n=self.sensivity) plt.xlabel('Frequency (MHz)') plt.ylabel('Relative power (dB)') plt.savefig(self.static_dir + '/img/fft.png', bbox_inches='tight', pad_inches = 0) plt.clf() encoded = base64.b64encode(open(self.static_dir + '/img/fft.png', "rb"). \ read()).decode("utf-8") return encoded if not scan else [encoded, max_freqs] except Exception as e: self.logcl.log("Failed to get graph data.\n" + str(e), 'error')