2012年11月17日土曜日

Radio Mobileで電波伝搬シミュレーション その1(インストール)

電波伝搬シミュレータ Radio Mobile を試してみました。
カナダのVE2DBE, Roger Coud氏によるフリーウエアで、どうやら有名らしいです。このソフトは、20MHz~20GHzに適用できるLongley-Rice Modelと呼ばれるモデルを使っているということです。

インストール
Radio Mobileのダウンロードページからダウンロードできますが、今回はイギリスのG3TVU氏が 配布しているインストーラを利用しました。

Step 1
VB6のランタイムがインストールされていなければ、Radio Mobile 'Quick Start' から Visual Basic Runtime (Service pack 6)  VB6.0-KB290887-X86.exe をダウンロードします。適当なフォルダにファイルを展開後、vbrun60sp6.exe をクリックしてインストールします。

Step 2
Radio Mobile Setup.zip を展開してインストールします。インストール先フォルダはデフォルトが良さそうです。

Step 3
デスクトップ上のRadio Mobileアイコンをクリックしてプログラムが起動できることを確認します。
(ひょっとすると地図は出なかったかも)


Step 4
SRTM(NASAが配布しているスペースシャトルから観測した標高データ)をダウンロード・解凍して C:\Radio Mobile\SRTM3 にコピーします。SRTM-3とは3秒メッシュ(90m)のデータです。
SRTMのファイルは、N36E139.hgt のような名前になっていて、その区画の左下が北緯36度 東経139度であることを表しています。ここでは、東京、神奈川、千葉のデータとして次のファイルをダウンロードしました。

N34E138.hgt
N34E139.hgt
N35E138.hgt
N35E139.hgt
N35E140.hgt
N36E139.hgt
N36E140.hgt

なお、SRTMやRadio Mobileの緯度経度は世界測地系(WGS84)を採用しています。任意の場所の緯度経度を知るには、Googleマップで任意の位置で右クリックして現れるコンテクストメニューから この場所について を選ぶと現れる緑色矢印アイコンにカーソルを重ねると表示が出ます。また、国土地理院の標高がわかるWeb地図を利用すれば、緯度経度の他に標高まで知ることができて便利です。


Step 5
Options → Internet を選びます。Internet Options 画面がでるので、SRTMの設定画面を選びます。"Use local files only" を指定して OK します。この設定はしなくても良いですが、シミュレーションのたびに Radio Mobileが SRTM データをダウンロードする場合があるようで、その対策です。



参考リンク
・Radio Mobile WEB Site
・G3TVU's Home Page - G3TVU氏によるドキュメント
・遠距離受信@Hachinohe - Radio Mobileで遊ぼう!(旧ページ)
・jp3pzd's photo diary - Radio Mobileで遊ぶ(3) Tipsなど
・数理設計研究所 - 電波伝搬シミュレータ Radio Mobile by VE2DBE

2012年10月29日月曜日

ロラン

北海道でロランの鉄塔を見かけました。GPSが一般化しているなか、とうの昔に運用を終えているものと思い込んでいたので意外です。この十勝太ロランC局は全国3カ所のうちの一つで、周波数100kHz、出力1500kW、鉄塔高さは193m。残念ながら来年2月1日付で廃止となるそうです。




近くまで行きたいところ、立入禁止の看板があり近付けません。
内部の様子は、一般公開に参加された方の記事に詳しいです。記事の最後に、アメリカ沿岸警備隊の管轄時に勤務されていた方のコメントが残っていてグっと来ます。



周囲にはのどかな風景が広がっています。27日の写真ですが、同じ日本とは思えない??





これは少し離れた場所。まるで現代アートのよう。


2012年9月28日金曜日

40MHz/入力レンジ80dBのUSB-FPGA信号処理実験基板

おじさん工房のAPB-3が、CQ出版から発売されます。
Spartan-6 FPGAと高速A/D, D/A搭載と言うことで、リリースを心待ちにしていました。
部品実装済みのプリント基板に、コネクタ・スイッチ類のはんだ付けが必要な半完成品キットで、価格は42,000円。トラ技の11月号から解説記事の連載がスタートするそうです。

