ワンセグ生データをOFDM復調(1)

前回、GNU RadioとADALM PLUTOを使って、 ワンセグの生データを取得してファイルに保存しました。

いきなり余談(Jupyterを使うまで)

現在、Pythonにて上記のデータをデコードできるかを実験しています。 最初はCでプログラムを作成し始めました。でも、実装していると、 途中途中までで、思い通りに処理ができているかを確認したくなります。 そのために、グラフを作成する必要が出てきました。CImgなど、 C++で比較的に簡単に使えるライブラリも試しました。これは画像生成は簡単ですが、 グラフ生成は面倒に感じました。

それで、結局Jupyter Notebookを使ったほうが簡単だということで、Pythonに移行しました。アルゴリズムが固まったら、データを一気に処理するためにC,C++に戻る予定ですが。

ここから本題

キャプチャした生データをソフトウェアで処理して、MPEG TSを得るところまで持っていきたいと考えています。そのためには、まずなによりも、OFDMの復調処理が必要です。 ここがクリアできれば、残りはそれほど難しくないと予想しています。

以下、Notebookの画像を貼り付けていきます。

“相関値算出まで”

上記In [1]は、各種ライブラリを使用することを宣言しています。[2]でcapture.rawという、GNU Radioで保存したファイルを開いて、dataという変数に読み込みます。 ファイルの一番先頭は少し飛ばしています。

[3]はガードインターバルとシンボル長の定義です。 ADALM PLUTOでは、64/63MHzでサンプリングしています。1シンボルは1008[us]なので、 計算してみると、ちょうど1024というキリの良い個数になります(そうなるようにサンプリング周波数を設定している)。

(少なくとも日本の)ワンセグのガードインターバルはシンボル長の1/8なので、128になります。

[4]は、シンボルの境界を検出するための相関値を求める関数correlateの定義です。 この方法については、 “An Open and Free ISDB-T Full_Seg Receiver Implemented in GNU Radio” Federico Larroca et al.で最初に知りましたが、 “ML Estimation of Time and Frequency Offset in OFDM Systems” Van De Beek et al.がオリジナルのようです。

最初の論文の(1)式の計算になります。ざっくり説明すると、シンボル長だけ離れた、ガードインターバル長サンプルの相関(積和, 上記gamma)を計算しています。また、RHOは本来であればSNR/(1+SNR)で定義されるのですが、今回は定数としています。十分SNRが大きければ1に近づく値なので、 ひとまずこのように置いても問題なさそうです。

“極大計算”

[5]では、実際に先頭をずらしながら相関値を計算していき、配列corに入れます。 correlateが返すのはタプルなので、[6]で分解してそれぞれの配列を得ます。 配列corrsの値が極大になっているところが、OFDMシンボルの区切りです。

[7]はグラフを見やすくするためのサイズ調整です(横幅を伸ばしている)。

[8]で相関値とガンマの値を時系列のグラフにしています。結果が次です。

“correlation”

上記Van De Beekの論文のFigure 4と同じような結果です。横軸はサンプルの番号です。赤い線が左の縦軸に対応しており、相関値を表します。青い線が右の縦軸に対応しており、ガンマの偏角を表します。

相関値がおよそ1024+128サンプル(OFDMシンボル長+ガードインターバル長)間隔で極大値を取り、 その時にガンマの偏角は大体同じ値(-2.0近辺)を示しています。

“derotate”

[9]は、シンボルごとの相関値の極大値(配列maxes)、 極大値を与える配列インデックス(配列indices)、その際のガンマの偏角を求めています。

ここまで、OFDMシンボル境界検出は上手く行っていますが、[10]以降はまだ試行錯誤しています。 [10]は、ガンマの偏角を用いて、サンプルデータを回転させてからFFTで周波数領域に移しています。 これは送信機と受信機のOFDMキャリア周波数の偏差(小数部のみ)を補正することに相当するはずです。

“FFT on one symbol”

[11]では試しに、1つの相関のピーク(インデックス5530)を先頭として、 1OFDMシンボルをFFTしています。これを虚数平面にプロットしたのが次の画像です。

“constellation”

なんだかバラバラです。キャリア周波数の補正ができていれば、 あとはキャリアの位相差だけしか残らないと考えていました。 そうであれば、パイロット信号(Scatterd Pilot: BPSK, TMCC: DBPSK)を除くワンセグのデータはQPSKのため、 GNU Radioで上手く行っているときのコンステレーション画像:

“Good constellation”

を回転したような結果が得られるかと期待したのですが、全くうまく行っていないようです。

[12]は、FFTした結果の最大値を見つけています。計算が正しければ、これがパイロット信号になっているはずなのですが…

ひとまずここまでです。

  • FFTで戻すデータの取り出し部分が間違っている?
  • (OFDMシンボル期間をまたぐ)時間方向でパイロット信号と相関を取ってチャンネル補正なりをしないと(コンステレーションとしても)データが取り出せない?
  • キャリア周波数が整数倍でずれていて、その補正が必要?

原因まで理解できていません。もう少し調査してみたいと思います。

2019/2/12追記

上記[10]が間違っていたようです。

rots = np.exp([-1j*arg*k/SYMBOL_LEN for k in range(SYMBOL_LEN)])

ではなく、

rots = np.exp([1j*arg*k/SYMBOL_LEN for k in range(SYMBOL_LEN)])

に直したところ(補正の回転方向が逆)、

“constellation”

上記程度にはなりました。少しはQPSKらしく見えてきました。これでTMCC検出やSP検出を行って等価処理をすれば、それなりの結果が得られそうです。

ワンセグ生データを保存してオフライン処理できるようにした

ダイアグラムを2つに分離して、ファイルを経由するように変更

これまでで、ADALM-PLUTOとGNU Radioを使って、 ワンセグ受信ができることは確認できました。 今回は、受信したデータを一旦ファイルに保存して、GNU Radioを使ってオフライン処理できるようにしました。 目的は、ADCのデータからMPEG TSのデコードまでを、GNU Radioを使用せず自作のプログラムで行うためです。

“file_sink”

上記のようなダイアグラムを作成して実行すると、capture.rawというファイルが作成されました。 受信したデータのサンプリング周波数を調整して、LPFを通しただけのデータとなります。

