新なんちゃってコリニアアンテナとカバレッジ

なんちゃってコリニアアンテナ再作成

昨年にデタラメ放題で作ったコリニアアンテナがAliExpressで購入したなんかよくわからないアンテナより遥かに良かったのに気を良くして新しいアンテナを作ることに。今回は屋外に設置すること前提でしっかり作る。ただし正しく作れているか確認するための測定機器は何もないので今回も「なんちゃって」なアンテナであることは変わらない。激安NanoVNAをeBayで注文したんだけど出品者がキャンセルしちゃったのよね。
今回使用したのは一般的なテレビアンテナのケーブルよりだいぶ細いRG58ケーブルで、芯線と網線の間の絶縁体(導体)が硬い充実ポリエチレンなので波長短縮率は67%。前回のなんちゃってアンテナ作成時に使ったS5CFVケーブルは発泡ポリエチレンで波長短縮率は80%だったのでそれより短いアンテナが作れる。短くなる分、リクツとしては長さ合わせはシビアになる筈だが、前回作った感想は「意外とデタラメでもイケるぞ」なので今回もお手軽に作る。送信ありだとデタラメじゃダメなんだろうけど、受信のみだからね。
ところで、今回のケーブルは日本のケーブルの分類では4D-2V(直径4mm+50Ω+充実ポリエチレン+シールド無し網線)あたりになると思うのよね。2Vと言われると高周波向けケーブルとしては良くないイメージだけど、アンテナのエレメントとしてはそれで良いのかしら?(シールドは要らないにしても充実ポリエチレンが)

1090MHzの波長は275.0389523mm
λ/2 = 137.51947616
λ/4 = 68.75973807
それぞれ短縮率を掛ける。
短λ/2 = 137.51947616 x 0.67 = 92.138049mm まるめて92mm
短λ/4 = 68.75973807 x 0.67 = 46.069024mm まるめて46mm

「がとらぼ」の中の人の工作精度だと整数ミリ単位が限度。それに、波長短縮率もこの同軸ケーブルを測定してケーブル素材での正しい長さを出しているわけではなく、あくまでもポリエチレンの場合のアバウトな率なのでこの数値で100%正しいということでもなく、計算上の長さで精度を出したところで意味がない。

コリニアアンテナ作製 1
短λ/2を8本(8段)、それぞれの両端に短λ/4を1つずつ取り付け、先端側の短λ/4の末端はショートした。その先にλ/4ほど芯線をビョンと伸ばすのは今回は無し。
購入したケーブルは丸まりクセがなく、どちらかというと解くと真っ直ぐになろうとするもので、それを購入してから2ヶ月ほど天井から真っ直ぐぶらさげて保管していたが、エレメントの長さに切ると何故か丸まろうとするのが不思議。
上の写真はピンぼけで、芯線も適切な長さ(網線の露出部分+0.5mm程度)にカットする前のもの。実はこのあと、アンテナが完成するまでの写真が全てカメラのSDカード不良で取り出せなかった。

コリニアアンテナ作製 2
これは失敗して使わなかったエレメントをスマホで撮影したもの。網線部分にハンダをしている。網線の下のポリエチレンに悪影響を与えないように90Wのはんだこてで一気にハンダを網線に染み込ませる。写真の手前側は少し厚くハンダを置いて、隣接するエレメントの芯線をひっつける部分になる(筈だった)。が、この写真のエレメントはその網線にハンダを染み込ませるのが綺麗にできなかったのでボツにした。同軸ケーブルの網線は「はんだ吸取り線」と同じようなのだから簡単な筈で失敗するのは恥ずかしいんだけどね。

前回はエレメントの接合は同軸ケーブルの外皮と網線の境に隣接するエレメントの芯線を突き刺すという簡易方式にしたが、今回はそれぞれのエレメントの外皮を7mmずつ剥いてきちんとハンダ付けした。また、エレメントの接合部はそうでない部分と比べて強度が劣るので力が加わるとそこから折れ曲がったりショートしたりで良くないので自己融着テープをしっかり巻きつけて防水且つ強度のある状態にした。本来はさらにその上から防護用にビニールテープを巻くんだろうけど、パイプの中に収めるのでエレメント接合部分はビニールテープは無しとした。

