PiZero2W+GPS/PPSでMacOSを高精度に時刻合わせする その3
その2の続きです。ここまでで、PiZero2WとMacをOTG接続できるようになり、GPSレシーバの準備もできました。ここでは、PiZero2WにGPSレシーバを接続し、高精度なNTPサーバとして仕立てます。
PiZero2Wをセットアップする
まずはPiZero2Wの電源が落ちていることを確認してから、microSDを取り出し、MacあるいはWindowsにマウントしてbootfsドライブを開きます。
以下、Macのターミナルでの作業時のプロンプトは % 、PiZero2Wにログインしての作業時は $ とします。
cmdline.txt編集
起動時のコマンド行からシリアル関連の部分を削除します。具体的には console=serial0,115200 の部分を削除します。
% vi /Volumes/bootfs/cmdlne.txt
console=tty1 root=${UUID} rootfstype=ext4 fsck.repair=yes rootwait modules-load=dwc2,g_ether
rootファイルシステムのUUIDは環境ごとに違いますので、ここでは${UUID}としています (変更しないで下さい)。
config.txt編集
PPSデバイスとUART (シリアル通信) を有効にする設定をファイル末尾に追加します。ついでにGPUに割り当てるメモリを減らして、利用可能な領域を広くしておきましょう。
% vi /Volumes/bootfs/config.txt
(ファイル末尾)
dtoverlay=pps-gpio,gpiopin=18
enable_uart=1
core_freq=250
gpu_mem=16
起動、SSH接続
上記の2ファイルの編集が済んだらmicroSDをPiZero2Wに戻し、USBケーブルでMacとOTG接続します。PiZero2Wが認識され、接続が確立したら、SSHでPiZero2Wにログインします。以下にアカウント名がpi、ホスト名がraspberrypiの場合の例を示します;
% ssh pi@raspberrypi.local
モジュール設定
ログインしたらまず、起動時にpps-gpioモジュールを読み込むよう /etc/modules ファイルの末尾に1行追加します。
$ vi /etc/modules
pps-gpio
動的スワップ無効化
RasPiではデフォルトで、ファイルシステム上に動的なスワップファイルを作成するよう設定されています。スワップはmicroSDの寿命に影響しますので、これを削除して無効にしておきます。
$ sudo apt -y purge dphys-swapfile
シャットダウン
設定が完了したらシャットダウンします。
$ sudo shutdown -h now
安全のため、USBケーブルをMacまたはPiZero2Wから抜いておきます。
GPSレシーバを接続する
ここまで設定が完了したら、GPSレシーバをPiZero2Wに接続します。データシートを確認すると、以下のような配線になっているようです。
https://akizukidenshi.com/goodsaffix/GT-502MGG.pdf
VCC: 赤
GND: 黒
TX: 橙
RX: 緑
PPS: 茶
これらをPiZeroW2の以下のピンに接続します。
赤 (VCC) → 1番 (3.3V)
黒 (GND) → 14番 (GND)
橙 (TX) → 10番 (UART_RX)
緑 (RX) → 8番 (UART_TX)
茶 (PPS) → 12番 (GPIO18) ※18番ピンではありません
VCC, GND, GPIOは複数ありますので厳密にはどこでも構いませんが、GPIOについてはconfig.txtの設定と合わせる必要があります。今回は偶数列のピンに集めました。なお、RasPiのGPiO 40ピンのレイアウトは以下の通りです。
このレイアウトはPiZero2Wとも共通ですが、microSDスロットがある方がこの図の上の方、1番ピンのある側となります。ボードを上から見て、GPIOピンを右側に置いた時に右上に来る方、としてもOKです。
gpsd
GPSモジュールをGPIOピンに接続したら、PiZero2Wを再度MacにOTG接続し、OTG接続が確立したらSSHでログインします。
インストール
gpsdと必要なパッケージをインストールします。
$ sudo apt -y install gpsd gpsd-clients pps-tools
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following package was automatically installed and is no longer required:
(大量のメッセージ)
大量の依存パッケージもインストールされるので、完了するまでしばらく待ちます。インストールが完了したら、DLされたパッケージのキャッシュを削除しておきます。
$ sudo apt clean
設定
/etc/defaults/gpsdを開き、以下のように値を設定します。
DEVICES="/dev/ttyAMA0 /dev/pps0"
GPSD_OPTIONS="-n -s 9600"
USBAUTO="false"
$ sudo vi /etc/defaults/gpsd
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyAMA0 /dev/pps0"
# Other options you want to pass to gpsd
GPSD_OPTIONS="-n -s 9600"
# Automatically hot add/remove USB GPS devices via gpsdctl
USBAUTO="false"
自動起動設定
gpsdと、gpsdが依存するgpsd.socketも自動で起動するようにします。
$ sudo systemctl enable gpsd.socket
$ sudo systemctl start gpsd.socket
$ sudo systemctl enable gpsd
$ sudo systemctl start gpsd
動作確認
なるべくGPSの信号を受信しやすいであろう南向きの空が開けた窓際に移動して、gpsmonを起動します。
$ gpsmon
測位が完了していれば、PPSも表示されると思います。TOFFの値とPPSの値は、この次のchronyの設定で用いますので、どこかにメモする等しておいて下さい。gpsmonはq -> Enterで終了できます。
測位が完了していない (Lon/Latが表示れない) 状態ではPPSもN/Aになりますので、より南向きの場所に移動するか、もうしばらく待つかしてみて下さい。
もし南向きの窓際に移動していくら待ってもPPSが表示されない場合は、以下のコマンドでPPS信号が取得できているか確認できます。
$ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1717515842.588359951, sequence: 14 - clear 0.000000000, sequence: 0
source 0 - assert 1717515843.588362164, sequence: 15 - clear 0.000000000, sequence: 0
source 0 - assert 1717515844.588363855, sequence: 16 - clear 0.000000000, sequence: 0
source 0 - assert 1717515845.588366797, sequence: 17 - clear 0.000000000, sequence: 0
source 0 - assert 1717515846.588369113, sequence: 18 - clear 0.000000000, sequence: 0
...
chrony
インストール
次に、chronyをインストールします。chronyと同じような機能を持つsystemd-timesyncdがデフォルトでインストール済みですが、chronyをインストールすると自動敵に削除されます。
$ sudo apt -y install chrony
設定
デフォルトの設定ファイルはリネーム (バックアップ) し、新たに設定ファイルを作成します。
$ sudo mv /etc/chrony/chrony.conf /etc/chrony/chrony.conf.orig
$ sudo vi /etc/chrony/chrony.conf
refclock PPS /dev/pps0 lock GPS refid PPS precision 1e-9 offset 0.002 trust
refclock SHM 0 refid GPS offset 0.3
allow 192.168.2.0/24
driftfile /var/lib/chrony/chrony.drift
rtcsync
makestep 1 3
leapsectz right/UTC
refid PPSとrefid GPSの各行についてoffsetの値を設定しますが、gpsmonのPPSの値とTOSSの値を大きく丸めた値をそれぞれ指定します。
再読み込み (再起動)
設定ファイルを保存したら、chronyを再起動して設定を反映させます。
$ sudo systemctl restart chrony
chronyはデフォルトで自動起動設定されていますので、gpsdのようにsystemctl enableする必要はありません。
動作確認
chronyを再起動したら、設定が反映されたか確認してみます。が、時刻ソースの読み込みには少々時間が掛かりますので、少し時間を置いてから実行します。
chronycはchronyデーモン (chronyd) と対になるクライアントです。様々な引数を渡すことでchronydの状態を取得したり、挙動を制御したりできます。ここでは時刻ソースの情報を取得するsourcesを実行します。
$ sudo chronyc sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* PPS 0 4 377 17 +377ns[ +574ns] +/- 216ns
#x GPS 0 4 377 16 +49ms[ +49ms] +/- 3801us
PPSの行の先頭2文字目が * になっていることが確認できました。これは時刻ソースとして選択されていることを示しています。
他に、時刻ソースの状態を取得するsourcestats, トラッキング情報を取得するtracking, 強制的に時刻を合わせmakestep, chronydを終了するshutdownなどがあります。詳細はhelpを実行して確認して下さい。
Overlay FS
Overlay FSを有効にすると、shutdownせずにいきなりUSBケーブルを引っこ抜いても大丈夫になります。若干本題からズレるトピックですでの、別の記事に切り出しました。
Overlay FSが有効になっていると (保守は若干面倒になりますが) 運用が楽になりますので設定することをお奨めします。
その4に続きます。