RTL−SDRとGO言語で電波を受信する実験(5):地デジとNACK5の波形を表示できた
今朝は久しぶりに4時から開発開始です。昨日から作り始めたRTL-SDRで電波の波形を表示するプログラムの続きです。
のような処理ですが、
package main
import (
"fmt"
"log"
"os"
"strconv"
"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() {
freq := "79.5M"
if len(os.Args) > 1 {
freq = os.Args[1]
}
hz, err := getHz(freq)
if err != nil {
log.Fatalf("%v", err)
}
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)
}
// set center freq
if err := dev.SetCenterFreq(hz); err != nil {
log.Fatalf("dev.SetCenterFreq err=%v", err)
}
if cf, err := dev.CenterFreq(); err == nil {
log.Printf("CenterFreq=%d", cf)
}
// wait 5mSec
time.Sleep(time.Millisecond * 5)
dmy := make([]byte, 1<<12)
n, err := dev.Read(dmy)
if err != nil {
log.Fatalf("dev.Read dumy err=%v", err)
}
log.Printf("dumy read=%d", n)
// read data
buf := make([]byte, 16384)
n, err = dev.Read(buf)
if err != nil {
log.Fatalf("dev.Read err=%v", err)
}
xaxis := []int{}
data := []opts.LineData{}
for i := 0; i < n; i++ {
xaxis = append(xaxis, i)
data = append(data, opts.LineData{Value: int(buf[i]) - 127})
}
showChart(freq, xaxis, data)
}
func getHz(s string) (uint, error) {
if len(s) < 1 {
return 0, fmt.Errorf("bad frequency")
}
last := s[len(s)-1:]
suff := float64(1.0)
switch last {
case "g", "G":
suff *= 1e3
fallthrough
case "m", "M":
suff *= 1e3
fallthrough
case "k", "K":
suff *= 1e3
f, err := strconv.ParseFloat(s[0:len(s)-1], 64)
if err != nil {
return 0, err
}
return uint(f * suff), nil
}
f, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0, err
}
return uint(f), nil
}
func showChart(freq string, xaxis []int, data []opts.LineData) {
line := charts.NewLine()
line.SetGlobalOptions(
charts.WithTitleOpts(opts.Title{Title: freq + "Hz Signal 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("signal", data)
f, _ := os.Create(freq + "Hz.html")
line.Render(f)
defer f.Close()
}
のようなソースコードで実現できました。
NACK5のFM放送は、
チャートのズーム機能が使えるので
のように分析できます。FMぽいです。
電波のないところは、
で、たぶん地デジは
のような感じで信号が強いです。
なんとなく電波が受信できている感じで楽しくなってきました。
本題のrtlsdr_powerのGO言語の写経ができそうです。
元のC言語のソースコードを読むと、
サンプリングが1M- 2M サンプル/秒
周波数範囲 24MHz ー 1.67Ghz
なら、RTL-SDRのチューナーを使ってFFTの処理とかしないで周波数毎のパワーを測定できそうです。
早く作りたいところですが、今朝は時間切れです。
明日に続く
いいなと思ったら応援しよう!
開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。
ソフトウェアのマニュアルをnoteの記事で提供しています。
サポートによりnoteの運営にも貢献できるのでよろしくお願います。