その8段コリニアアンテナは直径22mmの硬質ビニル電線管(J管)に収めた。FRPのパイプの方が良さそうだけどちょっと高いのと入手が難しいのよね。園芸用のダンポールPというのがFRPパイプに樹脂コーティングしてあって1〜3m程度の短く細いコリニアアンテナには良さそうだったので今度購入してみようかと考えている。ちょうど良い太さと長さのものが単品で販売されているかが問題だけど。
パイプの先端にはノック付きのツバ管を取り付けた。ツバ管だけどノック付きは実質的にはフタになる。(隙間があるので防水化必須)
テグスをコリニアアンテナ先端に固定して、そのテグスで引っ張り上げるようにしてパイプの先端のツバ管のノック部に留める。ツバ管はパイプの先端と一緒に自己融着テープで防水処理してからビニールテープを巻いて保護した。

アンテナの根本側は22mmのJ管の上に26mmのJ管を被せた。これは内径が22mmでNコネクタがすっぽり収まる太さだったから。コネクタ部分がパイプで隠れるようにした方がコネクタが雨に直接晒されなくて良いかなということで。2つのバイプを重ねると隙間があったので滑り止めシートを巻きつけて無理やりパイプをはめ込んだ。2種類のパイプの継ぎ目部分の外側は自己融着テープで防水処理してからビニールテープを巻いて保護した。

コリニアアンテナ作製 3
以前のAliExpressで購入したアンテナを屋根に設置したときは直径60mmの塩ビパイプにBPF+LNAとRTL-SDRドングルとOrangePi Zero Plusを入れたが、OrangePiの収まりが悪いのと結露にも困ったので今回は新しいケースを作った。
ダイソーで購入したパスタケースが長さ的に良さそうだったのでそれに穴を開けて中にモノ収めてホットボンドで穴を塞ぎ、さらに自己融着テープを貼って目張りをした上で防護為にのビニールテープを巻いた。ヒートシンク部分だけはホットボンドのみ。また、タッパーのフタも自己融着テープ+ビニールテープにした。これで防水はしっかりできた筈。暑い日に破裂する可能性はあるが、以前にパイプに一式収めたときは破裂を恐れてスポンジによる虫侵入防止付きの空気口を付けた結果が結露で水溜りになり大変なことになったので今回は密閉。
上の写真はタッパーの中の右の青いのがBPF+LNA、中央の緑がRTL-SDRドングル、左の青い基板がOrangePi Zero Plus(の裏面)。Orange PiとBPF+LNAを繋いでいる中央下の小さな基板はOrangePiからBPS+LNAに電力を供給する間に入れた整流ダイオード。この基板はホットボンドでタッパーの内側に留めている。

コリニアアンテナ作製 4
タッパーの裏側は、OrangePiのSoCに貼り付けた銅のキューブと同じサイズの穴を開けてキューブを貫通させてタッパーとの隙間をホットボンドで塞ぎ、ヒートシンクを銅キューブに貼り付けて、さらにヒートシンクをタッパーとホットボンドでぐるり1周しっかりと隙間を塞ぐように盛った。

コリニアアンテナ作製 5
残念ながら天候に恵まれず屋根に取り付けられなかったのでアンテナ台にタイバンドでアンテナを仮止めして地面に置くしかなかった。ここは周囲を建物に囲まれた中庭的な場所なので地面に置いたアンテナの水平方向は全ての方向で直線的には何かに邪魔された状態。感度は期待できないかなと思った。(この時点では)

コリニアアンテナ作製 6
1つ前の記事でdump1090-faのWeb-UIの画像を上げたが、それだとカバレッジは表示できないっぽいのでVirtual Radarでdump1090-faからデータを取るようにして1日放置した。つまりデータ取り始めてから約24時間で収集したカバレッジ。灰色のカバレッジが4万ft、青色のカバレッジが3万ft。
上の画像では何故か全ての飛行機がGo West。これは珍しくなく頻発する。東行きの飛行機はいないのかしら?(東行きの航路がカバレッジ外の伊勢湾の方みたい)
ところで、「がとらぼ」の中の人はオッサンなのでGo WestというとPet Shop Boys、お爺さんたちはVillage Peopleかな。若い人たちは誰を想像するのかしら?

カバレッジ

上の画像を見て「カバレッジ凄い狭いな」と思われた方もいるかもしれないが、「がとらぼ」の中の人の実家は内陸の「風の谷」みたいなところなので元々カバレッジの広さは期待できないところ。