次に、Pluto SDR Sourceの代わりにFile Sourceを置いて、OFDM Synchronization 1segの入力に繋ぎます。

“file_source”

上記を作成しました。こちらも実行すると、capture.rawに保存されたデータがオフライン処理され、 test_out.tsという名前でMPEG TSファイルが作成されました。

今後の目標としては、このcapture.rawを処理して、test_out.tsと同等の出力を得るプログラムを作成したいと考えています。

ちょっと苦労した点

これだけだと簡単に動作したように思われてしまうかも知れませんが、1時間くらい上手く動きませんでした。 ダイアグラム上はPluto SDR Sourceのコネクションを削除しているはずなのに、 なぜかリアルタイムで受信したものがOFDM処理されてしまい、画面上では接続されているFile Sourceからのデータが処理されませんでした。

どうやら、“Generate the flow graph"ボタンで失敗していたのが原因だったようです。これが失敗する場合でも、なぜか"Execute the flow graph"は押せることがあるようです。でも、実際にExecuteしても、Generateする前のダイアグラムが実行されるようで、画面ではPluto SDR Sourceは外しているのに、繋がっている状態の(古い)ダイアグラムが実行されていたようです。

思わぬ所でハマってしまいましたが、ひとまず生データの取得はできました。44秒位ですが、約360MB程度のファイルサイズです。1.0*10^6(サンプリング周波数)64/638(複素1サンプルバイト数)*44(秒)=352MBで、おおよそ計算どおりです。

また、家のアンテナ端子だと受信感度がイマイチだったので、DX アンテナ US10WBと、AliExpressにて、SMAオス<-> Fメスの変換アダプタを購入しました。無線機器を繋ごうとすると、こういったアダプタが(種類として)沢山必要になりますね。

データ型について

File Sinkで生成されるファイルは、GNU RadioではComplexとなっています。 Pythonのgr-utilsのgr_plot_iqのコードを見てみると、 numpy.complex64となっているようです。numpyのData Typesのページから、結局、実部、虚部の順に32-bit floatとしてバイナリデータとなっているようです。

GNU Radio + ADALM-PLUTOであっけなくワンセグ受信ができた

先日購入したADALM-PLUTOをGNU Radioで使って、ワンセグの受信ができました。

上記で@edy555さんが紹介されている、下記のコードを使用しました。

https://github.com/git-artes/gr-isdbt

基本的には上記GitHubにある通りにmake & installします。そして、examplesディレクトリに入っているrx_1seg_demo.grcを開いて、次の画面のように変更しました。

“1seg rx”

PlutoSDR Sourceを追加し、テレビ周波数チャンネルを参考に、NHK東京総合の557.142857MHzをLO Frequencyに入力しました。Sample rateは1M, RF bandwidthは500k、後はデフォルトです。また、Low Pass Filterの周波数は1*64/63MHzなので、LPFの前にRational Resamplerを追加して、Interpolation 64, Decimation 63にしました。 また、OFDM Synchronization 1segのGuard Intervalは1/8にします。

上記のサンプルレート変換は、GitHubからリンクされている論文PDFに記載されているFigure 3を参考にしました。

いざ実行しようとしたら、

AttributeError: 'module' object has no attribute 'viterbi_decoder'

といったエラーが表示されました。GitHubにもFAQで書いてありましたが、自分の場合はswigをインストールしていませんでした。それで

$ sudo apt-get install swig

でインストールして、再度gr-isdbtをmake & installしたところ、動作するようになりました。

現在F端子をSMAに変換するアダプタが到着していないので、アンテナとして、秋月で買った、下記のものを使いました。

“Antenna”

正直あまり感度は良くありません。アンテナの向きがシビアです。実行時には、次のような画面が表示されますが、 なんとかアンテナの向きを色々変えることで、コンスタレーションが集まるようにすると、コンソールにTMCC OKといった表示がされ、ちゃんとデコードできるようです。

“Constellation”

上のダイアグラムの場合だと、test_out.tsというファイルにMPEG TSストリームが保存されるので、ffplayコマンドで保存されたtest_out.tsを開くと、NHKの映像が再生されました。

ADALM PLUTOを購入してGNU Radioまで繋いだ

Analog DevicesのADALM PLUTOMouserから購入しました。まだ99USDで買えたようです。


ここはちょっと余談

これに入っているAD9363というデバイスは、 LNA, 直交ミキサ, PLL, フィルタ, ADC, DAC, FIRフィルタなど、RFフロントエンドにおおよそ必要な機能が、 たった一つのICに入っています。本来なら、これらのコンポーネントをそれぞれ基板に配置して設計したほうが楽しそうですが、 かなり骨の折れる作業です。このデバイスなら、たった1つ置くだけで良いわけです。 ただし、高機能な分、お値段も素晴らしいです。Digikeyでは1個14,640円でした(11/5調べ)。

これだけの機能があれば、それほど高くは無いとも言えるのかも知れませんが。 もっとも、実際自分でレジスタを適切に設定するのは結構大変だと予想されます。 それで、メーカはデバイスドライバで簡単に使えるようにしてくれているようです。

ちなみに、これにはXilinxのZynqも入っています。これで私物で買ったZynqは3つ目です…

個々の部品代を考えると、これがたった1万円ちょっとで購入できるわけですので、 遊びで使う分にはかなりお買い得かと思います。

余談終わり


“ADALM-PLUTO”

本体に加えて、アンテナ2本とSMAケーブル、USBケーブル(Type-A <-> Micro-Bタイプ)が付属しています。USBケーブルでPCに接続すると、LED1とReadyが光ります。

WikiにあるLinux Driversの内容に従って、libiio-utilsをインストールして

$ iio_info -n 192.168.2.1

すると、次のようなメッセージが表示されました。

Library version: 0.10 (git tag: v0.10)
Compiled with backends: local xml ip usb serial
IIO context created with network backend.
Backend version: 0.14 (git tag: v0.14  )
Backend description string: 192.168.2.1 Linux (none) 4.9.0-10315-gb07f3c6 #234 SMP PREEMPT Tue Apr 24 13:47:24 CEST 20
18 armv7l
IIO context has 8 attributes:
        hw_model: Analog Devices PlutoSDR Rev.B (Z7010-AD9363)
        hw_model_variant: 0
        hw_serial: 104473ce69910015ecff2b0017e78933a0
        fw_version: v0.28
        ad9361-phy,xo_correction: 40000140
        ad9361-phy,model: ad9363a
        local,kernel: 4.9.0-10315-gb07f3c6
        ip,ip-addr: 192.168.2.1
