Multi-USRP recv and save to file
USRP_RX_MULTI_RECV is used to create multi::usrp object of multiple synched SDR to recevive samples to files (metadata + IQ).
This modified work is based on tutorials provifded by Nilanjan from WINLAB. Some improvements are made with syncing up multi USRPs, exploring multi::usrp buffers and samps read with post-processing provided in MATLAB.
This simple probram acts as an illustration to help users understand how multi::usrp works for developing more complicated programs as Sounder
PLease install UHD here.
$ git clone https://github.com/Shadowcaster77/USRP_RX_MULTI_RECV.git
$ mkdir build
$ cd build
$ cmake ../
$ make
To check parameters that can be specified:
./rx_multi_receive --help
Example:
./rx_multi_receive --nsamps 1024 --rate 5e6 --args="addr0=10.10.23.2,addr1=10.10.23.3, … addr7=10.10.24.2" --subdev "A:0 B:0" --channels "0, 1, ... , 14, 15" --prefix "x310_`$now`_" --sync "pps" --secs 5
The program saves two files each run: metadata + IQ_binary files. To check information of Metadata:
more <metadata file name>
To have a quick view of binary file:
hexdump -v -e '"%010_ad [" 2/4 " %f " " ]\n"' <binary file name>
MATLAB post-processing is also being attached in the MATLAB_PostProcess folder, which the input file names is being hard-coded in the probram, users might need to make changes correspondingly on that. For example in plot_w_delay.m:
fileID = fopen('file name');
A = fread(fileID, 'float');
areal = A([1:2:length(A)]);
aimg = A([2:2:length(A)]);
Some parts of the C++ code can be modified by users' intend
The samps_per_buff
in the following can be set to arbitrary numers.
In the following implementation, the samps_per_buff
is set to be equal to total_num_samps
, which only reuslt in one recv() call throughtout
//receive multi channel buffers
size_t num_rx_samps = rx_stream->recv( MultiDeviceBufferPtrs.at(mdbp_idx++), samps_per_buff, md, timeout);
//use a small timeout for subsequent packets
timeout = 0.1;
Notice there is a limit (which depends on system) that the program can support, if the total number of samps users want to specify is going to be very large, the following revision is recommended:
while(num_acc_samps < total_num_samps){
//receive multi channel buffers
size_t num_rx_samps = rx_stream->recv( MultiDeviceBufferPtrs.at(mdbp_idx++), 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;
else if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) continue;
else if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
throw std::runtime_error(str(boost::format("Recv'd samples %i\nReceiver error %s") % num_acc_samps % md.strerror()));
}
where samps_per_buff
can be set to a relatively small number as:
smap_er_buff = rx_stream->get_max_num_smaps(); // which actually it can go over this max