[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Discuss-gnuradio] Cannot receive after one run of the code?
From: |
Zenny Zhang |
Subject: |
[Discuss-gnuradio] Cannot receive after one run of the code? |
Date: |
Mon, 20 Oct 2008 19:24:32 -0400 |
Dear All,
I am writing because I am really in need for some advice. I wrote a
program that
(1) receives from the sender and estimates the channel
(2) switch to the transmitting mode and sends the channel estimation
back to the sender
(3) switch back to the receiving mode to receive data
A while ago, I asked about how to switch between these modes without
having to stop the flow graph, and Eric gave me excellent advice on
looking at tunnel.py. Recently, after did some optimizations, I found
that the code is having a weird problem, and I have struggled on it
about a week on it but still don't know what to do.
Basically, after power-on the USRP, the code runs perfectly once. But
most often, it runs well exactly once -- the next time I run it, the
receiver at step 1 cannot receive any signal. To run it again, I have
to unplug the USRP.
Here, by not receiving any signal, I mean that the signals read from
USRP have an average square value of around 0.8. When things are
working fine, the value is around 200 when the sender is not sending,
and is around 1000000 when the sender is sending.
At first I thought it was because I did not set mux right. But it does
not seem to be so. I also noticed that after I screw it up, I cannot
even run the benchmark_rx.py, because it will also not receive
anything. But I can run usrp_oscope.py and I can see the waveform when
I have a transmitter sending.
I really appreciate if someone could give me a hint on this. Thanks so much!
Best regards,
Zhenghao
---------------------------------------------------------------
I have simplified my code and I am posting it here. This code has
exactly the same problem as I described. If other information is
needed, please let me know. Thanks!
from gnuradio import gr, gru, modulation_utils
from gnuradio.blksimpl import psk
import cmath
import Numeric
from pprint import pprint
from gnuradio import usrp
from pick_bitrate import pick_rx_bitrate
import time
import sys
from array import array
from pick_bitrate import pick_tx_bitrate
# default values (used in __init__ and add_options)
_def_samples_per_symbol = 2
_def_excess_bw = 0.35
_def_gray_code = True
_def_verbose = True
_def_log = True
_def_costas_alpha = 0.05 # the original setting
_def_gain_mu = 0.03
_def_mu = 0.05
_def_omega_relative_limit = 0.005
_def_rv_tx_freq = 2470000000
_def_rv_rx_freq = 2420000000
_def_found_delta_f = 0.025
_def_bitrate = 500000
_def_PI = 3.141592653
_def_rv_tx_power = 2000 #org: 12000
# /////////////////////////////////////////////////////////////////////////////
# DBPSK demodulator
#
# Differentially coherent detection of differentially encoded BPSK
# /////////////////////////////////////////////////////////////////////////////
class dbpsk_demod(gr.hier_block):
def __init__(self, fg,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
costas_alpha=_def_costas_alpha,
gain_mu=_def_gain_mu,
mu=_def_mu,
omega_relative_limit=_def_omega_relative_limit,
gray_code=_def_gray_code,
verbose=_def_verbose,
log=_def_log):
"""
Hierarchical block for RRC-filtered differential BPSK demodulation
The input is the complex modulated signal at baseband.
The output is a stream of bits packed 1 bit per byte (LSB)
@param fg: flow graph
@type fg: flow graph
@param samples_per_symbol: samples per symbol >= 2
@type samples_per_symbol: float
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
@param costas_alpha: loop filter gain
@type costas_alphas: float
@param gain_mu: for M&M block
@type gain_mu: float
@param mu: for M&M block
@type mu: float
@param omega_relative_limit: for M&M block
@type omega_relative_limit: float
@param gray_code: Tell modulator to Gray code the bits
@type gray_code: bool
@param verbose: Print information about modulator?
@type verbose: bool
@param debug: Print modualtion data to files?
@type debug: bool
"""
self._fg = fg
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._costas_alpha = costas_alpha
self._gain_mu = gain_mu
self._mu = mu
self._omega_relative_limit = omega_relative_limit
self._gray_code = gray_code
self._rx_freq = _def_rv_rx_freq
self._rx_gain = 45 # receiver's gain
self._rx_subdev_spec = None
self._bitrate = _def_bitrate
self._decim = 64 # Decimating rate for
the USRP (prelim)
self._fusb_block_size = 0
self._fusb_nblocks = 0
if self._rx_freq is None:
sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ
must be specified\n")
raise SystemExit
# Set up USRP source; also adjusts decim, samples_per_symbol,
and bitrate
self._setup_usrp_source()
g = self.subdev.gain_range()
if 1:
print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g" \
% (g[0], g[1], g[2])
self.set_gain(self._rx_gain)
self.set_auto_tr(True) # enable Auto
Transmit/Receive switching
# Set RF frequency
ok = self.set_freq(self._rx_freq)
if not ok:
print "Failed to set Rx frequency to %s" %
(eng_notation.num_to_str(self._rx_freq))
raise ValueError, eng_notation.num_to_str(self._rx_freq)
alpha = 0.001
thresh = 30 # in dB, will have to adjust
self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
# Design filter to get actual channel we want
sw_decim = 1
chan_coeffs = gr.firdes.low_pass (1.0, # gain
sw_decim *
self._samples_per_symbol, # sampling rate
1.0, #
midpoint of trans. band
0.5, #
width of trans. band
gr.firdes.WIN_HANN) # filter type
# Decimating channel filter
# complex in and out, float taps
self.chan_filt = gr.fft_filter_ccc(sw_decim, chan_coeffs)
#self.chan_filt = gr.fir_filter_ccf(sw_decim, chan_coeffs)
if samples_per_symbol < 2:
raise TypeError, "samples_per_symbol must be >= 2, is %r"
% (samples_per_symbol,)
arity = pow(2,self.bits_per_symbol())
# Automatic gain control
scale = (1.0/16384.0)
self.pre_scaler = gr.multiply_const_cc(scale) # scale the
signal from full-range to +-1
#self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100)
self.agc = gr.feedforward_agc_cc(16, 1.0)
ntaps = 11 * self._samples_per_symbol
self.rrc_taps = gr.firdes.root_raised_cosine(
1.0, # gain
self._samples_per_symbol, # sampling rate
1.0, # symbol rate
self._excess_bw, # excess bandwidth (roll-off factor)
ntaps)
self.rrc_filter=gr.fir_filter_ccf(1, self.rrc_taps)
# find closest constellation point
rot = 1
#rot = .707 + .707j
#print "psk.constellation[arity]=", psk.constellation[arity] #chen
rotated_const = map(lambda pt: pt * rot, psk.constellation[arity])
print "rotated_const =", rotated_const
# symbol clock recovery
omega = self._samples_per_symbol
gain_omega = .25 * self._gain_mu * self._gain_mu
#if not self._mm_gain_mu:
# self._mm_gain_mu = 0.1
#self._mm_omega = self._samples_per_symbol
#self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu
self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha
#fmin = -0.025
#fmax = 0.025
fmin = -0.1
fmax = 0.1
self.receiver=gr.mpsk_receiver_cc(arity, 0,
self._costas_alpha, self._costas_beta,
fmin, fmax,
self._mu, self._gain_mu,
omega, gain_omega,
self._omega_relative_limit)
self.diffdec = gr.diff_phasor_cc()
#self.diffdec = gr.diff_decoder_bb(arity)
self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity))
if self._gray_code:
self.symbol_mapper = gr.map_bb(psk.gray_to_binary[2])
else:
self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[2])
# unpack the k bit vector into a stream of bits
self.unpack = gr.unpacked_to_packed_bb(self.bits_per_symbol(),
gr.GR_MSB_FIRST)
self.file_sink_1 = gr.file_sink(gr.sizeof_gr_complex, "DBPSKDemod.dat")
# Connect and Initialize base class
#self._fg.connect(self.u, self.pre_scaler, self.agc, self.chan_filt,
self.rrc_filter, self.receiver, self.file_sink_1)
self._fg.connect(self.u, self.pre_scaler, self.chan_filt,
self.rrc_filter, self.receiver, self.file_sink_1)
self.dst = gr.vector_sink_b()
self._fg.connect(self.u, self.probe)
gr.hier_block.__init__(self, self._fg, self.u, self.file_sink_1)
def samples_per_symbol(self):
return self._samples_per_symbol
def bits_per_symbol(self=None): # staticmethod that's also
callable on an instance
return 1
bits_per_symbol = staticmethod(bits_per_symbol) # make it a
static method. RTFM
def _setup_usrp_source(self):
self.u = usrp.source_c (fusb_block_size=self._fusb_block_size,
fusb_nblocks=self._fusb_nblocks)
adc_rate = self.u.adc_rate()
# derive values of bitrate, samples_per_symbol, and decim from
desired info
(self._bitrate, self._samples_per_symbol, self._decim) = \
pick_rx_bitrate(self._bitrate, 1, \
self._samples_per_symbol, self._decim, adc_rate)
self.u.set_decim_rate(self._decim)
# determine the daughterboard subdevice we're using
if self._rx_subdev_spec is None:
self._rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec)
mux_value = usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec)
self.u.set_mux(mux_value)
#print "-------------- usrp source mux_value = %d
----------------" %mux_value
def set_freq(self, target_freq):
"""
Set the center frequency we're interested in.
@param target_freq: frequency in Hz
@rypte: bool
Tuning is a two step process. First we ask the front-end to
tune as close to the desired frequency as it can. Then we use
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
r = self.u.tune(0, self.subdev, target_freq)
if r:
return True
return False
def set_gain(self, gain):
"""
Sets the analog gain in the USRP
"""
if gain is None:
r = self.subdev.gain_range()
gain = (r[0] + r[1])/2 # set gain to midpoint
self.gain = gain
return self.subdev.set_gain(gain)
def set_auto_tr(self, enable):
return self.subdev.set_auto_tr(enable)
def bitrate(self):
return self._bitrate
def samples_per_symbol(self):
return self._samples_per_symbol
def decim(self):
return self._decim
def carrier_sensed(self):
"""
Return True if we think carrier is present.
"""
#return self.probe.level() > X
return self.probe.unmuted()
def carrier_threshold(self):
"""
Return current setting in dB.
"""
return self.probe.threshold()
def set_carrier_threshold(self, threshold_in_db):
"""
Set carrier threshold.
@param threshold_in_db: set detection threshold
@type threshold_in_db: float (dB)
"""
self.probe.set_threshold(threshold_in_db)
#//////////////////////////////////////////////////////////////////
#
#
#//////////////////////////////////////////////////////////////////
class dbpsk_mod(gr.hier_block):
def __init__(self, fg,
samples_per_symbol=_def_samples_per_symbol,
excess_bw=_def_excess_bw,
gray_code=_def_gray_code,
verbose=_def_verbose,
log=_def_log):
"""
Hierarchical block for RRC-filtered differential BPSK modulation.
The input is a byte stream (unsigned char) and the
output is the complex modulated signal at baseband.
@param fg: flow graph
@type fg: flow graph
@param samples_per_symbol: samples per baud >= 2
@type samples_per_symbol: integer
@param excess_bw: Root-raised cosine filter excess bandwidth
@type excess_bw: float
@param gray_code: Tell modulator to Gray code the bits
@type gray_code: bool
@param verbose: Print information about modulator?
@type verbose: bool
@param log: Log modulation data to files?
@type log: bool
"""
self._tx_freq = _def_rv_tx_freq
self._tx_amplitude = _def_rv_tx_power #original setting is 12000
self._fusb_block_size = 0
self._fusb_nblocks = 0
self._bitrate = _def_bitrate
self._tx_subdev_spec = None
self._fg = fg
self._samples_per_symbol = samples_per_symbol
self._excess_bw = excess_bw
self._gray_code = gray_code
self.phase_diff_est = 192
# Set up USRP sink; also adjusts interp, samples_per_symbol, and bitrate
self._setup_usrp_sink()
# Set center frequency of USRP
ok = self.set_freq(self._tx_freq)
if not ok:
print "Failed to set Tx frequency to %s" %
(eng_notation.num_to_str(self._tx_freq),)
raise ValueError
# Set the USRP for maximum transmit gain
# (Note that on the RFX cards this is a nop.)
self.set_gain(self.subdev.gain_range()[1])
self.amp = gr.multiply_const_cc(1)
self.set_tx_amplitude(self._tx_amplitude)
# enable Auto Transmit/Receive switching
self.set_auto_tr(True)
if not isinstance(self._samples_per_symbol, int) or
self._samples_per_symbol < 2:
raise TypeError, ("sbp must be an integer >= 2, is %d" %
self._samples_per_symbol)
ntaps = 11 * self._samples_per_symbol
arity = pow(2,self.bits_per_symbol())
# turn bytes into k-bit vectors
self.bytes2chunks = \
gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
if self._gray_code:
self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity])
else:
self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity])
self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[2])
self.rrc_taps = gr.firdes.root_raised_cosine(
1.0, # gain
self._samples_per_symbol, # sampling rate
1.0, # symbol rate
self._excess_bw, # excess bandwidth (roll-off factor)
ntaps)
self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol,
self.rrc_taps)
self.bytes_src1 = gr.null_source(gr.sizeof_char)
self.diffenc = gr.diff_encoder_bb(arity)
fg.connect(self.bytes_src1, self.bytes2chunks,
self.symbol_mapper, self.diffenc, self.chunks2symbols,
self.rrc_filter, self.amp, self.u)
gr.hier_block.__init__(self, self._fg, self.bytes_src1, self.u)
def samples_per_symbol(self):
return self._samples_per_symbol
def bits_per_symbol(self=None): # static method that's also
callable on an instance
return 1
bits_per_symbol = staticmethod(bits_per_symbol) # make it a
static method. RTFM
def _setup_usrp_sink(self):
"""
Creates a USRP sink, determines the settings for best bitrate,
and attaches to the transmitter's subdevice.
"""
self.u = usrp.sink_c(fusb_block_size=self._fusb_block_size,
fusb_nblocks=self._fusb_nblocks)
dac_rate = self.u.dac_rate();
# derive values of bitrate, samples_per_symbol, and interp
from desired info
(self._bitrate, self._samples_per_symbol, self._interp) = \
pick_tx_bitrate(self._bitrate, 1,
self._samples_per_symbol, None, dac_rate)
self.u.set_interp_rate(self._interp)
# determine the daughterboard subdevice we're using
if self._tx_subdev_spec is None:
self._tx_subdev_spec = usrp.pick_tx_subdevice(self.u)
mux_value = usrp.determine_tx_mux_value(self.u, self._tx_subdev_spec)
self.u.set_mux(mux_value)
self.subdev = usrp.selected_subdev(self.u, self._tx_subdev_spec)
def set_freq(self, target_freq):
"""
Set the center frequency we're interested in.
@param target_freq: frequency in Hz
@rypte: bool
Tuning is a two step process. First we ask the front-end to
tune as close to the desired frequency as it can. Then we use
the result of that operation and our target_frequency to
determine the value for the digital up converter.
"""
r = self.u.tune(self.subdev._which, self.subdev, target_freq)
if r:
return True
return False
def set_gain(self, gain):
"""
Sets the analog gain in the USRP
"""
self.gain = gain
self.subdev.set_gain(gain)
def set_tx_amplitude(self, ampl):
"""
Sets the transmit amplitude sent to the USRP
@param: ampl 0 <= ampl < 32768. Try 8000
"""
self._tx_amplitude = max(0.0, min(ampl, 32767.0))
self.amp.set_k(self._tx_amplitude)
def set_auto_tr(self, enable):
"""
Turns on auto transmit/receive of USRP daughterboard (if
exits; else ignored)
"""
return self.subdev.set_auto_tr(enable)
if __name__ == '__main__':
fg1 = gr.flow_graph()
objDemod1 = dbpsk_demod(fg1)
fg1.start() #objDemod1._fg.start()
count = 0
while count < 10:
time.sleep(0.1) #orig: 0.001
print "level %f" % objDemod1.probe.level()
count = count + 1
fg1.stop()#objDemod1._fg.stop()
fg2 = gr.flow_graph()
objmod = dbpsk_mod(fg2)
objmod.set_tx_amplitude(_def_rv_tx_power)
fg2.start()
time.sleep(0.003)
objmod.set_tx_amplitude(0)
fg2.stop()
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Discuss-gnuradio] Cannot receive after one run of the code?,
Zenny Zhang <=