6 min read

ラズパイでGPSからのntp鯖構築

前々からやってみたかった。
最初軽く調べたらきのこアンテナなるものを発見。
ebayで売ってたけどさすがにトータル1万かけて輸入するのもなんだかなと思って安い選択肢を模索。

秋月でこんなものが売っているので買って構築してみることに。
GNSS(GPS・GLONASS・QZSS)受信機キット 1PPS出力 みちびき3機対応 アンテナセット付キット

案外このGPSモジュールを使った記事は目にしたので情報は豊富。

目次

GPSからntpのセットアップまでやったのでちょっと長くなりすぎてしまった

環境

  • Raspberry Pi 2 Model B
    • Raspbian Buster Lite
  • 上記GPS受信機キット

接続方法

GPSモジュール ラズパイGPIO
VDD5V 04 (5V)
GND 06 (GND)
TXD 10 (UART RX)
RXD 08 (UART TX)
1PPS 12 (GPIO 18)

GPS受信機キット 1PPS出力付き 「みちびき」3機受信対応
よくネットの記事で見かけるアンテナ一体型のこいつと同じようなものかと思っていたのだが、よく見るとTXとRXが逆だった。
そのせいで2時間くらい無駄にした。(よく見ない奴が悪い)

ちなみに下では1PPSをGPIO18に繋いでいる例なので変える場合は適宜読み替えて

シリアルコンソール無効化

/boot/cmdline.txtconsole=serial0,115200を削除する

#console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
# Raspberry Pi 3: ttyS0
# Raspberry Pi 2: ttyAMA0
sudo systemctl stop serial-getty@ttyAMA0.service
sudo systemctl mask serial-getty@ttyAMA0.service # disableできないので注意

UART有効化

/boot/config.txtenable_uart=1を追記

sudo su -c 'echo -e "\nenable_uart=1" >> /boot/config.txt'

1PPS受信設定

/boot/config.txtdtoverlay=pps-gpio,gpiopin=18,assert_falling_edge=trueを追記

sudo su -c 'echo "dtoverlay=pps-gpio,gpiopin=18,assert_falling_edge=true" >> /boot/config.txt'

/etc/modulespps-gpioを追記

sudo su -c 'echo "pps-gpio" >> /etc/modules'

重要

assert_falling_edge=true

このGPSモジュールはPPS信号を立ち下がりエッジで送信する模様。
デフォルトでは立ち上がりエッジでの検出になっているので、これがないと絶対100msずれる。(実際なった)
誤差修正で数時間悩んでいたので絶対に忘れてはいけない。

assert_falling_edgeをtrueにすることで、1PPS入力について下りエッジで反応するようにしています。今回用いた太陽誘電製のGPSモジュールは、アクティブローの端子であるためこのような設定となっています。同モジュールのPPS出力は、1秒ごとに100msほどアクティブロー状態となる動作であります。最初この設定を忘れていたために、後に誤差を確認する際NICTのサーバ群と100msほど確実にずれてしまうという事象に陥ることになりました。
Raspberry Piの設定メモ - 日記テスト運用中

まさにこれ。

これで準備はOKなのでsudo reboot

gpsdとかのインストール

sudo apt install gpsd gpsd-clients pps-tools
# Raspberry Pi 3: ttyS0
# Raspberry Pi 2: ttyAMA0

$ cat /etc/default/gpsd
START_DAEMON="true"
USBAUTO="true"
DEVICES="/dev/ttyAMA0 /dev/pps0"
GPSD_OPTIONS="-n"
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket
sudo reboot

受信の確認系コマンド

  • sudo ppstest /dev/pps0
  • cgps
  • gpsmon

これでGPSやPPSはOK

ntp鯖を立ち上げる

sudo apt install ntp

gpsd127.127.28.uのシェアードメモリ経由で時刻の情報を提供してくれる。

$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x4e545030 0          root       600        80         1                       
0x4e545031 32769      root       600        80         1                       
0x4e545032 65538      root       666        80         2                       
0x4e545033 98307      root       666        80         1                       
0x4e545034 131076     root       666        80         1                       
0x4e545035 163845     root       666        80         1                       
0x4e545036 196614     root       666        80         1                       
0x4e545037 229383     root       666        80         1                       
0x47505344 262152     root       666        8928       1                       
0x00000000 294921     zabbix     600        344        6          dest         
0x00000000 327690     zabbix     600        365032     6          dest

0x4e54503uがシェアードメモリーらしい。
今回はpermissionが666なユニット2を使う。

$ cat /etc/ntp.conf
~略~
server 127.127.28.2 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.2 refid SHM

server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid PPS

この他にもserverpoolを指定し、GPSからの時刻が本当に合っているかを確認する。

数時間放置してからのntpq -p
なお、コピペする前にntpを再起動してしまったのでSHMとPPS以外のpollが低い

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 s2csntp.miz.nao .POOL.          16 p    -   64    0    0.000    0.000   0.001
 ntp.nict.jp     .POOL.          16 p    -   64    0    0.000    0.000   0.001
 ntp.jst.mfeed.a .POOL.          16 p    -   64    0    0.000    0.000   0.001
*SHM(2)          .SHM.            0 l    7   16  377    0.000    0.005   0.001
oPPS(0)          .PPS.            0 l    6   16  377    0.000    0.005   0.001
-133.40.41.135   133.40.41.133    2 u   53   64  377   10.681   -0.690   0.186
+ntp-b3.nict.go. .NICT.           1 u   60   64  377    3.674    0.440   0.063
-133.40.41.134   133.40.41.133    2 u   63   64  377   11.053   -0.958   0.128
-133.40.41.136   133.40.41.133    2 u    7   64  277   10.531   -1.125   0.283
+ntp-b2.nict.go. .NICT.           1 u   42   64  377    3.706    0.405   0.085

GPSからの時刻はちゃんと合ってるみたいね。

なお、ntp.nict.jpポーリング間隔に制限を設けているので注意。

ローカルにntp鯖として公開

$ cat /etc/ntp.conf
# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

driftfile /var/lib/ntp/ntp.drift

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery limited
restrict -6 default kod notrap nomodify nopeer noquery limited

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1
# うちでは10.0.0.0/24がLAN
restrict 10.0.0.0 mask 255.255.255.0 nomodify notrap

# Needed for adding pool entries
restrict source notrap nomodify noquery

# pool servers
# お好きな外部ntp鯖

# gpsd shared memory
server 127.127.28.2 minpoll 4 maxpoll 4 prefer
fudge 127.127.28.2 refid SHM

# pps
server 127.127.22.0 minpoll 4 maxpoll 4
fudge 127.127.22.0 refid PPS

一応GPSになにかあった時のために外部のntp鯖も一緒に参照候補に入れといたほうがいいと思う。

最後にntp用のポートを開けて終わり

sudo ufw allow 123/udp

おわり

いろいろ試行錯誤してなんとかst1のntp鯖を構築することができた。
一番苦労したのはやはり最初100msズレてて焦ったこと。
立ち下がりエッジでの検出にしたらすんなり解決してクソデカ溜息だった。

それと、当初GPSアンテナを屋外に設置しないといけないと思っていたが、そんなことはなかった。
窓際に置いておくだけでも常時15個の衛星を掴んでいた。
屋外に設置しなくていいのは天候対策をしなくていいのでかなり良かった点。

なにはともあれ高精度なntp鯖が完成して満足。
ローカルからのntp参照を旧鯖からこの新鯖に移行しようと思う。

参考