On Wed, Sep 6, 2017 at 7:37 PM, Marcus D. Leech <mle...@ripnet.com> wrote:

> On 09/06/2017 01:07 PM, Michael M wrote:
>
>
>
> 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.
>
>
> I don't see any code where you're arranging for streaming to start at a
> particular time, if you're doing something like:
>
>       wait-until-USRP-says-it's-time
>       start-receiving
>
> There'll be micro-second-to-millisecond-scale uncertainty about exactly
> when streaming will start, because some unknown amount of ftime
>   will elapse between those two steps.
>
>
> I am not setting a start time in the usrp_source gnuradio block, but it
looks like even if I don't set a start time, the block does set a start
time as follows:

         static const double reasonable_delay = 0.1; //order of magnitude
over RTT
         ::uhd::stream_cmd_t stream_cmd(::uhd::stream_cmd_
t::STREAM_MODE_START_CONTINUOUS);
         stream_cmd.stream_now = _stream_now;
          stream_cmd.time_spec = get_time_now() +
::uhd::time_spec_t(reasonable_delay);
          this->issue_stream_cmd(stream_cmd);

For me it's not important when the stream starts, as long as it has a
precise timestamp (between 50-150 ns is good), which I get from the
metadata coming in with the stream, which is done when receiving samples as
follows:

      size_t num_samps = _rx_stream->recv(
          output_items,
          noutput_items,
          _metadata,
          _recv_timeout,
          true /* one packet -> minimize latency */
      );

My issue is that I get consistent timing in one run of the flow (under
50-100ns for running even hours at a time), but if I stop it, then run it
again, the delta between that run and the run before can be several
microseconds (relative to the top of the second).  As I mentioned before, I
am using a reference transmitter which has a transmit time variance much
smaller than 50ns and has been shown to be accurate.

Do I need to do something different with setting the start time?
_______________________________________________
USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Reply via email to