準備するもの
・RaspberryPi 本体(筆者はRaspberryPi 2で構築しています。)
・microSD(RaspberryPiの構築に必要です。)
・GPS受信キット1PPS出力付き 「みちびき」対応(https://akizukidenshi.com/catalog/g/gK-09991/)
(受信機とケーブルを繋ぐL字ピンがついているのですが、5ピンでいいのに6ピンのものが付属していました。問い合わせてみたら、ロットでどちらかが入っている仕様らしく…。笑
恐る恐るカットしてみましたが、意外と軽い力でカットできました。)
・ジャンパーワイヤー(https://www.amazon.co.jp/dp/B06Y48V9DL?tag=kigashir-22&linkCode=ogi&th=1&psc=1)
箱の中には「オス-メス」「オス-オス」「メス-メス」の3種類のケーブルが入っているので、使うときに間違えないように!(今回は、「メス-メス」を使います。)
ハードを接続する
「RaspberryPi 本体」と「ジャンパーケーブル」と「L字ピン」を接続して最後に「GPS受信機」を接続します。
結構簡単でした。RaspberryPiにケーブルを挿すときは、位置だけ間違えないように気をつけます。
裏面にボタン電池も付けられるのですが、
GPS受信機の設定をデフォルトから変更した際に、設定情報を維持するためのバックアップ電源の役割のようです。
今回は、使わないのでスルーします。
必要な方はつけるようにして下さい。
RaspberryPiを起動して設定
ハードの準備ができたので、設定をしてゆきます。
RaspberryPiの初期設定ができていることを前提に進めます。
いちいち、HDMIケーブルやらキーボードやらを挿して操作するのは面倒臭い!という方にはリモートをお勧めします。
ちなみに、この設定をしておけば、Macからでも、「Microsoft Remote Desktop」を使えばリモートが可能です。
ちょっと脱線しましたが、戻ります。
RaspberryPiでGPSを受信して時刻を読み込む
まず、シリアルコンソールを無効化。
sudo nano /boot/cmdline.txt
既存の行はコメントアウト。新しく追記します。
# console=serial0,115200 console=tty1 root=PARTUUID=2924e30a-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
systemdの設定を変更。
sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service
/boot/config.txtを編集します。
sudo nano /boot/config.txt
# UARTを有効
enable_uart=1
# タイムパルスを受信できるように設定
dtoverlay=pps-gpio,gpiopin=18,assert_falling_edge=true
/etc/modulesを編集し、pps-gpioを追加します。
sudo nano /etc/modules
pps-gpio
ここで再起動。
sudo reboot
gpsdとpps-toolsをインストール。
sudo apt-get install gpsd gpsd-clients pps-tools
gpsdの設定。
sudo nano /etc/default/gpsd
START_DAEMON="true"
DEVICES="/dev/ttyS0 /dev/pps0"
GPSD_OPTIONS="-n"
systemdの設定を変更し、gpsd.socketを有効化。
sudo systemctl enable gpsd.socket
またまた再起動。
sudo reboot
GPSの受信確認
GPSモジュールを水平に配置して、以下のコマンドを叩きます。
sudo ppstest /dev/pps0
ちゃんと受信できていると、このような表示がでます!
ちなみに、GPSの信号を受信できていないと、
「time_pps_fetch() error -1 (Connection timed out)」のエラーが表示されます。
この場合には、直接空が見える位置や窓際に設置場所を移して10分ほど放置してあげて下さい。
(筆者もこのエラーが続き、全然受信せずに困っていました。最終的にはベランダまで出してコネクションしました…。)
gpsmonを起動して、時刻を取得できているか確認します。
gpsmon
ここまで来たら、あとはNTPサーバを構築していきます。
受信したGPSを現在時刻として使う
日付設定スクリプトを作成して、受信したGPS情報から日付情報をゲットしてそれを現在時刻として読み込みます。
nano ~/setdatefromgps.sh
GPSの受信を1分待って、さらに1分待ってからもう一度セットすることにしました。
#!/bin/sh
echo start at `/bin/date`
for i in 1m 1m; do
echo sleep $i
/bin/sleep $i
GPSDATE="`/usr/bin/gpspipe -w | /usr/bin/head -10 | /bin/grep TPV | /bin/sed -r 's/.*"time":"([^"]*)".*/\1/' | /usr/bin/head -1`"
echo $GPSDATE
/bin/date -s "$GPSDATE"
done
echo end at `/bin/date`
cronで起動時に日付設定スクリプトを実行するように設定。
sudo crontab -e
1行追加。
@reboot /home/pi/setdatefromgps.sh > /home/pi/setdatefromgps.log 2>&1
ここまで設定して、再起動をしたら、
再起動後に、スクリプトが正しく実行されているか確認をします。
# ログを確認
cat setdatefromgps.log
ちなみに、私は「setdatefromgps.log」をチェックしようとしたところ、「Permission Deny」のエラーが出ました。
その際には一度、「setdatefromgps.sh」のパーミッションを確認して、以下のように設定されているか見てあげて下さい。
また脱線したので戻ります…。
再起動して上がってきたら、ログを確認してみます。
しっかりと取得できていることが確認できます。
NTP設定とGPSとの同期
apt-srcをインストールします。
sudo apt-get install apt-src build-essential
/etc/apt/sources.lstファイルを編集。
sudo nano /etc/apt/sources.list
3行目のコメントを外して、deb-src行を有効化。
(記述の「buster」の部分は、Raspbianのバージョンによって異なるため注意。)
deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
パッケージのリストをアップデート
sudo apt-src update
パッケージソースのチェックを行い、「ntp」がいることを確認。
(めっちゃ多いので探すの大変ですが。)
dpkg -l
NTPのパッケージソースをインストール。
apt-src install ntp
「./configureオプションを」設定するため、notepadで「rules」を開きます。
「ntp-4.2.8p12+dfsg/debian/rules」の中に保管されているので、探します。
ATOMを追加します。
override_dh_auto_configure:
dh_auto_configure --
・・・
--enable-ATOM ¥
追加すると画像のように「–enable-ATOM ¥」が追記されています。これで保存。
その後、ビルドします。
apt-src build ntp
ビルドしたパッケージ「*.deb」ファイルがいくつか生成されていることをチェック。
ls -al *.deb
ビルドしたパッケージをインストール。
sudo dpkg --install *.deb
インストールが完了したら、コマンドを実行してntpdが存在することを一度確認します。
ls -al `which ntpd`
次に、以下のコマンドで、既存の「ntpd」を「ntpd.default」にリネームし、
インストールした「ntpd」をコピーして置き換えます。
sudo mv /usr/sbin/ntpd /usr/sbin/ntpd.default
sudo cp ntp-4.2.8p12+dfsg/ntpd/ntpd /usr/sbin/
置き換え後は、日付が更新されていることを確認します。
/dev/pps0のパーミッション変更するために、「/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グループもアクセスが可能になるそうです。
(再起動必須。)
ntpの実行ユーザ/グループが、
/etc/passwdと/etc/groupに合っているか確認。
NTPのパッケージをインストール。
sudo apt-get install ntp
ntp.confを編集。
sudo nano /etc/ntp.conf
既存の記述を全て消して、以下の記述を追加する。(Ctrl +Kが便利。)
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.0.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
NTPのサービスを再起動。
sudo systemctl stop ntp
sudo systemctl start ntp
ntpqで正しく時刻が同期しているか確認。
ntpq -p
次に動作チェックをします。
ntpstatをインストールして、
sudo apt-get install ntpstat
インストールが完了したら、5秒おきにテストするようにしてみると。
watch -n 5 sh -c "ntpstat; ntpq -p -crv;"