def __init__(self, args): gr.top_block.__init__(self, "Nordic Single-Channel Receiver Example") self.freq = 2414e6 self.gain = args.gain self.symbol_rate = 2e6 self.sample_rate = 4e6 # Channel map channel_count = 3 channel_map = [14, 18, 10] # Data rate index dr = 2 # 2M # SDR source (gr-osmosdr source) self.osmosdr_source = osmosdr.source() self.osmosdr_source.set_sample_rate(self.sample_rate * channel_count) self.osmosdr_source.set_center_freq(self.freq) self.osmosdr_source.set_gain(self.gain) self.osmosdr_source.set_antenna('TX/RX') # PFB channelizer taps = firdes.low_pass_2(1, self.sample_rate, self.symbol_rate / 2, 100e3, 30) self.channelizer = filter.pfb_channelizer_ccf(channel_count, taps, 1) # Stream to streams (PFB channelizer input) self.s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, channel_count) self.connect(self.osmosdr_source, self.s2ss) # Demodulators and packet deframers self.nordictap_printer = nordictap_printer() self.demods = [] self.rxs = [] for x in range(channel_count): self.connect((self.s2ss, x), (self.channelizer, x)) self.demods.append(digital.gfsk_demod()) self.rxs.append(nordic.nordic_rx(x, 5, 2, dr)) self.connect((self.channelizer, x), self.demods[x]) self.connect(self.demods[x], self.rxs[x]) self.msg_connect(self.rxs[x], "nordictap_out", self.nordictap_printer, "nordictap_in")
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 5000 # baseband sampling rate ifs = M*fs # input samp rate to channelizer taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = blocks.add_cc() freqs = [-230., 121., 110., -513., 203.] for i in xrange(len(freqs)): f = freqs[i] + (M/2-M+i+1)*fs data = sig_source_c(ifs, f, 1, N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add,i)) s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, s2ss) snks = list() for i in xrange(M): snks.append(blocks.vector_sink_c()) self.tb.connect((s2ss,i), (pfb,i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) # Adjusted phase rotations for data p0 = 0.11058379158914133 p1 = 4.5108246571401693 p2 = 3.9739891674564594 p3 = 2.2820531095511924 p4 = 1.3782797467397869 # Filter delay is the normal delay of each arm tpf = math.ceil(len(taps) / float(M)) delay = -(tpf - 1.0) / 2.0 delay = int(delay) # Create a time scale that's delayed to match the filter delay t = map(lambda x: float(x)/fs, xrange(delay, L+delay)) # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 1000 # baseband sampling rate ifs = M*fs # input samp rate to channelizer taps = filter.firdes.low_pass_2(1, ifs, 500, 50, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = blocks.add_cc() freqs = [-200, -100, 0, 100, 200] for i in xrange(len(freqs)): f = freqs[i] + (M/2-M+i+1)*fs data = sig_source_c(ifs, f, 1, N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add,i)) s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, s2ss) snks = list() for i in xrange(M): snks.append(blocks.vector_sink_c()) self.tb.connect((s2ss,i), (pfb,i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) t = map(lambda x: float(x)/fs, xrange(L)) # Adjusted phase rotations for data p0 = 0 p1 = math.pi*0.51998885 p2 = -math.pi*0.96002233 p3 = math.pi*0.96002233 p4 = -math.pi*0.51998885 # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 5000 # baseband sampling rate ifs = M * fs # input samp rate to channelizer taps = filter.firdes.low_pass_2( 1, ifs, fs / 2, fs / 10, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = blocks.add_cc() freqs = [-230., 121., 110., -513., 203.] for i in xrange(len(freqs)): f = freqs[i] + (M / 2 - M + i + 1) * fs data = sig_source_c(ifs, f, 1, N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add, i)) s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, s2ss) snks = list() for i in xrange(M): snks.append(blocks.vector_sink_c()) self.tb.connect((s2ss, i), (pfb, i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) # Adjusted phase rotations for data p0 = -2 * math.pi * 0 / M p1 = -2 * math.pi * 1 / M p2 = -2 * math.pi * 2 / M p3 = -2 * math.pi * 3 / M p4 = -2 * math.pi * 4 / M # Filter delay is the normal delay of each arm tpf = math.ceil(len(taps) / float(M)) delay = -(tpf - 1.0) / 2.0 delay = int(delay) # Create a time scale that's delayed to match the filter delay t = map(lambda x: float(x) / fs, xrange(delay, L + delay)) # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)
def test_000(self): N = 1000 # number of samples to use M = 5 # Number of channels to channelize fs = 1000 # baseband sampling rate ifs = M * fs # input samp rate to channelizer taps = filter.firdes.low_pass_2( 1, ifs, 500, 50, attenuation_dB=80, window=filter.firdes.WIN_BLACKMAN_hARRIS) signals = list() add = blocks.add_cc() freqs = [-200, -100, 0, 100, 200] for i in xrange(len(freqs)): f = freqs[i] + (M / 2 - M + i + 1) * fs data = sig_source_c(ifs, f, 1, N) signals.append(blocks.vector_source_c(data)) self.tb.connect(signals[i], (add, i)) s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M) pfb = filter.pfb_channelizer_ccf(M, taps, 1) self.tb.connect(add, s2ss) snks = list() for i in xrange(M): snks.append(blocks.vector_sink_c()) self.tb.connect((s2ss, i), (pfb, i)) self.tb.connect((pfb, i), snks[i]) self.tb.run() Ntest = 50 L = len(snks[0].data()) t = map(lambda x: float(x) / fs, xrange(L)) # Adjusted phase rotations for data p0 = 0 p1 = math.pi * 0.51998885 p2 = -math.pi * 0.96002233 p3 = math.pi * 0.96002233 p4 = -math.pi * 0.51998885 # Create known data as complex sinusoids at the different baseband freqs # the different channel numbering is due to channelizer output order. expected0_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+p0) + \ 1j*math.sin(2.*math.pi*freqs[2]*x+p0), t) expected1_data = map(lambda x: math.cos(2.*math.pi*freqs[3]*x+p1) + \ 1j*math.sin(2.*math.pi*freqs[3]*x+p1), t) expected2_data = map(lambda x: math.cos(2.*math.pi*freqs[4]*x+p2) + \ 1j*math.sin(2.*math.pi*freqs[4]*x+p2), t) expected3_data = map(lambda x: math.cos(2.*math.pi*freqs[0]*x+p3) + \ 1j*math.sin(2.*math.pi*freqs[0]*x+p3), t) expected4_data = map(lambda x: math.cos(2.*math.pi*freqs[1]*x+p4) + \ 1j*math.sin(2.*math.pi*freqs[1]*x+p4), t) dst0_data = snks[0].data() dst1_data = snks[1].data() dst2_data = snks[2].data() dst3_data = snks[3].data() dst4_data = snks[4].data() self.assertComplexTuplesAlmostEqual(expected0_data[-Ntest:], dst0_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected1_data[-Ntest:], dst1_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected2_data[-Ntest:], dst2_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected3_data[-Ntest:], dst3_data[-Ntest:], 3) self.assertComplexTuplesAlmostEqual(expected4_data[-Ntest:], dst4_data[-Ntest:], 3)