BluepillとADF7021でAISターゲット信号源を作る ~李下に冠を正さず~


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を使用しました。

最終的には、生成した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=2VCOADJ=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システムへ不要な信号を送信する用途を想定していません。