On Mon, Sep 4, 2017 at 6:14 PM, Marcus D. Leech via USRP-users <
usrp-users@lists.ettus.com> wrote:

> On 09/04/2017 04:54 PM, Michael M via USRP-users wrote:
>
>> I'm having an issue with my Ettus E310 where I'm seeing inconsistent
>> timestamping from one run to another.
>>
>> First, I set up a reference transmitter that is designed to output a
>> waveform at the top of each second.  The transmitter has been tested and
>> shown to be within a few nanoseconds of GPS time with other test
>> equipment.  This transmitter is connected to the RX2 input of the USRP E310.
>>
>> I am then setting the time source on the E310 to GPSDO and the clock
>> source to INTERNAL.  I am waiting until the gps is locked and the reference
>> is locked.  Once this is done, we are getting the gps time from the E310
>> and setting the clock to what the GPS time should be at the next 1PPS.
>> This is all working fine and the time looks correct.
>>
>> Then, I receive the signal, write it out to files with the time stamps
>> and correlate with the signal that is being transmitted by the reference
>> transmitter.  Within one run, I'm getting a standard deviation of under
>> 50ns for arrival time relative to the top of each second.  If I stop
>> receiving and start again, I am again getting a standard deviation of under
>> 50ns for arrival time.  The problem is that that arrival time varies as
>> much as a couple of microseconds between separate recordings.
>>
>> My question is, can anyone think of what might be the cause of this
>> variance from one run to another?  Could it be something I'm doing wrong?
>> Could the process of locking the digital PLL to the 1pps reference have
>> enough jitter that once locked it is tracking a value that can be off by a
>> couple microseconds?  I'd like to be able to get repeatable results from
>> one run to another (within 100ns).
>>
>> Thanks,
>>
>> Michael
>>
>> How are you starting your receive process?  How is that time-coordinated?


Here's a quick snippet of what we were doing.  We started with the
usrp_source_impl in gnuradio (
https://github.com/gnuradio/gnuradio/blob/master/gr-uhd/lib/usrp_source_impl.cc),
and added the following code to set the timecode to gps time:

      this->set_clock_source("internal",0);
      //Set time source to GPSDO
      this->set_time_source("gpsdo",0);
      //Wait for GPS Lock
      while(this->get_mboard_sensor("gps_locked",0).value != "true") {
        boost::this_thread::sleep(boost::posix_time::seconds(2));
      }
      //Wait for REF Lock
      while(this->get_mboard_sensor("ref_locked",0).value != "true") {
        boost::this_thread::sleep(boost::posix_time::seconds(2));
      }
      //Extra Sleep never Hurts
      boost::this_thread::sleep(boost::posix_time::seconds(5));
      //Set PPS Time
      long long this_pps, last_pps;
      this_pps = last_pps = this->get_time_last_pps(0).to_ticks(1.0);
      //Wait for PPS Edge
      while (this_pps == last_pps) {
        this_pps = this->get_time_last_pps(0).to_ticks(1.0);
      }
      boost::this_thread::sleep(boost::posix_time::seconds(.2));

this->set_time_next_pps(::uhd::time_spec_t(this->get_mboard_sensor("gps_time",0).to_int()
+ 1.0));
      this_pps = last_pps = this->get_time_last_pps(0).to_ticks(1.0);
      //Wait for PPS Edge
      while (this_pps == last_pps) {
        this_pps = this->get_time_last_pps(0).to_ticks(1.0);
      }
      boost::this_thread::sleep(boost::posix_time::seconds(.2));
      int sec_gps = this->get_mboard_sensor("gps_time",0).to_int();
      long long pps_sec = this->get_time_last_pps(0).to_ticks(1.0);
      if (sec_gps == pps_sec) {
        std::cout << "SYNC GOOD" << std::endl;
      } else {
        std::cout <<"FAILED TO SYNC" <<std::endl;
      }


Then, in the work method, we also added a check to see if 10 seconds had
elapsed, in which case we tag the output to include the new timecode:
(fullSecs is initialized to 0 and newGoal is initialized to true when
starting)

...
      if(newGoal && fullSecs != 0) {
        newGoal = false;
        goalSecs = fullSecs + 10;
        //std::cout << "New Goal Set" << std::endl;
      }
      switch(_metadata.error_code) {
      case ::uhd::rx_metadata_t::ERROR_CODE_NONE:
        if(fullSecs >= goalSecs) {
          _tag_now = true;
          newGoal = true;
        } else {
          fullSecs = _metadata.time_spec.get_full_secs();
          //std::cout << fullSecs << std::endl;
        }
        if(_tag_now) {
          _tag_now = false;
          fullSecs = _metadata.time_spec.get_full_secs();
          //create a timestamp pmt for the first sample
          const pmt::pmt_t val = pmt::make_tuple
            (pmt::from_uint64(_metadata.time_spec.get_full_secs()),
             pmt::from_double(_metadata.time_spec.get_frac_secs()));
          //create a tag set for each channel
          for(size_t i = 0; i < _nchan; i++) {
            this->add_item_tag(i, nitems_written(0), TIME_KEY, val, _id);
            this->add_item_tag(i, nitems_written(0), RATE_KEY,
                               pmt::from_double(_samp_rate), _id);
            this->add_item_tag(i, nitems_written(0), FREQ_KEY,
                               pmt::from_double(this->get_center_freq(i)),
_id);
          }
        }
        break;
...

We then wrote a gnuradio block that writes out files every time we get a
new tag (using the previously received timestamp, approximately every 10
seconds).  We connected that block to the output of the usrp_source  We
then used external processing to do the correlations with the reference
file.
_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to