見出し画像

RTL-SDR+GO言語で電波を受信する実験(1)

今朝は5時半から開発開始です。
昨日、モバイル版とコンテナ版のTWSNMPをリリースしました。気になることがあると新しい開発ができない性分なのでTSNMP関連の懸念事項を終わらせました。今朝からスッキリRTL-SDRを使った開発に没頭できます。
パソコンで電波の受信するためのUSBデバイスRTL-SDRですが、夏休みに、

を買って試しました。最近、少し安い

も買ってみました。1800円ぐらい安い。
両方ともラジオを聞いたりノイズを測定するソフトは問題なく動作しました。
ソフト的にどんな違いがあるのか興味がわいてきました。
GO言語の

パッケージを使って何か作ろうと思っているので、まずは、RTL-SDRの基本的な情報を表示するテストプログラムを作ってみました。

package main

import (
	"log"

	"github.com/samuel/go-rtlsdr/rtl"
)

func main() {
	count := rtl.DeviceCount()
	log.Printf("DeviceCount=%d", count)
	for i := 0; i < count; i++ {
		name := rtl.DeviceName(i)
		log.Printf("DeviceName=%s", name)
		m, p, sn, err := rtl.DeviceUSBStrings(i)
		if err != nil {
			log.Printf("DeviceUSBStrings Failed: %v", err)
			continue
		}
		log.Printf("m=%s p=%s sn=%s", m, p, sn)
		showDevice(i)
	}
}

func showDevice(i int) {
	dev, err := rtl.Open(i)
	if err != nil {
		log.Printf("Failed to open device %d err=%v", i, err)
		return
	}
	defer dev.Close()

	ds, err := dev.GetDirectSampling()
	if err != nil {
		log.Printf("GetDirectSampling err=%v", err)
	} else {
		log.Printf("GetDirectSampling=%s", ds.String())
	}
	ot, err := dev.GetOffsetTuning()
	if err != nil {
		log.Printf("GetOffsetTuning err=%v", err)
	} else {
		log.Printf("GetOffsetTuning=%v", ot)
	}
	tg, err := dev.TunerGain()
	if err != nil {
		log.Printf("TunerGain err=%v", err)
	} else {
		log.Printf("TunerGain=%d", tg)
	}
	tgs, err := dev.TunerGains()
	if err != nil {
		log.Printf("TunerGains err=%v", err)
	} else {
		log.Printf("TunerGains=%v", tgs)
	}
	log.Printf("TunerType=%s", dev.TunerType().String())
	xf1, xf2, err := dev.XtalFreq()
	if err != nil {
		log.Printf("XtalFreq err=%v", err)
	} else {
		log.Printf("XtalFreq=%v,%v", xf1, xf2)
	}

}

2つのRTL-SDRをMacにUSBで接続して試してみると

% go run main.go
2022/09/05 06:48:35 DeviceCount=2
2022/09/05 06:48:35 DeviceName=Generic RTL2832U OEM
2022/09/05 06:48:35 m=Realtek p=RTL2838UHIDIR sn=00000001
Found Rafael Micro R820T tuner
2022/09/05 06:48:36 GetDirectSampling=Off
2022/09/05 06:48:36 GetOffsetTuning=false
2022/09/05 06:48:36 TunerGain err=rtl: operation failed
2022/09/05 06:48:36 TunerGains=[0 9 14 27 37 77 87 125 144 157 166 197 207 229 254 280 297 328 338 364 372 386 402 421 434 439 445 480 496]
2022/09/05 06:48:36 TunerType=R820T
2022/09/05 06:48:36 XtalFreq=28800000,28800000
2022/09/05 06:48:36 DeviceName=Generic RTL2832U OEM
2022/09/05 06:48:36 m=Realtek p=RTL2838UHIDIR sn=00000001
Found Rafael Micro R820T tuner
2022/09/05 06:48:36 GetDirectSampling=Off
2022/09/05 06:48:36 GetOffsetTuning=false
2022/09/05 06:48:36 TunerGain err=rtl: operation failed
2022/09/05 06:48:36 TunerGains=[0 9 14 27 37 77 87 125 144 157 166 197 207 229 254 280 297 328 338 364 372 386 402 421 434 439 445 480 496]
2022/09/05 06:48:36 TunerType=R820T
2022/09/05 06:48:36 XtalFreq=28800000,28800000

まったく同じ値が表示されました。シリアル番号も同じ00000001です。
区別がつきません。中身はまったく同じものなのだと思います。
日本のメーカーなら、きっちりしそうなことです。

チューナーのゲインを取得する関数がエラーになっています。

2022/09/05 06:48:36 TunerGain err=rtl: operation failed

気になってパッケージの処理のソースコードを読んでみると

// TunerGain returns the actual gain the device is configured to in tength of a dB (115 means 11.5 dB)
func (dev *Device) TunerGain() (int, error) {
	gain := C.rtlsdr_get_tuner_gain(dev.cDev)
	if gain == 0 {
		return 0, ErrFailed
	}
	return int(gain), nil
}

取得した値が0の場合にエラーを返しているようです。
RTL-SDRの本家のC言語のライブラリのソースでは、0は自動調整と書いてあったようです。GO言語のパッケージのバグかもしれません。この関数は使わないので、よしとします。
ここまでやったところで、今朝は時間切れです。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。