先日秋月で衝動買いしたGPS受信機キットとraspberry pi(jessie)で、PPS信号同期のNTPサーバを作ってみた。特にPPS関連ではまったので、将来の自分が同じところでつまずかないようにポイントをメモ。
(1)標準カーネルはPPSに対応しているが、設定が必要
まずは、/boot/config.txtに、以下を追記。
dtoverlay=pps-gpio,gpiopin=18,assert_falling_edge=true
念のため、メモしておくと、PPS信号を受け取るのに使うGPIOは、ここでは18番。PPSにGPIO18番を使うと、GPSとraspberry piのピン配置が同一になるので、接続が混乱なくできる。お勧め。
また、ググって出てくる他のGPSと違って、秋月のこのGPSはPPS信号が立下りなので、assert_falling_edgeを追記しないと、100ms後の立下りをつかんでしまい、それがそのまま誤差になって出てくるので注意。100msもずれるなら、PPS信号を使う価値なし。
次に、動作確認のために、ユーザランドのソフトのインストール。
% sudo apt-get install pps-tools
これで、適切に設定ができていれば、
% sudo ppstest /dev/pps0
とすると、一秒に一行ずつ表示されるはず。
(2)インストール済みのgpsdとntpdは、PPS信号に対応していない
いずれも、リコンパイルが必要です。
もう少しいうと、ntpdの127.127.22.0ドライバを使えるようにするには、ntpdのコンパイルが必要でした。これ必須。
また、gpsdのgpsmonでPPSを見られるようにするには、gpsdのコンパイルが必要でした。ただし、gpsdからntpへPPSを渡すことはできないよう(ntpdの127.127.46.0で、mode 1にすると、連携できなくなる)なので、必ずしも必須ではありません。
なお、gpsdでPPSを使うには、/etc/default/gpsdに、
DEVICES="/dev/gps0 /dev/pps0"
と、GPSシリアルデバイスと、PPSデバイスを指定してやる必要があります。
(3)GPSからシリアル経由でデータ取得するために、シリアルのgettyを止める必要あり。
systemdとやらのおかげで、/etc/inittabがなくなってて、さあ大変。
シリアルが、ttyAMA0の場合には、
$ sudo systemctl stop serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyAMA0.service
とすると、止まるらしい。
また、/boot/cmdline.txtから、
console=ttyAMA0,115200
を消す必要あり。これを消さないと、起動のたびに115200bpsに設定変更されるみたい。これが原因で、GPSと通信できなくなることがある。
以上の設定で、数十μsオーダで同期しているみたい。
参考に、今のntpd.confをつけておく。
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid PPS
server 127.127.46.0 minpoll 4 maxpoll 4 prefer
fudge 127.127.46.0 time2 0.438
GPS側にpreferをつけないと、なぜかPPS同期してくれない点に注意。