2012年9月15日土曜日

FPGA FMトランスミッタ: レベルメータをつける

変調度メータを動かしてみました。プリエンファシスをオンにすると、高音のレベルが持ち上げられて思いっきり過変調になります。わかってはいましたが、これほどとは思っていませんでしたから、実際に目にして驚きました。





FPGA FMトランスミッタ: 設定用レジスタをつける

操作パネルからFPGA基板への機能設定は、某チップのSPI(もどき)を真似ることにしました。想定している信号波形と、レジスタの仕様は次の通りです。

SPIインターフェース信号波形


FPGA内 機能設定用レジスタ





2012年8月28日火曜日

FPGA FMトランスミッタ: ステレオセパレーションの測定

FPGA FMステレオチューナに接続してステレオセパレーションを測ってみました。チューナのセパレーション特性と比較すると、1kHz以上はチューナの特性に依存していてそれ以下は、トランスミッタの特性が見えているように思います。デジタルフィルタの特性のためにf特が波を打つならわかりますが、低域に向けて単調にセパレーションが低下するのは何故でしょう。

ステレオセパレーション

Lch 1kHz 100%変調(Lチャンネル)

Lch 1kHz 100%変調(Rチャンネルへの漏話)

2012年8月11日土曜日

FPGA FMトランスミッタ: FM変調器

FM変調器については、過去の記事(FM変調器(1)、 FM変調器(2)、FM変調器(3))に書いてますので、今回は具体的なところを書きます。と、言ってもお手軽なCoreGenを使いましたので簡単にできあがってしましました。

CoreGenの設定
DDSの位相アキュムレータは32ビットにしてあります。

DDS Compilerの設定1

DDS Compilerの設定2

DDS Compilerの設定3

DDS Compilerの設定4

DDS Compiler IP Symbol

周波数設定値
D/Aコンバータの動作クロックは77.824MHzですので、基本波としてFM放送波帯の周波数を生成することはできませんが、イメージ成分なら利用できます。例えば、83.5MHzが欲しいとき、DDSで5.676MHzを生成すれば、77.824MHz ±5.676MHz のイメージが出るので83.5MHzだけをフィルタで取り出すという手法があります。
※FMトランスミッタの製作スタート時の発想は、10.7MHzを生成して外付けのアップコンでFM放送波帯に変えようというものでした。

DDSの周波数設定値に適切な重み付けをした音声信号を重畳すればFM変調できたことになります。周波数偏移は、音声のフルスケールで200%変調、すなわち±150kHzになるように合わせます。DDSの動作クロックは77.824MHz、位相アキュムレータは32ビットなので周波数設定入力のMSBから9ビット目以降に音声信号 を接続すれば77.824MHz ×(2^23 / 2^32)  = 152kHzの変調度になります。このため事前に音声信号の振幅を150/152倍しておきます。(mod_level.v)
また、音声信号は2の補数形式のためストレートバイナリ形式に変換します。すると、入力信号のない無音時でも音声信号のMSBビットが立つことになり、あたかも周波数設定値にオフセットがかかったように見えます。従って周波数設定値は、このオフセット分を相殺した数値とします。

DDSの周波数設定値

測定結果
DDSで5.676MHzを発生させて、イメージの83.5MHzを見てみます。最初の2枚は、緑色がアナログ入力、黄色がデジタル入力で無音の場合です。デジタル入力の場合、ソースによってはDCオフセットがあるらしく、ぴょこっと周波数がずれてしまうことがありました。DCカット用にハイパスフィルタが必要だと思います。
3枚目は広帯域のスプリアスの様子です。77.824MHzのクロック周波数のほかイメージ成分2本が見えますが、わけのわからないノイズが多すぎます。スプリアスはフィルタを使えば取り除くことができるのでしょうが、仮に送信機のエキサイタとして利用するには素地が良くない気がしますが、チューナの試験用としてなら十分使えます。
訳のわからないノイズは、基板設計の拙さによって他のデバイスのノイズを受けてしまっているからと思っています。

