从零开始USRP 03 实现一个USRP收发demo(hello world)

发布时间 2023-04-10 19:22:20作者: 爱和九九

这里用的源码来自:

UHD C/C++ 编程实例 USRP发送、接收数据

我所使用的USRP型号是N210r4,因此默认地址的最后一位是4,使用Ubuntu 20.04运行(至于为什么之前配的是18.04,那是因为之前是在我的虚拟机上玩耍的,但是我的虚拟机配网络有点麻烦,因此我给学姐的学长借了一台Linux笔记本,用这台笔记本做的实验。)

我的N210照片如下:

 

 

 编译命令:

g++ rx.cpp -o rx -luhd

tx同理。

实际上,Cmake和G++在我电脑上的虚拟机上都很好使,但是在师姐给的这台linux上都很不好使,版本有点低,比如需要uhdlib4.0.0.0这个问题,当然这种简单的版本问题不存在什么学会学不会,只存在知道不知道,直接问ChatGPT老师就可以了。与此同时我也出现了找不到hpp文件的问题,也是直接问gpt老师就可以了,一般它列出来的条例能够解决99%的问题。但即使这样,在师姐上重新编译我已经编译好的文件,也废了我不少功夫。

 

 

 后来呢,Tx和Rx两个cpp都编译好了,开始发射。

Tx运行正常,Rx运行正常!

只是二者都有亿点点warning,无视就好了(坏习惯,但是跑个hello world,你不无视,你不无视,你不无视尼玛呢!!)

然而,二者只是单独运行正常,周一来了我同时开始跑两个程序,即首先打开接收程序,然后开始发射,然后呢?接收程序就崩溃了,报了一个错误:

 

 

 随后,我开始解决,解决了一整天,硬是解决不了。这次,这个问题网上基本上没有人遇到类似的问题,

 

 

找到的唯一和我报错相同的帖子只有这个:https://github.com/EttusResearch/uhd/issues/121
但是人家做的事情和我在做的事情基本没啥关系,而且这个帖子的问题最终也没有得到解决……
当然了,研究了一整天,问了师兄问了师姐,师兄后来还开始了玄学调bug哈哈可爱捏,最后得出了问题的根源。我这么好的人,我当然要在那个没有解决问题的帖子下面回复一下辣:

 

 

 

 


对没错,我研究了一整天的问题,很有可能就是因为,一台USRP只能使用一个程序来调用。可能这对于这个领域的人来说这简直是吃饭睡觉一样的常识性问题,但是对于我,一个从来没有接触过硬件的小白来说,这真的问题很大好吧,一整天的时间全部浪费了。

此外,这种常识性的问题,ChatGPT老师知道吗?

 

 我就是问过他之后,我才肯定的这一点。

可以写到一个程序中调用收发,但是线程又很有可能出大问题……因此,我不玩了,先这样吧,这个HelloWorld浪费的时间太多了。我还是喜欢两个程序,调用两台USRP去模拟。但是我来福州出差就带了一台USRP,等回到清华之后,我找两台USRP来测试一下,按理来说,下面粘好的两版代码应该是没有问题了。

 

源码:

发射数据:

 

#include <uhd/usrp/multi_usrp.hpp>
#include <signal.h>
 
#define SAMPLE_PER_BUFF 2000
 
int stop_signal_called = 0;
void sig_int_handle(int)
{
    stop_signal_called = 1;
    printf("stop tx.........\n");
    exit(0);
}
 
