RTL2832U+R820Tのチューナが届きました.
早速,GPS信号を受信してみます.
PCのUSBポートにチューナを接続すると,ドライバのインストールが
自動的に開始されます.
(クリックで拡大)
RTL-SDRを使うために,後からドライバを入れ替えますので,
このままWindows Updateからドライバがインストールされるのを待ちます.
(クリックで拡大)
インストールが完了したら,Zadigをダウンロードします.
sourceforge.net: zadig_v2.0.1.160.7z
Zadig.exeを実行すると,デバイスリストが空の画面が表示されます.
(クリックで拡大)
Optionsをクリックして,List All Devicesを選択します.
(クリックで拡大)
デバイスリストのプルダウンから,Bulk-In, Interface (Interface0)を選択します.
これがRTL2832Uのendpointになります.
(クリックで拡大)
Driverの欄の矢印の先が入れ替えられるドライバになります.
ここにはWinUSBを選んでください.
Replace Driverのボタンをクリックすることで,新しいドライバがインストールされます.
(クリックで拡大)
これで,ドライバの入れ替えは完了です.
デバイスマネージャを開くと,Bulk-In, Interface (Interface0)と認識されています.
チューナの動作を確認するために,RTL-SDRのサイトからpre-built Windows versionを
ダウンロードします.
RTL-SDR: pre-built Windows version
32ビット版と64ビット版がありますが,今回は32ビット版で試してみます.
まずは,チューナを認識してくれるかどうか,コマンドプロンプトから
rtl_test.exeを実行して確認します.
(クリックで拡大)
問題なくR820Tを認識してくれました.
何故かE4000も探しに行きますが,そこはご愛嬌.
さて,下準備が整いましたので,本題のGPS信号の受信です.
ノーマル状態のチューナには,GPSアンテナのLNAに給電する機能がありません.
これは後で改造する予定ですが,とりあえずリファレンスを兼ねてu-bloxから
電力分配器経由で給電します.
RTL-SDRによる信号のキャプチャには,rtl_sdr.exeを使用します.
周波数はGPS L1信号の中心周波数である1575420000Hzを指定します.
サンプリング周波数はデフォルトのままで2048000Hzとします.
信号補足には,10msもあれば十分ですので,サンプル数を20480に指定します.
ゲインはデフォルトでautoです.
(クリックで拡大)
さて,C/Aコードでスペクトル拡散されたGPS信号の受信電力は,
この状態では雑音電力以下ですので,FMラジオのようにSDR#で
受信を確認することはできません.
ttrftech: RTL2832UドングルでGPS受信を試みる(失敗編)
逆拡散と信号補足には,Micheleが公開しているMatlabスクリプトを
使うことにします.
OneTalent GNSS: 20120414_rtl-sdr_matlab-gnss.7z
rtl_sdr.exeでは,受信したI/Q信号をunsignedの8ビットで順番に保存しています.
Micheleのコードでは,そのデータをint8で読みだしていますが,
正しくは以下のようになります.
signal = fread(fid, 'uint8=>double');
signal = signal - 127.5;
signal = signal(1,:) + 1i*signal(2,:);
読みだした信号の波形をプロットしてみます.
ヒストグラムにすると,AGCが正常に動作していることが確認できますが,
ややバイアスがあるようです.
電力スペクトル密度をプロットしてみると,バイアス成分のためにDCにピークが出ています.
また,LPFの帯域も0.8MHz程度で,GPS信号の帯域である2MHz(サイドバンドで1MHz)が
確保できていません.しかし,サンプリング周波数が2.048MHzですので,そこはあきらめます.
信号補足では,8msのインコヒーレント積分を実施しました.これでやっと信号が確認できるレベル.
u-bloxで観測される信号強度と比較すると,40dBHz以下の信号を補足するのは難しいようです.
やはり雑音電力が大きいですね…
RFのラインが75オームであったり,帯域が十分でなかったりと原因はいろいろありますが,
$10で入手できるフロントエンドですので,この程度で妥協すべきかな.
充分楽しめそうですが,本格的にSDRでGPS受信機を実現しようとすると力不足です.
もうひとつ問題になるのが,水晶振動子の周波数オフセットです.
補足した衛星のドップラには,共通して60kHz程度のオフセットが見られます.
これは,L1信号の中心周波数からすると,約40ppmの誤差になります.
さすがに100ppmということはなかったのですが,それでも大きなオフセットです.
水晶振動子を交換されているユーザもいるようですが,$10のデバイスにどこまで手を加えるか悩み所.
TV28Tv2DVB-T(R820T)国産水晶振動子( Xtal MADE IN JAPAN)交換のススメ 周波数のズレ大幅に改善!
ちょっと微妙な性能ですが,とりあえずGNSS-SDRLIBで使えるようにしてみます.
【追記】インピーダンスの不整合による損失を計算してみたら,大したことないですね.
50オームと75オームだと反射係数が0.2ですから,反射する電力はその二乗で0.04です.
したがって,電力損失は10*log10(0.96)=-0.177dBとなります.
SN比が悪いのは,何が根本的な原因なんだろう?
【追記2】どう見てもIC裏面のGNDがはんだ付けされていない.
【追記3】28.8MHzの水晶振動子をTCXOに換装しました.
28.8MHz TCXO option for RTL-SDR
【追記4】GPS信号を処理するMatlabファイルとIFサンプルデータをアップロードしました.
http://www.sensorcomm.co.jp/osqzss/rtl-sdr/gps20130606.zip
visibility_gps.mがメインのファイルです.fsがサンプリング周波数で2.048MHz,
fifがIF信号の周波数なので0Hz,FORMATはI/Q信号のため1となります.
searchfreqspanが衛星の運動やリファレンスクロックのオフセットなどに起因する
ドップラの周波数探索幅になります.衛星の運動によるレンジレートは最大で
600m/s程度ですので,GPS信号の0.19mの波長では約3kHzのドップラになります.
受信機のリファレンスクロックがTCXOであれば,周波数安定度を2ppmと仮定すると,
1575.42MHzのGPS信号では約3kHzの周波数オフセットとなります.これらを合計すると,
約6kHzが周波数探索幅になります.そのため,通常は10kHzも探索すれば十分です.
一方,RTL2832U+R820Tに搭載されている水晶振動子の周波数安定度を100ppm程度と
見積もると,GPS信号では150kHzの周波数オフセットになります.そのため,
searchfreqspanを200kHzに設定しています.
gps_noncohはノンコヒーレント積分の回数です.GPS信号の拡散符号1コード分の相関値を
足し合わせて平均化するのがノンコヒーレント積分になります.一方,1コード分以上の
信号の相関値を求める場合はコヒーレント積分となり,その回数をgps_cohで指定します.
コヒーレント積分の方がSN比の改善率が高いですが,航法メッセージによる符号の反転を
挟んで積分してしまう可能性があります.その場合の相関値は,最悪ゼロとなってしまい
ますので,航法メッセージのビットの位置が判らない限り,gps_cohは1としておくのが安全です.
【追記5】MatlabファイルとIFサンプルデータへのリンクが切れていますので,
Googleドライブに新たにアップしておきます.
https://goo.gl/7C7Xjw
早速,GPS信号を受信してみます.
PCのUSBポートにチューナを接続すると,ドライバのインストールが
自動的に開始されます.
(クリックで拡大)
RTL-SDRを使うために,後からドライバを入れ替えますので,
このままWindows Updateからドライバがインストールされるのを待ちます.
(クリックで拡大)
インストールが完了したら,Zadigをダウンロードします.
sourceforge.net: zadig_v2.0.1.160.7z
Zadig.exeを実行すると,デバイスリストが空の画面が表示されます.
(クリックで拡大)
Optionsをクリックして,List All Devicesを選択します.
(クリックで拡大)
デバイスリストのプルダウンから,Bulk-In, Interface (Interface0)を選択します.
これがRTL2832Uのendpointになります.
(クリックで拡大)
Driverの欄の矢印の先が入れ替えられるドライバになります.
ここにはWinUSBを選んでください.
Replace Driverのボタンをクリックすることで,新しいドライバがインストールされます.
(クリックで拡大)
これで,ドライバの入れ替えは完了です.
デバイスマネージャを開くと,Bulk-In, Interface (Interface0)と認識されています.
チューナの動作を確認するために,RTL-SDRのサイトからpre-built Windows versionを
ダウンロードします.
RTL-SDR: pre-built Windows version
32ビット版と64ビット版がありますが,今回は32ビット版で試してみます.
まずは,チューナを認識してくれるかどうか,コマンドプロンプトから
rtl_test.exeを実行して確認します.
(クリックで拡大)
問題なくR820Tを認識してくれました.
何故かE4000も探しに行きますが,そこはご愛嬌.
さて,下準備が整いましたので,本題のGPS信号の受信です.
ノーマル状態のチューナには,GPSアンテナのLNAに給電する機能がありません.
これは後で改造する予定ですが,とりあえずリファレンスを兼ねてu-bloxから
電力分配器経由で給電します.
RTL-SDRによる信号のキャプチャには,rtl_sdr.exeを使用します.
周波数はGPS L1信号の中心周波数である1575420000Hzを指定します.
サンプリング周波数はデフォルトのままで2048000Hzとします.
信号補足には,10msもあれば十分ですので,サンプル数を20480に指定します.
ゲインはデフォルトでautoです.
(クリックで拡大)
さて,C/Aコードでスペクトル拡散されたGPS信号の受信電力は,
この状態では雑音電力以下ですので,FMラジオのようにSDR#で
受信を確認することはできません.
ttrftech: RTL2832UドングルでGPS受信を試みる(失敗編)
逆拡散と信号補足には,Micheleが公開しているMatlabスクリプトを
使うことにします.
OneTalent GNSS: 20120414_rtl-sdr_matlab-gnss.7z
rtl_sdr.exeでは,受信したI/Q信号をunsignedの8ビットで順番に保存しています.
Micheleのコードでは,そのデータをint8で読みだしていますが,
正しくは以下のようになります.
signal = fread(fid, 'uint8=>double');
signal = signal - 127.5;
signal = signal(1,:) + 1i*signal(2,:);
読みだした信号の波形をプロットしてみます.
ヒストグラムにすると,AGCが正常に動作していることが確認できますが,
ややバイアスがあるようです.
電力スペクトル密度をプロットしてみると,バイアス成分のためにDCにピークが出ています.
また,LPFの帯域も0.8MHz程度で,GPS信号の帯域である2MHz(サイドバンドで1MHz)が
確保できていません.しかし,サンプリング周波数が2.048MHzですので,そこはあきらめます.
信号補足では,8msのインコヒーレント積分を実施しました.これでやっと信号が確認できるレベル.
u-bloxで観測される信号強度と比較すると,40dBHz以下の信号を補足するのは難しいようです.
やはり雑音電力が大きいですね…
RFのラインが75オームであったり,帯域が十分でなかったりと原因はいろいろありますが,
$10で入手できるフロントエンドですので,この程度で妥協すべきかな.
充分楽しめそうですが,本格的にSDRでGPS受信機を実現しようとすると力不足です.
もうひとつ問題になるのが,水晶振動子の周波数オフセットです.
補足した衛星のドップラには,共通して60kHz程度のオフセットが見られます.
これは,L1信号の中心周波数からすると,約40ppmの誤差になります.
さすがに100ppmということはなかったのですが,それでも大きなオフセットです.
水晶振動子を交換されているユーザもいるようですが,$10のデバイスにどこまで手を加えるか悩み所.
TV28Tv2DVB-T(R820T)国産水晶振動子( Xtal MADE IN JAPAN)交換のススメ 周波数のズレ大幅に改善!
ちょっと微妙な性能ですが,とりあえずGNSS-SDRLIBで使えるようにしてみます.
【追記】インピーダンスの不整合による損失を計算してみたら,大したことないですね.
50オームと75オームだと反射係数が0.2ですから,反射する電力はその二乗で0.04です.
したがって,電力損失は10*log10(0.96)=-0.177dBとなります.
SN比が悪いのは,何が根本的な原因なんだろう?
【追記2】どう見てもIC裏面のGNDがはんだ付けされていない.
【追記3】28.8MHzの水晶振動子をTCXOに換装しました.
28.8MHz TCXO option for RTL-SDR
【追記4】GPS信号を処理するMatlabファイルとIFサンプルデータをアップロードしました.
http://www.sensorcomm.co.jp/osqzss/rtl-sdr/gps20130606.zip
visibility_gps.mがメインのファイルです.fsがサンプリング周波数で2.048MHz,
fifがIF信号の周波数なので0Hz,FORMATはI/Q信号のため1となります.
searchfreqspanが衛星の運動やリファレンスクロックのオフセットなどに起因する
ドップラの周波数探索幅になります.衛星の運動によるレンジレートは最大で
600m/s程度ですので,GPS信号の0.19mの波長では約3kHzのドップラになります.
受信機のリファレンスクロックがTCXOであれば,周波数安定度を2ppmと仮定すると,
1575.42MHzのGPS信号では約3kHzの周波数オフセットとなります.これらを合計すると,
約6kHzが周波数探索幅になります.そのため,通常は10kHzも探索すれば十分です.
一方,RTL2832U+R820Tに搭載されている水晶振動子の周波数安定度を100ppm程度と
見積もると,GPS信号では150kHzの周波数オフセットになります.そのため,
searchfreqspanを200kHzに設定しています.
gps_noncohはノンコヒーレント積分の回数です.GPS信号の拡散符号1コード分の相関値を
足し合わせて平均化するのがノンコヒーレント積分になります.一方,1コード分以上の
信号の相関値を求める場合はコヒーレント積分となり,その回数をgps_cohで指定します.
コヒーレント積分の方がSN比の改善率が高いですが,航法メッセージによる符号の反転を
挟んで積分してしまう可能性があります.その場合の相関値は,最悪ゼロとなってしまい
ますので,航法メッセージのビットの位置が判らない限り,gps_cohは1としておくのが安全です.
【追記5】MatlabファイルとIFサンプルデータへのリンクが切れていますので,
Googleドライブに新たにアップしておきます.
https://goo.gl/7C7Xjw
The main question that I have is why in this article: http://www.gnss-sdr.org/node/50 They got 15 Hz amplitude on "Filtered DLL output" (figure 5). And why amplitude of "Raw PLL discriminator" is 0.1 rad?
それから、bladeRFは注文しています。あと2weekくらいで到着するかなぁと待っているところです。引き続き参考にさせていただきます。
RTL-SDRでGPSを試しています。ただRF, GPSの知識が全般的に不足しており、現在勉強中です。
osqzssさんの通り、20120414_rtl-sdr_matlab-gnss.7z を実行してみようとしています。GPSデータをrtl_sdrコマンドで取得までしました。
その後、matlab(私はoctaveですが)から、visibility_gps()を使用すると思うのですが、第2引数以降には何を指定すればよいでしょうか?初歩的な質問ですみません。
早速、やってみました。octaveで、自分で取得したGPS信号を処理できました。見つかったGPSは、1個だけでしたが...。
ソース内容も確認し、勉強しますね。
今後も、blog更新楽しみにしてます。
私は卒業研究でsdrを使っています。
さて私は受信した信号のIQ信号データを取得したいのですが、どうすればよろしいでしょうか
記事ではmatlabを使っているようですが、それ以外に方法はあるのでしょうか?