commit 8018f38cefde4457f497146bb96f1582f1793b93 Author: Melissa Date: Sat Jun 15 18:38:39 2013 -0400 a star is born diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf61195 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +pyrtlsdr-peakfinder +============== + +The quickest, dirtiest scanner imaginable to spit out frequencies on which signal peaks are detected for RTL-SDR radios. It is probably not very efficient, but it does work. For my hardware. Good luck. + +Usage: `peakfinder.py 88.0 110.0` (in megahertz) + +The values in the script were empirically determined and you should feel free to adjust them. Reported frequencies may lean slightly right of the signal's center. + +Copyright © 2013 Melissa Elliott (0xabad1dea) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +- Neither the name of the software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +![Secret fourth clause: more Kasane Teto](http://i.imgur.com/Ikzrr4Q.png) + +[image source](http://seiga.nicovideo.jp/seiga/im1354345) \ No newline at end of file diff --git a/peakfinder.py b/peakfinder.py new file mode 100755 index 0000000..f3c721f --- /dev/null +++ b/peakfinder.py @@ -0,0 +1,134 @@ +#! /usr/bin/python +# quick and dirty peakfinder for RTL-SDR by 0xabad1dea +# scans a range and reports signals found in mhz + +# Tries very hard to not report those !@#$ phantom lines --- +# but as a result, avoid centering the window exactly on a +# frequency if you're specifically looking for it, as it may +# disappear or split into two. + +# probably not very efficient + +# BSD three-clause + +# depends: https://github.com/roger-/pyrtlsdr + + +# fixme: narrow down the import... +from pylab import * +from rtlsdr import * + +sdr = RtlSdr() + +# configure device +sdr.sample_rate = 2.4e6 +# lower the gain to, like, 4 if you don't want to hear about weak signals +sdr.gain = 19 + + +######################################################################## +def peakdet(v, delta, x = None): +# hacked up from https://gist.github.com/endolith/250860 + maxtab = [] + + if x is None: + x = arange(len(v)) + + v = asarray(v) + + mn, mx = Inf, -Inf + mnpos, mxpos = NaN, NaN + + lookformax = True + + for i in arange(len(v)): + this = v[i] + if this > mx: + mx = this + mxpos = x[i] + if this < mn: + mn = this + mnpos = x[i] + + if lookformax: + if this < mx-delta: + maxtab.append((mxpos, mx)) + mn = this + mnpos = x[i] + lookformax = False + else: + if this > mn+delta: + mx = this + mxpos = x[i] + lookformax = True + + return array(maxtab) + +######################################################################## + +def findsignals(candidates): +# input and output as [ [strength, strength, strength], [freq, freq, freq] ] + sigdelta = 0.08 # adjacent peaks closer than this are collated + + # remove the center false spike before analysis + cf = sdr.center_freq / 1e6 + + # there's probably a more pythonic way to do this + # but I'm just a humble C programmer + for i in range(len(candidates[1])): + if candidates[1][i] > (cf - (sigdelta/2)) and candidates[1][i] < (cf + (sigdelta/2)) : + candidates[0][i] = 0.0 + + # find local peaks + max = peakdet(candidates[0],.0001) # empirical - adjust as desired + # (make it smaller if you're looking for faint, wide signals) + + signals = [] + prevfreq = 0.0 + + # collate adjacent peaks + for i in max: + if candidates[1][i[0]] - prevfreq < sigdelta: + # leans right rather than left + # (a cool person would perfectly center it?) + del(signals[-1]) + signals.append([i[1], candidates[1][i[0]]]) + prevfreq = candidates[1][i[0]] + + return signals + +######################################################################## + +signals = [] + +if len(sys.argv) != 3: + exit("usage: peakfinder.py 88.0 110.0") + +start = float(sys.argv[1]) +end = float(sys.argv[2]) +if start <= 0 or end <= 0: + exit("error: bad arguments") + +if end < start: + exit("error: end < start") + +freq = start + +while(freq <= end): + sdr.center_freq = freq * 1e6 + freq += 2.2 # this number was picked empirically to avoid overlap on my device + samples = sdr.read_samples(256*1024) + # plot the spectrum + results = psd(samples, NFFT=1024, Fs=sdr.sample_rate/1e6, Fc=sdr.center_freq/1e6) + + signals.extend(findsignals(results)) + + +# print just the frequency part +print "++++++++++" +for i in signals: + print "%.2f" % i[1] +print "++++++++++" + + +