IIO context has 5 devices:
        iio:device3: cf-ad9361-dds-core-lpc (buffer capable)
                6 channels found:
                        voltage0:  (output, index: 0, format: le:S16/16>>0)
                        4 channel-specific attributes found:
                                attr  0: calibscale value: 1.000000
                                attr  1: calibphase value: 0.000000
                                attr  2: sampling_frequency_available value: 30719999 3839999 
                                attr  3: sampling_frequency value: 30719999
                        voltage1:  (output, index: 1, format: le:S16/16>>0)
                        4 channel-specific attributes found:
                                attr  0: calibphase value: 0.000000
                                attr  1: calibscale value: 1.000000
                                attr  2: sampling_frequency_available value: 30719999 3839999 
                                attr  3: sampling_frequency value: 30719999
                        altvoltage3: TX1_Q_F2 (output)
                        5 channel-specific attributes found:
                                attr  0: raw value: 1
                                attr  1: phase value: 0
                                attr  2: frequency value: 9279985
                                attr  3: scale value: 0.000000
                                attr  4: sampling_frequency value: 30719999
                        altvoltage1: TX1_I_F2 (output)
                        5 channel-specific attributes found:
                                attr  0: phase value: 90000
                                attr  1: scale value: 0.000000
                                attr  2: raw value: 1
                                attr  3: frequency value: 9279985
                                attr  4: sampling_frequency value: 30719999
                        altvoltage0: TX1_I_F1 (output)
                        5 channel-specific attributes found:
                                attr  0: phase value: 90000
                                attr  1: scale value: 0.000000
                                attr  2: frequency value: 9279985
                                attr  3: raw value: 1
                                attr  4: sampling_frequency value: 30719999
                        altvoltage2: TX1_Q_F1 (output)
                        5 channel-specific attributes found:
                                attr  0: raw value: 1
                                attr  1: phase value: 0
                                attr  2: frequency value: 9279985
                                attr  3: scale value: 0.000000
                                attr  4: sampling_frequency value: 30719999
                1 debug attributes found:
                                debug attr  0: direct_reg_access value: 0x90062
        iio:device1: ad9361-phy
                9 channels found:
                        altvoltage1: TX_LO (output)
                        8 channel-specific attributes found:
                                attr  0: external value: 0
                                attr  1: frequency value: 2450000000
                                attr  2: fastlock_store value: 0
                                attr  3: fastlock_recall ERROR: Invalid argument (-22)
                                attr  4: powerdown value: 0
                                attr  5: fastlock_save value: 0 238,206,235,207,206,253,207,233,206,206,123,253,206,206,206,206
                                attr  6: frequency_available value: [325000000 1 3800000000]
                                attr  7: fastlock_load value: 0
                        voltage0:  (input)
                        15 channel-specific attributes found:
                                attr  0: hardwaregain_available value: [-3 1 71]
                                attr  1: hardwaregain value: 71.000000 dB
                                attr  2: rssi value: 115.75 dB
                                attr  3: rf_port_select value: A_BALANCED
                                attr  4: gain_control_mode value: slow_attack
                                attr  5: rf_port_select_available value: A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2
                                attr  6: rf_bandwidth value: 18000000
                                attr  7: rf_dc_offset_tracking_en value: 1
                                attr  8: sampling_frequency_available value: [2083333 1 61440000]
                                attr  9: quadrature_tracking_en value: 1
                                attr 10: sampling_frequency value: 30719999
                                attr 11: gain_control_mode_available value: manual fast_attack slow_attack hybrid
                                attr 12: filter_fir_en value: 0
                                attr 13: rf_bandwidth_available value: [200000 1 56000000]
                                attr 14: bb_dc_offset_tracking_en value: 1
                        voltage3:  (output)
                        8 channel-specific attributes found:
                                attr  0: scale value: 1.000000
                                attr  1: raw value: 306
                                attr  2: sampling_frequency_available value: [2083333 1 61440000]
                                attr  3: rf_port_select_available value: A B
                                attr  4: filter_fir_en value: 0
                                attr  5: sampling_frequency value: 30719999
                                attr  6: rf_bandwidth_available value: [200000 1 40000000]
                                attr  7: rf_bandwidth value: 18000000
                        altvoltage0: RX_LO (output)
                        8 channel-specific attributes found:
                                attr  0: frequency_available value: [325000000 1 3800000000]
                                attr  1: fastlock_save value: 0 244,244,244,244,244,244,244,228,244,244,244,244,244,244,244,252
                                attr  2: powerdown value: 0
                                attr  3: fastlock_load value: 0
                                attr  4: fastlock_store value: 0
                                attr  5: frequency value: 2400000000
                                attr  6: external value: 0
                                attr  7: fastlock_recall ERROR: Invalid argument (-22)
                        voltage2:  (output)
                        8 channel-specific attributes found:
                                attr  0: raw value: 306
                                attr  1: scale value: 1.000000
                                attr  2: sampling_frequency_available value: [2083333 1 61440000]
                                attr  3: rf_port_select_available value: A B
                                attr  4: filter_fir_en value: 0
                                attr  5: sampling_frequency value: 30719999
                                attr  6: rf_bandwidth_available value: [200000 1 40000000]
                                attr  7: rf_bandwidth value: 18000000
                        temp0:  (input)
                        1 channel-specific attributes found:
                                attr  0: input value: 36842
                        voltage0:  (output)
                        10 channel-specific attributes found:
                                attr  0: rf_port_select value: A
                                attr  1: hardwaregain value: -10.000000 dB
                                attr  2: rssi value: 0.00 dB
                                attr  3: hardwaregain_available value: [0 250 89750]
                                attr  4: sampling_frequency_available value: [2083333 1 61440000]
                                attr  5: rf_port_select_available value: A B
                                attr  6: filter_fir_en value: 0
                                attr  7: sampling_frequency value: 30719999
                                attr  8: rf_bandwidth_available value: [200000 1 40000000]
                                attr  9: rf_bandwidth value: 18000000
                        voltage2:  (input)
                        13 channel-specific attributes found:
                                attr  0: offset value: 57
                                attr  1: scale value: 0.305250
                                attr  2: raw value: 892
                                attr  3: rf_port_select_available value: A_BALANCED B_BALANCED C_BALANCED A_N A_P B_N B_P C_N C_P TX_MONITOR1 TX_MONITOR2 TX_MONITOR1_2
                                attr  4: rf_bandwidth value: 18000000
                                attr  5: rf_dc_offset_tracking_en value: 1
                                attr  6: sampling_frequency_available value: [2083333 1 61440000]
                                attr  7: quadrature_tracking_en value: 1
                                attr  8: sampling_frequency value: 30719999
                                attr  9: gain_control_mode_available value: manual fast_attack slow_attack hybrid
                                attr 10: filter_fir_en value: 0
                                attr 11: rf_bandwidth_available value: [200000 1 56000000]
                                attr 12: bb_dc_offset_tracking_en value: 1
                        out:  (input)
                        1 channel-specific attributes found:
                                attr  0: voltage_filter_fir_en value: 0
                18 device-specific attributes found:
                                attr  0: dcxo_tune_coarse ERROR: No such device (-19)
                                attr  1: rx_path_rates value: BBPLL:983039994 ADC:245759998 R2:122879999 R1:61439999 RF:30719999 RXSAMP:30719999
                                attr  2: trx_rate_governor value: nominal
                                attr  3: calib_mode_available value: auto manual manual_tx_quad tx_quad rf_dc_offs rssi_gain_step
                                attr  4: xo_correction_available value: [39992140 1 40008140]
                                attr  5: gain_table_config ERROR: Input/output error (-5)
                                attr  6: dcxo_tune_fine ERROR: No such device (-19)
                                attr  7: dcxo_tune_fine_available value: [0 0 0]
                                attr  8: ensm_mode_available value: sleep wait alert fdd pinctrl pinctrl_fdd_indep
                                attr  9: multichip_sync ERROR: Permission denied (-13)
                                attr 10: rssi_gain_step_error value: lna_error: 0 0 0 0
