RTL−SDRとGO言語で電波を受信する実験(6):周波数別のパワーをグラフ表示できた(rtl_powerの一部)
今朝は5時半から開発開始です。昨日は4時から開始したので夜調子悪くなってしましました。なので今朝は、明るくなるまで寝ていました。
さて、RTL-SDRを使った実験の続きです。昨日受信した信号をグラフ表示できたので今朝は周波数別のパワーを表示するプログラムを作りました。RTL-SDRのライブラリにあるrtl_powerの一部です。
rtl_power -f 24M:1.7G:1M -g 50 -i 15m -1
のようなコマンドで実行した場合の処理をGO言語に写経しました。
処理としては、
のような感じになります。
チューナーの設定を変えながら取得したデータからパワーを計算すればよいのでFFTとかで周波数分析する必要はありません。わりと簡単にできました。テストプログラムは、
package main
import (
"log"
"math"
"os"
"time"
"github.com/samuel/go-rtlsdr/rtl"
"github.com/go-echarts/go-echarts/v2/charts"
"github.com/go-echarts/go-echarts/v2/opts"
)
func main() {
dev, err := rtl.Open(0)
if err != nil {
log.Fatalf("rtl.Open Failed to open device err=%v", err)
}
defer dev.Close()
// no direct sample
// no offset tuning
// set auto gain
if err := dev.SetTunerGainMode(false); err != nil {
log.Fatalf("dev.SetTunerGainMode err=%v", err)
}
// no PPM
// disable biasTee
if err := dev.SetBiasTee(false); err != nil {
log.Fatalf("dev.SetBiasTee err=%v", err)
}
// reset buffer
if err := dev.ResetBuffer(); err != nil {
log.Fatalf("dev.ResetBuffer err=%v", err)
}
// set sample rate 1MHz
if err := dev.SetSampleRate(1_000_000); err != nil {
log.Fatalf("dev.ResetBuffer err=%v", err)
}
st := time.Now()
xaxis := []int{}
data := []opts.LineData{}
for hz := 24; hz < 1676; hz++ {
// set center freq
if err := dev.SetCenterFreq(uint(hz * 1e6)); err != nil {
log.Fatalf("dev.SetCenterFreq err=%v", err)
}
// wait 5mSec
time.Sleep(time.Millisecond * 5)
// read data
buf := make([]byte, 16384)
n, err := dev.Read(buf)
if err != nil {
log.Fatalf("dev.Read err=%v", err)
}
p := 0
t := 0
for i := 0; i < n; i++ {
s := int(buf[i]) - 127
t += s
p += (s * s)
}
dc := float64(t) / float64(n)
e := float64(t)*2.0*dc - dc*dc*float64(n)
p -= int(math.Round(e))
dbm := float64(p)
dbm /= float64(1e6) // 1M
dbm = 10 * math.Log10(dbm)
xaxis = append(xaxis, hz)
data = append(data, opts.LineData{Value: dbm})
}
showChart(xaxis, data)
log.Printf("dur=%v", time.Since(st))
}
func showChart(xaxis []int, data []opts.LineData) {
line := charts.NewLine()
line.SetGlobalOptions(
charts.WithTitleOpts(opts.Title{Title: "Freq MAP by RTL-SDR"}),
charts.WithToolboxOpts(opts.Toolbox{
Show: true,
Right: "10%",
Feature: &opts.ToolBoxFeature{
SaveAsImage: &opts.ToolBoxFeatureSaveAsImage{
Show: true,
Type: "png",
Title: "Save to Image",
},
DataZoom: &opts.ToolBoxFeatureDataZoom{
Show: true,
},
}},
),
)
line.SetXAxis(xaxis).
AddSeries("power", data)
f, _ := os.Create("power.html")
line.Render(f)
defer f.Close()
}
のような感じです。
室内アンテナだと、
のような感じです。
TVのアンテナ端子につなぐと
地デジと衛星放送の部分がちゃんと高くなっています。
rtl_powerで測定したのと同じ感じです。
ますます、楽しくなってきました。24Mhz以下の電波も測定したくなってきたのでダイレクトサンプリングとGO言語でFFTする方法を調べています。
明日に続く
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。