83.5MHz ステレオモード(SPAN 200kHz)

83.5MHz モノラルモード(SPAN 200kHz)

スプリアス(83.5MHz、SPAN 40MHz)

次に、基本波を見てみます。最初の2枚は、緑色がアナログ入力、黄色がデジタル入力で無音の場合です。イメージよりノイズレベルが低く、コーデックのノイズがよく見えます。
3枚目は、広帯域(DC-20MHz)のスペクトラムで、目立ったスプリアスもなく良い感じです。やはりこれを所定の周波数までアップコンしたいところですね。
4枚目と5枚目は、1kHz 100%変調相当での占有周波数帯域幅です。

5.676MHz ステレオモード(SPAN 200kHz)

5.676MHz モノラルモード(SPAN 200kHz)

スプリアス( 5.676MHz、SPAN 20MHz)

5.676MHz ステレオモード占有帯域幅

5.676MHz モノラルモード占有帯域幅


fm_mod.v

module fm_mod(
  mod_i, mod_o, clk, reset, mod_set
  );

  input [23:0] mod_i;
  output [13:0] mod_o;
  input clk;
  input reset;
  input mod_set;

  wire [13:0] mod_o;
  wire [31:0] mod_data;
  reg [31:0] pinc_in;

//  parameter [24:0] FREQ_OFFSET = 32'h22B286BC;  // 10.7MHz
  parameter [31:0] FREQ_OFFSET = 32'h122BCA1A;  // 5.676MHz(83.5MHz)
//  parameter [24:0] FREQ_OFFSET = 32'h2229E50D7;  // 10.676MHz(88.5MHz)

  assign mod_data = {8'b0, (mod_i[23:0] ^ 24'h800000)};

  always @(posedge clk or posedge reset)
    begin
      if (reset)
        pinc_in <= FREQ_OFFSET + 32'h00800000;
      else
        pinc_in <= FREQ_OFFSET + mod_data;
    end

  dds_mod dds_mod (
    .clk(clk),
    .pinc_in(pinc_in),
    .sine(mod_o));

endmodule


mod_level.v

module mod_level(
  ml_i, ml_o,
  clk, reset, ml_thru
  );

  input [23:0] ml_i;
  output [23:0] ml_o;
  input clk;  // 64fs
  input reset;
  input ml_thru;

  reg [5:0] state64;
  reg [23:0] input_reg;
  reg [23:0] output_reg;
  reg [23:0] ml_o;
  wire latch_out;
  wire ml_thru;

  // State counter
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        state64 <= 0;
      else if (state64 == 63)
        state64 <= 0;
      else
        state64 <= state64 + 1;
    end

  assign latch_out = (state64 ==7);

  // Attenuation
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        begin
          input_reg <= 0;
          output_reg <= 0;
        end

      else
        begin
          case (state64)
            0:  input_reg <= ml_i;
            1:  // GAIN * (505/512)
              output_reg <= {input_reg[23], input_reg[23:1]}
                        + {{2{input_reg[23]}}, input_reg[23:2]};
            2:  output_reg <= output_reg
                        + {{3{input_reg[23]}}, input_reg[23:3]};
            3:  output_reg <= output_reg
                        + {{4{input_reg[23]}}, input_reg[23:4]};
            4:  output_reg <= output_reg
                        + {{5{input_reg[23]}}, input_reg[23:5]};
            5:  output_reg <= output_reg
                        + {{6{input_reg[23]}}, input_reg[23:6]};
            6:  output_reg <= output_reg
                        + {{9{input_reg[23]}}, input_reg[23:9]};
          endcase
        end
    end

  //  output data register
  always @(posedge clk or posedge reset)
    begin
      if (reset)
        ml_o <= 0;
      else if (ml_thru)
        ml_o <= ml_i;
      else if (latch_out)
        ml_o <= output_reg;
    end

endmodule