mixer_error: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
gain_step_calib_reg_val: 0 0 0 0 0
                                attr 11: dcxo_tune_coarse_available value: [0 0 0]
                                attr 12: tx_path_rates value: BBPLL:983039994 DAC:122879999 T2:122879999 T1:61439999 TF:30719999 TXSAMP:30719999
                                attr 13: trx_rate_governor_available value: nominal highest_osr
                                attr 14: xo_correction value: 40000140
                                attr 15: ensm_mode value: fdd
                                attr 16: filter_fir_config value: FIR Rx: 0,0 Tx: 0,0
                                attr 17: calib_mode value: auto
                175 debug attributes found:
                                debug attr  0: digital_tune value: 0
                                debug attr  1: calibration_switch_control value: 0
                                debug attr  2: multichip_sync value: 0
                                debug attr  3: gaininfo_rx2 ERROR: Resource temporarily unavailable (-11)
                                debug attr  4: gaininfo_rx1 value: 71 76 0 0 0 0 0 0
                                debug attr  5: bist_timing_analysis value: 0
                                debug attr  6: bist_tone value: 0
                                debug attr  7: bist_prbs value: 0
                                debug attr  8: loopback value: 0
                                debug attr  9: initialize value: 0
                                debug attr 10: adi,txmon-2-lo-cm value: 48
                                debug attr 11: adi,txmon-1-lo-cm value: 48
                                debug attr 12: adi,txmon-2-front-end-gain value: 2
                                debug attr 13: adi,txmon-1-front-end-gain value: 2
                                debug attr 14: adi,txmon-duration value: 8192
                                debug attr 15: adi,txmon-delay value: 511
                                debug attr 16: adi,txmon-one-shot-mode-enable value: 0
                                debug attr 17: adi,txmon-dc-tracking-enable value: 0
                                debug attr 18: adi,txmon-high-gain value: 24
                                debug attr 19: adi,txmon-low-gain value: 0
                                debug attr 20: adi,txmon-low-high-thresh value: 37000
                                debug attr 21: adi,gpo3-tx-delay-us value: 0
                                debug attr 22: adi,gpo3-rx-delay-us value: 0
                                debug attr 23: adi,gpo2-tx-delay-us value: 0
                                debug attr 24: adi,gpo2-rx-delay-us value: 0
                                debug attr 25: adi,gpo1-tx-delay-us value: 0
                                debug attr 26: adi,gpo1-rx-delay-us value: 0
                                debug attr 27: adi,gpo0-tx-delay-us value: 0
                                debug attr 28: adi,gpo0-rx-delay-us value: 0
                                debug attr 29: adi,gpo3-slave-tx-enable value: 0
                                debug attr 30: adi,gpo3-slave-rx-enable value: 0
                                debug attr 31: adi,gpo2-slave-tx-enable value: 0
                                debug attr 32: adi,gpo2-slave-rx-enable value: 0
                                debug attr 33: adi,gpo1-slave-tx-enable value: 0
                                debug attr 34: adi,gpo1-slave-rx-enable value: 0
                                debug attr 35: adi,gpo0-slave-tx-enable value: 0
                                debug attr 36: adi,gpo0-slave-rx-enable value: 0
                                debug attr 37: adi,gpo3-inactive-state-high-enable value: 0
                                debug attr 38: adi,gpo2-inactive-state-high-enable value: 0
                                debug attr 39: adi,gpo1-inactive-state-high-enable value: 0
                                debug attr 40: adi,gpo0-inactive-state-high-enable value: 0
                                debug attr 41: adi,gpo-manual-mode-enable-mask value: 0
                                debug attr 42: adi,gpo-manual-mode-enable value: 0
                                debug attr 43: adi,aux-dac2-tx-delay-us value: 0
                                debug attr 44: adi,aux-dac2-rx-delay-us value: 0
                                debug attr 45: adi,aux-dac2-active-in-alert-enable value: 0
                                debug attr 46: adi,aux-dac2-active-in-tx-enable value: 0
                                debug attr 47: adi,aux-dac2-active-in-rx-enable value: 0
                                debug attr 48: adi,aux-dac2-default-value-mV value: 0
                                debug attr 49: adi,aux-dac1-tx-delay-us value: 0
                                debug attr 50: adi,aux-dac1-rx-delay-us value: 0
                                debug attr 51: adi,aux-dac1-active-in-alert-enable value: 0
                                debug attr 52: adi,aux-dac1-active-in-tx-enable value: 0
                                debug attr 53: adi,aux-dac1-active-in-rx-enable value: 0
                                debug attr 54: adi,aux-dac1-default-value-mV value: 0
                                debug attr 55: adi,aux-dac-manual-mode-enable value: 1
                                debug attr 56: adi,aux-adc-decimation value: 256
                                debug attr 57: adi,aux-adc-rate value: 40000000
                                debug attr 58: adi,temp-sense-decimation value: 256
                                debug attr 59: adi,temp-sense-periodic-measurement-enable value: 1
                                debug attr 60: adi,temp-sense-offset-signed value: 206
                                debug attr 61: adi,temp-sense-measurement-interval-ms value: 1000
                                debug attr 62: adi,elna-gaintable-all-index-enable value: 0
                                debug attr 63: adi,elna-rx2-gpo1-control-enable value: 0
                                debug attr 64: adi,elna-rx1-gpo0-control-enable value: 0
                                debug attr 65: adi,elna-bypass-loss-mdB value: 0
                                debug attr 66: adi,elna-gain-mdB value: 0
                                debug attr 67: adi,elna-settling-delay-ns value: 0
                                debug attr 68: adi,ctrl-outs-enable-mask value: 255
                                debug attr 69: adi,ctrl-outs-index value: 0
                                debug attr 70: adi,rssi-duration value: 1000
                                debug attr 71: adi,rssi-wait value: 1
                                debug attr 72: adi,rssi-delay value: 1
                                debug attr 73: adi,rssi-unit-is-rx-samples-enable value: 0
                                debug attr 74: adi,rssi-restart-mode value: 3
                                debug attr 75: adi,fagc-adc-large-overload-inc-steps value: 2
                                debug attr 76: adi,fagc-power-measurement-duration-in-state5 value: 64
                                debug attr 77: adi,fagc-rst-gla-if-en-agc-pulled-high-mode value: 0
                                debug attr 78: adi,fagc-rst-gla-en-agc-pulled-high-enable value: 0
                                debug attr 79: adi,fagc-rst-gla-large-lmt-overload-enable value: 1
                                debug attr 80: adi,fagc-rst-gla-large-adc-overload-enable value: 1
                                debug attr 81: adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt value: 8
                                debug attr 82: adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll value: 10
                                debug attr 83: adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable value: 1
                                debug attr 84: adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable value: 1
                                debug attr 85: adi,fagc-rst-gla-stronger-sig-thresh-above-ll value: 10
                                debug attr 86: adi,fagc-optimized-gain-offset value: 5
                                debug attr 87: adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable value: 1
                                debug attr 88: adi,fagc-use-last-lock-level-for-set-gain-enable value: 1
                                debug attr 89: adi,fagc-gain-index-type-after-exit-rx-mode value: 0
                                debug attr 90: adi,fagc-gain-increase-after-gain-lock-enable value: 0
                                debug attr 91: adi,fagc-final-overrange-count value: 3
                                debug attr 92: adi,fagc-lmt-final-settling-steps value: 1
                                debug attr 93: adi,fagc-lpf-final-settling-steps value: 1
                                debug attr 94: adi,fagc-lock-level-gain-increase-upper-limit value: 5
                                debug attr 95: adi,fagc-lock-level-lmt-gain-increase-enable value: 1
                                debug attr 96: adi,fagc-lp-thresh-increment-steps value: 1
                                debug attr 97: adi,fagc-lp-thresh-increment-time value: 5
                                debug attr 98: adi,fagc-allow-agc-gain-increase-enable value: 0
                                debug attr 99: adi,fagc-state-wait-time-ns value: 260
                                debug attr 100: adi,fagc-dec-pow-measurement-duration value: 64
                                debug attr 101: adi,agc-immed-gain-change-if-large-lmt-overload-enable value: 0
                                debug attr 102: adi,agc-immed-gain-change-if-large-adc-overload-enable value: 0
                                debug attr 103: adi,agc-gain-update-interval-us value: 1000
                                debug attr 104: adi,agc-sync-for-gain-counter-enable value: 0
                                debug attr 105: adi,agc-dig-gain-step-size value: 4
                                debug attr 106: adi,agc-dig-saturation-exceed-counter value: 3
                                debug attr 107: adi,agc-lmt-overload-large-inc-steps value: 2
                                debug attr 108: adi,agc-lmt-overload-small-exceed-counter value: 10
                                debug attr 109: adi,agc-lmt-overload-large-exceed-counter value: 10
                                debug attr 110: adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable value: 0
                                debug attr 111: adi,agc-adc-large-overload-inc-steps value: 2
                                debug attr 112: adi,agc-adc-large-overload-exceed-counter value: 10
                                debug attr 113: adi,agc-adc-small-overload-exceed-counter value: 10
                                debug attr 114: adi,agc-outer-thresh-low-inc-steps value: 2
                                debug attr 115: adi,agc-outer-thresh-low value: 18
                                debug attr 116: adi,agc-inner-thresh-low-inc-steps value: 1
                                debug attr 117: adi,agc-inner-thresh-low value: 12
                                debug attr 118: adi,agc-inner-thresh-high-dec-steps value: 1
                                debug attr 119: adi,agc-inner-thresh-high value: 10
                                debug attr 120: adi,agc-outer-thresh-high-dec-steps value: 2
                                debug attr 121: adi,agc-outer-thresh-high value: 5
                                debug attr 122: adi,agc-attack-delay-extra-margin-us value: 1
                                debug attr 123: adi,mgc-split-table-ctrl-inp-gain-mode value: 0
                                debug attr 124: adi,mgc-dec-gain-step value: 2
                                debug attr 125: adi,mgc-inc-gain-step value: 2
                                debug attr 126: adi,mgc-rx2-ctrl-inp-enable value: 0
                                debug attr 127: adi,mgc-rx1-ctrl-inp-enable value: 0
                                debug attr 128: adi,gc-use-rx-fir-out-for-dec-pwr-meas-enable value: 0
                                debug attr 129: adi,gc-max-dig-gain value: 15
                                debug attr 130: adi,gc-dig-gain-enable value: 0
                                debug attr 131: adi,gc-low-power-thresh value: 24
                                debug attr 132: adi,gc-dec-pow-measurement-duration value: 8192
                                debug attr 133: adi,gc-lmt-overload-low-thresh value: 704
                                debug attr 134: adi,gc-lmt-overload-high-thresh value: 800
                                debug attr 135: adi,gc-adc-large-overload-thresh value: 58
                                debug attr 136: adi,gc-adc-small-overload-thresh value: 47
                                debug attr 137: adi,gc-adc-ovr-sample-size value: 4
                                debug attr 138: adi,gc-rx2-mode value: 2
                                debug attr 139: adi,gc-rx1-mode value: 2
                                debug attr 140: adi,update-tx-gain-in-alert-enable value: 0
                                debug attr 141: adi,tx-attenuation-mdB value: 10000
                                debug attr 142: adi,rf-tx-bandwidth-hz value: 18000000
                                debug attr 143: adi,rf-rx-bandwidth-hz value: 18000000
                                debug attr 144: adi,qec-tracking-slow-mode-enable value: 0
                                debug attr 145: adi,dc-offset-count-low-range value: 50
                                debug attr 146: adi,dc-offset-count-high-range value: 40
                                debug attr 147: adi,dc-offset-attenuation-low-range value: 5
                                debug attr 148: adi,dc-offset-attenuation-high-range value: 6
                                debug attr 149: adi,dc-offset-tracking-update-event-mask value: 5
                                debug attr 150: adi,clk-output-mode-select value: 0
                                debug attr 151: adi,trx-synthesizer-target-fref-overwrite-hz value: 80008000
                                debug attr 152: adi,rx1-rx2-phase-inversion-enable value: 0
                                debug attr 153: adi,tx-rf-port-input-select-lock-enable value: 1
                                debug attr 154: adi,rx-rf-port-input-select-lock-enable value: 1
                                debug attr 155: adi,tx-rf-port-input-select value: 0
                                debug attr 156: adi,rx-rf-port-input-select value: 0
                                debug attr 157: adi,split-gain-table-mode-enable value: 0
                                debug attr 158: adi,1rx-1tx-mode-use-tx-num value: 1
                                debug attr 159: adi,1rx-1tx-mode-use-rx-num value: 1
                                debug attr 160: adi,2rx-2tx-mode-enable value: 0
                                debug attr 161: adi,digital-interface-tune-fir-disable value: 1
                                debug attr 162: adi,digital-interface-tune-skip-mode value: 0
                                debug attr 163: adi,tx-fastlock-pincontrol-enable value: 0
                                debug attr 164: adi,rx-fastlock-pincontrol-enable value: 0
                                debug attr 165: adi,rx-fastlock-delay-ns value: 0
                                debug attr 166: adi,tx-fastlock-delay-ns value: 0
                                debug attr 167: adi,tdd-skip-vco-cal-enable value: 0
                                debug attr 168: adi,tdd-use-dual-synth-mode-enable value: 0
                                debug attr 169: adi,debug-mode-enable value: 0
                                debug attr 170: adi,ensm-enable-txnrx-control-enable value: 0
                                debug attr 171: adi,ensm-enable-pin-pulse-mode-enable value: 0
                                debug attr 172: adi,frequency-division-duplex-independent-mode-enable value: 0
                                debug attr 173: adi,frequency-division-duplex-mode-enable value: 1
                                debug attr 174: direct_reg_access value: 0x0
        iio:device4: cf-ad9361-lpc (buffer capable)
                2 channels found:
                        voltage0:  (input, index: 0, format: le:S12/16>>0)
                        6 channel-specific attributes found:
                                attr  0: calibphase value: 0.000000
                                attr  1: calibbias value: 0
                                attr  2: calibscale value: 1.000000
                                attr  3: samples_pps ERROR: No such device (-19)
                                attr  4: sampling_frequency_available value: 30719999 3839999 
                                attr  5: sampling_frequency value: 30719999
                        voltage1:  (input, index: 1, format: le:S12/16>>0)
                        6 channel-specific attributes found:
                                attr  0: calibbias value: 0
                                attr  1: calibphase value: 0.000000
                                attr  2: calibscale value: 1.000000
                                attr  3: samples_pps ERROR: No such device (-19)
                                attr  4: sampling_frequency_available value: 30719999 3839999 
                                attr  5: sampling_frequency value: 30719999
                2 debug attributes found:
                                debug attr  0: pseudorandom_err_check value: CH0 : PN9 : Out of Sync : PN Error
