Raspberry Pi に GPS センサを接続し、 gpsd と chrony の サービス を有効にして位置情報取得と時刻補正をする
動作環境
- HW: Raspberry Pi 4B
- OS: Raspberry Pi OS
- センサ: GNSS 受信機キット(秋月電子)
- USB 変換器: USBシリアル変換モジュール(秋月電子)
配線接続
用意した GPS センサは UART 接続用だが、Raspberry Pi 以外の機器にも適用するため変換器を使用して USB 接続する
接続確認
USB 変換器が認識されると/dev/ttyUSB0
が作成される
通信内容を読み取り GPS センサが接続されていることを確認する
cat /dev/ttyUSB0
コマンド実行すると、下記のような NMEA 形式の応答がある
(注) 既に gpsd を設定・起動しているとDevice or resource busy
と表示される
GNGLL,3422.1331,N,13518.0431,E,141613.000,A,A*48
GNGSA,A,3,17,28,04,14,09,03,19,06,22,,,,1.19,0.86,0.82*18
...
gpsd を有効にして位置情報を取得する
位置情報を受け取る仕組み
GPS センサから NMEA 形式の信号を受け取った gpsd は、gpsd_json 形式に変換した位置情報レポートを TCP/IP 通信(ポート2947)で配信する。レポートの内容は cgps などの gpsd クライアントを使用して簡単に表示できる
gpsd、gpsd クライアントのインストール
sudo apt install gpsd gpsd-clients
gpsd 設定
/etc/default/gpsd
を編集する
# Default settings for the gpsd init script and the hotplug wrapper.
# Start the gpsd daemon automatically at boot time
START_DAEMON="true"
# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="true"
# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyUSB0"
# Other options you want to pass to gpsd
GPSD_OPTIONS="-F /var/run/gpsd.sock -b -n -r"
オプションの意味はman gpsd
で確認できる
-F ソケットのファイルパス
-b デバイス保護モード(GPS センサへの設定書き込み禁止)
-n リクエストがくるまでセンサ接続待機する機能を無効にする。
-r 補正完了前でも GPS の時刻を使用する。RTC 内蔵センサなら補正完了前でも有効な時刻が取得できる
gpsd を再起動する
sudo systemctl restart gpsd.service
位置情報を取得する
cgps や gpsmon などの gpsd クライアントを使用して位置情報を取得する
cgps -s
こちらのライブラリを使用すると python で位置情報を取得することもできる
chrony を有効にして位置情報を取得する
chrony とは
ntpd とは異なる NTP 実装。ホストマシンが頻繁にシャットダウンやネットワーク切断状態となるケースで安定して動作することが特徴[公式]。CentOS や Red Hat では ntpd に変わりデフォルトとなっていることから信頼性も高い
chorny は gpsd が shared memory に書き込んだ情報を読み取って時刻補正する
chrnoy 設定
Raspberry Pi OS ではデフォルトでsystemd-timesyncd
が起動しているので無効化する
sudo systemctl stop systemd-timesyncd
sudo systemctl disable systemd-timesyncd
chrony をインストールする
sudo apt install chrony
/etc/chrony/chrony.conf
を編集する
# ネットワーク上の時刻サーバとの同期させない場合はコメントアウト
# pool 2.debian.pool.ntp.org iburst
# shared memoryから読み取る設定を追加
refclock SHM 0 refid GPS precision 1e-1
chrony を再起動する
sudo systemctl restart chrony.service
chrony sources
コマンドで状況を確認できる
暫く放置して GPS の左側に*が表示されたら時刻同期完了している
210 Number of sources = 1
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* GPS 0 4 377 20 +18ms[ +32ms] +/- 100ms
参考
http://manpages.ubuntu.com/manpages/focal/man8/gpsd.8.html
https://manpages.ubuntu.com/manpages/precise/man5/gpsd_json.5.html
https://gpsd.gitlab.io/gpsd/gpsd-time-service-howto.html#_feeding_chrony_from_gpsd
https://gpsd.gitlab.io/gpsd/client-howto.html#_introduction