Example #1
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()
Example #2
0
async def main():
    import math

    sdr = RtlSdr()

    print('Configuring SDR...')
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10
    print('  sample rate: %0.6f MHz' % (sdr.rs/1e6))
    print('  center frequency %0.6f MHz' % (sdr.fc/1e6))
    print('  gain: %d dB' % sdr.gain)

    print('Streaming samples...')

    i = 0
    async for samples in sdr.stream():
        power = sum(abs(s)**2 for s in samples) / len(samples)
        print('Relative power:', 10*math.log10(power), 'dB')

        i += 1

        if i > 100:
            sdr.stop()
            break

    print('Done')

    sdr.close()
Example #3
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()
Example #4
0
async def main():
    import math

    sdr = RtlSdr()

    print('Configuring SDR...')
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10
    print('  sample rate: %0.6f MHz' % (sdr.rs / 1e6))
    print('  center frequency %0.6f MHz' % (sdr.fc / 1e6))
    print('  gain: %d dB' % sdr.gain)

    print('Streaming samples...')

    i = 0
    async for samples in sdr.stream():
        power = sum(abs(s)**2 for s in samples) / len(samples)
        print('Relative power:', 10 * math.log10(power), 'dB')

        i += 1

        if i > 100:
            sdr.stop()
            break

    print('Done')

    sdr.close()
Example #5
0
def main():
    sdr = RtlSdr()

    # some defaults
    sdr.rs = 2.4e6
    sdr.fc = 146e6
    sdr.gain = 50

    noiseWindowLength = 20
    noiseWindow = []

    rampWindowLength = 5
    rampWindow = []
    rampPercent = 1.2

    backgroundNoise = False
    pulseFound = False

    results = []

    # Loop enough times to collect 3 seconds of data
    sampleLoops = int(sdr.rs * 3 / 1024)

    for i in range(0, sampleLoops):
        samples = sdr.read_samples(1024)
        curMag, freqs = magnitude_spectrum(samples, Fs=sdr.rs)
        maxSignal = max(curMag)

        noiseWindow.append(maxSignal)
        if len(noiseWindow) > noiseWindowLength:
            noiseWindow.pop(0)
            backgroundNoise = sum(noiseWindow) / noiseWindowLength
            rampWindow.append(backgroundNoise)

            if len(rampWindow) > rampWindowLength:
                rampWindow.pop(0)

                if rampWindow[rampWindowLength -
                              1] > rampWindow[0] * rampPercent:
                    pulseFound = True
                else:
                    pulseFound = False

        results.append([maxSignal, backgroundNoise, pulseFound])

    sdr.close()

    f = open("data.csv", "w")
    for result in results:
        f.write(str(result[0]))
        f.write(",")
        f.write(str(result[1]))
        f.write(",")
        f.write(str(result[2]))
        f.write("\n")
    f.close()
Example #6
0
def main():
    sdr = RtlSdr()

    # some defaults
    sdr.rs = 2.4e6
    sdr.fc = 146e6
    sdr.gain = 50

    noiseWindowLength = 20
    noiseWindow = []

    rampWindowLength = 5
    rampWindow = []
    rampPercent = 1.2

    backgroundNoise = False
    pulseFound = False

    sampleCount = int(sdr.rs * 3 / 1024)

    f = open("data.csv", "w")

    for i in range(0, sampleCount):
        samples = sdr.read_samples(1024)
        curMag, freqs = magnitude_spectrum(samples, Fs=sdr.rs)
        maxSignal = max(curMag)

        noiseWindow.append(maxSignal)
        if len(noiseWindow) > noiseWindowLength:
            noiseWindow.pop(0)
            backgroundNoise = sum(noiseWindow) / noiseWindowLength
            rampWindow.append(backgroundNoise)

            if len(rampWindow) > rampWindowLength:
                rampWindow.pop(0)

                if rampWindow[rampWindowLength -
                              1] > rampWindow[0] * rampPercent:
                    pulseFound = True
                else:
                    pulseFound = False

        f.write(str(maxSignal))
        f.write(",")
        f.write(str(backgroundNoise))
        f.write(",")
        f.write(str(pulseFound))
        f.write("\n")

    f.close()

    # cleanup
    sdr.close()
Example #7
0
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10

    wf.start()

    # cleanup
    sdr.close()
Example #8
0
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    sdr.gain = 10

    wf.start()

    # cleanup
    sdr.close()
Example #9
0
def main():
    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print '   sample rate: %0.6f MHz' % (sdr.rs/1e6)
    print '   center ferquency %0.6f MHz' % (sdr.fc/1e6)
    print '   gain: %d dB' % sdr.gain

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)
Example #10
0
def main():
    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print 'Configuring SDR...'
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print '   sample rate: %0.6f MHz' % (sdr.rs / 1e6)
    print '   center ferquency %0.6f MHz' % (sdr.fc / 1e6)
    print '   gain: %d dB' % sdr.gain

    print 'Testing callback...'
    sdr.read_samples_async(test_callback)
