我正在使用带有通用DVB-T棒的RTL_SDR编写模拟FM无线电的Seek例程(调谐器是FC0013(。代码主要取自rtl_power.c
和rtl_fm.c
。
我的方法是:
- 调整新频率
- 收集一些样品
- 测量RSSI并存储它
- 对下一个频率做同样的事情
- 检测到高于一定阈值的局部峰后,调整了检测到的频率。
问题是我无法可靠地将样本映射到它们收集的频率。这是相关(伪(代码段:
/* freq is the new target frequency */
rtlsdr_cancel_async(dongle.dev);
optimal_settings(freq, demod.rate_in);
fprintf(stderr, "nSeek: currently at %d Hz (optimized to %d).n", freq, dongle.freq);
rtlsdr_set_center_freq(dongle.dev, dongle.freq);
/* get two bursts of samples to measure RSSI */
if (rtlsdr_read_sync(dongle.dev, samples, samplesSize, &samplesRead) < 0)
fprintf(stderr, "nSeek: rtlsdr_read_sync failedn");
/* rssi = getRssiFromSamples(samples, samplesRead) */
fprintf(stderr, "nSeek: rssi=%.2f", rssi);
if (rtlsdr_read_sync(dongle.dev, samples, samplesSize, &samplesRead) < 0)
fprintf(stderr, "nSeek: rtlsdr_read_sync failedn");
/* rssi = getRssiFromSamples(samples, samplesRead) */
fprintf(stderr, "nSeek: rssi=%.2fn", rssi);
当我用代码段扫描FM频段时,我看到两个RSSI测量值通常会显着差异。特别是,第一个测量通常位于从前频率中采取的第二个测量的附近,表明某些样品仍被调整为旧频率。
。我还尝试在收集样品之前插入rtlsdr_reset_buffer()
的呼叫,以冲洗所有仍然卡在管道中的样品,但没有明显的效果。甚至
usleep(500000);
rtlsdr_cancel_async(dongle.dev);
rtlsdr_reset_buffer(dongle.dev)
除了usleep()
大大减慢搜索操作之外,不会更改图片。(缓冲区的大小为16384个样本,样本率为200万,因此usleep()
延迟远高于获取样品爆发所需的时间。(
如何确保在调整新频率之后获得我的样品?
- 是否有任何样品缓冲区,我需要在调整不同频率后需要冲洗?
- 我可以依靠
rtlsdr_set_center_freq()
返回时间完成调音,还是调谐器需要一些时间才能稳定?在后一种情况下,我该如何可靠地分辨何时完成频率? - 我可能错过了什么?
再次浏览rtl_power.c
的代码,我找到了此功能:
void retune(rtlsdr_dev_t *d, int freq)
{
uint8_t dump[BUFFER_DUMP];
int n_read;
rtlsdr_set_center_freq(d, (uint32_t)freq);
/* wait for settling and flush buffer */
usleep(5000);
rtlsdr_read_sync(d, &dump, BUFFER_DUMP, &n_read);
if (n_read != BUFFER_DUMP) {
fprintf(stderr, "Error: bad retune.n");}
}
本质上,调谐器需要安定下来,没有明显的指标表明该过程何时完成。
rtl_power.c
通过等待5毫秒,然后丢弃一些样品(BUFFER_DUMP
定义为4096,以1-2.8m之间的样本定义(解决了这一问题。
我发现4096个样本不足,所以我最多获得了16384。结果看起来更加稳定,尽管即使这似乎并不总是足以使调谐器稳定。
对于频带扫描,另一种方法是使循环获取样品并确定其RSSI,直到RSSI值开始稳定为止,即变化不再单调或低于某个阈值。