Водоспад діапазону за допомогою SDR-приймача
Архівний запис.
Добре було б записувати історію водоспаду протягом дня чи тижня, щоб потім її аналізувати. Для цього є чудова програмка rtl_power від Kyle Keen. Але є заковика: для роботи rtl_power потрібен окремий SDR-приймач. Тут нам на допомогу приходить OpenWebRX. Ми просто створюємо ще одне TCP-з’єднання через NetCat і тягнемо потік сирих даних для обробки.
Обробляти дані будемо так само за допомогою csdr, у якого є спеціальні опції для обробки FFT.
csdr fft_cc <fft_size> <out_of_every_n_samples>
csdr logaveragepower_cf <add_db> <fft_size> <avgnumber>
csdr fft_exchange_sides_ff <fft_size>
Спочатку я використовував fft_size = 4096, і виходили картинки 4096px X 44000px, які практично неможливо було відкрити в браузері. Приклад водоспаду за 30 хвилин при значенні 4096, вага картинки 3.2Mb. Тому поки що зупинився на числі 1024. Число обов’язково має бути степенем двійки. Параметр out_of_every_n_samples відповідає за те, скільки семплів буде пропущено перед наступною видачею даних. Не дуже розумію, як правильно його вираховувати, але при значеннях fft_cc 1024 109226 роздільна здатність картинки виходить 1.4khz і 2 секунди на один піксель. Тобто по вертикалі 5 пікселів дорівнюють 10 секундам, чого, на мій погляд, вистачить для огляду, і файл не виходитиме аж надто довгим.
У підсумку в мене вийшла така команда, яка раз на 2 секунди видає значення в децибелах, кожне з яких відповідає одному пікселю.
nc -v 127.0.0.1 4951 | csdr convert_u8_f | csdr fft_cc 1024 109226 | csdr logaveragepower_cf -80 1024 40 | csdr fft_exchange_sides_ff 1024 | csdr dump_f
Можна було б написати програму, яка за цими даними будувала б водоспад тощо, але я вирішив зробити потокове конвертування даних у формат rtl_power, щоб використовувати вже наявні побудовники:
- rtl-gopow — його ми й використовуватимемо, бо він найшвидший.
- heatmap.py
- flatten.py — Turn a 2D table into a 1D line. Useful for generating noise and RA plots.
- ViewRF — Spectrum analyzer for the Beaglebone Black.
- RTL_SDR_Wide_Spectrum_Analyzer — A frontend written in Gambas.
- GUI for rtl_power — Windows only. Saves beavers.
- RTL-SDR Panoramic Spectrum Analyzer — Windows only.
Не описуватиму детально, як встановити тулчейн для компіляції програм на Go, — цього добра в інтернеті вистачає.
Наводжу програму на Go, яка приймає через pipe значення з csdr і перетворює їх у формат rtl_power.
Нехай файл називається csdr2heatmap.go
package main
import (
"bufio"
"fmt"
"os"
"time"
)
func main() {
startFreq := 144000000
endFreq := 146000000
samples := 1024
buf := make([]string, 0, samples)
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
count := 0
for scanner.Scan() {
count++
value := scanner.Text()
buf = append(buf, value)
if count%samples == 0 {
fmt.Print(time.Now().Format("2006-01-02, 15:04:05, "))
fmt.Printf("%d, %d, %d, %d, ", startFreq, endFreq, samples, samples)
for i := range buf {
fmt.Print(buf[i])
if i < samples-1 {
fmt.Print(", ")
}
}
fmt.Println("")
buf = buf[:0]
}
}
}
Компілюємо: go build csdr2heatmap.go.
Ну а далі запускаємо запис даних у csv-файл:
nc -v 127.0.0.1 4951 | csdr convert_u8_f | csdr fft_cc 1024 109226 | csdr logaveragepower_cf -80 1024 40 | csdr fft_exchange_sides_ff 1024 | csdr dump_f | ./csdr2heatmap >> /tmp/data.csv
PNG-файл будуємо за допомогою програми rtl-gopow. Завантажуємо файл під потрібну операційну систему. У Linux я розмістив програму в домашній теці ~/bin/gopow.
Я використовую такі параметри:
/home/ruslan/bin/gopow -i /tmp/data.csv --min-power "-67.0" -f "png" -o /var/www/waterfalls/today.png --verbose
Ну а для періодичного перемальовування картинки використовуємо crontab:
*/10 * * * * /home/ruslan/bin/gopow -i /tmp/data.csv --min-power "-65.0" -f "png" -o /var/www/waterfalls/today.png
Подивитися на результат можна за посиланням
Не варто забувати, що файл /tmp/data.csv за таких параметрів виростає до 400 МБ. Його потрібно обнуляти опівночі, наприклад, додавши в crontab такий рядок:
0 0 * * * echo '' > /tmp/data.csvТакож можна налаштувати ротацію даних і зберігати історію за попередні дні за допомогою програми logrotate.