W dniu 26.02.2018 o 12:43, Piotr Krysik via USRP-users pisze:
> W dniu 26.02.2018 o 11:29, Piotr Krysik via USRP-users pisze:
>> W dniu 25.02.2018 o 20:08, Marcus D. Leech via USRP-users pisze:
>>> OK, so (and apologies if this was in your previous data)  what is the
>>> average magnitude of the time discrepancy? 
>> Usually it was about few hundreds us (random). I will try to perform
>> more measurements.
>>
> I measured some values of the delay - they are in the attachment.
> Usually the offset is larger than what I said. It's about ~10ms.
>
> What is interesting is that the values I got in these measurements were
> always positive.
Hi Marcus,

I've finally found out what the reason for the large offset is !!
One of USRPs B210 changes master clock rate AFTER setting the internal
time counter.
I've found it out when I printed USRPs time at the end of time setting
function and seen this:

...
-- Asking for clock rate 32.000000 MHz...
-- Actually got clock rate 32.000000 MHz.
-- Performing timer loopback test... pass
-- Performing timer loopback test... pass
set_min_output_buffer on block 2 to 10000000
USRP1 time:  1.003918125
USRP2 time:  1.004056625
-- Asking for clock rate 16.000000 MHz... Asking for clock rate
16.000000 MHz...
-- Actually got clock rate 16.000000 MHz.
-- Performing timer loopback test...
-- Actually got clock rate 16.000000 MHz.
-- Performing timer loopback test... pass
-- Performing timer loopback test... pass
-- Performing timer loopback test... pass
-- pass
...

Whole part below "USRP2 time:  1.004056625" shouldn't be there. The
device at that moment is changing its master clock rate from 32MHz to
16MHz. So what I did was setting master clock rate explicitly to 16MHz.
*This solved the issue*.

Many thanks for your advices that stimulated me to think about solution
the problem.

I'm attaching the recorder to the post, so others will be able to start
synchronizing their B210s from something that works.

Best Regards,
Piotr Krysik


Attachment: recorder.grc
Description: application/gnuradio-grc

#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from recorder_grc import *
import time

class recorder(recorder_grc):
    def __init__(self, fc=1000e6, gain1=30, gain2=30, samp_rate=1e6, start_time="", rec_len=1, gain3=30, gain4=30, serial1="", serial2=""):
        super(recorder, self).__init__(fc=fc, gain1=gain1, gain2=gain2, samp_rate=samp_rate,  rec_len=rec_len, gain3=gain3, serial1=serial1, serial2=serial2)
        self.set_time_unknown_pps_costam(uhd.time_spec(0.0)) 
        self.uhd_usrp_source_0.set_start_time(uhd.time_spec(3.0))
        self.uhd_usrp_source_0_0.set_start_time(uhd.time_spec(3.0))

    def set_time_unknown_pps_costam(self, time_spec):
        time.sleep(4.0)
        time_last_pps = self.uhd_usrp_source_0.get_time_last_pps()
        while(self.uhd_usrp_source_0.get_time_last_pps() == time_last_pps):
            time.sleep(0.01)
        
        self.uhd_usrp_source_0.set_time_next_pps(time_spec)
        self.uhd_usrp_source_0_0.set_time_next_pps(time_spec)

        time.sleep(2.0)
        print "USRP1 time: ",self.uhd_usrp_source_0.get_time_now().get_real_secs()
        print "USRP2 time: ",self.uhd_usrp_source_0_0.get_time_now().get_real_secs()


if __name__ == '__main__':
    main(top_block_cls=recorder)
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Recorder Grc
# Generated: Mon Feb 26 14:57:51 2018
##################################################

from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio import uhd
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import time