Example #11
0
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    # Sample rate
    sdr.rs = 1e6
    sdr.set_direct_sampling('q')

    sdr.fc = 0
    sdr.gain = 10

    wf.start()

    # cleanup
    sdr.close()
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    # Sample rate
    sdr.rs = 1e6
    sdr.set_direct_sampling('q')

    sdr.fc = 0
    sdr.gain = 10

    wf.start()

    # cleanup
    sdr.close()
Example #13
0
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 2.4e6
    sdr.fc = 100e6
    #sdr.gain = 10
    sdr.gain = 'auto'

    ### setting up TCP server
    t1 = threading.Thread(target=server_run, args=(q2,))
    t1.start()
    wf.start()

    # cleanup
    sdr.close()
def main():

    sdr = RtlSdr(1)

    wf = Waterfall(sdr)

    # some defaults

    sdr.rs = 1.024e6

    sdr.fc = 89.3e6

    sdr.gain = 'auto'

    wf.start()

    # cleanup

    sdr.close()
Example #15
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()
Example #16
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()
Example #17
0
def main():

    gin=sys.argv[1]
    ppm=sys.argv[2]
    chn=sys.argv[3]
    if ppm=='0': ppm='1'
    if chn=='a': frc=161.975e6
    if chn=='b': frc=162.025e6

    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 1e6
    sdr.fc = frc
    sdr.gain = float(gin)
    sdr.freq_correction = int(float(ppm))

    wf.start()

    # cleanup
    sdr.close()
Example #18
0
def main():

    @limit_time(0.01)
    @limit_calls(20)
    def read_callback(buffer, rtlsdr_obj):
        print('In callback')
        print('   signal mean:', sum(buffer)/len(buffer))

    from rtlsdr import RtlSdr

    sdr = RtlSdr()

    print('Configuring SDR...')
    sdr.rs = 1e6
    sdr.fc = 70e6
    sdr.gain = 5
    print('   sample rate: %0.6f MHz' % (sdr.rs/1e6))
    print('   center ferquency %0.6f MHz' % (sdr.fc/1e6))
    print('   gain: %d dB' % sdr.gain)

    print('Testing callback...')
    sdr.read_samples_async(read_callback)
Example #19
0
def main():

    gin = sys.argv[1]
    ppm = sys.argv[2]
    chn = sys.argv[3]
    if ppm == '0': ppm = '1'
    if chn == 'a': frc = 161.975e6
    if chn == 'b': frc = 162.025e6

    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 1e6
    sdr.fc = frc
    sdr.gain = float(gin)
    sdr.freq_correction = int(float(ppm))

    wf.start()

    # cleanup
    sdr.close()
Example #20
0
def main():
    sdr = RtlSdr()
    wf = Waterfall(sdr)

    # some defaults
    sdr.rs = 1e6
    sdr.fc = 103.4e6
    sdr.gain = 10

    # mqtt client

    client.on_connect = on_connect
    client.username_pw_set("slip","slip")
    client.connect("ec2-35-180-123-52.eu-west-3.compute.amazonaws.com",1883)
   
    
    #client.loop_start()
    #client.publish("laverie/1","102.5,0")
    #client.disconnect()
#client.loop_stop()
    wf.start()
    # cleanup
    sdr.close()
Example #21
0
def storing_stream_with_windows(lock, rs, cf, gain, ns, device, path_storing):

    if 0==0:#librtlsdr.rtlsdr_get_device_count() > 0:
        lock.acquire(timeout=ns/rs*1.1)
        print("locked")
        sdr = RtlSdr(device_index = device)

        # some defaults
        sdr.rs = rs
        sdr.fc = cf
        sdr.gain = gain

        timestamp = time.time()
        samples = sdr.read_bytes(ns * 2)
        sdr.close()

        lock.release()
    #print("print")

        filename = get_groundstationid() + "_f" + str(cf) + "_d" + str(device) + "_t" + str(int(timestamp))
        f = open(path_storing + filename + ".tmp", 'wb')
        f.write(samples)
        f.close()
        os.rename(path_storing + filename + ".tmp", path_storing + filename + ".dat")
Example #22
0
#!/bin/python

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from rtlsdr import RtlSdr

sdr = RtlSdr()
# Sampling rate
sdr.rs = 256000. #1024e3
# Pins 4 and 5
sdr.set_direct_sampling(2)

# Center frequency
sdr.fc = 0
# I don't think this is used?
sdr.gain = 1

