Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
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();
Ejemplo n.º 4
0
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;
Ejemplo n.º 5
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
class FMRadio:

    sample_buffer = Queue.Queue(maxsize=100)
    base_spectrum = np.ones(5780)

    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.is_sampling = False

        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 = 1,
                                    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 2048/44100 amount's time
        return self.sdr.read_samples(self.N_samples)

    def getSamplesAsync(self):
        #Asynchronous call. Meant to be put in a loop w/ a calback fn
        #print 'gonna sample'
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)

    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
              #  print 'gottum'
            except:
                print "wtf idk no samples?"
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)

            self.play(audio_out)

        print 'gonna try to finish off the to-do list'
        sample_buffer.join()


    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))

        #lp_samples = self.lowpass_filter(lp_samples,4)
        power = np.abs(self.rms(lp_samples))
        lp_samples /= power
        #print np.abs(self.rms(lp_samples))

    # polar discriminator
        dphase = np.zeros(lp_samples.size)

        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()


        spectrum = np.fft.fft(rebuilt) #* self.lpf2

        n_z = spectrum.size
        #base_spectrum = np.append(spectrum[0:1024],spectrum[n_z-1024:n_z])
        self.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])

        output = np.fft.ifft(self.base_spectrum)

        output = self.lowpass_filter(np.real(output),8) # just the tip (kills the 19k pilot)

#         toplot = False
#         if(toplot):
#             fig = plt.figure()
#             plt.plot(np.real(output))
#             plt.show()

        return np.real(output)

    def updateimg(self,base_spectrum):
        spectralimg = np.zeros((base_spectrum.size/20,base_spectrum.size/10))
        for i in np.r_[0:base_spectrum.size/10]:
            spectralimg[np.abs(np.fft.fftshift(base_spectrum)[i*10]/10),i] = 1
        cv2.imshow('spectrum',spectralimg)

    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)

# utility functions #

    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 mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # 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):
        streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        streamer.start()
        self.count = 0
        while(1):
            if not self.is_sampling:
                self.getSamplesAsync() # sampler loop
