rtl_sdr:可靠地检测频率变化,丢弃之前获得的样本
rtl_sdr: reliably detect frequency changes, discard samples obtained prior
我正在使用 rtl_sdr 和通用 DVB-T 棒(调谐器是 FC0013)为模拟 FM 收音机编写搜索例程。代码主要取自 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 failed\n");
/* 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 failed\n");
/* rssi = getRssiFromSamples(samples, samplesRead) */
fprintf(stderr, "\nSeek: rssi=%.2f\n", 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()
returns 之前完成调谐吗?还是调谐器在此之后需要一些时间来稳定?在后一种情况下,我如何可靠地判断频率更改何时完成?
- 还有什么我可能遗漏的吗?
再次查看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 值开始稳定,即变化不再单调或低于某个阈值。
我正在使用 rtl_sdr 和通用 DVB-T 棒(调谐器是 FC0013)为模拟 FM 收音机编写搜索例程。代码主要取自 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 failed\n");
/* 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 failed\n");
/* rssi = getRssiFromSamples(samples, samplesRead) */
fprintf(stderr, "\nSeek: rssi=%.2f\n", 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()
returns 之前完成调谐吗?还是调谐器在此之后需要一些时间来稳定?在后一种情况下,我如何可靠地判断频率更改何时完成? - 还有什么我可能遗漏的吗?
再次查看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 值开始稳定,即变化不再单调或低于某个阈值。