Как да тестваме нашия RTL-SDR в RadioConda среда. Можем ли да го използваме за наблюдение на водородната линия?
Трябва да знаете, че следните две команди ще работят ако имаме инсталирана RadioConda среда, командите тръгват вътре в нея. В нашия случай ще изследваме RTL-SDR FM/DAB+ADS-B Receiver (TCXO 0.5 PPM R820T)

- rtl_test
- rtl_power
rtl_test

Found 1 device(s)
Using device 0: Generic RTL2832U OEM
Found Fitipower FC0013 tuner
Устройството е разпознато и тунерът е FC0013
Supported gain values (23): -9.9 -7.3 … 19.7
Списък с gain стъпките, които тунерът поддържа.
Sampling at 2048000 S/s.
Reading samples in async mode…
Това е стандартният тест — чете данни с 2.048 MS/s.
lost at least 32 bytes
lost at least 16 bytes
Това означава загуба на проби. Възможни причини са USB порта не смогва, лош контакт, слаб кабел, натоварен компютър, скоростта на семплиране е твърде висока, драйверът или USB контрлерът не се справят добре.
Проблеми които могат да се покажат:
- usb_open error -3 → драйверът не е WinUSB или устройството е заето
- no supported tuner found → хардуерен проблем
rtl_power

-f 1415M:1425M:10k
Честотен диапазон: от 1415 MHz до 1425 MHz
Стъпка: 10 kHz
-g 20
Усилване: 20 dB (реално е избрал най-близкото – 19.70 dB)
-i 1
Интервал: запис на данни на всеки 1 секунда
-e 30s
Време на измерване: 30 секунди
test.csv
Файлът, в който се записва спектърът.
Number of frequency hops: 4
Диапазонът 1415–1425 MHz е по-широк от моментната честотна лента на донгъла (~2.5 MHz), затова той го „обхожда“ на 4 поддиапазона.
Dongle bandwidth: 2500000 Hz
Честотна лента на RTL‑SDR
Total FFT bins / Logged FFT bins: 1024
Спектърът е разделен на 1024 честотни „кошчета“ (bins), всички се записват.
FFT bin size: 9765.62 Hz
Всяко bin покрива ~9.8 kHz честотна ширина.
Reporting every 1 seconds
На всяка секунда се записва по един ред (за целия обхванат диапазон).
Файлът с данните може да се отвори с Excel, Libre Office или с друг текстов редактор. Със скрипт на Python можем да го визуализираме.
rtl_power -f 88M:108M:10k -g 20 -i 1 -e 30s fm.csv
Това е команда за тест от 88 MHz до 108 MHz и изображението генерирано от получените данни.

rtl_power -f 1415M:1425M:10k -g 20 -i 1 -e 30s test.csv
Нека проверим какво се получава при 1420.4? Това е водородната линия.

Оказва се, че и да искаме не можем да използваме този приемник за наблюдение на любимата ни водородна линия. Чипът FC0013 използван за направата му е доста стар и не работи стабилно над 1 GHz. Официалния мудиапазон е от 22MHz до 1100 MHz. По различни сайтове се представя, че работи до над 1700 MHz, но реалноста е друга. Ето и изображение от 1080 MHz до 1100 MHz. На 1090 MHz се предават ADS-B сигналите (Automatic Dependent Surveillance–Broadcast), чрез които съвременните самолети съобщават своята позиция, скорост и височина в реално време.

Примерен код за Python, който ще визуализира записания файл .csv
import numpy as np
import matplotlib.pyplot as plt
from collections import defaultdict
filename = r"C:/rr/work/test5.csv"
# групиране по timestamp (дата+час)
groups = defaultdict(list)
with open(filename, "r") as f:
for line in f:
if line.startswith("#"):
continue
parts = [p.strip() for p in line.strip().split(",")]
date = parts[0]
time = parts[1]
key = f"{date} {time}"
start_f = float(parts[2])
end_f = float(parts[3])
powers = []
for x in parts[6:]:
try:
powers.append(float(x))
except:
powers.append(np.nan)
groups[key].append((start_f, end_f, powers))
# за всеки timestamp: сортираме по start_f и слепваме по честота
rows = []
for key in sorted(groups.keys()):
chunks = sorted(groups[key], key=lambda x: x[0]) # по start_f
row_powers = []
for start_f, end_f, pwr in chunks:
row_powers.extend(pwr)
rows.append(row_powers)
# подравняване по минимална дължина
min_len = min(len(r) for r in rows)
rows = [r[:min_len] for r in rows]
data = np.array(rows)
# честотна ос – от най-малкия start до най-големия end
all_starts = [c[0] for chunks in groups.values() for c in chunks]
all_ends = [c[1] for chunks in groups.values() for c in chunks]
f_start = min(all_starts) / 1e6
f_end = max(all_ends) / 1e6
bins = data.shape[1]
freqs = np.linspace(f_start, f_end, bins)
plt.figure(figsize=(14, 6))
plt.imshow(
data,
aspect='auto',
origin='lower',
cmap='viridis',
vmin=np.nanpercentile(data, 5),
vmax=np.nanpercentile(data, 95)
)
plt.colorbar(label='Power (dB)')
xticks = np.linspace(0, bins-1, 10)
plt.xticks(xticks, np.round(np.linspace(freqs[0], freqs[-1], 10), 1))
plt.xlabel('Frequency (MHz)')
plt.ylabel('Time')
plt.title('RTL Power Heatmap (FM Band, stitched by timestamp)')
plt.show()