class recorder_grc(gr.top_block):

    def __init__(self, fc=1000e6, gain1=20, gain2=20, gain3=20, gain4=20, rec_len=4, samp_rate=1e6, serial1='3094DB1', serial2='30AD35A'):
        gr.top_block.__init__(self, "Recorder Grc")

        ##################################################
        # Parameters
        ##################################################
        self.fc = fc
        self.gain1 = gain1
        self.gain2 = gain2
        self.gain3 = gain3
        self.gain4 = gain4
        self.rec_len = rec_len
        self.samp_rate = samp_rate
        self.serial1 = serial1
        self.serial2 = serial2

        ##################################################
        # Blocks
        ##################################################
        self.uhd_usrp_source_0_0 = uhd.usrp_source(
        	",".join(("serial="+serial2, '')),
        	uhd.stream_args(
        		cpu_format="fc32",
        		channels=range(2),
        	),
        )
        self.uhd_usrp_source_0_0.set_clock_rate(16e6, uhd.ALL_MBOARDS)
        self.uhd_usrp_source_0_0.set_clock_source('external', 0)
        self.uhd_usrp_source_0_0.set_time_source('external', 0)
        self.uhd_usrp_source_0_0.set_samp_rate(samp_rate)
        self.uhd_usrp_source_0_0.set_center_freq(fc, 0)
        self.uhd_usrp_source_0_0.set_gain(gain3, 0)
        self.uhd_usrp_source_0_0.set_antenna('TX/RX', 0)
        self.uhd_usrp_source_0_0.set_bandwidth(1e6, 0)
        self.uhd_usrp_source_0_0.set_center_freq(fc, 1)
        self.uhd_usrp_source_0_0.set_gain(gain4, 1)
        self.uhd_usrp_source_0_0.set_antenna('RX2', 1)
        self.uhd_usrp_source_0_0.set_bandwidth(1e6, 1)
        (self.uhd_usrp_source_0_0).set_min_output_buffer(10000000)
        self.uhd_usrp_source_0 = uhd.usrp_source(
        	",".join(("serial="+serial1, '')),
        	uhd.stream_args(
        		cpu_format="fc32",
        		channels=range(2),
        	),
        )
        self.uhd_usrp_source_0.set_clock_rate(16e6, uhd.ALL_MBOARDS)
        self.uhd_usrp_source_0.set_clock_source('external', 0)
        self.uhd_usrp_source_0.set_time_source('external', 0)
        self.uhd_usrp_source_0.set_samp_rate(samp_rate)
        self.uhd_usrp_source_0.set_center_freq(fc, 0)
        self.uhd_usrp_source_0.set_gain(gain1, 0)
        self.uhd_usrp_source_0.set_antenna('RX2', 0)
        self.uhd_usrp_source_0.set_bandwidth(1e6, 0)
        self.uhd_usrp_source_0.set_center_freq(fc, 1)
        self.uhd_usrp_source_0.set_gain(gain2, 1)
        self.uhd_usrp_source_0.set_antenna('RX2', 1)
        self.uhd_usrp_source_0.set_bandwidth(1e6, 1)
        (self.uhd_usrp_source_0).set_min_output_buffer(10000000)
        self.blocks_tag_debug_0_0 = blocks.tag_debug(gr.sizeof_gr_complex*1, '', ""); self.blocks_tag_debug_0_0.set_display(True)
        self.blocks_tag_debug_0 = blocks.tag_debug(gr.sizeof_gr_complex*1, '', ""); self.blocks_tag_debug_0.set_display(True)
        self.blocks_head_0_0_1 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate*rec_len))
        self.blocks_head_0_0_0 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate*rec_len))
        self.blocks_head_0_0 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate*rec_len))
        self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex*1, int(samp_rate*rec_len))
        self.blocks_file_sink_0_1 = blocks.file_sink(gr.sizeof_gr_complex*1, 'ch2.sfile', False)
        self.blocks_file_sink_0_1.set_unbuffered(True)
        self.blocks_file_sink_0_0_0 = blocks.file_sink(gr.sizeof_gr_complex*1, 'ch4.sfile', False)
        self.blocks_file_sink_0_0_0.set_unbuffered(True)
        self.blocks_file_sink_0_0 = blocks.file_sink(gr.sizeof_gr_complex*1, 'ch3.sfile', False)
        self.blocks_file_sink_0_0.set_unbuffered(True)
        self.blocks_file_sink_0 = blocks.file_sink(gr.sizeof_gr_complex*1, 'ch1.sfile', False)
        self.blocks_file_sink_0.set_unbuffered(True)



        ##################################################
        # Connections
        ##################################################
        self.connect((self.blocks_head_0, 0), (self.blocks_file_sink_0, 0))
        self.connect((self.blocks_head_0_0, 0), (self.blocks_file_sink_0_0, 0))
        self.connect((self.blocks_head_0_0_0, 0), (self.blocks_file_sink_0_1, 0))
        self.connect((self.blocks_head_0_0_1, 0), (self.blocks_file_sink_0_0_0, 0))
        self.connect((self.uhd_usrp_source_0, 0), (self.blocks_head_0, 0))
        self.connect((self.uhd_usrp_source_0, 1), (self.blocks_head_0_0_0, 0))
        self.connect((self.uhd_usrp_source_0, 0), (self.blocks_tag_debug_0, 0))
        self.connect((self.uhd_usrp_source_0_0, 0), (self.blocks_head_0_0, 0))
        self.connect((self.uhd_usrp_source_0_0, 1), (self.blocks_head_0_0_1, 0))
        self.connect((self.uhd_usrp_source_0_0, 0), (self.blocks_tag_debug_0_0, 0))

    def get_fc(self):
        return self.fc

    def set_fc(self, fc):
        self.fc = fc
        self.uhd_usrp_source_0_0.set_center_freq(self.fc, 0)
        self.uhd_usrp_source_0_0.set_center_freq(self.fc, 1)
        self.uhd_usrp_source_0.set_center_freq(self.fc, 0)
        self.uhd_usrp_source_0.set_center_freq(self.fc, 1)

    def get_gain1(self):
        return self.gain1

    def set_gain1(self, gain1):
        self.gain1 = gain1
        self.uhd_usrp_source_0.set_gain(self.gain1, 0)


    def get_gain2(self):
        return self.gain2

    def set_gain2(self, gain2):
        self.gain2 = gain2
        self.uhd_usrp_source_0.set_gain(self.gain2, 1)


    def get_gain3(self):
        return self.gain3

    def set_gain3(self, gain3):
        self.gain3 = gain3
        self.uhd_usrp_source_0_0.set_gain(self.gain3, 0)


    def get_gain4(self):
        return self.gain4

    def set_gain4(self, gain4):
        self.gain4 = gain4
        self.uhd_usrp_source_0_0.set_gain(self.gain4, 1)


    def get_rec_len(self):
        return self.rec_len

    def set_rec_len(self, rec_len):
        self.rec_len = rec_len
        self.blocks_head_0_0_1.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0_0_0.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0_0.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0.set_length(int(self.samp_rate*self.rec_len))

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        self.samp_rate = samp_rate
        self.uhd_usrp_source_0_0.set_samp_rate(self.samp_rate)
        self.uhd_usrp_source_0.set_samp_rate(self.samp_rate)
        self.blocks_head_0_0_1.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0_0_0.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0_0.set_length(int(self.samp_rate*self.rec_len))
        self.blocks_head_0.set_length(int(self.samp_rate*self.rec_len))

    def get_serial1(self):
        return self.serial1

    def set_serial1(self, serial1):
        self.serial1 = serial1

    def get_serial2(self):
        return self.serial2

    def set_serial2(self, serial2):
        self.serial2 = serial2


