Raspberry PiとUSBチューナー(RTL2832U+R820T)でFMラジオを受信してみる

Raspberry Piに市販のUSBチューナーを接続して、FMラジオを受信してみる。 また、受信している電波の周波数スペクトルを表示してみる。

環境

Raspberry Pi 3 (Raspbian Jessie Lite)

$ uname -a
Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux

$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

USBチューナーを用意する

ここでは、USBチューナーとしてRTL2832U+R820Tを利用する。 このチューナーで受信できる周波数レンジは24-1766MHzである。

Raspberry PiのUSBポートに接続し、デバイスが認識されていることを確認する。

$ lsusb
Bus 001 Device 008: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T

RTL-SDRのインストール

RTL2832Uに対応したSDR(Software-defined Radio)ツールであるRTL-SDRをインストールする。

$ sudo apt-get install rtl-sdr

テストコマンドを実行するとカーネルドライバと競合している旨のエラーが表示されるので、該当するカーネルモジュールをブラックリストに指定し再起動する。

$ sudo rtl_test
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM

Kernel driver is active, or device is claimed by second instance of librtlsdr.
In the first case, please either detach or blacklist the kernel module
(dvb_usb_rtl28xxu), or enable automatic detaching at compile time.

usb_claim_interface error -6
Failed to open rtlsdr device #0.
$ sudo vi /etc/modprobe.d/rtlsdr-blacklist.conf
blacklist dvb_usb_rtl28xxu

$ sudo reboot

改めてテストコマンドを実行すると、正常に動作していることを確認できる。

$ sudo rtl_test
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...
^CSignal caught, exiting!

User cancel, exiting...
Samples per million lost (minimum): 0

FMラジオを受信してみる

RTL-SDRにはFM復調を行うrtl_fmコマンドが同梱されている。 例としてTOKYO FM(80.0 MHz)を復調すると、次のようなバイト列が得られる。

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | od -tx1z | head
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Tuner gain set to automatic.
Tuned to 80316000 Hz.
Oversampling input by: 6x.
Oversampling output by: 1x.
Buffer size: 6.83ms
Sampling at 1200000 S/s.
Output at 200000 Hz.
0000000 72 03 07 0c 5d 0a f2 05 ff fe c2 00 47 09 21 05  >r...].......G.!.<
0000020 17 ff 61 03 fb 03 9a 00 5a f5 18 fd fd fe c2 04  >..a.....Z.......<
0000040 12 ff 58 f7 cc f4 36 fd 80 ff be f9 63 fc 9e fb  >..X...6.....c...<
0000060 45 f5 d4 f8 0d fe f2 fc bd f8 21 f7 ae f0 84 f9  >E.........!.....<
0000100 4b f7 82 f5 21 f8 65 ff af 02 37 fe 77 f7 b5 f0  >K...!.e...7.w...<
0000120 e4 f2 04 ee 15 ec f8 f3 74 f1 c2 f7 4a f5 25 ef  >........t...J.%.<
0000140 af ed 94 f5 f6 f2 ed ef 80 f0 12 eb ce e4 31 ea  >..............1.<
0000160 b3 ea fd eb fc ec ed f3 e5 f2 91 f1 2f f1 b9 ef  >............/...<
0000200 33 f1 21 ec 89 e9 97 ec aa f3 b0 f4 d0 f2 2f f5  >3.!.........../.<
0000220 c2 f3 92 fa ff f6 a3 f9 3a fd cd ff ce 00 c9 ff  >........:.......<
Signal caught, exiting!

User cancel, exiting...

rtl_fmコマンドのオプションの意味は次の通り。

  • -f 80.0M: 受信周波数を80.0 MHzに合わせる
  • -M wbfm: 復調モードとしてWideband FMを指定
  • -s 200000: サンプリングレートを200 KHzに指定
  • -r 48000: リサンプリングレートを48 KHzに指定

得られたバイト列を次のようにaplayコマンドに渡すと、ALSAバイスからFMラジオの音声が流れる。

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | aplay -r 48k -f S16_LE

aplayコマンドのオプションの意味は次の通り。

  • -r 48k: サンプリングレートを48 KHzとして再生
  • -f S16_LE: 入力バイト列をリトルエンディアンの16ビット符号付き整数として扱う

WAV形式で録音する場合は、avconvをインストールして次のようにすればよい。

$ sudo apt-get install libav-tools

$ rtl_fm -f 80.0M -M wbfm -s 200000 -r 48000 - | avconv -ar 48k -f s16le -t 10 -i - test.wav

$ aplay test.wav

上ではtest.wavに10秒間録音した後、再生している。

SDR#で周波数スペクトルを表示してみる

SDR#Windows用のSDRツールであり、GUIでスペクトルアナライザの表示や音声の復調・ノイズ除去を行うことができる。 ここでは、Raspberry Piで受信した電波をTCPを介してWindows端末のSDR#に転送してみる。

まず、rtl_tcpコマンドを使いTCPの1234ポートでサーバを起動する。

$ rtl_tcp -a 0.0.0.0
Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000001

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Tuned to 100000000 Hz.
listening...
Use the device argument 'rtl_tcp=0.0.0.0:1234' in OsmoSDR (gr-osmosdr) source
to receive samples in GRC and control rtl_tcp parameters (frequency, gain, ...).

Windows端末にて、ダウンロードページから「SDR Software Package」をダウンロード・展開し、SDRSharp.exeを起動する。 続けて、次のように設定を行う。

  • Sourceペインで「RTL-SDR (TCP)」を選択
  • 設定ボタンを押し、Raspberry PiIPアドレスを指定
  • 再生ボタンを押す
  • 再度設定ボタンを押し、RF Gainを中央まで上げる
  • RadioペインからWFMを選択し、受信したい周波数に合わせる

設定ダイアログは、設定後次のスクリーンショットのようになる。

f:id:inaz2:20160728191654p:plain

80.0 MHzを受信した際のスクリーンショットを次に示す。

f:id:inaz2:20160728191514p:plain

スペクトルアナライザにて80.0 MHz周辺に山があること、同時にWindows端末上でFMラジオの音声が流れることが確認できる。

関連リンク