从零开始USRP 04 连接硬件的时候的一些教训

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

在连接硬件的时候出现了一堆问题,大概记录一下。

我用的代码是:https://www.cnblogs.com/loveandninenine/p/17286194.html

然而,连接到硬件上,收端收不到,发射端发不出去,哈哈哈哈哈哈呕了。

先说一下我的硬件连接。

我一共用了三台USRP,其中A设备负责发射,BC设备负责接收。BC之间做了同步。

首先,关于发射端,我用的确实是tx.cpp那个代码,但是那个代码并没有成功发射。这里注意,发射的时候最好是设置一点间隔,比如1ms,sleep(1),不能sleep太久,也不能不sleep,否则容易导致收不到信息。

另外,传输的内容最好是用MATLAB生成的有意义的数据,这样传输过去可以查看是不是真的接受到了。

 

那有人就要问了,你是不是,硬件连接有毛病啊?天线有问题?

并没有,我用gnuradio测试过了,硬件绝对是可以正常发射和接收的,而且我没有使用天线,直接用导线连接的tx和rx口,其中用了一个分线器。然而,两边的gunradio,任意一端换成我的cpp文件都没法正常使用。

其实最后tx仍然是有点问题的,我也不知道为什么收不到,我明明是循环不停发送一个文件的啊……

最后改好了rx.cpp,可以收了。

为什么rx开始有问题?

主要是因为:stream_cmd.stream_now = false;

最一开始的时候,我们设置的这个stream_now是false。

咋说呢,最早找的rx代码其实这个值是个true,它表示控制流将立即执行流里的命令,但是为了做同步,我们需要设置成false,让两台USRP同时执行命令。

简码如下:

// create receive streamers for both USRPs
uhd::stream_args_t rx_stream_args("fc32", wire); // complex floats
rx_stream_args.channels = "0,1,2,3";
uhd::rx_streamer::sptr rx_stream_usrp0 = usrp0->get_rx_stream(rx_stream_args);
uhd::rx_streamer::sptr rx_stream_usrp1 = usrp1->get_rx_stream(rx_stream_args);

// setup streaming for both USRPs
uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
stream_cmd.stream_now = false;
stream_cmd.time_spec = uhd::time_spec_t(usrp0->get_time_now() + uhd::time_spec_t(1.0));
rx_stream_usrp0->issue_stream_cmd(stream_cmd);

stream_cmd.time_spec = uhd::time_spec_t(usrp1->get_time_now() + uhd::time_spec_t(1.0));
rx_stream_usrp1->issue_stream_cmd(stream_cmd);

// receive samples from both USRPs
uhd::rx_metadata_t md;
std::vector<std::complex<float>> buff_usrp0(usrp0_rx_buff_size);
std::vector<std::complex<float>> buff_usrp1(usrp1_rx_buff_size);

while (true) {
    size_t num_rx_samps_usrp0 = rx_stream_usrp0->recv(&buff_usrp0[0], buff_usrp0.size(), md, 1.0);
    size_t num_rx_samps_usrp1 = rx_stream_usrp1->recv(&buff_usrp1[0], buff_usrp1.size(), md, 1.0);

    // process received samples from both USRPs
    // ...
}

当然,USRP必然要声明两个,但是stream_cmd不需要那么多,可以只声明一个,但是我们声明一个之后,发现跑不起来,一直timeout,所以我们让ChatGPT帮着写了上面的版本,ChatGPT声明了两个,因此我们也照葫芦画瓢,发现仍然跑不起来……每次都是有一个能正常运行,另一个没有跑动,还是timeout。

原来,这里还涉及到一个问题,timeout的类型有很多,很多问题都可能是timeout,这里的问题在于我们没有接入时钟源。GPT老师写的没有问题,快谢谢神奇的GPT老师。

什么意思,我们做同步为什么没有接入时钟源呢?因为我们最早的时候用gnuradio跑通了,我们就把时钟源拆掉了……接下来只是在调试代码,想跑通代码,后来发现,不接入时钟源是没办法跑通的。所有的USRP都是interval的时钟源,然而两个USRP的时间并不一致, 因此虽然我们让两个USRP都获得了当前时间“get_time_now”,但是二者get到的time_now可能会差出非常离谱的误差,因此等待这几秒时间后发现,我可以走了,但是你还早着呢,或者我可以走了,但是你早就该走了,已经超时了,因此就报出了timeout。

解决方案就是找一个时钟源接入,就可以跑通啦~~~

讲道理,这些api写的真的一般,timeout能不能细化一下,我一直以为是接不到数据,结果最后的问题是接不到命令,或者命令响应超时,但凡提醒我一下这个问题我都能立马接入时钟源。