fig = plt.figure()
ax = fig.add_subplot(211, autoscale_on=False, xlim=(-1, 513), ylim=(-1.1,1.1))
ax.grid()
rline, = ax.plot([], [], 'r-', lw=2)
iline, = ax.plot([], [], 'g-', lw=2)
ax = fig.add_subplot(212, autoscale_on=False, xlim=(-1, 513), ylim=(-1.3,1.3))
ax.grid()
mline, = ax.plot([], [], 'b-', lw=2)

def animate(i):
    samples = sdr.read_samples(1024)
    try:
      zc = np.where(np.diff(np.sign(samples))>0)[0][0]
Example #23
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
Example #24
0
def run_total_power_int(num_samp, gain, rate, fc, t_int):
    '''
    Implement a total-power radiometer. Raw, uncalibrated power values.

    Inputs:
    num_samp:   Number of elements to sample from the SDR IQ timeseries per call
    gain:       Requested SDR gain (dB)
    rate:       SDR sample rate, intrinsically tied to bandwidth in SDRs (Hz)
    fc:         Bandpass center frequency (Hz)
    t_int:      Total integration time (s)

    Returns:
    p_tot:   Time-averaged power in the signal from the sdr, in 
             uncalibrated units
    '''
    import rtlsdr.helpers as helpers

    # Start the RtlSdr instance
    print('Initializing rtl-sdr with pyrtlsdr:')
    sdr = RtlSdr()

    try:
        sdr.rs = rate
        sdr.fc = fc
        sdr.gain = gain
        print('  sample rate: {} MHz'.format(sdr.rs / 1e6))
        print('  center frequency {} MHz'.format(sdr.fc / 1e6))
        print('  gain: {} dB'.format(sdr.gain))
        print('  num samples per call: {}'.format(num_samp))
        print('  requested integration time: {}s'.format(t_int))
        # For Nyquist sampling of the passband dv over an integration time
        # tau, we must collect N = 2 * dv * tau real samples.
        # https://www.cv.nrao.edu/~sransom/web/A1.html#S3
        # Because the SDR collects complex samples at a rate rs = dv, we can
        # Nyquist sample a signal of band-limited noise dv with only rs * tau
        # complex samples.
        # The phase content of IQ samples allows the bandlimited signal to be
        # Nyquist sampled at a data rate of rs = dv complex samples per second
        # rather than the 2* dv required of real samples.
        N = int(sdr.rs * t_int)
        print('  => num samples to collect: {}'.format(N))
        print('  => est. num of calls: {}'.format(int(N / num_samp)))

        global p_tot
        global cnt
        p_tot = 0.0
        cnt = 0

        # Set the baseline time
        start_time = time.time()
        print('Integration began at {}'.format(
            time.strftime('%a, %d %b %Y %H:%M:%S',
                          time.localtime(start_time))))

        # Time integration loop
        @helpers.limit_calls(N / num_samp)
        def p_tot_callback(iq, context):
            # The below is a total power measurement equivalent to summing
            # P = V^2 / R = (sqrt(I^2 + Q^2))^2 = (I^2 + Q^2)
            global p_tot
            p_tot += np.sum(np.real(iq * np.conj(iq)))
            global cnt
            cnt += 1

        sdr.read_samples_async(p_tot_callback, num_samples=num_samp)

        end_time = time.time()
        print('Integration ended at {} after {} seconds.'.format(
            time.strftime('%a, %d %b %Y %H:%M:%S'), end_time - start_time))
        print('{} calls were made to SDR.'.format(cnt))
        print('{} samples were measured at {} MHz'.format(
            cnt * num_samp, fc / 1e6))
        print('for an effective integration time of {:.2f}s'.format(
            (num_samp * cnt) / rate))

        # Compute the average power value based on the number of measurements
        # we actually did
        p_avg = p_tot / (num_samp * cnt)

        # nice and tidy
        sdr.close()

    except OSError as err:
        print("OS error: {0}".format(err))
        raise (err)
    except:
        print('Unexpected error:', sys.exc_info()[0])
        raise
    finally:
        sdr.close()

    return p_avg
Example #25
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
Example #26
0
    process(samples, rtl_sdr_obj)


parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument('--ppm', type=int, default=0, help='ppm error correction')

parser.add_argument('--gain', type=int, default=20, help='RF gain level')

parser.add_argument('--freq',
                    type=int,
                    default=92900000,
                    help='frequency to listen to, in Hertz')

parser.add_argument('--verbose', action='store_true', help='mute audio output')

args = parser.parse_args()

sdr = RtlSdr()

sdr.rs = 1024000

sdr.fc = args.freq

sdr.gain = args.gain

sdr.err_ppm = args.ppm

