[USRP-users] PPS sync not working?

Jonathan Verlant-Chenet jverlant at gmail.com
Sat Sep 28 06:26:47 EDT 2013


Hi Frank,

Thanks for your answer.
I added the outfile2.close(), unfortunately it didn't solve the problem.

Jonathan



On Fri, Sep 27, 2013 at 10:21 PM, Wallace, Frank L CIV NSWCDD, Q41 <
frank.l.wallace1 at navy.mil> wrote:

> I didn't see an "outfile2.close()" statement.  I don' t know if that
> matters.
>
> Thanks,
> Frank
>
> -----Original Message-----
> From: USRP-users [mailto:usrp-users-bounces at lists.ettus.com] On Behalf Of
> Jonathan Verlant-Chenet
> Sent: Friday, September 27, 2013 7:10 AM
> To: usrp-users at lists.ettus.com
> Subject: [USRP-users] PPS sync not working?
>
> Hi,
>
> My configuration is the following :
>
> *       2 USRP (RX) connected to my computer through a gigabit switch
>
> *       1 USRP (TX) continuusly sending QPSK signals over wired link
> between him and the two other USRPs (I use a SMA splitter to be sure the
> same signal is sent to both USRPs)
>
> *       A function generator (handyscope HS3) sending 1 Hz square signal
> to the PPS ports of both USRPs
>
> *       I'm trying to export the samples provided by both USRPs in 2
> different text files (to import them later in Matlab)
>
> *       I use a modified version of the example "rx_multi_samples.cpp",
> you can find my code below this email (the bold text are the parts that I
> added)
>
>
> The problem is that the recieved signals seems to be different :
> - text files doesn't have the same size (typicaly 9 Mb and 2 Mb)
> - When I import them to matlab, the correlation between the two signals is
> 0
>
> I tried to use "get_time_now()" and "get_time_synchronized()"  to verify
> sync between the 2 USRPs, it seems to be OK :
>
>
>         mb0 time 0.908774
>         mb1 time 0.910785
>         get_time_synchronized returns 1
>
>
> Thanks in advance for your help,
> Jonathan
>
>
>
> #include <uhd/utils/thread_priority.hpp> #include
> <uhd/utils/safe_main.hpp> #include <uhd/usrp/multi_usrp.hpp> #include
> <boost/program_options.hpp> #include <boost/format.hpp> #include
> <boost/thread.hpp> #include <boost/lexical_cast.hpp> #include
> <boost/algorithm/string.hpp> #include <iostream> #include <complex>
> #include <fstream>
>
>
>
>
> namespace po = boost::program_options;
>
>
> int UHD_SAFE_MAIN(int argc, char *argv[]){
>     uhd::set_thread_priority_safe();
>
>
>     //variables to be set by po
>     std::string args, file, file2, sync, subdev, channel_list;
>     double seconds_in_future;
>     size_t total_num_samps;
>     double rate, freq, gain;
>
>
>     //setup the program options
>     po::options_description desc("Allowed options");
>     desc.add_options()
>         ("help", "help message")
>         ("args",
> po::value<std::string>(&args)->default_value("addr0=192.168.192.101,
> addr1=192.168.192.201"), "multiple uhd device address args")
>         ("file",
> po::value<std::string>(&file)->default_value("test1.txt"), "name of the
> file to write binary samples to")
>         ("file2",
> po::value<std::string>(&file2)->default_value("test2.txt"), "name of the
> file to write binary samples to")
>         ("secs", po::value<double>(&seconds_in_future)->default_value(1),
> "number of seconds in the future to receive")
>         ("nsamps",
> po::value<size_t>(&total_num_samps)->default_value(500000), "total number
> of samples to receive") // default : 10000 | 500000
>         ("rate", po::value<double>(&rate)->default_value(100e6/10), "rate
> of incoming samples")
>         ("freq", po::value<double>(&freq)->default_value(2449000000), "rf
> center frequency in Hz")
>         ("gain", po::value<double>(&gain)->default_value(50), "gain for
> the RF chain")
>         ("sync", po::value<std::string>(&sync)->default_value("pps"),
> "synchronization method: now, pps, mimo")
>         ("subdev", po::value<std::string>(&subdev), "subdev spec
> (homogeneous across motherboards)")
>         ("dilv", "specify to disable inner-loop verbose")
>         ("channels",
> po::value<std::string>(&channel_list)->default_value("0"), "which
> channel(s) to use (specify \"0\", \"1\", \"0,1\", etc)")
>     ;
>     po::variables_map vm;
>     po::store(po::parse_command_line(argc, argv, desc), vm);
>     po::notify(vm);
>     bool verbose = vm.count("dilv") == 0;
>
>
>     //create a usrp device
>     std::cout << std::endl;
>     std::cout << boost::format("Creating the usrp device with: %s") % args
> << std::endl << std::endl;
>     uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
> std::cout << std::endl;
>
>
>     //set the rx sample rate (sets across all channels), set the rx center
> frequency, set the rx rf gain
> usrp->set_rx_rate(rate); std::cout << boost::format("Actual RX Rate: %f
> usrp->Msps...") % (usrp->get_rx_rate()/1e6) << std::endl;
>     usrp->set_rx_freq(freq); std::cout << boost::format("Actual RX Freq:
> %f Mhz...") % (usrp->get_rx_freq()/1e6) << std::endl;
>     usrp->set_rx_gain(gain); std::cout << boost::format("Actual RX Gain:
> %f dB...") % usrp->get_rx_gain() << std::endl << std::endl;
>
>
> //sync
>     std::cout << boost::format("Setting device timestamp to 0...") <<
> std::endl;
>     usrp->set_time_source("external");
> usrp->set_time_unknown_pps(uhd::time_spec_t(0.0));
> //boost::this_thread::sleep(boost::posix_time::seconds(1)); //wait for pps
> sync pulse
>
>
> std::cout << "mb0 time " << usrp->get_time_now(0).get_real_secs() <<
> std::endl; std::cout << "mb1 time " <<
> usrp->get_time_now(1).get_real_secs() << std::endl; std::cout <<
> usrp->get_time_synchronized() << std::endl;
>
>
>     //detect which channels to use
>     std::vector<std::string> channel_strings;
>     std::vector<size_t> channel_nums;
>     boost::split(channel_strings, channel_list, boost::is_any_of("\"',"));
>     for(size_t ch = 0; ch < channel_strings.size(); ch++){
>         size_t chan = boost::lexical_cast<int>(channel_strings[ch]);
>         if(chan >= usrp->get_rx_num_channels()){
>             throw std::runtime_error("Invalid channel(s) specified.");
>         }
>         else
> channel_nums.push_back(boost::lexical_cast<int>(channel_strings[ch]));
>     }
>
>
>     //create a receive streamer
>     //linearly map channels (index0 = channel0, index1 = channel1, ...)
>     uhd::stream_args_t stream_args("fc32"); //complex floats
>     stream_args.channels = channel_nums;
>     uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
>
>
>     //setup streaming
>     std::cout << std::endl;
>     std::cout << boost::format(
>         "Begin streaming %u samples, %f seconds in the future..."
>     ) % total_num_samps % seconds_in_future << std::endl;
>     uhd::stream_cmd_t
> stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
>     stream_cmd.num_samps = total_num_samps;
>     stream_cmd.stream_now = false;
>     stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future);
>     usrp->issue_stream_cmd(stream_cmd); //tells all channels to stream
>
>
>     //meta-data will be filled in by recv()
>     uhd::rx_metadata_t md;
>
>
>     //allocate buffers to receive with samples (one buffer per channel)
>     const size_t samps_per_buff = rx_stream->get_max_num_samps();
>     std::vector<std::vector<std::complex<float> > > buffs(
>         usrp->get_rx_num_channels(), std::vector<std::complex<float>
> >(samps_per_buff)
>     );
>
>
>     //create a vector of pointers to point to each of the channel buffers
>     std::vector<std::complex<float> *> buff_ptrs;
>     for (size_t i = 0; i < buffs.size(); i++)
> buff_ptrs.push_back(&buffs[i].front());
>
>
>     //the first call to recv() will block this many seconds before
> receiving
>     double timeout = seconds_in_future + 0.1; //timeout (delay before
> receive + padding)
>
>
>     size_t num_acc_samps = 0; //number of accumulated samples
>     std::ofstream outfile(file.c_str(), std::ofstream::out); std::ofstream
> outfile2(file2.c_str(), std::ofstream::out);
>
>
>
>
>     while(num_acc_samps < total_num_samps){
>         //receive a single packet
>         size_t num_rx_samps = rx_stream->recv(
>             buff_ptrs, samps_per_buff, md, timeout
>         );
>
>
>         //use a small timeout for subsequent packets
>         timeout = 0.1;
>
>
>         //handle the error code
>         if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break;
>         if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
>             throw std::runtime_error(str(boost::format(
>                 "Unexpected error code 0x%x"
>             ) % md.error_code));
>         }
>
>
>         // if(verbose) std::cout << boost::format("Received packet: %u
> samples, %u full secs, %f frac secs") % num_rx_samps %
> md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl;
>
>
> for (int idxFile = 0;idxFile<=num_rx_samps-1;idxFile++)
> {
> outfile<<buffs[0][idxFile].real()<<std::endl; //writing real part from
> USRP 192.168.192.101 outfile<<buffs[0][idxFile].imag()<<std::endl;
> //writing imaginary part from USRP 192.168.192.101
> outfile2<<buffs[1][idxFile].real()<<std::endl; //writing real part from
> USRP 192.168.192.201
>
> outfile2<<buffs[1][idxFile].imag()<<std::endl; //writing imaginary part
> from USRP 192.168.192.201 }
>
>         num_acc_samps += num_rx_samps;
>     }
>
>
>     if (num_acc_samps < total_num_samps) std::cerr << "Receive timeout
> before all samples received..." << std::endl;
>
>
>     outfile.close();
>
>
>     //finished
>     std::cout << std::endl << "Done!" << std::endl << std::endl;
>
>
>     return EXIT_SUCCESS;
> }
>
>
>
>
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ettus.com/pipermail/usrp-users_lists.ettus.com/attachments/20130928/81a3c12d/attachment-0002.html>


More information about the USRP-users mailing list