Ejemplo n.º 9
0
def run_gpu_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
    '''
    import cupy as cp
    import cusignal

    # 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(device_index=0)

    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 = cp.zeros(nbins)
        p_xx_tot = cp.zeros(nbins, dtype=complex)
        # Create mapped, pinned memory for zero copy between CPU and GPU
        gpu_iq = cusignal.get_shared_mem(num_samp, dtype=np.complex128)
        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
        for cnt in range(num_loops):
            # Move USB-collected samples off CPU and onto GPU for calc
            gpu_iq[:] = sdr.read_samples(num_samp)

            freqs, p_xx = cusignal.welch(gpu_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))

        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
        # 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. * cp.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 cp.asnumpy(freqs), cp.asnumpy(p_avg_db_hz)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
    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")

#while(1):

#for i in range(5):
while (1):

    values = sdr.read_samples(1024000)
    #Calculate Signal Power
    #SigPower = 20*np.log10(abs(values)/32768)
    SigPower = 10 * np.log10(10 * ((values.real**2) + (values.imag**2)))
    #FFT = np.fft.fft(values)
    #print(FFT)
    #print('\n')
    mean = np.mean(SigPower)
    st_dev = np.std(SigPower)
    dist_mean = abs(SigPower - mean)
    max_dev = 1
    not_outlier = dist_mean < (max_dev * st_dev)
    no_outliers = SigPower[not_outlier]
    Pmax = max(no_outliers)
    floor = -36
    Pmin = min(no_outliers)
Ejemplo n.º 12
0
print args.output_path + '--' + csvfile + '.csv'
sys.stdout.flush()
for x in range(0, 1000000):
	time.sleep(5)
	cent_freq = (int(low_freq) + (x%steps))
	# configure device
	sample_rate = samp_rate
#	sdr.freq_correction = 82
	#freq = 1379.913e6
#	freq = [freq_int*10)+stepsize*x*10 if freq_int*10<(freq_int*10+int(bw)) else cent_freq]
	print 'low_freq,',low_freq
	sdr.sample_rate = sample_rate  # Hz
	sdr.center_freq = cent_freq     # Hz
	sdr.gain = 'auto'
	sampnumber = 8192*2*2*2*2*2*2
	samples2 = sdr.read_samples(sampnumber)
	#ser.write("\x8f\x78" + freq_str + stepsize_str + samples_str)
#	print freq
        time.sleep(1)
	
#print "please wait..."
#print s
       # byte_list = map(ord,t)
	
	bdrate = 2000
	phasesarr=[]
	phases=np.arctan2((samples2.imag),(samples2.real))
	codeword="001001011101010111000000110011101000100110010000111101101100100101000110000110111111011110011100110110100010101000111111001100010111011001101111000010010011011010111001111001000000100001100011"
	interp = sample_rate/bdrate
	print 'interp=',interp
	for qrs in range(0,len(codeword)-1):
Ejemplo n.º 13
0
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()))
Ejemplo n.º 14
0
from rtlsdr import RtlSdr

sdr = RtlSdr()

# configure device
sdr.sample_rate = 240e3  # Hz
sdr.center_freq = 101.7e6     # Hz
sdr.freq_correction = 0   # PPM
sdr.gain = 'auto'

print(sdr.read_samples(512))
Ejemplo n.º 15
0
# Install rtlsdr package from pyrtlsdr
from rtlsdr import RtlSdr
import matplotlib.pyplot as plt
import numpy as np
from plot import opsd

# Initiate RtlSdr
sdr = RtlSdr()

# configure device
sdr.sample_rate = 2.4e6
sdr.center_freq = 102.2e6

# Read samples
samples = sdr.read_samples(1024)

# Close RTLSDR device connection
sdr.close()

print(samples[1:100])
# Number of samples equals the length of samples
sample_length = samples.shape[0]

# Get the powerlevels and the frequencies
PXX, freqs, _ = opsd(samples,
                     nfft=1024,
                     sample_rate=sdr.sample_rate / 1e6,
                     scale_by_freq=True,
                     sides='twosided')
Ejemplo n.º 16
0
from scipy import signal
from commpy import filters
from commpy import impairments
from rtlsdr import RtlSdr

samples_per_symbol = 8
num_samples = 65536 * 8

sdr = RtlSdr()

# configure device
sdr.sample_rate = 1e6  # Hz
sdr.center_freq = 920e6  # Hz
sdr.gain = 'auto'

rx = sdr.read_samples(num_samples)
rx = sdr.read_samples(num_samples)

# Generate root raised cosine
num_taps = 50 * samples_per_symbol + int(samples_per_symbol / 2)
alpha = 0.35
t, h = filters.rrcosfilter(num_taps, alpha, 1, samples_per_symbol)

#FFT of signal
s = rx * np.hamming(len(rx))
S = np.fft.fftshift(np.fft.fft(s))
S_mag = np.abs(S)
f = np.linspace(-0.5, 0.5, len(rx))
plt.figure(0)
plt.plot(f, S_mag, '.-')
plt.show()
Ejemplo n.º 17
0
class Sampler(QtCore.QObject):
    abortStart = QtCore.pyqtSignal()

    def __init__(self, gain, samp_rate, freqs, num_samples, q_in, parent=None):
        super(Sampler, self).__init__(parent)
        self.gain = gain
        self.samp_rate = samp_rate
        self.freqs = freqs
        self.num_samples = num_samples
        self.queue = q_in
        self.offset = 0

        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.samp_rate
        except IOError:
            self.WORKING = False
            print "Failed to initiate device. Please reconnect."

    def sampling(self):
        print 'Starting sampler...'
        while self.WORKING:
            prev = 0
            counter = 0
            gain = self.gain
            num_samples = self.num_samples
            self.BREAK = False
            self.sdr.gain = gain
            start = time.time()
            #print self.sdr.get_gain()
            for i in range(len(self.freqs)):
                if self.BREAK:
                    break
                else:
                    center_freq = self.freqs[i]
                    #print "frequency: " + str(center_freq/1e6) + "MHz"
                    if center_freq != prev:
                        try:
                            self.sdr.set_center_freq(center_freq)
                        except:
                            self.WORKING = False
                            print "Device failure while setting center frequency"
                            break
                        prev = center_freq
                    else:
                        pass

                    #time.sleep(0.01)
                    try:
                        x = self.sdr.read_samples(2048)
                        data = self.sdr.read_samples(num_samples)
                    except:
                        self.WORKING = False
                        print "Device failure while getting samples"
                        break
                    if self.MEASURE:
                        self.offset = np.mean(data)
                    #print data
                    #self.sdr.close()
                    counter += 1
                    self.queue.put([i, center_freq, data])
            print str(counter) + " samples in " + str(time.time() -
                                                      start) + " seconds"
        self.abortStart.emit()

    @QtCore.pyqtSlot(int)
    def changeGain(self, gain):
        self.gain = gain
Ejemplo n.º 18
0
sampsize = 2048
steps = 10

samples = np.empty((steps, sampsize), 'complex')
power = np.zeros((steps, sampsize))
freqstart = 100e6
freqstop = 120e6

#freqstep = (freqstop-freqstart) / steps
#cfreqs = np.linspace(freqstop, freqstart, steps)
cfreqs = np.arange(freqstart, freqstop, 2.048e6)
for a in range(10):
    for i in range(steps):
        sdr.center_freq = cfreqs[i]
        samples[i, :] = sdr.read_samples(sampsize)

    samplesfft = fft(samples, axis=1)
    samplesfft[:, 0:2] = samplesfft[:, 3:5]
    samplesfft[:, -3:-1] = samplesfft[:, -7:-5]
    power = power + np.abs(samplesfft)**2

power = fftshift(power, axes=(1, ))
db = np.ravel(np.log(power))
freq = np.linspace(freqstart - samprate / 2, freqstop + samprate / 2, db.size)
#freq = fftfreq(n, d=timestep)

plt.figure()
#plt.psd(samples[0,:], NFFT=sampsize, Fc=sdr.fc/1e6, Fs=sdr.rs/1e6)
#plt.plot(np.log(np.abs(samplesfft[0,:])))
plt.plot(freq, db)
Ejemplo n.º 19
0
from rtlsdr import RtlSdr

sdr = RtlSdr()

# configure device
sdr.sample_rate = 2.048e6  # Hz
sdr.center_freq = 1039e5  # Hz
sdr.freq_correction = 60  # PPM
sdr.gain = 'auto'

for i in sdr.read_samples(512):
    print(i)
    print(type(i))
Ejemplo n.º 20
0
def testPhysical():
    '''
    Tests the physical execution of commands with 
    the sequencer via serial port
    '''
    from rtlsdr import RtlSdr # for controlling the RTL SDR
    from multiprocessing.pool import ThreadPool # for simultaneous function execution
    import matplotlib.pyplot as plt # for plotting
    import numpy as np # for array math
    from matplotlib.mlab import psd, specgram # for fft
    from scipy import signal # for filtering

    tariUs = 12 # reader data-0 length in us
    freqMHz = 866.3 # reader center frequency
    blfMHz = 0.32 # tag backscatter link frequency
    
    # generate pulses
    reader = Reader(tariUs, blfMHz, 'COM4')

    # init sdr
    sdr = RtlSdr(serial_number='00000001')
    sdr.sample_rate = 2.048e6
    sdr.center_freq = freqMHz*1e6
    sdr.gain = 0
    sdr.read_samples(sdr.sample_rate*0.05) # dummy read

    # get samples asyncronously...
    pool = ThreadPool(processes=1)
    sampling = pool.apply_async(sdr.read_samples, (sdr.sample_rate*0.05,))
    # ...while sending command
    reader.enablePower()

    msg = Query(m=8, trExt=True)
    print('Testing physically with {}'.format(msg))
    reader.sendMsg(msg)

    msg = Query(m=1, trExt=False, q=1)
    print('Testing physically with {}'.format(msg))
    reader.sendMsg(msg)

    msg = QueryRep()
    print('Testing physically with {}'.format(msg))
    reader.sendMsg(msg)

    reader.enablePower(False)
    # block until samples are aquired
    samples = sampling.get()

    # plot
    _, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 10))
    blfStyle = {'linewidth': 1, 'linestyle': 'dashed', 'alpha': 0.6}
    # time domain
    timeSec = np.arange(len(samples))/sdr.sample_rate
    ax1.plot(timeSec, np.abs(samples), linewidth=0.5)
    ax1.set_xlabel('time [s]')
    ax1.set_ylabel('magnitude')
    ax1.set_title('Observed communication with \n'
        'tari: {}us, freq: {}MHz, blf: {}MHz'.format(tariUs, freqMHz, blfMHz))
    ax1.grid()
    
    # frequency domain
    nFFT = 512
    maxHold = False
    if maxHold:
        traces, _, _ = specgram(samples, NFFT=nFFT)
        trace = np.max(traces, axis=1) # max hold over time
    else:
        trace, _ = psd(samples, NFFT=nFFT)
    trace = 20*np.log10(trace) # to dB
    freqsMHz = np.linspace(sdr.center_freq-sdr.sample_rate/2, sdr.center_freq+sdr.sample_rate/2, nFFT)/1e6
    ax2.plot(freqsMHz, trace, linewidth=0.5)
    ax2.set_xlabel('frequency [MHz]')
    ax2.set_ylabel('magnitude [dB]')
    ax2.grid()
    # mark tag response
    ax2.axvline(freqMHz-blfMHz, color='r', **blfStyle)
    ax2.axvline(freqMHz+blfMHz, color='r', label='backscatter frequency', **blfStyle)
    ax2.legend(loc='upper right')

    # spectrogram
    traces, _, _ = specgram(samples)
    traces = np.clip(20*np.log10(traces), -100, -30)
    ax3.imshow(traces, extent=(timeSec[0], timeSec[-1], freqsMHz[0], freqsMHz[-1]), aspect='auto', cmap='jet')
    ax3.axhline(freqMHz-blfMHz, color='w', **blfStyle)
    ax3.axhline(freqMHz+blfMHz, color='w', label='backscatter frequency', **blfStyle)
    ax3.legend(loc='upper right')
    ax3.set_xlabel('time [s]')
    ax3.set_ylabel('frequency [MHz]')

    # try to parse with tag
    tag = Tag()
    edges = tag.samplesToEdges(np.abs(samples), sdr.sample_rate)
    print('Parsed raising edge durations: {}'.format(edges))
    cmds = tag.fromEdges(edges)
    for cmd in cmds:
        print('Parsed edges: {}'.format(cmd.edges))
        print('Parsed bits: {}'.format(cmd.bits))
        print('Parsed message: {}'.format(cmd.message))
        if cmd.blf:
            print('Parsed BLF: {} kHz'.format(int(cmd.blf*1e3)))
        print('Parsed Tari: {} us'.format(cmd.tari))
        ax1.axvline(cmd.start/1e6, color='g')
        ax1.axvline(cmd.end/1e6, color='g')
        txt = str(cmd.bits) if not cmd.message else str(cmd.message)
        txt += '\nTari: {:.1f} us'.format(cmd.tari)
        if cmd.blf:
            txt += ', BLF: {} kHz'.format(int(cmd.blf*1e3))
        ax1.text(cmd.start/1e6, 0.5*np.max(np.abs(samples)), txt, color='g', backgroundcolor='w')
    
    plt.show()
Ejemplo n.º 21
0
    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
pozadi_temp = 0
if pozadi_volba == 'a':
    pozadi_temp = 1
    raw_input("Probehne mereni pozadi, pro pokracovani stiskni ENTER")

while provede_mereni == 1:  # test zda-li se provede dvakrat pro kontrolu pozadi
    fft = np.linspace(
        0, 0, pocet_oken * (int(round(pocet_vzorku * (1 / 1.2))))
    )  # definice velikosti pole pro vyslednou FFT - zde se zapisuje
    for aktualni_okno in range(1, pocet_oken + 1):
        print('Merim')
        time.sleep(0.08)  # bezpecnostni prodleva pro preladeni a ustaleni
        data = sdr.read_samples(pocet_vzorku)
        sdr.center_freq = sdr.center_freq + 1e6
Ejemplo n.º 22
0
class Receiver:
    def __init__(self, frequency, sample_rate, ppm, resolution, num_FFT):

        self.sdr = RtlSdr()

        # configure SDR
        self.sdr.sample_rate = sample_rate
        self.sdr.center_freq = frequency
        # For some reason the SDR doesn't want to set the offset PPM to 0 so we avoid that
        if ppm != 0:
            self.sdr.freq_correction = ppm
        self.sdr.gain = 'auto'

        self.resolution = 2**resolution
        self.num_FFT = num_FFT

    # Reads data from SDR, processes and writes it
    def receive(self):
        print(f'Receiving {self.num_FFT} samples...')
        data_PSD = self.sample()

        # Observed frequency range
        start_freq = self.sdr.center_freq - self.sdr.sample_rate / 2
        stop_freq = self.sdr.center_freq + self.sdr.sample_rate / 2
        freqs = np.linspace(start=start_freq,
                            stop=stop_freq,
                            num=self.resolution)

        # Samples a blank spectrum if the hydrogen line is within the observed frequency range.
        # This will be used for calculating the SNR
        if start_freq < 1420405000 and stop_freq > 1420405000:
            self.sdr.center_freq = self.sdr.center_freq + 3000000
            blank_PSD = self.sample()
            SNR_spectrum, SNR = self.estimate_SNR(data=data_PSD,
                                                  blank=blank_PSD)
            return freqs, SNR_spectrum, SNR
        else:
            return freqs, data_PSD

        # Close the SDR
        self.sdr.close()

    # Returns numpy array with PSD values averaged from "num_FFT" datasets
    def sample(self):
        counter = 0.0
        PSD_summed = (0, ) * self.resolution
        while (counter < self.num_FFT):
            samples = self.sdr.read_samples(self.resolution)

            # Perform FFT and PSD-analysis
            PSD = np.abs(np.fft.fft(samples) / self.sdr.sample_rate)**2
            PSD_log = 10 * np.log10(PSD)
            PSD_summed = tuple(
                map(operator.add, PSD_summed, np.fft.fftshift(PSD_log)))

            counter += 1.0

        averaged_PSD = tuple(sample / counter for sample in PSD_summed)
        return averaged_PSD

    # Calculates SNR from spectrum and H-line SNR
    def estimate_SNR(self, data, blank):
        SNR = np.array(data) - np.array(blank)
        noise_floor = np.mean(SNR[0])
        shifted_SNR = SNR - noise_floor
        H_SNR = max(shifted_SNR)

        return shifted_SNR, round(H_SNR, 5)
Ejemplo n.º 23
0
     if hopCount == 0:
	hopCount = 1

     sampleCount = options.dwell_time*options.samp_rate
	
     p = int(math.log(sampleCount,2) + 1)
	
     sampleCount = pow(2,p)
	
     print "SampleCount ", sampleCount
   
     sdr = RtlSdr()
     sdr.sample_rate = options.samp_rate
     sdr.gain = 4
     sdr.freq_correction = 60

     while True:
         for i in range(0,int(hopCount) - 1):
	     sdr.center_freq = startHz + i*options.samp_rate + offset
	     samples = sdr.read_samples(sampleCount)
	     energy = numpy.linalg.norm(samples)/sampleCount
	     print "Center Freq ", (startHz + i*options.samp_rate + offset)/1e6 , " Mhz", " Energy ", energy


     
    
     


Ejemplo n.º 24
0
def main(argv):

    if (not len(argv)):
        sys.exit("Usage:\n1420_psd.py -i <integration time(s)>")
    try:
        opts, args = getopt.getopt(argv, "hi:", [
            "integrate=",
            "background",
            "do_fsw",
            "doplot",
            "verbose",
            "device_index=",
            "progressbar",
            "freqcorr=",
            "obs_lat=",
            "obs_lon=",
            "altitude=",
            "azimuth=",
            "suffix=",
        ])
    except getopt.GetoptError:
        print('Usage:\n1420_psd.py -i <integration time (s)> (--background)')
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print('Usage:\n1420_psd.py -i <integration time (s)>')
            sys.exit()
        elif opt in ("-i", "--integrate"):
            if arg.isdigit():
                int_time = int(arg)
                if (int_time <= 0):
                    sys.exit(
                        "Integration time must be a positive integer number of seconds"
                    )
            else:
                sys.exit(
                    "Error: argument must be an integer number of seconds")

    opts = dict(opts)
    if '--background' in opts:
        filesuffix = '_background'
    else:
        filesuffix = ""

    if '--suffix' in opts:
        suffix = str(opts['--suffix'])
    else:
        suffix = ""

    if "--doplot" in opts:
        doplot = True
    else:
        doplot = False

    if "--verbose" in opts:
        verbose = True
    else:
        verbose = False

    if "--progressbar" in opts:
        progressbar = tqdm.tqdm
    else:
        progressbar = lambda x: x

    if "--do_fsw" in opts:
        do_fsw = True
        try:
            velthrow = int(opts['--do_fsw']) * u.km / u.s
        except:
            velthrow = 50 * u.km / u.s
    else:
        do_fsw = False

    if '--device_index' in opts:
        device_index = int(opts['--device_index'])
        if verbose:
            print(f"Using device index {device_index}")
    else:
        device_index = 0

    if '--freqcorr' in opts:
        freqcorr = int(opts['--freqcorr'])
    else:
        freqcorr = None

    if verbose:
        print(opts)

    import time
    t0 = time.time()

    # initialize SDR
    sdr = RtlSdr(device_index=device_index)

    if do_fsw:
        freqthrow = ((velthrow / constants.c) * hi_restfreq).to(u.Hz).value
        if verbose:
            print(f"velthrow={velthrow}, freqthrow={freqthrow}")

    sdr.sample_rate = 2.4e6
    # center frequency in Hertz
    sdr.center_freq = hi_restfreq.to(u.Hz).value
    # max gain is ~50?
    sdr.gain = 50

    if freqcorr is not None:
        if verbose:
            print(f"setting freqcorr={freqcorr}")
        sdr.set_freq_correction(freqcorr)

    numsamples = 2048
    passes = int(int_time * sdr.rs / numsamples)

    if do_fsw:
        nfsw = 4
        #fsw_time = int_time / nfsw

    #chanwidth = sdr.rs / numsamples
    #chanwidth_kms = (chanwidth / sdr.center_freq) * constants.c.to(u.km/u.s).value

    if verbose:
        print(
            f"Center freq: {sdr.fc}  readsize: {sdr.fc}  numsamples: {numsamples} passes: {passes}  do_fsw={do_fsw}"
        )

    # collect data

    if do_fsw:
        power = {1: [], -1: []}
        frequency = {}
        sign = 1
    else:
        power = []

    if verbose:
        print('Warning: expect execution to take 4-5x your integration time')
        print('Collecting Data...')

    time.sleep(
        0.05
    )  # try to prevent 'pll not locked' errors by adding inter-operation delays

    if do_fsw:
        for fsw_id in progressbar(range(nfsw)):
            cfreq_target = hi_restfreq.to(u.Hz).value + freqthrow * sign
            if verbose:
                print(f"For fswd_id={fsw_id}, cfreq={cfreq_target}")

            sdr.center_freq = cfreq_target
            if verbose:
                print(f"Set center_freq={sdr.center_freq}")
            time.sleep(
                0.01
            )  # try to prevent 'pll not locked' errors by adding inter-operation delays
            sign = sign * -1

            frq = np.fft.fftfreq(numsamples)
            idx = np.argsort(frq)
            frequency[sign] = sdr.fc + sdr.rs * frq[idx]

            for ii in range(passes // nfsw):
                samples = sdr.read_samples(numsamples)

                ps = np.abs(np.fft.fft(samples))**2

                ps[0] = np.mean(ps)

                n = len(samples)
                power[sign].append(ps[idx] / n)
    else:
        frq = np.fft.fftfreq(numsamples)
        idx = np.argsort(frq)
        frequency = sdr.fc + sdr.rs * frq[idx]
        for ii in progressbar(range(passes)):
            samples = sdr.read_samples(numsamples)

            ps = np.abs(np.fft.fft(samples))**2

            ps[0] = np.mean(ps)

            n = len(samples)
            power.append(ps[idx] / n)

    if verbose:
        print(f"sampling time = {time.time()-t0} for tint={int_time}")

    if do_fsw:
        avgpower = {
            key: np.array(pow).mean(axis=0)
            for key, pow in power.items()
        }

        # fsw = low-frequency minus high frequency
        fsw = avgpower[-1] - avgpower[1]

        # radio velocity = (nu_0 - nu) / nu_0
        rvel1 = (constants.c * (
            (hi_restfreq - u.Quantity(frequency[-1], u.Hz)) / hi_restfreq)).to(
                u.km / u.s).value
        rvel2 = (constants.c * (
            (hi_restfreq - u.Quantity(frequency[1], u.Hz)) / hi_restfreq)).to(
                u.km / u.s).value
        rvel = rvel1
    else:
        avgpower = np.array(power).mean(axis=0)
        rvel = (constants.c * (
            (hi_restfreq - u.Quantity(frequency, u.Hz)) / hi_restfreq)).to(
                u.km / u.s).value

    now = str(datetime.datetime.now().strftime("%y%m%d_%H%M%S"))

    if doplot:
        fig, ax = plt.subplots(figsize=(14, 6))
        if do_fsw:
            ax.plot(
                rvel,
                10 * np.log10(fsw),
            )
        else:
            ax.plot(
                rvel,
                10 * np.log10(avgpower),
            )
        ax.tick_params(labelsize=6)
        ax.get_xaxis().get_major_formatter().set_useOffset(False)
        ax.set_xlabel('Relative Velocity (km/s)')
        ax.set_ylabel('Measured Power (dB)')
        try:
            fig.savefig('psd_' + now + '.pdf')
        except:
            print("FAILED savefig")

    # write csv

    if do_fsw:
        filename = f"psd_{now}_tint{int_time}s_sdr{device_index}_fsw{filesuffix}{suffix}.fits"

        dat = {
            'freq1': frequency[-1],
            'freq2': frequency[1],
            'power1': avgpower[-1],
            'power2': avgpower[1],
            'fsw_rvel1': rvel1,
            'fsw_rvel2': rvel2,
            'fsw_pow': fsw
        }
    else:
        filename = f"psd_{now}_tint{int_time}s_sdr{device_index}{filesuffix}{suffix}.fits"

        dat = {'freq': frequency, 'rvel': frequency, 'power': avgpower}
    tbl = Table(dat)

    if verbose:
        print(filename)

    for key in ('obs_lat', 'obs_lon', 'altitude', 'azimuth'):
        if f'--{key}' in opts:
            tbl.meta[f'--{key}'] = opts[f'--{key}']

    tbl.meta['device'] = str(device_index)
    tbl.meta['tint'] = int_time
    tbl.meta['suffix'] = suffix
    tbl.meta['is_bg'] = filesuffix
    tbl.meta['date-obs'] = now
    tbl.write(filename)

    if verbose:
        print(f"total time = {time.time()-t0} for tint={int_time}")

    return filename
Ejemplo n.º 25
0
            sat_name = sorted_sats[0][0]
            sat = sorted_sats[0][1]
            tles = active_orbcomm_satellites[sat_name]['tles']

            print("Receiving from: {}".format(sat_name))
            frequencies = active_orbcomm_satellites[sorted_sats[0][0]]['frequencies']
            print("Satellite frequencies: {}".format(frequencies))
            # Decode the lower of the two channels
            sat_center_frequency = frequencies[0]
            center_freq = sat_center_frequency   # we will change this later.
            sdr.fc = center_freq


            print('Recording samples.')
            # Record samples twice just to fill up buffers (not sure if needed)
            samples = sdr.read_samples(num_samples_per_recording)
            samples = sdr.read_samples(num_samples_per_recording)

            context_dict = {
                            'sdr':sdr,
                            'observer':obs,
                            'sat':sat,
                            'sat_name':sat_name,
                            'tles':[tles],
                            'fs': sample_rate/decimation,
                            'fc': center_freq,
                            }
            sdr.read_samples_async(rtlsdr_callback, num_samples_per_recording, context_dict)

            if should_finish:
                break
Ejemplo n.º 26
0
    mag_file.write('%s]\n' % magnitude[i])
    freq_file.write('%s]\n' % frequency[i])
    return;

sdr = RtlSdr()
# np.set_printoptions(threshold=np.inf)

# configure device
sdr.sample_rate = 2.4e6      # Hz
sdr.center_freq = 95.1e6       # Hz
sdr.freq_correction = 60  # PPM
sdr.gain = 4 # 'auto'

# extract data
data_points = 1024
data = sdr.read_samples(256*data_points)

# initialize
samples = sdr.read_samples(256*data_points)
mag_file_path = '/home/pi/magtest.txt'
freq_file_path = '/home/pi/freqtest.txt'

sdr.close()

# PSD plot
psddata = psd(samples, NFFT=data_points, Fs=sdr.sample_rate/1e6, Fc=sdr.center_freq/1e6)
#xlabel('Frequency (MHz)')
#ylabel('Relative power (dB)')
#show()

magnitude = psddata[0]
Ejemplo n.º 27
0
class Single(threading.Thread):
    def __init__(self, opts, system_mods, settings):
        self.stoprequest = threading.Event()
        threading.Thread.__init__(self)

        self.connector = system_mods['connector']
        devmod = system_mods['devices']

        self.freq = opts['freq']
        self.thresh = opts['thresh']

        self.devid = opts['devid']
        self.gain = devmod.get_rtlsdr_gain(self.devid)
        self.ppm = devmod.get_rtlsdr_ppm(self.devid)
        self.sysdevid = devmod.get_sysdevid(self.devid)

        self.settings = settings

    def run(self):
        try:
            self.sdr = RtlSdr(self.sysdevid)
            self.sdr.sample_rate = Fs
            self.sdr.center_freq = self.freq
            self.sdr.gain = self.gain
            self.sdr.ppm = self.ppm
        except:
            gammarf_util.console_message("error initializing device", MOD_NAME)
            devmod.freedev(self.devid)
            self.sdr.close()
            return

        data = {}
        data['module'] = MODULE_SINGLE
        data['protocol'] = PROTOCOL_VERSION

        self.lpf = signal.remez(LPF_TAPS,
                                [0, F_BW, F_BW + (Fs / 2 - F_BW) / 4, Fs / 2],
                                [1, 0],
                                Hz=Fs)

        while not self.stoprequest.isSet():
            x1 = self.sdr.read_samples(N)
            x3 = signal.lfilter(self.lpf, 1.0, x1)

            pwr = (10 * np.log10(np.mean(np.absolute(x3))))
            if pwr > self.thresh:
                if self.settings['print_all']:
                    gammarf_util.console_message(
                        "hit on {}: {}".format(self.freq, pwr), MOD_NAME)

                data['freq'] = self.freq
                data['thresh'] = self.thresh
                data['pwr'] = pwr
                self.connector.senddat(data)

        try:
            self.sdr.close()
        except:
            gammarf_util.console_message("error closing device", MOD_NAME)
            self.devmod.removedev(self.devid)

        return

    def join(self, timeout=None):
        self.stoprequest.set()
        super(Single, self).join(timeout)
Ejemplo n.º 28
0
from matplotlib import pylab
from pylab import psd, xlabel, ylabel, show
from rtlsdr import RtlSdr

sdr = RtlSdr()

# configure device
sdr.sample_rate = 2.4e6
sdr.center_freq = 1039e5
sdr.gain = 4

samples = sdr.read_samples(256 * 1024)

# use matplotlib to estimate and plot the PSD
psd(samples, NFFT=1024, Fs=sdr.sample_rate / 1e6, Fc=sdr.center_freq / 1e6)
xlabel('Frequency (MHz)')
ylabel('Relative power (dB)')

show()
Ejemplo n.º 29
0
import numpy as np

powe = np.ndarray(0)
freq = np.ndarray(0)

SAMPLERATE = 2.4e6  # Hz

for i in np.arange(50, 1000, SAMPLERATE / 1e6):
    sdr = RtlSdr()

    # configure device
    sdr.sample_rate = SAMPLERATE
    sdr.center_freq = i * 1e6  # Hz
    sdr.freq_correction = 60  # PPM
    sdr.gain = 'auto'  # 4
    samples = sdr.read_samples(8 * 1024)
    sdr.close()
    sdr = None
    # use matplotlib to estimate and plot the PSD
    power, psd_freq = mlab.psd(samples, NFFT=1024, Fs=SAMPLERATE / 1e6)
    psd_freq = psd_freq + i
    powe = np.concatenate((powe, np.array(power)))
    freq = np.concatenate((freq, np.array(psd_freq)))
    print(f"{i}/1000")

plt.semilogy(freq, powe)

plt.xlabel('Frequency (MHz)')
plt.ylabel('Relative power (dB)')
plt.show()
Ejemplo n.º 30
0
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
Ejemplo n.º 31
0
class FMRadio(QtGui.QMainWindow,Ui_MainWindow):
    sample_buffer = Queue.Queue(maxsize=10)
    base_spectrum = np.ones(5780)

    plotOverall = True
    plotChannel = False
    plotPlaying = False
    plotWaveform = False
    useStereo = False
    stereoWidth = 10
    useMedianFilt = True
    useLPFilt = False
    demodFiltSize = 11
    useAudioFilter = True
    audioFilterSize = 16
    toDraw = True
    demodMain = True
    demodSub1 = False
    demodSub2 = False
    toDrawWaterfalls = True
    toDrawPlots = False

    prevCutoff = 0

    toPlot = (np.cumsum(np.ones(5780)),np.cumsum(np.ones(5780)))

    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 createQtConnections(self):
        QtCore.QObject.connect(self.ui.freqSelect, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.setFreq)
        QtCore.QObject.connect(self.ui.checkBox, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.setUseStereo)
        QtCore.QObject.connect(self.ui.mainchannel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodMain)
        QtCore.QObject.connect(self.ui.subband1, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub1)
        QtCore.QObject.connect(self.ui.subband2, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub2)
        QtCore.QObject.connect(self.ui.stereoWidthSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setStereoWidth)
        QtCore.QObject.connect(self.ui.spectrum_overall, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumOverall)
        QtCore.QObject.connect(self.ui.spectrum_channel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumChannel)
        QtCore.QObject.connect(self.ui.spectrum_playing, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumPlaying)
        QtCore.QObject.connect(self.ui.spectrum_waveform, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumWaveform)
        QtCore.QObject.connect(self.ui.demodFiltMedian, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltMedian)
        QtCore.QObject.connect(self.ui.demodFiltLP, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltLP)
        QtCore.QObject.connect(self.ui.demodFilterSize, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setDemodFiltSize)
        QtCore.QObject.connect(self.ui.audioFilterActive, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setAudioFiltUse)
        QtCore.QObject.connect(self.ui.audioFilterSizeSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setAudioFiltSize)
        QtCore.QObject.connect(self.ui.exitButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.terminate)
        QtCore.QObject.connect(self.ui.drawPlot, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawSpec)
        QtCore.QObject.connect(self.ui.waterfallButton, QtCore.SIGNAL(_fromUtf8('toggled(bool)')), self.setDrawWaterfalls)
      #  QtCore.QObject.connect(self.ui.plotButton, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawPlot)

        self.bindPlot()


    def bindPlot(self):
        self.dpi = 100
        self.fig = Figure((4.31,2.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.ui.plotFrame)

        self.initplot()

        #self.anim = animation.FuncAnimation(self.fig,self.replot,interval=2000,blit=False)
        #self.canvas.mpl_connect('click_event',self.on_click_plot)


#         self.curve = QwtPlotCurve("Frequencies")
#         self.curve.setData(self.toPlot[0],self.toPlot[1]) #np.r_[-5e5:5e5:1e6/self.toPlot.size],np.abs(self.toPlot))
#         self.curve.attach(self.ui.spectrumPlot)
#         self.ui.spectrumPlot.replot()
#         #threading.Timer(1,self.replot).start()

    def initplot(self):
        self.axes = self.fig.add_subplot(111, aspect=200/431)
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        #self.axes.invert_yaxis()

    def replot(self):
       self.axes.clear()
       #self.axes.set_s
       self.axes.plot(self.toPlot[0],self.toPlot[1])
       self.axes.set_aspect('auto',anchor='C')
       self.canvas.draw()

    def setDrawSpec(self,s):
        self.toDraw = s

    def drawSpectrum(self):
        self.axes.clear()
        self.axes.imshow(self.spectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawChspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.chspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawPlspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.plspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def setDrawPlots(self,s):
        self.toDrawPlots = s
        self.toDrawWaterfalls = not s

    def setDrawWaterfalls(self,s):
        self.toDrawWaterfalls = s
        self.toDrawPlots = not s

    def setFreq(self,freq):
        freq /= 10.0
        text = "%.1f MHz" % freq
        self.ui.curFreq.setText(text)
        self.center_freq = freq*1e6 #+ 250e3
        setf_t = threading.Thread(target=self.setF_th, args=[self.center_freq,])
        setf_t.start()
        setf_t.join()

    def setF_th(self,f):
        while(self.is_sampling == True):
            pass
        self.sdr.center_freq = f

    def setUseStereo(self,u):
        self.useStereo = u
    def setStereoWidth(self,w):
        self.stereoWidth = np.sqrt(10*w)

    def setDemodMain(self,s):
        self.demodMain = s
        self.demodSub1 = not s
        self.demodSub2 = not s
        #self.useStereo = True
    def setDemodSub1(self,s):
        self.demodMain = not s
        self.demodSub1 = s
        self.demodSub2 = not s
        #self.useStereo = False
    def setDemodSub2(self,s):
        self.demodMain = not s
        self.demodSub1 = not s
        self.demodSub2 = s
        #self.useStereo = False

    def setSpectrumOverall(self,s):
        #self.initplot()
        self.plotOverall = s
        self.plotChannel = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumChannel(self,s):
        #self.initplot()
        self.plotChannel = s
        self.plotOverall = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumPlaying(self,s):
        #self.initplot()
        self.plotPlaying = s
        self.plotChannel = not s
        self.plotOverall= not s
        self.plotWaveform = not s
    def setSpectrumWaveform(self,s):
        self.plotWaveform = s
        self.plotPlaying = not s
        self.plotChannel = not s
        self.plotOverall= not s

    def setDemodFiltMedian(self,s):
        self.useMedianFilt = s
        self.useLPFilt = not s
    def setDemodFiltLP(self,s):
        self.useLPFilt = s
        self.useMedianFilt = not s
    def setDemodFiltSize(self,s):
        if(s % 2 == 0):
            s+=1
        self.demodFiltSize = s

    def setAudioFiltUse(self,s):
        self.useAudioFilter = s
    def setAudioFiltSize(self,s):
        self.audioFilterSize = s

    def terminate(self):
        self.__del__()

    def __del__(self):
        #QtGui.QMainWindow.__del__()
        #Ui_MainWindow.__del__()
        #self.streamer.stop()
        #self.sampler_t.stop()
        print "sdr closed"
        self.sdr.close()
        print "pyaudio terminated"
        self.pa.terminate()
        sys.exit()

    def getSamples(self):
        #N_samples = self.N_samples # 1/24.4 seconds   ~46336 #approximately a 2048/44100 amount's time
        return self.sdr.read_samples(self.N_samples)

    def getSamplesAsync(self):
        #Asynchronous call. Meant to be put in a loop w/ a calback fn
        #print 'gonna sample'
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)

    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
              #  print 'gottum'
            except:
                print "wtf idk no samples?"
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)

            self.play(audio_out)

        print 'gonna try to finish off the to-do list'
        sample_buffer.join()


    def demodulate(self,samples):
        # DEMODULATION CODE
        #samples = #self.sample_buffer.get()
        # LIMITER goes here

        # low pass & down sampling via fft


        spectrum = np.fft.fftshift(np.fft.fft(samples))

        self.spectrogram = np.roll(self.spectrogram, 1,axis=1)
        self.spectrogram[:,0] = np.log(np.abs(spectrum[::100]))


        if(self.toDraw and self.plotOverall and self.count % 10 == 9):

#             self.toPlot = (np.linspace(-5e5,5e5,spectrum.size),np.abs(spectrum))
#             self.replot()
            self.drawSpectrum()

        self.count += 1



            #fig = plt.figure()
            #plt.plot(np.abs(spectrum))
            #plt.show()
#
#         spectrum *= self.lpf
# # 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 #.25*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

# #             fig = plt.figure()
# #             plt.plot(np.abs(np.fft.ifftshift(channel_spectrum)))
# #             plt.show()
#             #self.fig.plot(np.fft.ifftshift(channel_spectrum))
#
#
#         lp_samples = np.fft.ifft(np.fft.ifftshift(channel_spectrum))
#
        lp_samples = samples



      #  lp_samples /= power


    # polar discriminator



        dphase = np.zeros(lp_samples.size, dtype='complex')

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase[1:] = ( A * np.conj(B) )

        dphase[0] = lp_samples[0] * np.conj(self.prevCutoff) #dphase[dphase.size-2]
        self.prevCutoff = lp_samples[lp_samples.size-1]

#         if self.useMedianFilt:
#             rebuilt = signal.medfilt(np.angle(dphase)/np.pi,self.demodFiltSize) #  np.cos(dphase)
#         else:
#             rebuilt = self.lowpass(np.angle(dphase),self.demodFiltSize)
        rebuilt = np.angle(dphase) / np.pi
#         toplot = False
#         if toplot:
#             fig = plt.figure()
#             ax = fig.add_subplot(111)
#             ax.plot(rebuilt)

        power = np.abs(self.mad(lp_samples))
        self.ui.signalMeter.setValue(20*(np.log10(power)))

        demodMain = False
        demodSub1 = False
        demodSub2 = False
        if self.demodMain:
            demodMain = True

           # lp_samples = samples
        elif self.demodSub1:
            demodSub1 = True

            #lp_samples = samples * np.exp(-1j*2*np.pi*67650/2.4e5*np.r_[0:samples.size])
        elif self.demodSub2:
            demodSub2 = True
            #lp_samples = samples * np.exp(-1j*2*np.pi*92000/2.4e5*np.r_[0:samples.size])


        spectrum = np.fft.fft(rebuilt)


         #toplot = self.plotChannel
        self.chspectrogram = np.roll(self.chspectrogram, 1,axis=1)
        self.chspectrogram[:,0] = np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:50]))
        if(self.toDraw and self.plotChannel and self.count % 10 == 9):
            self.drawChspectrum()
             #plotspectrum = np.abs(channel_spectrum[::100])
             #self.toPlot = (np.linspace(-np.pi,np.pi,plotspectrum.size),plotspectrum)
             #self.replot()


        isStereo = False
        #demodSub1 = False
        #demodSub2 = False
        n_z = rebuilt.size
        if demodMain:

            #stereo_spectrum = spectrum
            if self.useStereo:
                isStereo = True
                #modulated = rebuilt * np.exp(-2j*np.pi*38000/2.4e5*np.r_[0:rebuilt.size])
                #h = signal.firwin(128,22000,nyq=1.2e5)
                #lp_mod = signal.fftconvolve(modulated,h,mode='same')
                #decim = lp_mod[::self.decim_r2]
                #dphase = np.zeros(decim.size, dtype='complex')
#
#                A = decim[1:decim.size]
#                B = decim[0:decim.size-1]
#
#                dphase[1:] = np.angle( A * np.conj(B) )
                #h = signal.firwin(128,22000,nyq=24000)

                #diff = dphase# [::self.decim_r2]
                mod_spectrum = np.roll(spectrum,int(.5*n_z*38000/120000))
                mod_spectrum += np.roll(spectrum,int(-.5*n_z*38000/120000)) #np.fft.fft(modulated)
                mod_spectrum *= self.lpf #np.fft.ifftshift(np.hamming(stereo_spectrum.size))
                stereo_spectrum = np.append(mod_spectrum[0:np.ceil(n_z/self.decim_r2*.5)],mod_spectrum[n_z-np.ceil(n_z/self.decim_r2*.5):n_z])
                diff = np.fft.ifft(stereo_spectrum)
            #self.base_spectrum = np.append(spectrum[0:int(n_z/self.decim_r2*.5)],spectrum[n_z-int(n_z/self.decim_r2*.5):n_z])
            #output = np.fft.ifft(self.base_spectrum)
            h = signal.firwin(128,16000,nyq=1.2e5)
            output = signal.fftconvolve(rebuilt,h,mode='same')
            output = rebuilt[::self.decim_r2]
#             h = signal.firwin(128,16000,nyq=2.4e4)
#             output = signal.fftconvolve(output,h,mode='same')
        elif demodSub1:

            demod = rebuilt * np.exp(-2j*np.pi*67650/2.4e5*np.r_[0:rebuilt.size])
         #   spectrum = np.fft.fft(demod)*self.lpf_s1
            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]
        #    base_spectrum = np.append(spectrum[0:int(.5*n_z*7500/2.4e5)],spectrum[n_z-int(.5*n_z*7500/2.4e5):n_z])
        #    decim = np.fft.ifft(base_spectrum)

            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.angle( A * np.conj(B) )
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

            #retoutput)

        elif demodSub2:
            demod = rebuilt * np.exp(-2j*np.pi*92000/2.4e5*np.r_[0:rebuilt.size])
          #  spectrum = np.fft.fft(demod)*self.lpf_s2
            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]
          #  base_spectrum = np.append(spectrum[0:int(.5*n_z*7500/2.4e5)],spectrum[n_z-int(.5*n_z*7500/2.4e5):n_z])
          #  decim = np.fft.ifft(base_spectrum)

            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.angle( A * np.conj(B) )
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

            #return np.real(output)

        output -= np.mean(output)

        stereo = np.zeros(output.size*2, dtype='complex')
        if (isStereo):
            #diff = np.fft.ifft(stereo_spectrum)
            w = self.stereoWidth  # adjust to change stereo wideness
         #print w
            left = output + w/10 * diff
            right = output - w/10 * diff

            if(self.useAudioFilter):
                left = self.lowpass(left,self.audioFilterSize)
                right = self.lowpass(right,self.audioFilterSize)

            stereo[0:stereo.size:2] = left
            stereo[1:stereo.size:2] = right
        else:
            if self.useAudioFilter:
                output = self.lowpass(output,self.audioFilterSize) # just the tip (kills the 19k pilot)
            stereo[0:stereo.size:2] = output
            stereo[1:stereo.size:2] = output


        spectrum = np.fft.fft(stereo[::2])
        self.plspectrogram = np.roll(self.plspectrogram, 1,axis=1)
        self.plspectrogram[:,0] = np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:20]))
        if(self.toDraw and self.plotPlaying): # and self.count % 2 == 0):
            if self.toDrawWaterfalls:
                self.drawPlspectrum()
            else:
                sm = np.abs(np.fft.fftshift(spectrum[::20]))
                self.toPlot = (np.linspace(-2.4e4,2.4e4,sm.size),sm)
                self.replot()


        if(self.toDraw and self.plotWaveform):
            sm = np.real(stereo[::20])
            self.toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
            self.replot()


        return np.real(stereo)


#     def updateimg(self,base_spectrum):
#         spectralimg = np.zeros((base_spectrum.size/20,base_spectrum.size/10))
#         for i in np.r_[0:base_spectrum.size/10]:
#             spectralimg[np.abs(np.fft.fftshift(base_spectrum)[i*10]/10),i] = 1
#         cv2.imshow('spectrum',spectralimg)

    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(.5*output)

# utility functions #

    def lowpass(self,x,width):
        #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi
        #wndw = np.kaiser(width,6)
        wndw = signal.firwin(16,width*990,nyq=24000)
        #wndw /= np.sum(wndw)
        new_array = signal.fftconvolve(x, wndw, mode='same')

        return new_array

    # calculate mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # 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):
        self.streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        self.streamer.start()
        self.count = 0
        self.sampler_t = threading.Thread(target=self.getSamplesAsync) # sampler loop
        self.sampler_t.start()
Ejemplo n.º 32
0
#echos rtlsdr read_samples output (without lines starting with hyphen) to console and to ~/finaldata.txt
import os
from rtlsdr import RtlSdr

os.chdir(os.path.expanduser("~/"))
sdr = RtlSdr()

sdr.sample_rate = 2.048e6 #Hz
sdr.center_freq = 70e6 # Hz
sdr.freq_correction = 60 # PPM
sdr.gain = 'auto'

sdroutput = str(sdr.read_samples(512))
savefile = open('finaldata.txt', 'w')
sdr1 = sdroutput.translate(None, '[]').split()
sdr2 = sdr1
finaldata = ''
for line in sdr2:
    if not "-" in line:
        finaldata+=line+"\n"

print finaldata
savefile.write(finaldata)
savefile.close()
Ejemplo n.º 33
0
sdr = RtlSdr()

#config
sdr.samle_rate = 2.048e6
sdr.center_freq = 433888000
#sdr.freq_correction = 60
sdr.gain = 'auto'

#print(sdr.read_samples(512))

burst = 0
burst_time = 0
overall_avg = 20

while True:
	samples = sdr.read_samples(512*2);
	#run an FFT and take absolute value to get freq magnitudes
	freqs = np.absolute(np.fft.fft(samples))
	#ignore the mean/DC values at ends
	freqs = freqs[1:-1]
	#Shift FFT result positions to put center frequency in center
	freqs = np.fft.fftshift(freqs)
	#convert to decibels
	freqs = 20.0*np.log10(freqs)

	mean = np.mean(freqs)
	min = np.min(freqs)
	max = np.max(freqs)
	diff = max - mean
	percent_diff = overall_avg/max
Ejemplo n.º 34
0
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.")
sdr2 = RtlSdr(device_index1)
sdr2.sample_rate = 1e6
sdr2.center_freq = 434 * 1e6
sdr2.gain = 1

#--------------------------- use github

N = 1  # times of sample PSD values
#raw_data=zeros((N,1024))

while 1:

    for ii in range(0, N):

        #start = time.time()
        samples1 = sdr1.read_samples(56 * 1024)  #256
        #sensingtime1 = (time.time() - start)
        #print('time for read_sample:',sensingtime1)

        # use matplotlib to estimate and plot the PSD
        plt.figure(1)
        #start = time.time()
        plt.cla()
        #p_density, fre = plt.psd(samples1, NFFT=1024, Fs=sdr1.sample_rate, Fc=sdr1.center_freq) # get psd using github package

        #print(np.max(20*np.log(p_density)))

        p_density, fre = selfpsd(
            samples1, NFFT=1024, Fs=sdr1.sample_rate,
            Fc=sdr1.center_freq)  # get psd using own function
        re_pow1, new_psd1, f_new1 = received_power2(p_density, fre, 1, 128)
Ejemplo n.º 36
0
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')
Ejemplo n.º 37
0
from azure.servicebus import ServiceBusService
from rtlsdr import RtlSdr

sdr = RtlSdr()

# sdr
sdr.sample_rate = 2.4e6
sdr.center_freq = 105e6
#sdr.freq_correction = 60
#sdr.gain = 'auto'
sdr.gain = 4

# Azure
key_name = 'RootManageSharedAccessKey'
key_value = 'QIru9DStoatRrRFmQ6Sq6RfyBpe88TQyJUAemsrQzgk='
service_namespace = 'joksdr'

fft = 1024
s = 10
i = 0
samples = sdr.read_samples(s * fft)
sdr.close()
del (sdr)

sbs = ServiceBusService(service_namespace,
                        shared_access_key_name=key_name,
                        shared_access_key_value=key_value)
while (i < (s * fft)):
    sbs.send_event('sdr', '{"signalval": "' + str(samples[i]) + '"}')
    i = i + 1
Ejemplo n.º 38
0
    def run(self):
        logging.debug("PulseDetector.run")
        try:
            sdr = RtlSdr()
            sdr.rs = 2.4e6
            sdr.fc = 146e6
            sdr.gain = 10
        except Exception as e:
            logging.exception("SDR init failed")
            return

        last_max_mag = 0
        leadingEdge = False
        rgPulse = []
        lastPulseTime = time.time()
        #timeoutCount = 0
        pulseCount = 0

        while True:
            # Handle change in frequency
            try:
                newFrequency = self.setFreqQueue.get_nowait()
            except Exception as e:
                pass
            else:
                logging.debug("Changing frequency %d", newFrequency)
                sdr.fc = newFrequency

            # Handle change in gain
            try:
                newGain = self.setGainQueue.get_nowait()
            except Exception as e:
                pass
            else:
                sdr.gain = newGain
                logging.debug("Changing gain %d:%f", newGain, sdr.gain)

            # Adjust noise threshold
            sdrReopen = False
            #noiseThreshold = self.calcNoiseThreshold(self.amp, sdr.gain)
            #logging.debug("Noise threshold %f", noiseThreshold)

            # Read samples
            try:
                samples = sdr.read_samples(NUM_SAMPLES_PER_SCAN)
            except Exception as e:
                logging.exception("SDR read failed")
                sdrReopen = True
            if sdrReopen:
                logging.debug("Attempting reopen")
                try:
                    sdr.open()
                except Exception as e:
                    logging.exception("SDR reopen failed")
                    return
                try:
                    samples = sdr.read_samples(NUM_SAMPLES_PER_SCAN)
                except Exception as e:
                    logging.exception("SDR read failed")
                    return

            # Process samples
            mag, freqs = magnitude_spectrum(samples, Fs=sdr.rs)
            if not leadingEdge:
                # Detect leading edge
                strength = self.detectedPulseStrength(mag)
                if strength:
                    leadingEdge = True
                    #logging.debug("leading edge strength:background %d %d", strength, self.backgroundNoise)
                    rgPulse = [strength]
            else:
                # Detect trailing edge falling below background noise
                strength = self.detectedPulseStrength(mag)
                if strength:
                    rgPulse.append(strength)
                else:
                    leadingEdge = False
                    pulseCaptureCount = len(rgPulse)
                    self.adjustBackgroundNoise(strength)
                    if pulseCaptureCount >= self.minPulseCaptureCount:
                        pulseStrength = max(rgPulse)
                        pulseCount += 1
                        logging.debug(
                            "***** %d %d %d pulseStrength:len(rgPulse):background",
                            pulseStrength, pulseCaptureCount,
                            self.backgroundNoise)
                        if self.pulseQueue:
                            self.pulseQueue.put(pulseStrength)
                        lastPulseTime = time.time()
                    else:
                        logging.debug("pulse too short %d", pulseCaptureCount)
                        for skippedStrength in rgPulse:
                            self.adjustBackgroundNoise(skippedStrength)
                    rgPulse = []

            # Check for no pulse
            if time.time() - lastPulseTime > 3:
                #timeoutCount += 1
                if leadingEdge:
                    leadingEdge = False
                    logging.error(
                        "failed to detect trailing edge - len(rgPulse):background %d %d",
                        len(rgPulse), self.backgroundNoise)
                else:
                    logging.debug("no pulse for two seconds - background %d",
                                  self.backgroundNoise)
                    if self.pulseQueue:
                        self.pulseQueue.put(0)
                rgPulse = []
                lastPulseTime = time.time()
        sdr.close()
Ejemplo n.º 39
0
class Input(DataSource.DataSource):
    def __init__(self, source: str, data_type: str, sample_rate: float,
                 centre_frequency: float, input_bw: float):
        """
        The rtlsdr input source

        :param source: The device number, normally zero
        :param data_type: The data type the rtlsdr is providing, we will convert this
        :param sample_rate: The sample rate we will set the source to, note true sps is set from the device
        :param centre_frequency: The centre frequency the source will be set to
        :param input_bw: The filtering of the input, may not be configurable
        """
        # Driver converts to floating point for us, underlying is 8o?
        self._constant_data_type = "16tle"
        super().__init__(source, self._constant_data_type, sample_rate,
                         centre_frequency, input_bw)
        self._connected = False
        self._sdr = None
        self._tuner_type = 0
        self._device_index = 0
        self._gain_modes = ["auto", "manual"]  # would ask, but can't
        super().set_gain_mode(self._gain_modes[0])
        super().set_help(help_string)
        super().set_web_help(web_help_string)

    def open(self) -> bool:
        global import_error_msg
        if import_error_msg != "":
            msgs = f"No {module_type} support available, ", import_error_msg
            self._error = msgs
            logger.error(msgs)
            raise ValueError(msgs)

        if self._source == "?":
            self._error = self.find_devices()
            return False

        try:
            self._device_index = int(self._source)
        except ValueError as err:
            msgs = f"port number from {self._source}, {err}"
            self._error = str(err)
            logger.error(msgs)
            raise ValueError(err)

        try:
            self._sdr = RtlSdr(device_index=self._device_index)
        except Exception as err:
            self._error = f"Failed to connect {str(err)}"
            logger.error(self._error)
            raise ValueError(self._error)

        self._tuner_type = self._sdr.get_tuner_type()

        logger.debug(f"Connected to {module_type}")

        try:
            self.set_sample_rate_sps(self._sample_rate_sps)
            self.set_centre_frequency_hz(self._centre_frequency_hz)
            # self._sdr.freq_correction = 0 # ppm
            self.set_gain_mode('auto')
            self.set_gain(0)
        except ValueError:
            pass
        except Exception as err:
            self._error = str(err)
            raise ValueError(err)

        # recover the true values from the device
        self._sample_rate_sps = float(self._sdr.get_sample_rate())
        self._centre_frequency_hz = float(self._sdr.get_center_freq())
        logger.debug(
            f"{allowed_tuner_types[self._tuner_type]} {self._centre_frequency_hz / 1e6:.6}MHz @ "
            f"{self._sample_rate_sps:.3f}sps")
        self._connected = True

        return self._connected

    def close(self) -> None:
        if self._sdr:
            self._sdr.close()
            self._sdr = None
        self._connected = False

    @staticmethod
    def find_devices() -> str:
        devices = ""
        # could do with a call that returns the valid device_index's
        max_device = 10
        for device in range(max_device):
            try:
                sdr = RtlSdr(device_index=device)
                type_of_tuner = sdr.get_tuner_type()
                # index = sdr.get_device_index_by_serial('0000001')  # permissions required
                # addresses = sdr.get_device_serial_addresses() # permissions required
                sdr.close()
                devices += f"device {device}, type {type_of_tuner} {allowed_tuner_types[type_of_tuner]}\n"
            except Exception:
                pass
        if devices == "":
            devices = f"No rtlsdr devices found, scanned 0 to {max_device-1}"
        print(devices)
        return devices

    def get_sample_rate_sps(self) -> float:
        if self._sdr:
            self._sample_rate_sps = float(self._sdr.get_sample_rate())
        return self._sample_rate_sps

    def get_centre_frequency_hz(self) -> float:
        if self._sdr:
            if self._hw_ppm_compensation:
                self._centre_frequency_hz = float(self._sdr.get_center_freq())
        return self._centre_frequency_hz

    def set_sample_type(self, data_type: str) -> None:
        # we can't set a different sample type on this source
        super().set_sample_type(self._constant_data_type)

    def set_sample_rate_sps(self, sample_rate: float) -> None:
        # rtlsdr has limits on allowed sample rates
        # from librtlsdr.c data_source.get_bytes_per_sample()
        # 	/* check if the rate is supported by the resampler */
        # 	if ((samp_rate <= 225000) || (samp_rate > 3200000) ||
        # 	   ((samp_rate > 300000) && (samp_rate <= 900000))) {
        # 		fprintf(stderr, "Invalid sample rate: %u Hz\n", samp_rate);
        # 		return -EINVAL;
        # 	}
        # logger.info(f"set sr rtlsdr tuner type {self._tuner_type}, {allowed_tuner_types[self._tuner_type]}")

        if (sample_rate <= 225000) or (sample_rate > 3200000) or (
            (sample_rate > 300000) and (sample_rate <= 900000)):
            err = f"{module_type} invalid sample rate, {sample_rate}sps, 225000-3000000 and not 300000-900000"
            self._error = err
            logger.error(err)
            sample_rate = 1e6  # something safe

        self._sample_rate_sps = sample_rate
        if self._sdr:
            try:
                self._sdr.sample_rate = sample_rate
                self._sample_rate_sps = float(self._sdr.get_sample_rate())
            except Exception as err:
                self._error = str(err)
                logger.debug(
                    f"bad sr {sample_rate} now {self._sample_rate_sps}")

        logger.info(f"Set sample rate {sample_rate}sps")

    def set_centre_frequency_hz(self, frequency: float) -> None:
        # limits depend on tuner type: from https://wiki.radioreference.com/index.php/RTL-SDR
        # Tuner 	             Frequency Range
        # =======================================
        # Elonics E4000 	     52 – 1100 MHz / 1250 - 2200 MHz
        # Rafael Micro R820T(2)  24 – 1766 MHz
        # Fitipower FC0013 	     22 – 1100 MHz
        # Fitipower FC0012 	     22 - 948.6 MHz
        # FCI FC2580 	         146 – 308 MHz / 438 – 924 MHz

        freq_ok = True
        ok = True
        # logger.info(f"set cf rtlsdr tuner type {self._tuner_type}, {allowed_tuner_types[self._tuner_type]}")

        # what type of tuner do we have ?
        freq_range = ""
        if self._tuner_type == 1:
            # E4000
            if (frequency < 52e6) or (frequency > 2200e6):
                freq_ok = False
                freq_range = "52 – 1100 MHz and 1250 - 2200 MHz"
            elif (frequency > 1100e6) and (frequency < 1250e6):
                freq_ok = False
                freq_range = "52 – 1100 MHz and 1250 - 2200 MHz"
        elif self._tuner_type == 2:
            # FC0012
            if (frequency < 22e6) or (frequency > 948.6e6):
                freq_ok = False
                freq_range = "22 - 948.6 MHz"
        elif self._tuner_type == 3:
            # FC0013
            if (frequency < 22e6) or (frequency > 1100e6):
                freq_ok = False
                freq_range = "22 – 1100 MHz"
        elif self._tuner_type == 4:
            # FC2580
            if (frequency < 146e6) or (frequency > 924e6):
                freq_ok = False
                freq_range = "146 – 308 MHz and 438 – 924 MHz"
            elif (frequency > 308e6) and (frequency < 438e6):
                freq_ok = False
                freq_range = "146 – 308 MHz and 438 – 924 MHz"
        elif self._tuner_type == 5 or self._tuner_type == 6:
            # R820T or R828D
            if (frequency < 24e6) or (frequency > 1.766e9):
                freq_ok = False
                freq_range = "24 – 1766 MHz"
        else:
            self._error = f"Unknown tuner type {self._tuner_type}, frequency range checking impossible"
            logger.error(self._error)
            ok = False

        if not freq_ok:
            self._error = f"{allowed_tuner_types[self._tuner_type]} invalid frequency {frequency}Hz, " \
                          f"outside range {freq_range}"
            logger.error(self._error)
            ok = False

        if self._sdr and ok:
            try:
                if self._hw_ppm_compensation:
                    self._sdr.center_freq = frequency
                    self._centre_frequency_hz = float(
                        self._sdr.get_center_freq())
                else:
                    self._centre_frequency_hz = frequency
                    self._sdr.center_freq = self.get_ppm_corrected(frequency)
                    # print(f"freq {frequency} ppm {self._ppm} -> {frequency + (self._ppm * frequency / 1e6)}")
                logger.info(f"Set frequency {frequency / 1e6:0.6f}MHz")
            except Exception as err:
                self._error = str(err)

    def set_ppm(self, ppm: float) -> None:
        """
        +ve reduces tuned frequency
        -ve increases the tuned frequency

        :param ppm: Parts per million error,
        :return:
        """
        self._ppm = ppm
        self.set_centre_frequency_hz(self._centre_frequency_hz)

    def get_gain(self) -> float:
        if self._sdr:
            self._gain = self._sdr.get_gain()
        return self._gain

    def set_gain(self, gain: float) -> None:
        self._gain = gain
        if self._sdr:
            try:
                # horrible _sdr.set_gain() - either a number or string
                if self._gain_mode == 'auto':
                    self._sdr.set_gain('auto')
                else:
                    self._sdr.set_gain(float(gain))
            except Exception as err:
                self._error = f"failed to set gain of '{gain}', {err}"

    def set_gain_mode(self, mode: str) -> None:
        if mode in self._gain_modes:
            self._gain_mode = mode
            if self._sdr:
                # because the 'best' way to set the mode is to set the gain, apparently
                self.set_gain(self._gain)
        return

    def set_bandwidth_hz(self, bw: float) -> None:
        if self._sdr:
            try:
                self._sdr.set_bandwidth(int(bw))
            except Exception as err:
                self._error += str(err)
            self._bandwidth_hz = self._sdr.get_bandwidth()

    def get_bandwidth_hz(self) -> float:
        if self._sdr:
            self._bandwidth_hz = self._sdr.get_bandwidth()
        return self._bandwidth_hz

    def read_cplx_samples(self, number_samples: int) -> Tuple[np.array, float]:
        """
        Get complex float samples from the device

        Note that we don't use unpack() for this device

        :return: A tuple of a numpy array of complex samples and time in nsec
        """
        complex_data = None
        rx_time = 0

        if self._sdr and self._connected:
            try:
                complex_data = self._sdr.read_samples(
                    number_samples)  # will return np.complex128
                rx_time = self.get_time_ns()
                complex_data = np.array(
                    complex_data, dtype=np.complex64
                )  # (?) we need all values to be 32bit floats
            except Exception as err:
                self._connected = False
                self._error = str(err)
                logger.error(self._error)
                raise ValueError(err)

        return complex_data, rx_time
Ejemplo n.º 40
0
from scipy.io.wavfile import write
import matplotlib.pyplot as plt

F_station = int(88.7e6)  # Rutgers Radio
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(4 * 8192000)  # Samples to capture

sdr = RtlSdr()
sdr.sample_rate = Fs  # Hz
sdr.center_freq = Fc  # Hz s
sdr.freq_correction = 60  # PPM (Parts Per Million)
sdr.gain = 'auto'  #pick gain value
samples = sdr.read_samples(N)
print(samples)
sdr.close()

# Read in the samples:
IQ = np.array(samples, dtype=np.complex)
print("IQ (Saad): ", IQ)
multiplied = IQ[:-1] * np.conj(IQ[1:])
demodulated = np.angle(multiplied)
print("Demodulted (IQ Mert): ", demodulated)

plt.specgram(IQ, NFFT=2048, Fs=Fs)
plt.title("x1")
plt.ylim(-Fs / 2, Fs / 2)
plt.savefig("x1_spec.pdf", bbox_inches='tight', pad_inches=0.5)
plt.close()
Ejemplo n.º 41
0
#Esperamos 1 segundo
time.sleep(1)
arduino.flushInput()
arduino.setDTR(True)

with arduino:
    while True:

        cantidad = input("Ingrese cantidad de mediciones entre 1 y 9: ")

        arduino.write(cantidad.encode())

        #Leo lineas del arduino (posicion) hasta la palabra Fin
        for rawString in iter(lambda: arduino.readline(), b'Fin\r\n'):
            #Leo las muestras
            iq = sdr.read_samples(n * nfft)

            #Calculo la potencia de la señal
            potencia = get_potencia(iq) - sdr.gain

            #Imprimo los resultados
            print('Medicion ' + str(rawString.decode("utf-8")) +
                  ': {:2.2f} dB'.format(potencia))

            #Le mando al arduino que ya termine la medicion y "mueva los motores"
            arduino.write(bytes(b'r'))

# #Cierro los dispositivos
# arduino.close()
sdr.close()
Ejemplo n.º 42
0
	elif (arg == "-c"):
		config.center_freq = int(sys.argv[i+1])
	elif (arg == "-r"):
		config.sample_rate = int(sys.argv[i+1])

#init RTLSDR and if no then go out
try:
	sdr = RtlSdr()
except IOError:
	print "Probably RTLSDR device not attached"
	sys.exit(0)

# configure device
sdr.sample_rate = config.sample_rate  # Hz
sdr.center_freq = config.center_freq     # Hz
sdr.freq_correction = 60   # PPM
sdr.gain = 'auto'


samples = sdr.read_samples( config.sample_num )
if config.matlab_flag == False:
	print( samples )
else:
	print "samples = [",
	for s in samples:
		if s.imag < 0.0:
			print "%s%si "%(str(s.real), str(s.imag)),
		else:
			print "%s+%s "%(str(s.real), str(s.imag)),
	print "];"
Ejemplo n.º 43
0
class FMRadio(QtGui.QMainWindow,Ui_MainWindow):
    sample_buffer = Queue.Queue(maxsize=10)
    base_spectrum = np.ones(5780)

    plotOverall = True
    plotChannel = False
    plotPlaying = False
    plotWaveform = False
    useStereo = False
    stereoWidth = 10
    useMedianFilt = True
    useLPFilt = True
    demodFiltSize = 100000
    useAudioFilter = True
    audioFilterSize = 16
    toDraw = True
    demodMain = True
    demodSub1 = False
    demodSub2 = False
    toDrawWaterfalls = True
    toDrawPlots = False

    prevCutoff = 0
    prevSpec1 = np.zeros(128)
    prevSpec2 = np.zeros(128)
    prevSpec3 = np.zeros(128)
    prevConvo1 = np.zeros(128)
    prevConvo2 = np.zeros(128,dtype='complex')

    limiterMax = np.zeros(32)

    toPlot = (np.cumsum(np.ones(5780)),np.cumsum(np.ones(5780)))

    def __init__(self,freq,N_samples):
        self.spectrogram = np.zeros((512,400))
        self.chspectrogram = np.zeros((512,400))
        self.plspectrogram = np.zeros((256,400))
        self.cur_spectrogram = self.spectrogram


        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.createQtConnections()
        ftxt = "%.1f MHz" % (freq/1e6)
        self.ui.curFreq.setText(ftxt)

        self.sample_rate = 2.4e5 # tried 1.024e6 - not so great
        self.decim_r1 = 1 # 1.024e6/2.4e5 # for wideband fm down from sample_rate
        self.decim_r2 = 2.4e5/48000 # for baseband recovery
        self.center_freq = freq #+250e3
        self.gain = 16

        self.N_samples = N_samples
        self.is_sampling = False



        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)

        self.PLL = PhaseLockedLoop(self.N_samples,19000,self.sample_rate)

        self.initOpenCV()

        self.noisefilt = np.ones(6554)
        b,a = signal.butter(1, 2122/48000*2*np.pi, btype='low')
        self.demph_zf = signal.lfilter_zi(b, a)

        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)

    # Not currently used
    def getSamples(self):
        return self.sdr.read_samples(self.N_samples);

    def getSamplesAsync(self):
        #Asynchronous call. Initiates a continuous loop with the callback fn
        self.is_sampling = True
        samples = self.sdr.read_samples_async(self.sampleCallback,self.N_samples,context=self)
    def sampleCallback(self,samples,sself):

        self.is_sampling = False
        self.sample_buffer.put(samples)
        #print 'put some samples in the jar'

        # recursive loop
        #sself.getSamplesAsync()

    def demodulate_th(self):
        # Initiates a loop to process all the incoming blocks of samples from the Queue
        # This should be run in its own thread, or the program will become unresponsive
        while(1):

            try:
                samples = self.sample_buffer.get()
                #samples2 = self.sample_buffer.get()
            except:
                #print "wtf idk no samples?"  # even though this can't happen... (although I'm not sure why not)
                #print 'gonna try to finish off the to-do list'
                #self.sample_buffer.join()
                break

            out1 = self.demodulate(samples)
            self.sample_buffer.task_done()
            #out2 = self.demodulate(samples2)
            #self.sample_buffer.task_done()

            audio_out = out1 #np.append(out1,out2)
            self.play(audio_out)

    def gen_spectrogram(self,x,m,prevSpec):
        itsreal = np.isreal(x[0])

        m = int(m)
        lx = x.size
        nt = (lx) // m
        #NT = (lx +m -1)//m
        #padsize = NT*m -lx
        cutsize = lx -nt*m
        padsize = int(cutsize + m/2)


        if not prevSpec.size == padsize:
            prevSpec = np.zeros(padsize)

        xp = np.append(x[cutsize:],prevSpec)
        prevSpec = x[:(padsize)]

        xh = np.zeros((m,nt*2), dtype='complex')
        for n in range(int(nt*2)):
            block = xp[m*n//2:m*(n+2)//2]

            xh[:,n] = block*np.hanning(block.size)


        #if self.prevSpec.size == padsize:
        #    xb = np.append(self.prevSpec[:prevSpec.size-m/2],x)
        #    xc = np.append(self.prevSpec,x[:lx-m/2])
        #    self.prevSpec = x[lx-m/2:]
        #else:

        #    xb = np.append(x,np.zeros(-lx+nt*m))
        #    xc = np.append(x[m/2:],np.zeros(nt*m - lx + m/2))


        #xr = np.reshape(xb, (m,nt), order='F') * np.outer(np.hanning(m),np.ones(nt))
        #xs = np.reshape(xc, (m,nt), order='F') * np.outer(np.hanning(m),np.ones(nt))

        #xm = np.zeros((m,2*nt),dtype='complex')
        #xm[:,::2] = xr
        #xm[:,1::2] = xs

        if itsreal:
            spec = np.fft.fft(xh,m,axis=0)
            spec = spec[:m//2,:]
        else:
            spec = np.fft.fftshift(np.fft.fft(xh,m,axis=0))
        #mx = np.max(spec)

        pwr = np.log(np.abs(spec) + 1e-6)

        return (np.real(pwr),prevSpec)

    def initOpenCV(self):
        cv2.namedWindow("Spectrogram")

    def demodulate(self,samples):
        # DEMODULATION CODE - And the core function
        # samples must be passed in by the caller
        self.count += 1

        #spectral_window = signal.hanning

        #spectrum = np.fft.fftshift(np.fft.fft(samples*spectral_window(samples.size)))

        self.spectrogram = np.roll(self.spectrogram, 16,axis=1)
        stft,self.prevSpec1 = self.gen_spectrogram(samples,samples.size//8,self.prevSpec1)
        self.spectrogram[:,:16] = stft[::8,:]     # np.log(np.abs(spectrum[::100]))

        if(self.plotOverall): # and self.count % 10 == 9):
            #self.drawSpectrum()
            self.cur_spectrogram = self.spectrogram
            self.drawCurSpectrum()

#         cutoff = self.demodFiltSize
#         h = signal.firwin(128, cutoff,nyq=self.sample_rate/2)
#         lp = signal.fftconvolve(samples[::self.decim_r1],h,mode='full')
#         lps = lp.size
#         hs = h.size
#         prev = lp[lps-hs:]
#         lp[:hs/2] += self.prevConvo2[hs/2:]
#         lp = np.append(self.prevConvo2[:hs/2],lp)
#         self.prevConvo2 = prev
#         lp_samples = lp[:lps-hs+1]
        lp_samples = samples

        power = np.abs(self.mad(lp_samples))
        self.ui.signalMeter.setValue(20*(np.log10(power)))


    # polar discriminator

        dphase = np.zeros(lp_samples.size, dtype='complex')

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase[1:] = ( A * np.conj(B) )

        dphase[0] = lp_samples[0] * np.conj(self.prevCutoff) #dphase[dphase.size-2]
        self.prevCutoff = lp_samples[lp_samples.size-1]

    # limiting

        dphase /= np.abs(dphase)

#         if self.useMedianFilt:
#             rebuilt = signal.medfilt(np.angle(dphase)/np.pi,self.demodFiltSize) #  np.cos(dphase)
#         else:
#             rebuilt = self.lowpass(np.angle(dphase),self.demodFiltSize)

        rebuilt = np.real(np.angle(dphase) / np.pi)



        demodMain = False
        demodSub1 = False
        demodSub2 = False
        isStereo = False
        if self.demodMain:
            demodMain = True
            if self.useStereo:
                isStereo = True
        elif self.demodSub1:
            demodSub1 = True
        elif self.demodSub2:
            demodSub2 = True

        #spectrum = np.fft.fft(rebuilt* spectral_window(rebuilt.size))
        #print rebuilt.size/8
        self.chspectrogram = np.roll(self.chspectrogram, 16,axis=1)
        stft,self.prevSpec2 = self.gen_spectrogram(rebuilt,rebuilt.size/8,self.prevSpec2)
        self.chspectrogram[:,:16] = stft[::-4,:]                          # np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:50]))
        if(self.plotChannel):# and self.count % 10 == 9):
            self.cur_spectrogram = self.chspectrogram
            self.drawCurSpectrum()
             #plotspectrum = np.abs(channel_spectrum[::100])
             #self.toPlot = (np.linspace(-np.pi,np.pi,plotspectrum.size),plotspectrum)
             #self.replot()


        n_z = rebuilt.size
        if demodMain:

            h = signal.firwin(128,16000,nyq=1.2e5)
            output = signal.fftconvolve(rebuilt,h,mode='full')
            outputa = output    # could be done in place but I'm not concerned with memory

            outputa[:h.size/2] += self.prevConvo1[h.size/2:]   #add the latter half of tail end of the previous convolution
            outputa = np.append(self.prevConvo1[:h.size/2], outputa) # also delayed by half size of h so append the first half

            self.prevConvo1 = output[output.size-h.size:]   # set the tail for next iteration

            output = outputa[:output.size-h.size:self.decim_r2]  # chop off the tail and decimate


            #stereo_spectrum = spectrum
            if isStereo:

                #pilot = rebuilt * np.cos(2*np.pi*19/240*(np.r_[0:rebuilt.size]))
                h = signal.firwin(512,[18000,20000],pass_zero=False,nyq=1.2e5)
                pilot_actual = signal.fftconvolve(rebuilt,h,mode='same')
                self.PLL.adjust(pilot_actual)


                moddif = rebuilt * np.real(np.square(self.PLL.pll)) #np.cos(2*np.pi*38/240*(np.r_[0:ss] - phase_shift))
                h = signal.firwin(128,16000,nyq=1.2e5)
                moddif = signal.fftconvolve(moddif,h,mode='same')

                h = signal.firwin(64,16000,nyq=48000/2)
                diff = signal.fftconvolve(moddif[::self.decim_r2],h,mode='same')
                diff = np.real(diff)
#                 rdbs = rebuilt * np.power(self.PLL.pll,3)
#                 h = signal.hanning(1024)
#                 rdbs = signal.fftconvolve(rdbs,h)
#                 if np.mean(rdbs) > 0:
#                     # bit ONE
#                 else:
#                     # bit ZERO

        elif demodSub1:


            demod = rebuilt * np.exp(-2j*np.pi*67650/2.4e5*np.r_[0:rebuilt.size])

            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]


            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.real(np.angle( A * np.conj(B) ))
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')


        elif demodSub2:
            demod = rebuilt * np.exp(-2j*np.pi*92000/2.4e5*np.r_[0:rebuilt.size])

            h = signal.firwin(128,7500,nyq=2.4e5/2)
            lp_demod = signal.fftconvolve(demod,h,mode='same')
            decim = lp_demod[::self.decim_r2]


            dphase = np.zeros(decim.size, dtype='complex')
#
            A = decim[1:decim.size]
            B = decim[0:decim.size-1]
#
            dphase[1:] = np.real(np.angle( A * np.conj(B) ))
            h = signal.firwin(128,7500,nyq=24000)
            output = signal.fftconvolve(dphase,h,mode='same')

        # DC block filter, lol, srsly
        output = np.real(output) - np.mean(np.real(output))

        if np.isnan(output[0]):
            #print "error" # for some reason, output is NaN for the first 2 loops
            return np.zeros(6554)

        # deemphasis - # 2122/samplerate*2 *pi  - butterworth filter
        b,a = signal.butter(1, 2122/48000*2*np.pi, btype='low')
        output, zf = signal.lfilter(b, a, output,zi=self.demph_zf)
        self.demph_zf = zf

        stereo = np.zeros(output.size*2)
        if (isStereo):

            diff = signal.lfilter(b,a,diff)
            w = self.stereoWidth  # adjust to change stereo wideness
            left = output + w/10 * diff
            right = output - w/10 * diff

            if(self.useAudioFilter):
                left = self.lowpass(left,self.audioFilterSize)
                right = self.lowpass(right,self.audioFilterSize)

            stereo[0:stereo.size:2] = left
            stereo[1:stereo.size:2] = right
        else:
            if self.useAudioFilter:
                output = self.lowpass(output,self.audioFilterSize) # just the tip (kills the 19k pilot)
            stereo[0:stereo.size:2] = output
            stereo[1:stereo.size:2] = output

        #normalize to avoid any possible clipping when playing
        stereo /= 2*np.max(stereo)
        #spectrum = np.fft.fft(stereo[::2])
        output = .5*(stereo[::2]+stereo[1::2])

        #spectrum = np.fft.fft(.5*(stereo[::2]+stereo[1::2])*spectral_window(output.size))
        self.plspectrogram = np.roll(self.plspectrogram, 24,axis=1)
        stft,self.prevSpec3 = self.gen_spectrogram(output,512,self.prevSpec3)
        self.plspectrogram[:,:24] = stft[::-1,:]  # np.log(np.abs(spectrum[spectrum.size/2:spectrum.size:20]))
        if(self.plotPlaying): # and self.count % 2 == 0):
            #if self.toDrawWaterfalls:
            self.cur_spectrogram = self.plspectrogram
            self.drawCurSpectrum(invert=True)

                #self.drawPlspectrum()
            #else:

            #    sm = np.abs(np.fft.fftshift(spectrum[::20]))
            #    toPlot = (np.linspace(-2.4e4,2.4e4,sm.size),sm)
            #    self.replot(toPlot)


        #if(self.toDraw and self.plotWaveform):
        #    if self.toDrawWaterfalls:
        #        sm = np.real(output[::20])
        #        toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
        #        self.replot(toPlot)
        #    else:
        #        sm = np.real(self.PLL.pll[::200])
        #        toPlot = (np.linspace(0,output.size/48000,sm.size),sm)
        #        self.replot(toPlot)

        return np.real(stereo)


    # Alternate demodulator. Not used, but extremely simple
    def demodulate2(self,samples):
        # DEMODULATION CODE

        # LIMITER goes here

        # low pass & down sampling
        h = signal.firwin(128,80000,nyq=1.2e5)
        lp_samples = signal.fftconvolve(samples, h)

    # polar discriminator

        A = lp_samples[1:lp_samples.size]
        B = lp_samples[0:lp_samples.size-1]

        dphase = ( A * np.conj(B) ) / np.pi

        dphase.resize(dphase.size+1)
        dphase[dphase.size-1] = dphase[dphase.size-2]

        h = signal.firwin(128,16000,nyq=1.2e5)
        rebuilt = signal.fftconvolve(dphase,h)

        output = rebuilt[::self.decim_r2]

        output = self.lowpass(output, self.audioFilterSize)

        return np.real(output)

# utility functions #

    def lowpass(self,x,width):
        #wndw = np.sinc(np.r_[-15:16]/np.pi)/np.pi
        #wndw = np.kaiser(width,6)
        wndw = signal.firwin(16,width*999,nyq=24000)
        #wndw /= np.sum(wndw)
        new_array = signal.fftconvolve(x, wndw, mode='same')

        return new_array

    # calculate mean average deviation #
    def mad(self,samples):
        ave = np.mean(samples)
        return np.mean(np.abs(samples-ave))

    # 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() )


    # starting point
    def start(self):
        # Initiates running things
        self.streamer = MakeDaemon(self.demodulate_th) # run demodulation in the 'background'
        self.streamer.start()
        self.count = 0
        self.sampler_t = threading.Thread(target=self.getSamplesAsync) # sampler loop
        self.sampler_t.start()


    def createQtConnections(self):

        QtCore.QObject.connect(self.ui.freqSelect, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.setFreq)
        QtCore.QObject.connect(self.ui.checkBox, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.setUseStereo)
        QtCore.QObject.connect(self.ui.mainchannel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodMain)
        QtCore.QObject.connect(self.ui.subband1, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub1)
        QtCore.QObject.connect(self.ui.subband2, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodSub2)
        QtCore.QObject.connect(self.ui.stereoWidthSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setStereoWidth)
        QtCore.QObject.connect(self.ui.spectrum_overall, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumOverall)
        QtCore.QObject.connect(self.ui.spectrum_channel, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumChannel)
        QtCore.QObject.connect(self.ui.spectrum_playing, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumPlaying)
        QtCore.QObject.connect(self.ui.spectrum_waveform, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setSpectrumWaveform)
        QtCore.QObject.connect(self.ui.demodFiltMedian, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltMedian)
        QtCore.QObject.connect(self.ui.demodFiltLP, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDemodFiltLP)
        QtCore.QObject.connect(self.ui.demodFilterSize, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setDemodFiltSize)
        QtCore.QObject.connect(self.ui.audioFilterActive, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setAudioFiltUse)
        QtCore.QObject.connect(self.ui.audioFilterSizeSlider, QtCore.SIGNAL(_fromUtf8("sliderMoved(int)")), self.setAudioFiltSize)
        QtCore.QObject.connect(self.ui.exitButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.terminate)
        QtCore.QObject.connect(self.ui.drawPlot, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawSpec)
        QtCore.QObject.connect(self.ui.waterfallButton, QtCore.SIGNAL(_fromUtf8('toggled(bool)')), self.setDrawWaterfalls)
      #  QtCore.QObject.connect(self.ui.plotButton, QtCore.SIGNAL(_fromUtf8("clicked(bool)")), self.setDrawPlot)

        self.bindPlot()


    def bindPlot(self):
        self.dpi = 100
        self.fig = Figure((4.31,2.0), dpi=self.dpi)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.ui.plotFrame)

        self.initplot()


    def initplot(self):
        self.axes = self.fig.add_subplot(111, aspect=200/431)
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.fig.tight_layout()
        #self.axes.invert_yaxis()

        #self.anim = animation.FuncAnimation(self.fig,self.drawCurSpectrum,interval=750)


    def replot(self,toPlot):
        self.axes.clear()
        self.axes.plot(toPlot[0],toPlot[1])
        self.axes.set_aspect('auto',anchor='C')
        self.canvas.draw()

    def setDrawSpec(self,s):
        self.toDraw = s

    def drawCurSpectrum(self,invert=False):
        #self.axes.clear()
        #self.axes.imshow(self.cur_spectrogram, cmap='spectral')
        #self.axes.xaxis.set_major_locator(ticker.NullLocator())
        #self.axes.yaxis.set_major_locator(ticker.NullLocator())
        #self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        #self.canvas.draw()
        mx = np.max(self.cur_spectrogram)
        mn = np.min(self.cur_spectrogram)
        if invert:
            self.cur_spectrogram = -cv2.convertScaleAbs(self.cur_spectrogram,alpha=255 / (mx))
        else:
            self.cur_spectrogram = cv2.convertScaleAbs(self.cur_spectrogram,alpha=255 / (mn))
        self.cur_spectrogram = cv2.GaussianBlur(self.cur_spectrogram,(5,5),.6)
        cmapped =cv2.applyColorMap(self.cur_spectrogram,cv2.COLORMAP_JET)
        cv2.imshow('Spectrogram',cmapped)
        cv2.waitKey(1);

    def drawSpectrum(self):
        self.axes.clear()
        self.axes.imshow(self.spectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawChspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.chspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def drawPlspectrum(self):
        self.axes.clear()
        self.axes.imshow(self.plspectrogram, cmap='spectral')
        self.axes.xaxis.set_major_locator(ticker.NullLocator())
        self.axes.yaxis.set_major_locator(ticker.NullLocator())
        self.axes.set_aspect('auto',adjustable='box',anchor='NW')
        self.canvas.draw()

    def setDrawPlots(self,s):

        self.toDrawPlots = s
        self.toDrawWaterfalls = not s

    def setDrawWaterfalls(self,s):

        self.toDrawWaterfalls = s
        self.toDrawPlots = not s

    def setFreq(self,freq):
        if freq % 2 == 0:
            freq += 1
        freq /= 10.0
        text = "%.1f MHz" % freq
        self.ui.curFreq.setText(text)
        self.center_freq = freq*1e6 #+ 250e3
        setf_t = threading.Thread(target=self.setF_th, args=[self.center_freq,])
        setf_t.start()
        setf_t.join()



    # This function is what is used to adjust the tuner on the RTL
    # Currently, it causes the program to crash if used after an unspecified period of inactivity
    #     commented lines are attempts that didn't work
    def setF_th(self,f):
        while(self.is_sampling == True):
            pass
        #self.sdr.cancel_read_async()
        time.sleep(.1)
        self.sdr.center_freq = f
        #self.getSamplesAsync()

    def setUseStereo(self,u):
        self.useStereo = u
    def setStereoWidth(self,w):
        self.stereoWidth = w/5

    def setDemodMain(self,s):
        self.demodMain = s
        self.demodSub1 = not s
        self.demodSub2 = not s
        #self.useStereo = True
    def setDemodSub1(self,s):
        self.demodMain = not s
        self.demodSub1 = s
        self.demodSub2 = not s
        #self.useStereo = False
    def setDemodSub2(self,s):
        self.demodMain = not s
        self.demodSub1 = not s
        self.demodSub2 = s
        #self.useStereo = False

    def setSpectrumOverall(self,s):
        #self.initplot()
        #self.cur_spectrogram = self.spectrogram
        self.plotOverall = s
        self.plotChannel = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumChannel(self,s):
        #self.initplot()
        self.plotChannel = s
        self.plotOverall = not s
        self.plotPlaying = not s
        self.plotWaveform = not s
    def setSpectrumPlaying(self,s):
        #self.initplot()
        self.plotPlaying = s
        self.plotChannel = not s
        self.plotOverall= not s
        self.plotWaveform = not s
    def setSpectrumWaveform(self,s):
        self.plotWaveform = s
        self.plotPlaying = not s
        self.plotChannel = not s
        self.plotOverall= not s

    def setDemodFiltMedian(self,s):
        self.useMedianFilt = s
        self.useLPFilt = not s
    def setDemodFiltLP(self,s):
        self.useLPFilt = s
        self.useMedianFilt = not s
    def setDemodFiltSize(self,s):
        #if(s % 2 == 0):
        #    s+=1
        self.demodFiltSize = s

    def setAudioFiltUse(self,s):
        self.useAudioFilter = s
    def setAudioFiltSize(self,s):
        self.audioFilterSize = s

    def terminate(self):
        self.__del__()

    # Destructor - also used to exit the program when user clicks "Quit"
    def __del__(self):

        # Program will continue running in the background unless the RTL is told to stop sampling
        self.sdr.cancel_read_async()
        print "sdr closed"
        self.sdr.close()
        print "pyaudio terminated"
        self.pa.terminate()
        cv2.destroyAllWindows()
Ejemplo n.º 44
0
parser.add_argument('-n', action='store', dest='N',help='numero de muestras ej:1024e4',type=float,default=1024e4)
parser.add_argument('-f', action='store', dest='Fo',help='frecuencia centro en MHz ej:91.3',type=float,default=91.3)
parser.add_argument('--plot', action='store_true', default=False,dest='plot',help='Mostrar graficos de DEP y FFT')

args = parser.parse_args()

sdr = RtlSdr()
sdr.sample_rate = Fs  # Hz
sdr.center_freq = (args.Fo*1e6)     # Hz
sdr.freq_correction = 60   # PPM
sdr.gain = 'auto'

timer = Temporizador()
plotter = Plotter(Fs,(args.Fo*1e6)) if args.plot else None
fm = Demodulador(timer,plotter = plotter)

sFs = fm.outputFs()

timer.tag('inicio toma de muestras')
samples = sdr.read_samples(args.N)
timer.tag('fin toma de muestras')


audio = fm.demodular(samples)


timer.tag('reproduciendo audio')
sd.play(audio,sFs,blocking=True)
timer.tag('fin reproduccion')
timer.print()
plotter and plotter.show()
Ejemplo n.º 45
0
from rtlsdr import RtlSdr

sdr = RtlSdr()

# configure device
sdr.sample_rate = 2.048e6  # Hz
sdr.center_freq = 70e6     # Hz
sdr.freq_correction = 60   # PPM
sdr.gain = 'auto'

print(sdr.read_samples(512))
Ejemplo n.º 46
0
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});
Ejemplo n.º 47
0
class Sampler(QtCore.QObject):
    samplerError = QtCore.pyqtSignal(object)
    dataAcquired = QtCore.pyqtSignal(object)

    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 sampling(self):
        print 'Starting sampler...'
        while self.WORKING:
            prev = 0
            counter = 0
            gain = self.gain
            numSamples = self.numSamples
            self.BREAK = False
            self.sdr.gain = gain
            start = time.time()
            #print self.sdr.get_gain()
            for i in range(len(self.freqs)):
                if self.BREAK:
                    break
                else:
                    centerFreq = self.freqs[i]
                    #print "frequency: " + str(center_freq/1e6) + "MHz"
                    if centerFreq != prev:
                        try:
                            self.sdr.set_center_freq(centerFreq)
                        except:
                            self.WORKING = False
                            print "Device failure while setting center frequency"
                            self.errorMsg = "Device failure while setting center frequency"
                            self.samplerError.emit(self.errorMsg)
                            break
                        prev = centerFreq
                    else:
                        pass

                    #time.sleep(0.01)
                    try:
                        x = self.sdr.read_samples(2048)
                        data = self.sdr.read_samples(numSamples)

                    except:
                        self.WORKING = False
                        print "Device failure while getting samples"
                        self.errorMsg = "Device failure while getting samples"
                        self.samplerError.emit(self.errorMsg)
                        break

                    if self.MEASURE:
                        self.offset = np.mean(data)

                    counter += 1
                    self.dataAcquired.emit([i, centerFreq, data])

        if self.errorMsg is not None:
            self.samplerError.emit(self.errorMsg)
        if self.sdr is not None:
            self.sdr.close()
Ejemplo n.º 48
0
#from scipy import signal

sdr = RtlSdr()

# sdr
sdr.sample_rate = 2.048e6
sdr.center_freq = 105e6
sdr.freq_correction = 60
sdr.gain = 'auto'

# Azure
key_name = 'RootManageSharedAccessKey'
key_value = 'uoDYiA/o3Jjtp2Wb4f3HZnclv73VneyPigcZ0jwGMEU='
service_namespace = 'joksdrpsd'
evhub = 'sdr1'
sbs=ServiceBusService(service_namespace,shared_access_key_name=key_name,shared_access_key_value=key_value)
x = 1024 # FFT bins
i = 256  # Passes

while(True):
	samples = sdr.read_samples(i*x)
	sdr.close()
	power,freq = psd(samples, NFFT=x, Fs=sdr.sample_rate/1e6)
	
	for i in range(len(freq)):
		msg = '{"psd": "' + str(freq[i]) + ',' + str(power[i]) + '"}'
		sbs.send_event(evhub,msg)



Ejemplo n.º 49
0
class FMRadio:

     # 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
        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 = self.gain

        self.pa = pyaudio.PyAudio()
        self.stream = self.pa.open( format = pyaudio.paFloat32,
                                    channels = 1,
                                    rate = 44100,
                                    output = True)

        hamming = 10*signal.hamming(self.N_samples*.10 )
        lpf = np.append( np.zeros(self.N_samples*.45),hamming)
        self.lpf = np.fft.fftshift(np.append(lpf,np.zeros(self.N_samples*.45)))

    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 = np.append(spectrum[0:n_s/self.decim_r1*.5],spectrum[n_s-n_s/self.decim_r1*.5:n_s])

        #radio_spectrum -= np.mean(radio_spectrum) #attempt to remove dc bias

#         toplot = False
#         if(toplot):
#             fig = plt.figure()
#             plt.plot(np.abs(channel_spectrum))
#             plt.show()


        lp_samples = np.fft.ifft(channel_spectrum)

        #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,15) #  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)
#             ax.plot(phase)
#             plt.show()


        spectrum = np.fft.fft(rebuilt) #* self.lpf2
        n_s = spectrum.size
        base_spectrum = np.append(spectrum[0:n_s/self.decim_r2*.5],spectrum[n_s-n_s/self.decim_r2*.5:n_s])
        output = np.fft.ifft(base_spectrum)
        #check: should be 1807 or very close to it. it is!!

       # output = self.lowpass_filter(np.real(output),16) #[12:8204]

#         toplot = False
#         if(toplot):
#             fig = plt.figure()
#             plt.plot(np.real(output))
#             plt.show()


        return np.real(output)


    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)]



    def play(self,samples):
        self.stream.write( samples.astype(np.float32).tostring() )

    def start(self):
        while True:
            self.play(self.demodulate(self.getSamples()))