Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <uhd/usrp/multi_usrp.hpp>
- #include <vector>
- #include <complex>
- #include <boost/shared_ptr.hpp>
- #include <boost/thread/future.hpp>
- #include <boost/thread/shared_mutex.hpp>
- #define LOG_DEBUG std::cout
- #define newl std::endl;
- void Receive_Thread(boost::shared_ptr<uhd::usrp::multi_usrp> usrp,
- boost::shared_mutex& mutex);
- /**
- * Generates a simple tone based on the specified parameters
- * @param data buffer is automatically resized appropriately
- * @param freq tone frequency in hertz
- * @param amplitude max amplitude
- * @param fs sample rate in hertz
- * @param size number of samples
- */
- void Generate_Tone(std::vector<std::complex<float>>&data, double freq,
- double amplitude, double fs, double size);
- /**
- * Dumps the vector to a simple python file that can be used for visualization
- * @param data iq vector
- * @param rate sample rate with which the data was acquired
- * @param path save location including file name e.g. "/home/bob/file.py"
- */
- void Dump_to_Py(std::vector<std::complex<float> >& data, float rate,
- const std::string& path);
- //
- int main() {
- auto _usrp = uhd::usrp::multi_usrp::make(std::string(""));
- //configure tx first
- bool ack_reveived = false;
- std::vector<std::complex<float>> buffer;
- double rate = 1e6;
- double atten = 20;
- _usrp->set_tx_rate(rate);
- _usrp->set_tx_bandwidth(56e6);
- _usrp->set_tx_gain(30 + atten);
- uhd::tune_request_t tune(3.8e9);
- _usrp->set_tx_freq(tune);
- //create a 1kHz tone vector, 100k samples, 1M sample rate
- Generate_Tone(buffer, 1e3, 0.8, rate, 100e3);
- uhd::tx_metadata_t meta_data;
- meta_data.has_time_spec = false;
- meta_data.end_of_burst = true;
- meta_data.start_of_burst = true;
- LOG_DEBUG << "Tx waiting for Rx to begin receiving... " << newl;
- //configure and run an acquisition, use the mutex to know when the
- //acquisition begins
- boost::shared_mutex mutex;
- mutex.lock();
- //**************************************************************************
- //uncomment to see the issue disappear
- //uhd::stream_args_t stream_args("fc32"); // complex floats
- //auto streamer = _usrp->get_tx_stream(stream_args);
- //**************************************************************************
- auto rx_future = boost::async(boost::bind(&Receive_Thread,
- _usrp, boost::ref(mutex)));
- mutex.lock();
- LOG_DEBUG << "Got lock" << newl;
- //wait 100ms to show that the data rx is receiving is reasonable
- //play with this sleep to see the '0's move around in the captured waveform
- usleep(100 * 1000);
- LOG_DEBUG << "Creating tx streamer" << newl;
- uhd::stream_args_t stream_args("fc32"); // complex floats
- stream_args.channels = std::vector<size_t>(1, 0);
- auto streamer = _usrp->get_tx_stream(stream_args);
- LOG_DEBUG << "Transmitting..." << newl;
- auto sent = streamer->send(&buffer.at(0), buffer.size(), meta_data, 2);
- LOG_DEBUG << "Tx done" << newl;
- LOG_DEBUG << "Waiting for rx to complete..." << newl;
- rx_future.get();
- LOG_DEBUG << "Rx done" << newl;
- }
- void Receive_Thread(boost::shared_ptr<uhd::usrp::multi_usrp> usrp, boost::shared_mutex& mutex) {
- LOG_DEBUG << "rx thread started" << newl;
- double rate = 1e6;
- usrp->set_rx_rate(rate);
- usrp->set_rx_bandwidth(56e6);
- usrp->set_rx_gain(45);
- //offset the LO slightly
- uhd::tune_request_t tune(3.8e9 + 100e3);
- usrp->set_rx_freq(tune);
- std::vector<std::complex<float>> iq_data;
- size_t count = 300000;
- iq_data.resize(count);
- uhd::stream_args_t stream_args("fc32"); // complex floats
- stream_args.channels = std::vector<size_t>(1, 0);
- auto rx_stream = usrp->get_rx_stream(stream_args);
- uhd::stream_cmd_t start_stream_cmd(
- uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
- start_stream_cmd.stream_now = true;
- start_stream_cmd.num_samps = 0;
- // create the stream
- LOG_DEBUG << "Rx streaming started..." << newl;
- rx_stream->issue_stream_cmd(start_stream_cmd);
- //let the main (tx) thread know we're aquiring now
- mutex.unlock();
- size_t acquired = 0;
- uhd::rx_metadata_t rx_metadata;
- while (acquired < count) {
- acquired += rx_stream->recv(&iq_data.at(acquired), 50000, rx_metadata, 1);
- LOG_DEBUG << "Received: " << acquired << newl;
- }
- //stop
- uhd::stream_cmd_t stop_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
- stop_cmd.stream_now = true;
- stop_cmd.num_samps = 0;
- rx_stream->issue_stream_cmd(stop_cmd);
- //do a simple tally of consecutive zeros
- bool prev_was_0 = false;
- size_t zero_count = 0;
- for(auto & elem : iq_data){
- if(elem.real() == 0.0 && elem.imag() == 0){
- if(prev_was_0){
- zero_count++;
- }
- prev_was_0 = true;
- }
- }
- LOG_DEBUG << "Consecutive zeros count: " << zero_count << newl;
- Dump_to_Py(iq_data, rate, "/home/server/capture.py");
- }
- //
- void Generate_Tone(std::vector<std::complex<float>>&data, double freq,
- double amplitude, double fs, double size) {
- data.resize(size);
- for (int i = 0; i < size; i++) {
- double phase = 2 * M_PI * freq / fs*i;
- data.at(i) = std::complex<float>(amplitude * std::cos(phase),
- amplitude * std::sin(phase));
- }
- }
- //
- void Dump_to_Py(std::vector<std::complex<float> >& data, float rate,
- const std::string& path) {
- FILE* fid = fopen(&path.front(), "w");
- fprintf(fid, "import numpy as np\n");
- fprintf(fid, "import pylab as pl\n");
- fprintf(fid, "if(__name__ == \"__main__\"):\n");
- fprintf(fid, " x = np.zeros(%d, dtype=np.complex64)\n", data.size());
- for (int i = 0; i < data.size(); i++) {
- fprintf(fid, " x[%4u] = %12.4e + 1j*%12.4e\n", i, data.at(i).real()
- , data.at(i).imag());
- }
- fprintf(fid, " pl.figure()\n");
- fprintf(fid, " pl.plot(np.real(x))\n");
- fprintf(fid, " pl.plot(np.imag(x))\n");
- fprintf(fid, " pl.show()\n");
- // fprintf(fid, " return x, %f\n",rate);
- fclose(fid);
- }
Add Comment
Please, Sign In to add comment