2026/9/1 7M4MON
01はじめに
AIS対応のチャートプロッターを評価していると、「好きな場所に船を出せたら便利なのに」と思うことがあります。実際の海上には多くのAIS搭載船がいますが、評価したい条件の船が、都合のよい位置・速力・針路で現れてくれるわけではありません。とくにCPA/TCPA表示や衝突警報を確認したい場合には、こちらで条件を決めたAISターゲットを発生させられる環境が欲しくなります。
今回の最終的な目標は、PC上で複数の船舶を動かし、船舶位置、SOG、COG、MMSI、CPA、TCPAなどを時間とともに変化させながら、実機のAISプロッターへ入力できる評価環境を作ることです。その第一段階として、PCで生成したAISデータを実際のAIS受信機やプロッターへ入力するための、小型のAIS RFインターフェースを製作しました。
02市販品で済ませるつもりだった
最初から送信機を自作するつもりだったわけではありません。AISシミュレータとして利用できそうな既製品を探し、Quark-elecのAT011なども候補にしました。
欲しかったのは、PC側から任意の船舶データをリアルタイムに与えられる装置です。たとえば、複数の船を異なる位置・速度・針路で動かし、その状態を時々刻々と更新してプロッターへ表示させることを想定していました。
ところがメーカーに確認したところ、AT011のUSB仮想COMポートは付属設定ソフトで使用するためのもので、外部アプリケーションから任意の船舶データを直接書き込むための公開APIやコマンドセットは用意されていないとのことでした。そこで、シナリオジェネレータとRF部の間を自分で作ることにしました。
03本記事での公開範囲について
AISは航行安全に関わる無線システムです。任意のMMSI、位置、速度、針路などを設定して送信できる装置は、使い方によっては実在しない船舶を表示させるなどのいたずらにも利用できます。RFを伴う試験はダミーロード、アッテネータ、シールド環境などを使用した閉じた試験環境で行っています。
一方で、AIS送信技術そのものは既に公開事例があります。GNU Radioを使用したAIS送信機やAISシミュレータ、マイコンとRF ICを組み合わせた例、回路図やファームウェアまで公開されたAIS関連プロジェクトなども存在します。そこで本製作では、既存の公開事例と同程度の技術情報は公開する方針としました。
本記事では、システム構成、使用した主要部品、ADF7021の設定で試行錯誤した内容、AISメッセージから無線フレームを生成する処理、CRC、bit stuffing、NRZI、GMSKなどの仕組みを紹介します。
04システム構成
最終的なハードウェア構成は、PC、Bluepill(STM32F103)、RF7021SE(ADF7021)の3要素です。PCとはUSBシリアルで接続し、BluepillがAIS電文を受け取って無線フレームへ変換し、RF7021SEへ送信データを渡します。受信確認側にはRTL-SDRとAIS-catcherを使用しました。
USB Serial
STM32F103
ADF7021
減衰・結合
AIS-catcher
最終的には、生成したAISターゲットがAIS-catcher上で正常にデコードされ、位置まで表示されることを確認できました。
05なぜADF7021なのか
AISは161MHz帯で9600bit/sのGMSKを使用します。今回使用したADF7021は、ナローバンド用途向けのRFトランシーバICで、2FSK、GFSK、MSK系の変調機能を持っています。安価なRF7021SEモジュールとして入手でき、外付け部品も比較的少なく済むため採用しました。
ただし、AIS用の完成された設定例があるわけではありません。そこで、まず435MHz付近で基本動作を確認し、その後に161MHz帯へ移す段階的な検証を行いました。
06Bluepillとの接続
| RF7021SE | Bluepill | 用途 |
|---|---|---|
| DATA / TxRxDATA | PA0 | 送信時はHigh-Z扱い |
| SDATA | PA1 | ADF7021レジスタ設定 |
| CE | PA2 | Chip Enable |
| PAC | PA3 | RF7021SE送信切替 |
| SLE | PA4 | Serial Load Enable |
| SREAD | PA5 | Readback |
| SCLK | PA6 | Serial Clock |
| INT/LK | PA7 | 補助信号 |
| DCLK / TxRxCLK | PB0 | 送信データ入力 |
| MUX | PB1 | PLL Lock Detect |
| TX LED | PB13 | PA動作表示 |
07まず435MHzでキャリアを出す
RF7021SEに搭載されている基準クロックは19.68MHzでした。いきなり161MHzへ行くのではなく、ADF7021の内蔵VCOを利用できる435MHz付近で確認を始めました。435MHzでは内蔵インダクタVCOとRF divide-by-2を使用します。
この段階では、レジスタ書き込み、SREADによるReadback、PLL、VCO、PA、キャリア出力を一つずつ確認しました。ADF7021のデータシートだけでなく、MMDVMやBluebox系の公開コードも参考にしながら設定を追っていき、最終的には433.92MHz、435MHz、440MHz、470MHz付近でキャリアを確認できました。
08DCLKが出ない
次はデータ変調です。当初はRF7021SEの端子名から、DCLKはADF7021から出るクロック、DATAはMCUから入力する送信データだと考えていました。ところがDCLKにまともなクロックが出てきません。テスターで中途半端な電圧を示し、プローブやテスターリードを当てると受信機から「ブー」という変調音のようなものが聞こえました。
外付け10kΩでDCLKをGNDへPull-downすると、その現象は消えました。つまりDCLKは出力されていたのではなく、浮いた入力になっていたようです。
09UART/SPI modeで端子の意味が変わる
ここが今回最大のハマりどころでした。ADF7021では、R0_DB28でUART/SPI modeを有効にした場合、送信時のピン機能が変わります。
通常モード TxRxCLK = クロック出力 TxRxDATA = 送信データ入力 UART/SPI mode TxRxCLK = 送信データ入力 TxRxDATA = 送信時High-Z
RF7021SE上ではTxRxCLKがDCLK、TxRxDATAがDATAです。つまり、それまでDATA端子へ9600bit/sを入力していましたが、実際にはDCLK端子へ入れなければなりませんでした。BluepillのPB0を出力に変更し、DCLK端子へ送信データを入力すると、受信機から明らかにデータ通信らしい連続音が聞こえ、外部データによる変調が確認できました。
10161MHz帯へ移す
435MHzで基本動作が確認できたので、次にAIS周波数帯へ移しました。161MHz帯ではADF7021のExternal Inductor VCOを使用します。RF7021SEではL1-L2に外付けインダクタ(18nH)を追加した。
基準クロック19.68MHzでR dividerを1のまま使用するとPLLのN値が許容範囲を下回るため、R dividerを2とし、PFDを9.84MHz、RF divide-by-2をONとする構成に変更しました。
REF = 19.68MHz R divider = 2 PFD = 9.84MHz RF divide-by-2 = ON VCO = External Inductor VCO
11VCOの調整
External VCOでは、インダクタ値だけでなくVCO_BIASとVCO_ADJUSTの組み合わせも効いてきます。161MHz付近に設定した状態でVCO_BIASとVCO_ADJUSTを切り替えながらMUXOUTのLock Detectを確認した結果、VCOBIAS=2、VCOADJ=2の組み合わせが安定していました。VCOADJ=3でもロックする条件はありましたが、データシートの推奨VCO_BIASとも整合するため、現在は2/2を標準設定としています。
12AISの変調条件
AISは9600bit/sのGMSKを使用します。ADF7021ではGaussian 2FSKを選び、変調指数が約0.5になるように周波数偏移を設定しました。
Data rate = 9600bit/s Frequency dev. = 約±2.4kHz Modulation index = 約0.5
ただし、実際のAISではGaussian filterのBT積は0.4ですが、ADF7021のGaussian filterはBT=0.5固定です。したがって今回の信号はAIS受信機で正常に復調できるGMSK系信号ではあるものの、RF波形まで含めた完全なAIS規格準拠送信機という位置付けではありません。プロッターの表示・CPA/TCPA・衝突警報などを評価するための試験信号源として使用します。
13PCからAIS電文を受け取る
最終的なハードウェアでは、PCとのインターフェースをUSBシリアルにしました。PC側ではAIVDM形式のAISデータを生成し、BluepillがAIS payloadを取り出して無線区間で必要となるフレームへ変換します。
これにより、PC側のシナリオ生成部分とRF部分を分離できます。
14PN9とキャリア試験モード
デバッグ用に、通常のAIS送信以外にもキャリア連続送信、PN9連続送信、AISフレーム単発送信などの試験モードを用意しました。通常のAIS送信は短いバーストのため、オシロスコープやSDRで信号を追う場合にはPN9のような連続変調モードが非常に役立ちました。
15デバッグ用UART
USBはPCからのAISデータ入力に使用するため、別にデバッグ用UARTを用意しています。PA9をTX、PA10をRXとして115200bpsで使用します。PA10はUSB-UARTアダプタを外した状態で入力が浮き、動作が変わることがあったため、内蔵Pull-upを有効にしました。
PA9 : TX PA10 : RX 115200bps
デバッグUARTからはStatus表示、Register値確認、PN9開始、Carrier開始、TX停止、周波数切替、PA level変更などを行えるようにしています。
16PA動作LED
送信中かどうかを一目で確認できるよう、PB13へLEDを接続しました。LED制御はRF7021SEのPAC信号と連動させており、AIS送信中、PN9送信中、キャリア送信中のすべてで点灯します。
当初PB12を使用しようとしましたが、使用していたDFRobot Proto Boardの端の列が内部接続されていることに気付かず、意図しない配線になっていました。PB13へ移して問題は解決しました。
17OLEDを追加する
装置単体でも状態が分かるように0.91インチ、128×32ドットのI2C OLEDを追加しました。一般的なSSD1306系モジュールを使用し、PB8をSCL、PB9をSDAとして接続しました。起動時には装置名、周波数、USB入力待機状態、TX状態などを表示し、AIS電文を受信した場合には受信内容と送信状態を表示できるようにしています。
18Arduino環境でもう一度ハマる
今回のBluepill環境はArduino IDE 1.8.10、Roger Clark版Arduino_STM32、Generic STM32F103CB、STM32duino bootloaderという比較的古い構成です。そのため現在のSTM32duinoで使えるWire.setSCL()やWire.setSDA()は利用できませんでした。PB8/PB9をI2C1として使用するため、旧Arduino_STM32のI2Cリマップ機能を使用しています。
さらに最新版のAdafruit SSD1306 / Adafruit BusIOは旧Arduino_STM32のWire.write()との型定義が合わずコンパイルエラーになりました。最終的にはAdafruit系ライブラリへの依存を外し、標準WireだけでSSD1306を直接制御する実装へ変更しました。
19RTL-SDRとAIS-catcherで確認
最終試験はRFを外へ放射しない閉じた試験系で行いました。PCからAISデータを入力するとPB13のTX LEDが点灯し、送信終了後には消灯します。そしてRTL-SDRで受信した信号をAIS-catcherへ入力するとAISデータが正常にデコードされ、最終的には生成したターゲットの位置がAIS-catcherの画面上に表示されるところまで確認できました。
ここまで動けば、RFインターフェースとしての目的は達成です。
20現在のハードウェア
| 項目 | 内容 |
|---|---|
| MCU | STM32F103CB Bluepill |
| RF IC | ADF7021 |
| Module | RF7021SE |
| Reference | 19.68MHz TCXO |
| VCO | External Inductor VCO |
| Data rate | 9600bit/s |
| Modulation | Gaussian 2FSK / h≒0.5 |
| Gaussian BT | 0.5(AIS規格値は0.4) |
| PC interface | USB Serial |
| Debug | Serial1 115200bps |
| PLL monitor | MUXOUT |
| TX indicator | PB13 LED |
| Display | 128×32 SSD1306 OLED |
| Test mode | Carrier / PN9 |
| Verification | RTL-SDR + AIS-catcher |
21シナリオジェネレーターへの発展
今回作った装置だけを見ると「AIS送信機を作った」という話に見えます。しかし、本来の目的はそこではありません。
最初から作りたかったのは、任意のAISターゲットを時間とともに動かし、AISプロッターの表示やCPA/TCPA、衝突警報などを再現可能な条件で評価する環境でした。
PC側のAISターゲット/シナリオジェネレータはすでに作成してあり、複数船について位置、SOG、COGなどを時間とともに変化させながらAISデータを生成できます。
今回製作したRFインターフェースによって、そのシナリオジェネレータで作ったAISターゲットを、実際のAIS受信機やプロッターへ入力できるようになりました。
安全上の注意
本機はAIS帯のRF信号を生成できる試験装置です。実験は法令および周囲のAIS運用に十分配慮し、ダミーロード、十分なアッテネータ、シールド環境などを用いた閉じた試験環境で行うことを前提とします。公共のAISシステムへ不要な信号を送信する用途を想定していません。