def argument_parser():
    parser = OptionParser(usage="%prog: [options]", option_class=eng_option)
    parser.add_option(
        "-f", "--fc", dest="fc", type="eng_float", default=eng_notation.num_to_str(1000e6),
        help="Set fc [default=%default]")
    parser.add_option(
        "", "--gain1", dest="gain1", type="eng_float", default=eng_notation.num_to_str(20),
        help="Set gain1 [default=%default]")
    parser.add_option(
        "", "--gain2", dest="gain2", type="eng_float", default=eng_notation.num_to_str(20),
        help="Set gain2 [default=%default]")
    parser.add_option(
        "", "--gain3", dest="gain3", type="eng_float", default=eng_notation.num_to_str(20),
        help="Set gain3 [default=%default]")
    parser.add_option(
        "", "--gain4", dest="gain4", type="eng_float", default=eng_notation.num_to_str(20),
        help="Set gain4 [default=%default]")
    parser.add_option(
        "-T", "--rec-len", dest="rec_len", type="eng_float", default=eng_notation.num_to_str(4),
        help="Set rec_len [default=%default]")
    parser.add_option(
        "", "--samp-rate", dest="samp_rate", type="eng_float", default=eng_notation.num_to_str(1e6),
        help="Set samp_rate [default=%default]")
    parser.add_option(
        "", "--serial1", dest="serial1", type="string", default='3094DB1',
        help="Set 3094DB1 [default=%default]")
    parser.add_option(
        "", "--serial2", dest="serial2", type="string", default='30AD35A',
        help="Set 30AD35A [default=%default]")
    return parser


def main(top_block_cls=recorder_grc, options=None):
    if options is None:
        options, _ = argument_parser().parse_args()

    tb = top_block_cls(fc=options.fc, gain1=options.gain1, gain2=options.gain2, gain3=options.gain3, gain4=options.gain4, rec_len=options.rec_len, samp_rate=options.samp_rate, serial1=options.serial1, serial2=options.serial2)
    tb.start()
    tb.wait()


if __name__ == '__main__':
    main()
_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to