以前、Raspbery PiにGPSモジュールを接続して、起動時に時刻を合わせる設定を行いました。
別の方法として、PPSに対応したNTPデーモンをリビルドする方法を記録しておこうと思います。
RaspbianのPPS対応NTPサーバ構築手順
使用する機材
Rapberry Pi本体はLAN端子付きのもの
NTPサーバということで、遅延のない通信が必要になります。Wi-Fiでは正確な時刻の同期が難しいようです。Raspberry Pi本体は、有線のLAN端子があるものを選択します。GPSモジュール
こちらの記事の、GPSモジュールを使用させて頂きました。
記事の内容に沿って、GPSを接続し、初期設定を済ませます。Raspbianのインストールから始める場合は、よろしければこちらの記事を御覧ください。
LANケーブルで給電する場合
NTPサーバということで、Raspberry Pi+GPSモジュールを窓際など、空が見える位置に設置する必要があります。
こちらの記事のPoE機器を使用することで、LANケーブル1本で、LAN配線と同時にRaspberry Piへの電源の供給が可能になります。窓際に電源(コンセント)が無くても設置が可能になります。
この記事のNTPサーバは、実際にPoE給電を行ったRaspberry Piで作成致しました。NTPサーバにPoEによる影響がどの程度及ぶか、jitterやoffset等の数値から評価が可能かと思います。
NTPインストール(gpsd共有メモリー版)
こちらの記事の「NTPでシステム時刻をGPSと同期」の内容に従い、NTPのインストールを行います。
PPSに対応したNTPのビルド
直接PPSの入力に対応するため、NTPパッケージをビルドする必要があります。
こちらの記事は、apt-srcコマンドを使って、実際にPPSに対応したNTPのビルド手順になります。
手順の5番、ビルド前にdebian/rulesファイルを編集して./configureオプションに「–enable-ATOM」を追加します。ビルド後、ntpdバイナリを/usr/sbinへコピーしました。
PPS対応のNTP設定変更
/dev/pps0のパーミッション変更
ppsのパーミッションは、こちらの記事の内容を参考にさせて頂きました。
Raspbianのntpデーモンは、ntpユーザ(ntpグループ)権限で実行されるようです。ntpユーザが/dev/pps0を使用できるように、udevのルールファイルを作成しました。
- /etc/udev/rules.d/10-pps.rulesファイルを作成します。
sudo vi /etc/udev/rules.d/10-pps.rules
次の内容になります。
KERNEL=="pps0", OWNER=="root", GROUP=="ntp", MODE=="0660"
- 再起動すると、/dev/pps0デバイスのグループとモードが変わり、ntpグループからアクセス可能になります。
ntpd実行ユーザ/グループの確認
ntpの実行ユーザ/グループが、/etc/passwdと/etc/groupに合っているか確認しました。
ps -elfd |grep ntpd |grep -v grep
grep ntp /etc/passwd
grep ntp /etc/group
この場合、ntpdは -u 113:117オプションで起動しています。ユーザIDが113、グループIDが117のようです。
passwdファイルの113:117と、groupファイルの117で整合が取れていれば問題ありません。
実は、最初groupファイルは118になっていて、整合が取れていませんでした。117に書き換えて正しいグループでntpdが起動するようにしました。
ntp.conf変更
ntp.confの内容は、Raspbianフォーラムの内容を参考にさせて頂きました。
2点、変更があります。pps付きのgpsd共有メモリー(127.127.28.2)をpreferに設定、さらにNTPサーバとして使用するためristinct行を追加しました。
sudo vi /etc/ntp.conf
以下の内容になります。「restrict 192.168.150.0 mask 255.255.255.0」の行は、NTPサーバを公開するネットワークに合わせて変更して下さい。
tinker step 0.4 stepback 0.4 stepfwd 0.4
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid PPS stratum 0 flag3 1 flag4 1 time1 0.1
server 127.127.28.2 minpoll 3 maxpoll 3 prefer
fudge 127.127.28.2 refid SHM2 stratum 1 time1 0.1
restrict 127.0.0.1
restrict ::1
# local area NTP server
restrict 192.168.150.0 mask 255.255.255.0 nomodify notrap noquery
driftfile /var/lib/ntp/ntp.drift
logfile /var/log/ntp.log
#statistics
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
以上で設定完了です。systemctlにてNTPを再起動しました。
sudo systemctl restart ntp
NTPサーバの精度の確認
精度を確認するため、ntpstatをインストール後
sudo apt-get install ntpstat
5秒おきに実行してみました。
watch -n 5 sh -c "ntpstat; ntpq -p -crv;"
実は、最初はNTPサーバに100msec程度の誤差が生じておりました。
/etc/ntp.confを修正し、time1を追加して時刻のズレを補正してみました。
その結果、インターネット上の高精度なNTPサーバと同じ桁数までoffsetやjitterが改善されたようです。
他のNTPサーバを無効にする設定
Raspbian
他のNTPサーバを無効にする設定は、Raspbianの場合、/etc/dhcpcd.confを編集しました。
sudo vi /etc/dhcpcd.conf
「option ntp_servers」行を無効にしました。
Fedora 29
NTPクライアントはFedoraで確認しました。/etc/ntp.confに下記の行を追加後
server <NTPサーバのIPアドレス>
NTPが同期しない場合
どうやら、gpsdよりも先にntpdが起動してしまうと、同期に失敗する場合があるようです。いつまで経っても同期しない場合、ntpを再起動する必要があるようです。
sudo systemctl restart ntp
改善の余地がありますね。
ノイズの影響?
※19.4.1追記:
何日か動かしていたところ、GPSモジュールが衛星を補足しなくなる場合がありました。
GPSの電波がうまく受信できない可能性があるため、次の対策を行いました。
- Wi-FiとBluetoothをOFF。
- Raspberry Pi本体と、GPSモジュールの距離を離す。
対策後は再度、衛星を補足するようになりましたが、何かノイズ等の影響が考えられそうです。
GPSモジュールのPPS信号を使った、Raspberry PiのNTPサーバを構築してみました。
PoEにより、窓際への配線がLANケーブル1本で行えるため、手軽に設置することができました。またNTPのリビルドが必要でしたが、apt-srcコマンドを使用することで、比較的楽にビルドすることができました。
NTPサーバの精度は、最初100msec程度の誤差が生じていましたが、ntp.confに時刻のズレを補正する設定を行い、改善することができました。
クロックデバイスとして、NTPをリビルドして直接PPSを使うか、gpsdの共有メモリを使うか、どちらが良いかは、(gpsdにPPSを入力しているため)同じ程度の精度のようです。リビルドは不要かもしれません?
NTPパケットによるネットワークの負荷が、どの程度なのかはよくわかりませんが、ネットワーク帯域を消費していることは確かかと思います。
Raspberry Piはファンレスで消費電力も小さいかと思います。家庭用またはインターネットが使用できない環境で、NTPサーバとして使用するのも良い感じが致しました。