sdr.read_samples_async(read_callback, int(sdr.get_sample_rate()) // 16)
Example #27
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()
Example #28
0
# initialize a curve for the plot 
i_curve = data_plot.plot(pen='r', name = "In-Phase Signal")
q_curve = data_plot.plot(pen='y', name = "Quadrature Signal")

win.nextRow()
# initialize plot
fft_plot = win.addPlot(title="Power Vs. Frequency")
fft_plot.showGrid(True, True, alpha = 1)
fft_plot.addLegend()
# initialize a curve for the plot 
curve = fft_plot.plot(pen='g', name = "Power Spectrum")
max_curve = fft_plot.plot(pen='r', name = "Max Hold")
sdr = RtlSdr()
# some defaults
sdr.rs = 2e6
sdr.fc = 106.9e6
sdr.gain = 30
max_data = []
def update():
    global dut, curve, max_data
    samples = sdr.read_samples(SAMPLE_SIZE)
    samples = samples * np.hanning(len(samples))
    pow = 20 * np.log10(np.abs(np.fft.fftshift(np.fft.fft(samples))))
    i_curve.setData(samples.real)
    q_curve.setData(samples.imag)
    if len(max_data) == 0:
        max_data = pow
    else:
        max_data = np.maximum(max_data, pow)
    curve.setData(pow)
    max_curve.setData(max_data)
Example #29
0

app = Flask(__name__)


@app.route("/")
def hello():
    return render_template("index.html")


@app.route("/2m.json")
def samples():
    return jsonify({'samples': radio.getSamples().tolist(), 'minf': 146.0e6, 'maxf': 146.8e6})


if __name__ == "__main__":
    sdr = RtlSdr()
    radio = Radio(sdr)

    # some defaults
    sdr.freq_correction = 1
    sdr.rs = 0.95e6
    sdr.fc = 146.60e6
    sdr.gain = 35
     

    # start polling for samples
    radio.updateSamples()

    app.run(debug=True, use_reloader=False, host='0.0.0.0')
Example #30
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()

    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
        # Swap frequencies:
        tmp_first = freqs[:half_len].copy()
        tmp_last = freqs[half_len:].copy()
        freqs[:half_len] = tmp_last
        freqs[half_len:] = tmp_first

        # Swap powers:
        tmp_first = p_xx_tot[:half_len].copy()
        tmp_last = p_xx_tot[half_len:].copy()
        p_xx_tot[:half_len] = tmp_last
        p_xx_tot[half_len:] = tmp_first

        # 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)
# speed of light
c = 299792458.0  # m/s

# Set RTLSDR parameters and initialize
# This sample rate is used because it is a multiple of the baud rate
# Also it allows capturing the whole 1 MHz channel, which ensures getting
# both orbcomm channels without tuning to a different center frequency
# However, it is a much higher sample rate than would be needed.
sample_rate = 1.2288e6
center_freq = 137.5e6
gain = 'auto'  # Use AGC

sdr = RtlSdr()
sdr.rs = sample_rate
sdr.gain = gain
sdr.fc = center_freq

# dictionary/list to hold satellite plots
sat_gps_dict = {}
sat_plot_lines = []

# receive samples that are an integer multiple of 1024 from the RTLSDR
num_samples_per_recording = int(1024 * 128)
should_finish = False
queue_max_size = 30


# This is a callback function for async rtlsdr receive samples
def rtlsdr_callback(samples, context):
    global decoder
    global should_finish
Example #32
0
        self.psd_scan, self.f = psd(self.samples, NFFT=NFFT)
        threading.Timer(0.02, self.updateSamples).start()

    def getSamples(self):
        return self.psd_scan

app = Flask(__name__)

@app.route("/")
def hello():
    return render_template("index.html")

@app.route("/2m.json")
def samples():
    return jsonify({'samples': radio.getSamples().tolist(), 'minf': 144.0e6, 'maxf': 146.0e6})

if __name__ == "__main__":
    sdr = RtlSdr()
    radio = Radio(sdr)

    # some defaults
    sdr.rs = 2.0e6
    sdr.fc = 145.0e6
    sdr.gain = 10

    # start polling for samples
    radio.updateSamples()

    app.run(debug=True, use_reloader=False, host='0.0.0.0')

Example #33
0
#!/bin/python

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from rtlsdr import RtlSdr, limit_calls
from multiprocessing import Process

sdr = RtlSdr()
# Sampling rate
sdr.rs = 1024e3
# Pins 4 and 5
sdr.set_direct_sampling(2)

# Center frequency
sdr.fc = 0
# I don't think this is used?
sdr.gain = 1

fig = plt.figure()
ax = fig.add_subplot(211, autoscale_on=False, xlim=(-1, 129), ylim=(-1.1, 1.1))
ax.grid()
rline, = ax.plot([], [], 'r-', lw=2)
iline, = ax.plot([], [], 'g-', lw=2)
ax = fig.add_subplot(212, autoscale_on=False, xlim=(-1, 129), ylim=(-1.3, 1.3))
ax.grid()
mline, = ax.plot([], [], 'b-', lw=2)

global pdata
pdata = [0] * 128