def __init__(self): gr.top_block.__init__(self) usage = "usage: %prog [options] center_freq1 band_width1 [center_freq2 band_width2 ...]" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option( "-a", "--args", type="string", default="", help="UHD device device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate [default=%default]") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option( "", "--acquisition-period", type="eng_float", default=3, metavar="SECS", help= "time to delay (in seconds) after changing frequency [default=%default]" ) parser.add_option( "", "--dwell-delay", type="eng_float", default=3, metavar="SECS", help= "time to dwell (in seconds) at a given frequency [default=%default]" ) parser.add_option( "", "--meas-interval", type="eng_float", default=0.1, metavar="SECS", help= "interval over which to measure statistic (in seconds) [default=%default]" ) parser.add_option( "-c", "--number-channels", type="int", default=100, help= "number of uniform channels for which to report power measurements [default=%default]" ) parser.add_option( "-l", "--lo-offset", type="eng_float", default=0, metavar="Hz", help="lo_offset in Hz [default=half the sample rate]") parser.add_option("-F", "--fft-size", type="int", default=1024, help="specify number of FFT bins [default=%default]") parser.add_option("", "--real-time", action="store_true", default=False, help="Attempt to enable real-time scheduling") parser.add_option("-d", "--dest-url", type="string", default="", help="set destination url for posting data") parser.add_option("", "--skip-DC", action="store_true", default=False, help="skip the DC bin when mapping channels") (options, args) = parser.parse_args() if (len(args) < 2) or (len(args) % 2 == 1): parser.print_help() sys.exit(1) self.center_freq = [] self.bandwidth = [] for i in range(len(args) / 2): self.center_freq.append(eng_notation.str_to_num(args[2 * i])) self.bandwidth.append(eng_notation.str_to_num(args[2 * i + 1])) self.band_ind = len(self.center_freq) - 1 if not options.real_time: realtime = False else: # Attempt to enable realtime scheduling r = gr.enable_realtime_scheduling() if r == gr.RT_OK: realtime = True else: realtime = False print "Note: failed to enable realtime scheduling" # build graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if (options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if (options.antenna): self.u.set_antenna(options.antenna, 0) self.u.set_samp_rate(options.samp_rate) usrp_rate = self.u.get_samp_rate() if usrp_rate != options.samp_rate: if usrp_rate < options.samp_rate: # create list of allowable rates samp_rates = self.u.get_samp_rates() rate_list = [0.0] * len(samp_rates) for i in range(len(rate_list)): last_rate = samp_rates.pop() rate_list[len(rate_list) - 1 - i] = last_rate.start() # choose next higher rate rate_ind = rate_list.index(usrp_rate) + 1 if rate_ind < len(rate_list): self.u.set_samp_rate(rate_list[rate_ind]) usrp_rate = self.u.get_samp_rate() print "New actual sample rate =", usrp_rate / 1e6, "MHz" resamp = filter.fractional_resampler_cc( 0.0, usrp_rate / options.samp_rate) self.samp_rate = options.samp_rate if (options.lo_offset): self.lo_offset = options.lo_offset else: self.lo_offset = usrp_rate / 2.0 print "LO offset set to", self.lo_offset / 1e6, "MHz" self.fft_size = options.fft_size self.num_ch = options.number_channels self.acq_period = options.acquisition_period self.dwell_delay = options.dwell_delay self.head = blocks.head(gr.sizeof_gr_complex, int(self.dwell_delay * usrp_rate)) s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) mywindow = filter.window.blackmanharris(self.fft_size) ffter = fft.fft_vcc(self.fft_size, True, mywindow, True) window_power = sum(map(lambda x: x * x, mywindow)) c2mag = blocks.complex_to_mag_squared(self.fft_size) self.bin2ch_map = [[0] * self.fft_size for i in range(len(self.center_freq))] hz_per_bin = self.samp_rate / self.fft_size for i in range(len(self.center_freq)): channel_bw = hz_per_bin * round( self.bandwidth[i] / self.num_ch / hz_per_bin) self.bandwidth[i] = channel_bw * self.num_ch print "Actual width of band", i + 1, "is", self.bandwidth[ i] / 1e6, "MHz." start_freq = self.center_freq[i] - self.bandwidth[i] / 2.0 stop_freq = start_freq + self.bandwidth[i] for j in range(self.fft_size): fj = self.bin_freq(j, self.center_freq[i]) if (fj >= start_freq) and (fj < stop_freq): channel_num = int( math.floor((fj - start_freq) / channel_bw)) + 1 self.bin2ch_map[i][j] = channel_num if options.skip_DC: self.bin2ch_map[i][(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[i][(self.fft_size + 1) / 2:-1] self.bin2ch_map[i][(self.fft_size + 1) / 2] = 0 if self.bandwidth[i] > self.samp_rate: print "Warning: Width of band", i + 1, "(" + str( self.bandwidth[i] / 1e6), "MHz) is greater than the sample rate (" + str( self.samp_rate / 1e6), "MHz)." self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map[0]) meas_frames = max(1, int( round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames self.meas_duration = meas_frames * self.fft_size / self.samp_rate print "Actual measurement duration =", self.meas_duration, "s" self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames) # Divide magnitude-square by a constant to obtain power # in Watts. Assumes unit of USRP source is volts. impedance = 50.0 # ohms Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance) # Convert from Watts to dBm. W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB) f2c = blocks.float_to_char(self.num_ch, 1.0) self.dest_url = options.dest_url # file descriptor is set in main loop; use dummy value for now self.srvr = myblocks.file_descriptor_sink(self.num_ch * gr.sizeof_char, 0) self.connect(self.u, self.head) if usrp_rate > self.samp_rate: # insert resampler self.connect(self.head, resamp, s2v) else: self.connect(self.head, s2v) self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr) #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr) g = self.u.get_gain_range() if options.gain is None: # if no gain was specified, use the mid-point in dB options.gain = float(g.start() + g.stop()) / 2.0 self.set_gain(options.gain) print "gain =", options.gain, "dB in range (%0.1f dB, %0.1f dB)" % ( float(g.start()), float(g.stop())) self.atten = float(g.stop()) - options.gain
def __init__(self): gr.top_block.__init__(self) usage = "usage: %prog [options] center_freq band_width" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option( "-s", "--samp-rate", type="eng_float", default=10e6, help="set sample rate: 8/10/12.5/16/20 MHz [default=%default]") parser.add_option( "-g", "--rf-gain", type="eng_float", default=0, help="set the overall gain in dB (default is midpoint)" ) #FIXME range? parser.add_option( "", "--lna-gain", type="eng_float", default=24, help="set RX IF gain in dB (default is midpoint): 0-40dB, 8dB steps" ) parser.add_option( "", "--vga-gain", type="eng_float", default=32, help="set BB gain in dB (default is midpoint): 0-62dB, 2dB steps") parser.add_option("", "--antenna", action="store_false", default=True, help="Disable Antenna Port Power [default=%default]") parser.add_option( "", "--bandwidth", type="eng_float", default=10e6, help= "Set the BB Filter Bandwidth in MHz: 1.75-28 MHz[default=%default]" ) parser.add_option("", "--g-mode", action="store_false", default=True, help="set the gain mode[default=%default]") parser.add_option("", "--iq-balance", type="eng_float", default=2, help="set the iq_balance_mode [default=%default]") parser.add_option("", "--dc-off", type="eng_float", default=1, help="set the dc offset mode [default=%default]") parser.add_option( "", "--meas-interval", type="eng_float", default=0.1, metavar="SECS", help= "interval over which to measure statistic (in seconds) [default=%default]" ) parser.add_option( "-c", "--number-channels", type="int", default=56, help= "number of uniform channels for which to report power measurements [default=%default]" ) parser.add_option("-F", "--fft-size", type="int", default=1024, help="specify number of FFT bins [default=%default]") parser.add_option("", "--real-time", action="store_true", default=False, help="Attempt to enable real-time scheduling") parser.add_option("-d", "--dest-host", type="string", default="", help="set destination host for sending data") parser.add_option("", "--skip-DC", action="store_true", default=False, help="skip the DC bin when mapping channels") parser.add_option( "", "--avoid-LO", action="store_true", default=False, help= "Avoid LO by sampling at higher rate, shift frequency and take only a desired chunk" ) # parser.add_option("-l", "--lo-offset", type="eng_float", default=0, metavar="Hz", # help="lo_offset in Hz [default=half the sample rate]") # parser.add_option("", "--tx-VGA-gain", type="eng_float", default=None, # help="set TX IF gain in dB (default is midpoint): 0-47dB, 1dB steps") (options, args) = parser.parse_args() if len(args) != 2: parser.print_help() sys.exit(1) self.center_freq = eng_notation.str_to_num(args[0]) if options.avoid_LO: self.center_freq = self.center_freq + options.samp_rate / 4.0 print "Avoiding LO...\nShifting center Frequency to", self.center_freq self.bandwidth = eng_notation.str_to_num(args[1]) if not options.real_time: realtime = False else: # Attempt to enable realtime scheduling r = gr.enable_realtime_scheduling() if r == gr.RT_OK: realtime = True else: realtime = False print "Note: failed to enable realtime scheduling" # build graph self.u = osmosdr.source(args="numchan=" + str(1) + " " + "hackrf=0") self.u.set_sample_rate(options.samp_rate) self.u.set_freq_corr(0, 0) self.u.set_dc_offset_mode(int(options.dc_off), 0) self.u.set_iq_balance_mode(int(options.iq_balance), 0) print "options.g_mode: ", options.g_mode self.u.set_gain_mode(options.g_mode, 0) self.u.set_gain(options.rf_gain, 0) self.u.set_if_gain(options.lna_gain, 0) self.u.set_bb_gain(options.vga_gain, 0) self.u.set_antenna("", 0) self.u.set_bandwidth(options.bandwidth, 0) #if hackrf_rate != options.samp_rate: #FIXME How to read back hackrf_rate # if hackrf_rate < options.samp_rate: # # create list of allowable rates # samp_rates = self.u.get_samp_rates() # rate_list = [0.0]*len(samp_rates) # for i in range(len(rate_list)): # last_rate = samp_rates.pop() # rate_list[len(rate_list) - 1 - i] = last_rate.start() # # choose next higher rate # rate_ind = rate_list.index(hackrf_rate) + 1 # if rate_ind < len(rate_list): # self.u.set_samp_rate(rate_list[rate_ind]) # hackrf_rate = self.u.get_samp_rate() # print "New actual sample rate =", hackrf_rate/1e6, "MHz" # resamp = filter.fractional_resampler_cc(0.0, hackrf_rate / options.samp_rate) self.samp_rate = options.samp_rate self.fft_size = options.fft_size self.num_ch = options.number_channels self.avoid_LO = options.avoid_LO s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) mywindow = filter.window.blackmanharris(self.fft_size) ffter = fft.fft_vcc(self.fft_size, True, mywindow, True) window_power = sum(map(lambda x: x * x, mywindow)) c2mag = blocks.complex_to_mag_squared(self.fft_size) self.bin2ch_map = [0] * self.fft_size hz_per_bin = self.samp_rate / self.fft_size print "\nhz_per_bin: ", hz_per_bin / 1e3, "kHz" channel_bw = hz_per_bin * round( self.bandwidth / self.num_ch / hz_per_bin) print "RB Bandwidth: ", channel_bw / 1e3, "kHz" self.bandwidth = channel_bw * self.num_ch print "Actual width of band is", self.bandwidth / 1e6, "MHz." start_freq = self.center_freq - self.bandwidth / 2.0 #print "Initiallay set frequency range to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]" if options.avoid_LO: start_freq = (self.center_freq - options.samp_rate / 4) - self.bandwidth / 2.0 stop_freq = start_freq + self.bandwidth if options.avoid_LO: print "Avoiding LO, frequencies are shifted to: [", start_freq / 1e6, "MHz-", stop_freq / 1e6, "MHz ]" for j in range(self.fft_size): fj = self.bin_freq(j, self.center_freq) if (fj >= start_freq) and (fj < stop_freq): channel_num = int(math.floor( (fj - start_freq) / channel_bw)) + 1 self.bin2ch_map[j] = channel_num if options.skip_DC: self.bin2ch_map[(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[(self.fft_size + 1) / 2:-1] self.bin2ch_map[(self.fft_size + 1) / 2] = 0 if self.bandwidth > self.samp_rate: print "Warning: Width of band (" + str( self.bandwidth / 1e6), "MHz) is greater than the sample rate (" + str( self.samp_rate / 1e6), "MHz)." self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map) meas_frames = max(1, int( round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames self.meas_duration = meas_frames * self.fft_size / self.samp_rate print "Actual measurement duration =", self.meas_duration, "s" self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames) # Divide magnitude-square by a constant to obtain power # in Watts. Assumes unit of HackRF source is volts. impedance = 50.0 # ohms Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance) # Convert from Watts to dBm. W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB) f2c = blocks.float_to_char(self.num_ch, 1.0) self.dest_host = options.dest_host # ssl socket is set in main loop; use dummy value for now self.srvr = myblocks.sslsocket_sink(numpy.int8, self.num_ch, 0) if options.samp_rate > self.samp_rate: # insert resampler self.connect(self.u, resamp, s2v) else: self.connect(self.u, s2v) self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr) #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr) g_start = 0 g_stop = 20 # FIXME Find out the Gain range of HACK_RF if options.rf_gain is None: # if no gain was specified, use the mid-point in dB options.rf_gain = float(g_start + g_stop) / 2.0 self.set_gain(options.rf_gain) print "gain =", options.rf_gain, "dB in range (%0.1f dB, %0.1f dB)" % ( float(g_start), float(g_stop)) self.atten = float(g_stop) - options.rf_gain
def __init__(self): gr.top_block.__init__(self) usage = "usage: %prog [options] center_freq band_width" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-a", "--args", type="string", default="", help="UHD device device address args [default=%default]") parser.add_option("", "--spec", type="string", default=None, help="Subdevice of UHD device where appropriate") parser.add_option("-A", "--antenna", type="string", default=None, help="select Rx Antenna where appropriate") parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, help="set sample rate [default=%default]") parser.add_option("-g", "--gain", type="eng_float", default=None, help="set gain in dB (default is midpoint)") parser.add_option("", "--meas-interval", type="eng_float", default=0.1, metavar="SECS", help="interval over which to measure statistic (in seconds) [default=%default]") parser.add_option("-c", "--number-channels", type="int", default=100, help="number of uniform channels for which to report power measurements [default=%default]") parser.add_option("-l", "--lo-offset", type="eng_float", default=0, metavar="Hz", help="lo_offset in Hz [default=half the sample rate]") parser.add_option("-F", "--fft-size", type="int", default=1024, help="specify number of FFT bins [default=%default]") parser.add_option("", "--real-time", action="store_true", default=False, help="Attempt to enable real-time scheduling") parser.add_option("-d", "--dest-host", type="string", default="", help="set destination host for sending data") parser.add_option("", "--skip-DC", action="store_true", default=False, help="skip the DC bin when mapping channels") (options, args) = parser.parse_args() if len(args) != 2: parser.print_help() sys.exit(1) self.center_freq = eng_notation.str_to_num(args[0]) self.bandwidth = eng_notation.str_to_num(args[1]) if not options.real_time: realtime = False else: # Attempt to enable realtime scheduling r = gr.enable_realtime_scheduling() if r == gr.RT_OK: realtime = True else: realtime = False print "Note: failed to enable realtime scheduling" # build graph self.u = uhd.usrp_source(device_addr=options.args, stream_args=uhd.stream_args('fc32')) # Set the subdevice spec if(options.spec): self.u.set_subdev_spec(options.spec, 0) # Set the antenna if(options.antenna): self.u.set_antenna(options.antenna, 0) self.u.set_samp_rate(options.samp_rate) usrp_rate = self.u.get_samp_rate() if usrp_rate != options.samp_rate: if usrp_rate < options.samp_rate: # create list of allowable rates samp_rates = self.u.get_samp_rates() rate_list = [0.0]*len(samp_rates) for i in range(len(rate_list)): last_rate = samp_rates.pop() rate_list[len(rate_list) - 1 - i] = last_rate.start() # choose next higher rate rate_ind = rate_list.index(usrp_rate) + 1 if rate_ind < len(rate_list): self.u.set_samp_rate(rate_list[rate_ind]) usrp_rate = self.u.get_samp_rate() print "New actual sample rate =", usrp_rate/1e6, "MHz" resamp = filter.fractional_resampler_cc(0.0, usrp_rate / options.samp_rate) self.samp_rate = options.samp_rate if(options.lo_offset): self.lo_offset = options.lo_offset else: self.lo_offset = usrp_rate / 2.0 print "LO offset set to", self.lo_offset/1e6, "MHz" self.fft_size = options.fft_size self.num_ch = options.number_channels s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) mywindow = filter.window.blackmanharris(self.fft_size) ffter = fft.fft_vcc(self.fft_size, True, mywindow, True) window_power = sum(map(lambda x: x*x, mywindow)) c2mag = blocks.complex_to_mag_squared(self.fft_size) self.bin2ch_map = [0] * self.fft_size hz_per_bin = self.samp_rate / self.fft_size channel_bw = hz_per_bin * round(self.bandwidth / self.num_ch / hz_per_bin) self.bandwidth = channel_bw * self.num_ch print "Actual width of band is", self.bandwidth/1e6, "MHz." start_freq = self.center_freq - self.bandwidth/2.0 stop_freq = start_freq + self.bandwidth for j in range(self.fft_size): fj = self.bin_freq(j, self.center_freq) if (fj >= start_freq) and (fj < stop_freq): channel_num = int(math.floor((fj - start_freq) / channel_bw)) + 1 self.bin2ch_map[j] = channel_num if options.skip_DC: self.bin2ch_map[(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[(self.fft_size + 1) / 2 : -1] self.bin2ch_map[(self.fft_size + 1) / 2] = 0 if self.bandwidth > self.samp_rate: print "Warning: Width of band (" + str(self.bandwidth/1e6), "MHz) is greater than the sample rate (" + str(self.samp_rate/1e6), "MHz)." self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map) meas_frames = max(1, int(round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames self.meas_duration = meas_frames * self.fft_size / self.samp_rate print "Actual measurement duration =", self.meas_duration, "s" self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames) # Divide magnitude-square by a constant to obtain power # in Watts. Assumes unit of USRP source is volts. impedance = 50.0 # ohms Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance) # Convert from Watts to dBm. W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB) f2c = blocks.float_to_char(self.num_ch, 1.0) self.dest_host = options.dest_host # file descriptor is set in main loop; use dummy value for now self.srvr = myblocks.file_descriptor_sink(self.num_ch * gr.sizeof_char, 0) if usrp_rate > self.samp_rate: # insert resampler self.connect(self.u, resamp, s2v) else: self.connect(self.u, s2v) self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr) #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr) g = self.u.get_gain_range() if options.gain is None: # if no gain was specified, use the mid-point in dB options.gain = float(g.start()+g.stop())/2.0 self.set_gain(options.gain) print "gain =", options.gain, "dB in range (%0.1f dB, %0.1f dB)" % (float(g.start()), float(g.stop())) self.atten = float(g.stop()) - options.gain
def __init__(self): gr.top_block.__init__(self) usage = "usage: %prog [options] center_freq band_width" parser = OptionParser(option_class=eng_option, usage=usage) parser.add_option("-s", "--samp-rate", type="eng_float", default=10e6, help="set sample rate: 8/10/12.5/16/20 MHz [default=%default]") parser.add_option("-g", "--rf-gain", type="eng_float", default=0, help="set the overall gain in dB (default is midpoint)") #FIXME range? parser.add_option("", "--lna-gain", type="eng_float", default=24, help="set RX IF gain in dB (default is midpoint): 0-40dB, 8dB steps") parser.add_option("", "--vga-gain", type="eng_float", default=32, help="set BB gain in dB (default is midpoint): 0-62dB, 2dB steps") parser.add_option("", "--antenna", action="store_false", default=True, help="Disable Antenna Port Power [default=%default]") parser.add_option("", "--bandwidth", type="eng_float", default=10e6, help="Set the BB Filter Bandwidth in MHz: 1.75-28 MHz[default=%default]") parser.add_option("", "--g-mode", action="store_false", default=True, help="set the gain mode[default=%default]") parser.add_option("", "--iq-balance", type="eng_float", default=2, help="set the iq_balance_mode [default=%default]") parser.add_option("", "--dc-off", type="eng_float", default=1, help="set the dc offset mode [default=%default]") parser.add_option("", "--meas-interval", type="eng_float", default=0.1, metavar="SECS", help="interval over which to measure statistic (in seconds) [default=%default]") parser.add_option("-c", "--number-channels", type="int", default=56, help="number of uniform channels for which to report power measurements [default=%default]") parser.add_option("-F", "--fft-size", type="int", default=1024, help="specify number of FFT bins [default=%default]") parser.add_option("", "--real-time", action="store_true", default=False, help="Attempt to enable real-time scheduling") parser.add_option("-d", "--dest-host", type="string", default="", help="set destination host for sending data") parser.add_option("", "--skip-DC", action="store_true", default=False, help="skip the DC bin when mapping channels") parser.add_option("", "--avoid-LO", action="store_true", default=False, help="Avoid LO by sampling at higher rate, shift frequency and take only a desired chunk") # parser.add_option("-l", "--lo-offset", type="eng_float", default=0, metavar="Hz", # help="lo_offset in Hz [default=half the sample rate]") # parser.add_option("", "--tx-VGA-gain", type="eng_float", default=None, # help="set TX IF gain in dB (default is midpoint): 0-47dB, 1dB steps") (options, args) = parser.parse_args() if len(args) != 2: parser.print_help() sys.exit(1) self.center_freq = eng_notation.str_to_num(args[0]) if options.avoid_LO: self.center_freq = self.center_freq + options.samp_rate/4.0 print "Avoiding LO...\nShifting center Frequency to", self.center_freq self.bandwidth = eng_notation.str_to_num(args[1]) if not options.real_time: realtime = False else: # Attempt to enable realtime scheduling r = gr.enable_realtime_scheduling() if r == gr.RT_OK: realtime = True else: realtime = False print "Note: failed to enable realtime scheduling" # build graph self.u = osmosdr.source( args="numchan=" + str(1) + " " + "hackrf=0" ) self.u.set_sample_rate(options.samp_rate) self.u.set_freq_corr(0, 0) self.u.set_dc_offset_mode(int(options.dc_off), 0) self.u.set_iq_balance_mode(int(options.iq_balance), 0) print "options.g_mode: ", options.g_mode self.u.set_gain_mode(options.g_mode, 0) self.u.set_gain(options.rf_gain, 0) self.u.set_if_gain(options.lna_gain, 0) self.u.set_bb_gain(options.vga_gain, 0) self.u.set_antenna("", 0) self.u.set_bandwidth(options.bandwidth, 0) #if hackrf_rate != options.samp_rate: #FIXME How to read back hackrf_rate # if hackrf_rate < options.samp_rate: # # create list of allowable rates # samp_rates = self.u.get_samp_rates() # rate_list = [0.0]*len(samp_rates) # for i in range(len(rate_list)): # last_rate = samp_rates.pop() # rate_list[len(rate_list) - 1 - i] = last_rate.start() # # choose next higher rate # rate_ind = rate_list.index(hackrf_rate) + 1 # if rate_ind < len(rate_list): # self.u.set_samp_rate(rate_list[rate_ind]) # hackrf_rate = self.u.get_samp_rate() # print "New actual sample rate =", hackrf_rate/1e6, "MHz" # resamp = filter.fractional_resampler_cc(0.0, hackrf_rate / options.samp_rate) self.samp_rate = options.samp_rate self.fft_size = options.fft_size self.num_ch = options.number_channels self.avoid_LO = options.avoid_LO s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) mywindow = filter.window.blackmanharris(self.fft_size) ffter = fft.fft_vcc(self.fft_size, True, mywindow, True) window_power = sum(map(lambda x: x*x, mywindow)) c2mag = blocks.complex_to_mag_squared(self.fft_size) self.bin2ch_map = [0] * self.fft_size hz_per_bin = self.samp_rate / self.fft_size print "\nhz_per_bin: ", hz_per_bin/1e3, "kHz" channel_bw = hz_per_bin * round(self.bandwidth / self.num_ch / hz_per_bin) print "RB Bandwidth: ", channel_bw/1e3, "kHz" self.bandwidth = channel_bw * self.num_ch print "Actual width of band is", self.bandwidth/1e6, "MHz." start_freq = self.center_freq - self.bandwidth/2.0 #print "Initiallay set frequency range to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]" if options.avoid_LO: start_freq = (self.center_freq - options.samp_rate/4) - self.bandwidth/2.0 stop_freq = start_freq + self.bandwidth if options.avoid_LO: print "Avoiding LO, frequencies are shifted to: [",start_freq/1e6, "MHz-",stop_freq/1e6,"MHz ]" for j in range(self.fft_size): fj = self.bin_freq(j, self.center_freq) if (fj >= start_freq) and (fj < stop_freq): channel_num = int(math.floor((fj - start_freq) / channel_bw)) + 1 self.bin2ch_map[j] = channel_num if options.skip_DC: self.bin2ch_map[(self.fft_size + 1) / 2 + 1:] = self.bin2ch_map[(self.fft_size + 1) / 2 : -1] self.bin2ch_map[(self.fft_size + 1) / 2] = 0 if self.bandwidth > self.samp_rate: print "Warning: Width of band (" + str(self.bandwidth/1e6), "MHz) is greater than the sample rate (" + str(self.samp_rate/1e6), "MHz)." self.aggr = myblocks.bin_aggregator_ff(self.fft_size, self.num_ch, self.bin2ch_map) meas_frames = max(1, int(round(options.meas_interval * self.samp_rate / self.fft_size))) # in fft_frames self.meas_duration = meas_frames * self.fft_size / self.samp_rate print "Actual measurement duration =", self.meas_duration, "s" self.stats = myblocks.bin_statistics_ff(self.num_ch, meas_frames) # Divide magnitude-square by a constant to obtain power # in Watts. Assumes unit of HackRF source is volts. impedance = 50.0 # ohms Vsq2W_dB = -10.0 * math.log10(self.fft_size * window_power * impedance) # Convert from Watts to dBm. W2dBm = blocks.nlog10_ff(10.0, self.num_ch, 30.0 + Vsq2W_dB) f2c = blocks.float_to_char(self.num_ch, 1.0) self.dest_host = options.dest_host # ssl socket is set in main loop; use dummy value for now self.srvr = myblocks.sslsocket_sink(numpy.int8, self.num_ch, 0) if options.samp_rate > self.samp_rate: # insert resampler self.connect(self.u, resamp, s2v) else: self.connect(self.u, s2v) self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, f2c, self.srvr) #self.connect(s2v, ffter, c2mag, self.aggr, self.stats, W2dBm, self.srvr) g_start = 0 g_stop = 20 # FIXME Find out the Gain range of HACK_RF if options.rf_gain is None: # if no gain was specified, use the mid-point in dB options.rf_gain = float(g_start+g_stop)/2.0 self.set_gain(options.rf_gain) print "gain =", options.rf_gain, "dB in range (%0.1f dB, %0.1f dB)" % (float(g_start), float(g_stop)) self.atten = float(g_stop) - options.rf_gain