カバレッジ考察 1
以前にも紹介したHeyWhatsThatというウェブサイトで任意の場所で「期待できる見晴らし」を調べることができる。上の画像は「がとらぼ」の中の人がアンテナを地上20ft(屋根の上という想定)に置いた場所からの見晴らしの可能性を示したもの。
上の画像では3万ftの見晴らしがオレンジ線、4万ftの見晴らしが青線となっている。見た通り、北側と西側は特に狭く、南東側は直線に削り取られたようにごっそり狭い。これは地形的にこれ以上はどうしようもない。山の上にアンテナを持っていけば激的に改善するのは判っているけど無理だし。
さて、24時間で取ったカバレッジをHeyWhatsThatで得た「期待できる見晴らし」を比べると、奈良県方向と長野県方向が大幅に弱いものの、北西方向は意外と健闘していると思われる。しかも、これはアンテナが地面にあって周囲を建物に囲まれてるのでおそらく反射と回折で得ている電波。それを考えるとむしろビックリなくらい。

カバレッジ考察 2
HeyWhatsThatで得られた最も遠い陸地側は長野と群馬の境にある愛宕山(実際には愛宕山からは少し離れた下仁田)だが、そこからアンテナ設置場所までの電波の飛び方も表示してみた。下の方の灰色の凸凹しているのがアンテナ設置場所と愛宕山の間の地形の断面。愛宕山といってもその山頂からは途中の地形に邪魔されて全く光(電波)は届かない。上の図は愛宕山の上空で海抜4万ftからの1090MHz(ADS-B)の電波の飛び方(屈折)をオレンジの線で示している。1090MHzは光に近いほぼ1直線。これで左の方を見るとアンテナ設置場所から15マイル(24km)ほどにそれほど背が高いわけでもないのにごちゃごちゃと山があるのが判る。これが「がとらぼ」の中の人のアンテナからの見晴らしを悪くしている原因。ちょうど10マイル地点でオレンジの線とぶつかりかけている。つまり愛宕山の上空(海抜で)4万ft以下だと邪魔されるということ。

カバレッジ考察 3
場所は愛宕山から変えずに高さを半分の2万ftにした。左のアンテナから15マイルほどはオレンジの線が全て山の中を通っている。地中は電波は通らないのでつまり電波は遮られている。同じく、中央の80マイル手前の大きな山にも遮られている。

カバレッジ考察 4
上と同じく愛宕山で高さ2万ft。ただし、電波の周波数を極超短波の1090MHzではなく短波でアマチュア無線でよく使われる14MHzにした。光や周波数の高い電波だと直進性が高いので黒い直線だが、14MHzくらい低くなると大気中での屈折が大きくなるのでオレンジ色の弧の幅が出てくる。地形がオレンジに塗られている部分は地形により電波が遮られるが上の弧は地形に邪魔されていないので愛宕山2万ftから直接電波が届くということになる。この周波数は電離層で反射した電波も届くけど、ここでは直接波だけ。地形による(特に山頂などによる)回折はこの図で考慮されているのかはド素人なのでわからない。(おそらくされていない。)

何を言いたいのかというと、「がとらぼ」の中の人の実家からは高度の低い飛行機を捉えるのは難しそうだなと。

関連記事:

dump1090-fa

ADS-Bの受信用に購入したARM64のH5を搭載したシングルボードコンピュータのOrangePi Zero Plusは、DebianがベースのArmbianが動いている。昨年夏の時点ではADS-Bの受信にはdump1090-mutabilityを使用した。これはArmbianの標準リポジトリに入っているパッケージを単にインストールしたもの。簡単なので。
ただ、dump1090-mutabilityは昨年夏の時点で既にも既に開発者がもう開発を継続しないのでdump1090-faに移れと言っていたもの。流石に2020年に新しくインストールするならもうdump1090-mutabilityはナイ。
dump1090-faをググるとGithubではdump1090-faとしてhttps://github.com/adsbxchange/dump1090-fa がヒットするんだけど、こちらはArmbian上では全くビルドできなかった。
GitHubのdump1090-mutabilityのREADME.mdを見ると https://github.com/flightaware/dump1090 にリンクが張られていたので、dump1090-faはこちらが良いっぽい。

Orange Pi Zero Plus上でビルドする

$ sudo apt install git lighttpd debhelper librtlsdr-dev pkg-config dh-systemd libncurses5-dev libbladerf-dev libusb-1.0-0-dev

先ずはビルドに必要そうなパッケージをインストールする。Armbian新規インストール直後だともしかしたら他にも要るかも。後のビルド時のエラーを見て追加。