int main()
{
    std::string addr_args = "addr=192.168.10.4";
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(addr_args);
    printf("Create a usrp......\n");
 
    // set the ref and clock rate
    std::string ref = "internal";
    usrp->set_clock_source(ref);
 
    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f \n", usrp->get_master_clock_rate() );
 
    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_tx_rate(samp_rate);
    printf("set the tx sample rate to %0.2f \n", usrp->get_tx_rate());
 
    // set the center frequency
    float center_freq = 2.412e9;
    usrp->set_tx_freq(center_freq);
    printf("set the tx center freq to %0.2f \n", usrp->get_tx_freq());
 
    // set the rf gain
    float tx_gain = 90;
    usrp->set_tx_gain(tx_gain);
    printf("set the tx gain to %0.2f \n", usrp->get_tx_gain());
 
 
    // create a tx stream
    std::string cpu_format = "fc32";
    std::string wire_format = "sc16";
    uhd::stream_args_t stream_args(cpu_format, wire_format);
    uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args);
 
    uhd::tx_metadata_t md;
 
    // catch the INT signal
    signal(SIGINT, sig_int_handle);
    float read_buff[SAMPLE_PER_BUFF * 2] = {0};
 
    while(!stop_signal_called)
    {
        FILE *fp = fopen("hello_world.txt", "rb");
        md.start_of_burst = false;
        md.end_of_burst = false;
 
 
        while( (!md.end_of_burst) && (!stop_signal_called) )
        {
            int read_length = 0;
            if( (read_length = fread(read_buff, sizeof(uint32_t), SAMPLE_PER_BUFF * 2, fp) ) == (SAMPLE_PER_BUFF * 2) )
            {
                //int index;
                //for(index = 0; index < SAMPLE_PER_BUFF * 2; index++)
                //    printf("%0.2f ", read_buff[index]);
                //puts("");
 
                //md.start_of_burst = true;
                tx_stream->send(read_buff, SAMPLE_PER_BUFF, md);
                //md.start_of_burst = false;
                //sleep(1);
            }
            else if(read_length >= 0)
            {
                md.end_of_burst = true;
            }
        }
 
        fclose(fp);
    }
 
 
    return 0;
}

 

接收数据:

#include <uhd/usrp/multi_usrp.hpp>
#include <csignal>
 
#define SAMPLE_PER_BUFF 2000
 
int stop_signal_called = false;
void sig_int_handle()
{
    stop_signal_called = true;
}
 
int main()
{
    std::string addr_args = "addr=192.168.10.5";
    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(addr_args);
 
    // set the clock source and clock rate
    std::string ref = "internal";
    usrp->set_clock_source(ref);
 
    float clock_rate = 40e6;
    usrp->set_master_clock_rate(clock_rate);
    printf("set the  clock rate %0.2f \n", usrp->get_master_clock_rate() );
 
    // set the sample rate
    float samp_rate = 20e6;
    usrp->set_rx_rate(samp_rate);
    printf("set the tx sample rate to %0.2f \n", usrp->get_rx_rate());
 
    // set the center frequency
    float center_freq = 2.412e9;
    usrp->set_rx_freq(center_freq);
    printf("set the tx center freq to %0.2f \n", usrp->get_rx_freq());
 
    // set the rf gain
    float rx_gain = 80;
    usrp->set_rx_gain(rx_gain);
    printf("set the tx gain to %0.2f \n", usrp->get_rx_gain());
 
    std::string cpu_format = "fc32";
    std::string wire_format = "sc16";
    uhd::stream_args_t stream_args(cpu_format, wire_format);
    uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
 
    uhd::rx_metadata_t md;
 
    //uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
    uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
    stream_cmd.num_samps = SAMPLE_PER_BUFF;
    stream_cmd.stream_now = true;
    //stream_cmd.time_spec = uhd::time_spec_t();
    stream_cmd.time_spec = usrp->get_time_now();
    rx_stream->issue_stream_cmd(stream_cmd);
 
    uint32_t buff[SAMPLE_PER_BUFF*2] = {0};
    unsigned long long num_total_samps = 0;
 
    while(!stop_signal_called)
    {
        //int num_rx_samps = rx_stream->recv(buff, SAMPLE_PER_BUFF, md);
        memset(buff, 0, SAMPLE_PER_BUFF * sizeof(uint32_t));
        int num_rx_samps = rx_stream->recv(buff, SAMPLE_PER_BUFF, md, 3.0, false);
        if(md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
        {
            printf("Timeout while streaming......\n");
            break;
        }
        if(md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
        {
            printf("Overflowing while stream......\n");
            continue;
        }
        if(md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
        {
            //printf("Receive error: %s \n", md.strerror());
            continue;
        }
 
    //printf("num_rx_samps = %d \n",num_rx_samps);
        num_total_samps += num_rx_samps;
 
    }
    printf("num_total_samps = %lld \n", num_total_samps);
 
    stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS;
    rx_stream->issue_stream_cmd(stream_cmd);
 
    return 0;
}