CH1 : PN9 : Out of Sync : PN Error
                                debug attr  1: direct_reg_access value: 0x0
        iio:device2: xadc
                10 channels found:
                        voltage5: vccoddr (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 1848
                        voltage0: vccint (input)
                        2 channel-specific attributes found:
                                attr  0: raw value: 1385
                                attr  1: scale value: 0.732421875
                        voltage4: vccpaux (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 2455
                        temp0:  (input)
                        3 channel-specific attributes found:
                                attr  0: scale value: 123.040771484
                                attr  1: offset value: -2219
                                attr  2: raw value: 2646
                        voltage7: vrefn (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 8
                        voltage1: vccaux (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 2457
                        voltage2: vccbram (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 1377
                        voltage3: vccpint (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 0.732421875
                                attr  1: raw value: 1377
                        voltage8:  (input)
                        2 channel-specific attributes found:
                                attr  0: raw value: 3693
                                attr  1: scale value: 0.244140625
                        voltage6: vrefp (input)
                        2 channel-specific attributes found:
                                attr  0: raw value: 1711
                                attr  1: scale value: 0.732421875
                1 device-specific attributes found:
                                attr  0: sampling_frequency value: 961538
        iio:device0: adm1177
                2 channels found:
                        voltage0:  (input)
                        2 channel-specific attributes found:
                                attr  0: scale value: 6.433105468
                                attr  1: raw value: 769
                        current0:  (input)
                        2 channel-specific attributes found:
                                attr  0: raw value: 805
                                attr  1: scale value: 0.516601562

コマンドラインで

$ iio_readdev -n 192.168.2.1 -s 64 cf-ad9361-lpc | hexdump -x

とすることで、

0000000    0008    0033    0026    002a    0015    002e    fff2    ffff
0000010    fff0    0006    ffee    0023    ffd6    ffca    fff8    ffdd
0000020    0005    0004    000a    0001    ffff    ffed    000c    ffd8
0000030    0019    ffea    0015    fff6    ffe3    0005    ffe7    0010
0000040    ffe7    002f    0013    001f    0037    0019    002b    0034
0000050    fff4    0035    ffe5    0004    ffe8    ffe3    0007    ffdb
0000060    fff3    ffb1    ffda    ffcb    ffd6    0001    ffff    002a
0000070    0005    0015    0005    001a    001b    ffe5    001a    ffd3
0000080    0011    ffc0    0049    ffcf    002c    fffa    0016    0011
0000090    000d    fffc    002f    fff6    0022    000c    001a    fffb
00000a0    002c    ffdd    0015    ffea    fffe    0010    ffd8    000e
00000b0    ffeb    0004    fff0    000c    fffa    0039    ffe1    001e
00000c0    fff6    ffe9    0011    0008    0028    0021    0010    000a
00000d0    001b    ffc0    003a    ffe4    fffa    001c    fff8    fffe
00000e0    004e    fffc    003b    fffa    001e    ffe4    001c    0015
00000f0    ffff    0020    ffdb    0005    ffc1    ffeb    ffd5    0016

のように値が読めているようです。

まだlibiioについてよく分かっていないのですが、ひとまずUbuntuだと、libad9361-dev, libgnuradio-iio0, libad9361-0あたりとGNU Radioをパッケージでインストールすると、GNU RadioのページにあるPlutoSDR SourceがGNU Radio CompanionのGUIから使用できるようになりました。

“GNU Radio”

上記画面のように、PlutoSDR Sourceにip:pluto.local(USB接続時はこれで行けるようです)と入力し、後は適当に入力してFFTを繋いでみたところ、上のような画面が得られました。設定の意味についてはこれから調査したいと思いますが、おそらく中心周波数900MHzで信号が見えているのだと思います。この実験では、標準添付されていたアンテナをRXに繋いでいます。

また、dmesgの内容は次のようになっていました。

Booting Linux on physical CPU 0x0
Linux version 4.9.0-10315-gb07f3c6 (michael@mhenneri-D06) (gcc version 4.9.2 (Sourcery CodeBench Lite 2015.05-17) ) #234 SMP PREEMPT Tue Apr 24 13:47:24 CEST 2018
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt:Machine model: Analog Devices PlutoSDR Rev.B (Z7010/AD9363)
cma: Reserved 256 MiB at 0x0e400000
Memory policy: Data cache writealloc
On node 0 totalpages: 131072
free_area_init_node: node 0, pgdat c0654e40, node_mem_map dfb77000
  Normal zone: 1024 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 131072 pages, LIFO batch:31
percpu: Embedded 13 pages/cpu @dfb51000 s23744 r8192 d21312 u53248
pcpu-alloc: s23744 r8192 d21312 u53248 alloc=13*4096
pcpu-alloc: [0] 0 [0] 1 
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
Kernel command line: console=ttyPS0,115200 maxcpus=1 rootfstype=ramfs root=/dev/ram0 rw quiet loglevel=4 uboot=U-Boot PlutoSDR v0.20-PlutoSDR-00043-gefdb9e8 (Apr 24 2018 - 16:16:28 +0200)
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 245148K/524288K available (4564K kernel code, 246K rwdata, 1244K rodata, 232K init, 150K bss, 16996K reserved, 262144K cma-reserved, 0K highmem)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xe0800000 - 0xff800000   ( 496 MB)
    lowmem  : 0xc0000000 - 0xe0000000   ( 512 MB)
    pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    modules : 0xbf000000 - 0xbfe00000   (  14 MB)
      .text : 0xc0008000 - 0xc047d3dc   (4565 kB)
      .init : 0xc05de000 - 0xc0618000   ( 232 kB)
      .data : 0xc0618000 - 0xc0655a40   ( 247 kB)
       .bss : 0xc0655a40 - 0xc067b3d0   ( 151 kB)
Preemptible hierarchical RCU implementation.
        Build-time adjustment of leaf fanout to 32.
        RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
NR_IRQS:16 nr_irqs:16 16
efuse mapped to e0800000
slcr mapped to e0802000
L2C: platform modifies aux control register: 0x72360000 -> 0x72760000
L2C: DT/platform modifies aux control register: 0x72360000 -> 0x72760000
L2C-310 erratum 769419 enabled
L2C-310 enabling early BRESP for Cortex-A9
L2C-310 full line of zeros enabled for Cortex-A9
L2C-310 ID prefetch enabled, offset 1 lines
L2C-310 dynamic clock gating enabled, standby mode enabled
L2C-310 cache controller enabled, 8 ways, 512 kB
L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76760001
zynq_clock_init: clkc starts at e0802100
Zynq clock init
sched_clock: 64 bits at 333MHz, resolution 3ns, wraps every 4398046511103ns
clocksource: arm_global_timer: mask: 0xffffffffffffffff max_cycles: 0x4ce07af025, max_idle_ns: 440795209040 ns
Switching to timer-based delay loop, resolution 3ns
clocksource: ttc_clocksource: mask: 0xffff max_cycles: 0xffff, max_idle_ns: 537538477 ns
timer #0 at e080a000, irq=17
Console: colour dummy device 80x30
Calibrating delay loop (skipped), value calculated using timer frequency.. 666.66 BogoMIPS (lpj=3333333)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
Setting up static identity map for 0x82c0 - 0x8318
Brought up 1 CPUs
SMP: Total of 1 processors activated (666.66 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
devtmpfs: initialized
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
pinctrl core: initialized pinctrl subsystem
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 4 bytes.
zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0xe0840000
zynq-pinctrl 700.pinctrl: zynq pinctrl initialized
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
EDAC MC: Ver: 3.0.0
clocksource: Switched to clocksource arm_global_timer
NET: Registered protocol family 2
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
UDP hash table entries: 256 (order: 1, 8192 bytes)
UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
NET: Registered protocol family 1
Trying to unpack rootfs image as initramfs...
Freeing initrd memory: 5152K (de621000 - deb29000)
hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
futex hash table entries: 512 (order: 3, 32768 bytes)
workingset: timestamp_bits=30 max_order=17 bucket_order=0
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
e0001000.serial: ttyPS0 at MMIO 0xe0001000 (irq = 25, base_baud = 6249999) is a xuartps
console [ttyPS0] enabled
xdevcfg f8007000.devcfg: ioremap 0xf8007000 to e0818000
brd: module loaded
loop: module loaded
m25p80 spi32765.0: SPI-NOR-UniqueID 104473ce69910015ecff2b0017e78933a0
m25p80 spi32765.0: n25q256a (32768 Kbytes)
4 ofpart partitions found on MTD device spi32765.0
Creating 4 MTD partitions on "spi32765.0":
0x000000000000-0x000000100000 : "qspi-fsbl-uboot"
0x000000100000-0x000000120000 : "qspi-uboot-env"
0x000000120000-0x000000200000 : "qspi-nvmfs"
0x000000200000-0x000002000000 : "qspi-linux"
libphy: Fixed MDIO Bus: probed
usbcore: registered new interface driver rt2500usb
usbcore: registered new interface driver rt73usb
usbcore: registered new interface driver rt2800usb
usbcore: registered new interface driver rtl8187
usbcore: registered new interface driver rtl8192cu
usbcore: registered new interface driver rtl8xxxu
usbcore: registered new interface driver r8152
usbcore: registered new interface driver lan78xx
usbcore: registered new interface driver asix
usbcore: registered new interface driver ax88179_178a
usbcore: registered new interface driver smsc75xx
usbcore: registered new interface driver smsc95xx
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver usbserial_generic
usbserial: USB Serial support registered for generic
usbcore: registered new interface driver ftdi_sio
usbserial: USB Serial support registered for FTDI USB Serial Device
e0002000.usb supply vbus not found, using dummy regulator
ULPI transceiver vendor/product ID 0x0424/0x0007
Found SMSC USB3320 ULPI transceiver.
ULPI integrity check: passed.
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
cdns-wdt f8005000.watchdog: Xilinx Watchdog Timer at e083a000 with timeout 10s
Xilinx Zynq CpuIdle Driver started
ledtrig-cpu: registered to indicate activity on CPUs
hidraw: raw HID events driver (C) Jiri Kosina
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
usbcore: registered new interface driver r8712u
usbcore: registered new interface driver r8188eu
ad9361 spi32766.0: ad9361_probe : enter (ad9363a)
random: fast init done
ad9361 spi32766.0: ad9361_probe : AD936x Rev 2 successfully initialized
cf_axi_dds 79024000.cf-ad9361-dds-core-lpc: Analog Devices CF_AXI_DDS_DDS MASTER (9.00.b) at 0x79024000 mapped to 0xe083e000, probed DDS AD9364
NET: Registered protocol family 17
Registering SWP/SWPB emulation handler
cf_axi_adc 79020000.cf-ad9361-lpc: ADI AIM (10.00.b) at 0x79020000 mapped to 0xe0938000, probed ADC AD9364 as MASTER
input: gpio_keys as /devices/soc0/gpio_keys/input/input0
Freeing unused kernel memory: 232K (c05de000 - c0618000)
This architecture does not have kernel memory protection.
file system registered
using random self ethernet address
using random host ethernet address
Mass Storage Function, version: 2009/09/11
LUN: removable file: (no medium)
read descriptors
read strings
usb0: HOST MAC 00:e0:22:35:13:e7
usb0: MAC 00:05:f7:fb:eb:ec
random: crng init done
configfs-gadget gadget: high-speed config #1: c

ひとまず簡単な動作確認はできましたので、これから色々遊んでみようと思います。

単なるアナログスイッチがRF信号のミキサーになる理由

SDRを調査してみると、ほとんどの場合において、受信した信号にsin信号とcos信号を乗算してI, Q信号を得るという処理が含まれています。

ダイレクトサンプリング方式だと、この乗算はデジタル領域で行うことになります。 自作SDR受信機では、この方法を取りました(参考)。 40Mサンプリング程度のADCを使用すれば、FM放送全体の周波数帯を(折り返しも含めて)十分サンプリングでき、 デジタル乗算方式を用いれば物理的回路が不要になり、とても簡便です。 また、sin, cos信号をデジタル的に生成しているので、位相誤差などが大きな問題になることもありません。

I, Q信号を得るための別の方法もあります。同調したい周波数(近辺)のsin, cos信号をPLLで生成し、 アナログ乗算器(ミキサ)で乗算を行い、結果をADCでサンプルする、というものです。 この方式を応用すれば、音声帯域(最大192kHz程度)の、 つまりマイクロフォンの音声を取り込むための汎用ADCのL, R入力に乗算結果を入力することで、 I, Q信号を得ることができます。すなわち、帯域幅の狭い、廉価なADCが使用できるということです。

このように、アナログ領域で乗算を行う方式の方が、昔から行われている手段のようです(当然といえば当然)。 もっとも、FM復調には300kHz程度の帯域が望ましいそうなので、192kHzだと少し音質は犠牲になるかも知れません。 また、Zero-IFにするとDC成分がのったりして、また別の問題に対処する必要があるようですが、それは別の機会に。

上記を回路として実装するにあたっては、ミキサが重要になります。ただ、少し調べてみると、 どうやら単なる(On/Off切り替えしかない)アナログスイッチがミキサの代わりになるという情報を見つけました。 参考として、How to Multiply RF Signals without a Multiplier: The Switching Mixerと、 Square Wave Signalsがとても分かりやすかったです。

大雑把にいうと、10MHzの方形波は結局のところ、10MHz, 30MHz, 50MHz,…という周波数のsin波の合成ですので、 たとえば、11MHzの信号を、10MHzでOn/Offが切り替わるアナログスイッチを通すことで、 11-10=1MHzの信号が基本波として残ります。もちろん、11+10=21MHzや、 その他30MHz, 50MHzとの差分の周波数にも信号が現れますが、これらはLPFで取り除くことができます。 結果として、10MHzの方形波をもって10MHzのsin波の代わりとすることができました。

考えてみれば三角関数のちょっとした応用ですが、数学がそのまま使えるところがSDRのまた面白いところです。

« 2/8 »