$ git clone https://github.com/flightaware/dump1090 dump1090-fa
$ cd dump1090-fa
$ dpkg-buildpackage -b --no-sign

gitでダウンロードしてからビルド。
今回は普通にMakeするのではなくDebian用パッケージとして作製する。ラクだし。
ビルドが終わったら1つ上の階層にパッケージが出来ている筈。

$ ls ../
dump1090_3.8.0_all.deb
dump1090-fa  (dir)
dump1090-fa_3.8.0_arm64.buildinfo
dump1090-fa_3.8.0_arm64.changes
dump1090-fa_3.8.0_arm64.deb    ←これ
dump1090-fa-dbgsym_3.8.0_arm64.deb
いくつかパッケージが出来ている筈だが、インストールするのは1つだけ。
$ sudo dpkg -i dump1090-fa_3.8.0_arm64.deb

パッケージをインストール。systemd向けのサービス起動用ファイルも入るのでラク。

/lib/systemd/system/dump1090-fa.service (特に触る必要無し)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# dump1090-fa service for systemd

[Unit]
Description=dump1090 ADS-B receiver (FlightAware customization)
Documentation=https://flightaware.com/adsb/piaware/
Wants=network.target
After=network.target

[Service]
User=dump1090
RuntimeDirectory=dump1090-fa
RuntimeDirectoryMode=0755
ExecStart=/usr/share/dump1090-fa/start-dump1090-fa --write-json %t/dump1090-fa --quiet
SyslogIdentifier=dump1090-fa
Type=simple
Restart=on-failure
RestartSec=30
RestartPreventExitStatus=64
Nice=-5

[Install]
WantedBy=default.target
パッケージだと自動で入るが、内容の紹介だけ。

dump1090-faの設定

パッケージで入る設定ファイルは/etc/defaultにあるdump1090-fa。
この設定の初期値はRECEIVER_OPTIONSが--device-index 0 --gain -10 --ppm 0になっている。例えば手動でゲインを変更するなら--gain の後の数値を変える。初期値はマイナス値の-10で、この-10がオートゲイン向けらしいので触らないのが無難?
--ppmは激安RTL-SDR登載クロックオシレータが怪しいやつで周波数がズレるのを修正する用かしら。
SoCがH5なOrange Pi Zero Plusでは--enable-agc指定でdump1090-faのCPU使用率が30%に届かない程度。--enable-agc且つ--dcfilterを指定すると35%程度になった。でも、DC Filterって意味あるのかしら?
基本的にはあまり初期値から変更する必要はないと思うけど、アンテナ設置場所の座標(--lat 緯度 --lon 経度)だけは書いたほうが良さげ。でないと、ウェブUIの地図の表示の初期値がヨーロッパになるので日本まで地図をずらすのが面倒。座標を指定すると、その座標を中心とした同心円も地図に書かれるし。その座標オプションははレシーバーオプションなのかデコーダオプションなのかよく判らないがとりあえずRECEIVER_OPTIONSの方に足して機能している。なお、ウェブUIを使わないなら座標指定は要らない。
ネットワーク設定は設定ファイルの初期値のままで普通に他のホストから参照できる設定になっているので特に触らなくて良い筈。
ヘルプは dump1090-fa --helpで表示される。

dump1090-faの起動

$ sudo systemctl enable dump1090-fa.service
$ sudo service dump1090-fa start

1行目はdump1090-faのサービス有効化。これを実行すると次にワザと無効化するまでシステムを再起動しても有効化はずっと保たれる。
2行目はサービスの開始。先に有効化しないと開始できない。

JSON出力

各種JSONは/var/run/dump1090-fa下に出力される。(/lib/systemd/system/dump1090-fa.serviceの起動オプションによる)
このJSONを他のアプリに渡して利用することも可能。

Web UI

今回はウェブ出力付きでビルドしているのでhttp://IPアドレス/dump1090-faをブラウザで開く。

dump1090-fa Web-UI
表示される。うん、動いてる。でも、特に何かできるわけではないので要らないね。
ちなみに、この画像はdump1090-faの設定で座標を指定していないので同心円は描かれていない。また、ウェブ上の設定で飛行機の軌跡も描かないものになっている。

関連記事:

Fail2BanでBAN発生時に警告灯を点灯させる

警告灯をブラウザで制御

Fail2Banは、サービスのログを監視して、ネットから攻撃された際にファイアウォールでそのIPを指定時間弾く(BANする)というようなことに使うツール。BANが発生したときには、それを何かに通知するだろうが、多くはメールで通知する程度?まぁ、メールで通知されて何か役に立つわけではないが、届いたメールの数で「昨日は午後多かったね」くらいは判る。通知先を監視システムにしていれば、それで統計にしたりリアルタイムで監視したりというのも。
で、「がとらぼ」では警告灯を作ったのでそれに通知させることにした。つまり、BANが発生したら警告灯が光るようにした。通知方法はシンプルにWebhookを使う(またかよ)。

Fail2Banの設定

以下、設定ファイルのPathはFreeBSDのpkg/portsでFail2Ban(security/py-fail2ban)をインストールした場合に倣ったもの。Linuxなどでは/usr/local/etc下ではないと思うので適当に読み替えて欲しい。

/usr/local/etc/fail2ban/action.d/webhook.conf (新規)
1
2
3
4
[Definition]
actionban = /usr/local/bin/curl -X POST -H "Content-Type: application/json" \
            -d '{"data":{"name":"Fail2Ban", "status":"warning"}}' \
            http://hoge.example.com/path/webhook.php

アクション用のファイルをaction.d下に作製する。
今回はBANが発生したときにWebhookするというものなのでactionbanを書いた。
curlでJSONをPOSTするだけ。今回は警告灯を光らせるだけが目的なのでJSONの内容はdataの中でnameとstatusを内容固定にした。2〜4行目は本来は1行で書くところを行末の \ で改行している。4行目はwebhookの通知先。

/usr/local/etc/fail2ban/jail.local (1行追加)
1
2
3
4
[DEFAULT]
action = pf[name=%(__name__)s, bantime="%(bantime)s", actiontype=<allports>]
         %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s"]
         webhook[]
4行目が今回追加した行。
2〜4行目がアクションの指定。それぞれの行で、FreeBSDのパケットフィルタであるpfのテーブルに該当IPアドレスを追加、メールで通知、今回追加したアクションであるWebhookを指定している。上の例ではDEFAULTセクション(全てのフィルタのアクション)で指定しているが、サービス毎のセクションで指定するのももちろんあり。 今回は単に警告灯のランプを点灯させるだけの目的で、可変で何か情報を通知させたいわけではないのでwebhookの[ ]の中は何も無し。
# service fail2ban reload
OK

Fail2Banの設定をリロードさせる。OKが出れば設定に致命的なエラーもなく設定がリロードされた筈。
設定のリロードだけでなく、Fail2Banにサービスのログをリロードさせたい場合はFail2Banを再起動 (service fail2ban restart)。
/var/log/fail2ban.logを見てエラーが出ていないことを確認。
これで、Fail2Ban側が完了。

Webhookの受信側

上で設定したFail2Banのホストからネットワーク的に疎通できるウェブサーバにphpスクリプトを置く。上のFail2Banの設定では http://hoge.example.com/path/webhook.php になる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {

    //ここはfail2banのwebhookを単純に取得
    $body = file_get_contents('php://input');
    $json = json_decode($body, true);   // <- 2つめの引数にtrueを付けないと連想配列にならない
    //echo print_r($json);

    foreach($json as $ealert) {
        if ((array_key_exists('name', $ealert)) && ($ealert['name'] == 'Fail2Ban')) {
            light(2);       //黄色点灯
            usleep(500000); //0.5秒停止
            light(0);       //消灯
            exit;
        }
    }
}

function light($c) {
    switch ($c) {
        case 0:
            //警告灯 消灯
            $code = "0f";
            break;
        case 1:
            //警告灯 緑
            $code = "0b";
            break;
        case 2:
            //警告灯 黄
            $code = "0d";
            break;
        case 3:
            //警告灯 赤
            $code = "0e";
            break;
    }

    $cmd = 'echo "' .  $code . '" | xxd -r -p > /dev/cuaU0';
    exec($cmd , $error);
    //echo $error;
}
?>

このコードではdata内にnameが存在し、且つそのnameが「Fail2Ban」なWebhookを受けると0.5秒間だけ黄色点灯するというシンプルなもの。読みやすくするためFail2Ban側で送信したstatus内容の判断はこの例では入れていない。
ただし、これだと深夜0時からのFail2Banの再起動(日跨ぎ処理)の再BAN発生により暫く警告灯が激しくチカチカしまくることになる筈。点灯条件は必要に応じて増やしておいた方が良いと思う。

関連記事: