こちらは送料込みUS$11.5で購入したU-BLOX 7020チップなGPSレシーバー。USB接続だけど内部的にはシリアルポートにGPSが接続されている扱い。左側のGPSユニット本体部分の裏面は3Mの超強力両面テープになっていて迂闊に貼ってしまうと位置を変えようにも剥がすのが大変。貼る場所は空が開けて見える外壁か窓ガラス。防水ではないので濡れないところ。GPSレシーバーから生えてるUSBケーブルは1メートル程度の長さしか無いのでPCからGPSレシーバー設置場所まで距離があるならどこのご家庭にも余っているUSBの延長ケーブルを使う。ただし、ブースター無しなら一応全部込みで5メートルまで。
まずは動作確認のためにWindows PCに接続してみる。
デバイスマネージャを開き「ポート(COMとLPT)」を見る。「USBシリアルデバイス(COM3)」として正常に認識されている。Windowsのセンサー&ロケーションAPI用のドライバを使っていれば「ポート(COMとLPT)」ではなく「センサー」の方に表示される筈。
仮想シリアルポートの通信内容を見てもドカドカ表示されるだけで何がなんだかなのでublocksのu-center for Windowsというアプリを使用して状態を見る。
左上の方のコネクタアイコン(画像の赤い枠で囲われた部分)を押してGPSレシーバーのデバイスを選択して接続状態にする。今回のレシーバーはCOM3 としてWindowsに認識されているのでそれを選択。
初めてu-centerを使うなら画面左半分が空白なのでビューから表示したい画面を選択。上の画像では見えるべき衛星の位置が表示されている。実際に衛星を掴んでいる受信レベルの状況は画面中央右の少し右下の縦棒グラフの部分で確認できる。上の画像は横800pxに縮めているので窮屈で文字が重なりあってよくわからないがウインドウサイズを大きくすれば分かりやすくなる。
フルHDの画面だとこんな感じ。この画面では左半分にGPSユニットからの受信メッセージが流れている。
とりあえず正常に作動していることが確認できたのでWindowsでの利用は終わり。
FreeBSDのPCにGPSユニットを接続する。どのようなデバイス名で認識されるかわからないので接続前と接続後に ls /dev で確認。一応、シリアルポートはttyまたはcuaで始まる名前の筈。
foobar@example:~ % ls /dev acpi ctty hpet0 pass2 ttyU0.lock ttyve ad4 cuaU0 io pass3 ttyv0 ttyvf ad4p1 cuaU0.init kbd0 pass4 ttyv1 ufssuspend ad4p2 cuaU0.lock kbd1 pci ttyv2 ugen0.1 ada0 da0 kbdmux0 pf ttyv3 ugen0.2 ada0p1 da1 klog pts ttyv4 ugen0.3 ada0p2 da2 kmem random ttyv5 ugen0.4 apm da3 log reroot ttyv6 ugen0.5 apmctl devctl mdctl sndstat ttyv7 ugen1.1 atkbd0 devctl2 mem stderr ttyv8 ugen1.2 audit devstat midistat stdin ttyv9 urandom bpf fd nfslock stdout ttyva usb bpf0 fido null sysmouse ttyvb usbctl console geom.ctl pass0 ttyU0 ttyvc xpt0 consolectl gptid pass1 ttyU0.init ttyvd zero foobar@example:~ % cu -l /dev/cuaU0 -s 9600 Connected $GPRMC,054138.00,A,nnnn.nnnnn,N,nnnnn.nnnnn,E,0.015,,110616,,,A*7C $GPVTG,,T,,M,0.015,N,0.027,K,A*22 $GPGGA,054138.00,nnnn.nnnnn,N,nnnnn.nnnnn,E,1,09,0.90,114.7,M,34.9,M,,*58 $GPGSA,A,3,08,27,16,07,11,26,01,30,10,,,,1.82,0.90,1.58*06 $GPGSV,4,1,13,01,27,200,35,04,03,115,,07,42,300,27,08,67,324,29*7C $GPGSV,4,2,13,09,04,246,,10,15,082,47,11,44,221,30,16,45,095,40*70 $GPGSV,4,3,13,18,05,050,09,23,00,220,,26,19,113,27,27,52,037,48*7D $GPGSV,4,4,13,30,19,317,40*41 $GPGLL,nnnn.nnnnn,N,nnnnn.nnnnn,E,054138.00,A,A*60 $GPTXT,01,01,02,u-blox ag - www.u-blox.com*50 $GPTXT,01,01,02,HW UBX-G70xx 00070000 *77 $GPTXT,01,01,02,ROM CORE 1.00 (59842) Jun 27 2012 17:43:52*59 $GPTXT,01,01,02,PROTVER 14.00*1E $GPTXT,01,01,02,ANTSUPERV=AC SD PDoS SR*20 $GPTXT,01,01,02,ANTSTATUS=OK*3B
上の例ではデバイス名がcuaU0 (ttyU0)として認識されていることがわかる。
購入したGPSユニットは通信速度が9600bpsのみ対応なので cu -l /dev/cuaU0 -s 9600を実行するとGPSユニットからのメッセージが表示される。終了させたいなら ~. を入力するが、コンソールからではなくSSHでFreeBSDにリモート接続して操作している場合はそのセッションが切れる場合があるので[~]の後に[Ctrl]+[D]
これでFreeBSDでも正常に認識されて使えることが確認できた。
GPSモジュールが複数の通信速度に対応している場合は、GPSモジュール側とPC側の両方で利用可能な範囲でなるべく速い速度に合わせる。
uBlox系のチップを搭載したGPSモジュールでシリアルポートcuaU0で57600 bpsにするなら echo "B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 C2 01 00 07 00 03 00 00 00 00 00 C0 7E" | xxd -r -p > /dev/cuaU0
GPSモジュールが設定を記憶するタイプならとりあえずこれで良いが、設定を記憶する能力がないモジュールもあるのでFreeBSDのシステム起動時にコマンドをGPSモジュールに送信するようにする。
1 2 3 4 5 6 7 8 9 10 | #!/bin/sh
#9600 bps : '\xB5\x62\x06\x09\x0D\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x17\x2F\xAE'
#19200 bps : '\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\x4B\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\x48\x57'
#38400 bps : '\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\x96\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\x93\x90'
#57600 bps : '\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\xE1\x00\x00\x07\x00\x03\x00\x00\x00\x00\x00\xDE\xC9'
#115200 bps : '\xB5\x62\x06\x00\x14\x00\x01\x00\x00\x00\xD0\x08\x00\x00\x00\xC2\x01\x00\x07\x00\x03\x00\x00\x00\x00\x00\xC0\x7E'
echo 'B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 C2 01 00 07 00 03 00 00 00 00 00 C0 7E' | xxd -r -p > /dev/cuaU0
|
なお、ntpd実行中にはntpdがシリアルポートを専有していて制御させて貰えないので9行目の前後でntpdを停める・開始するという処理が要る筈。
今回購入したGPSレシーバーはNMEAだけで1PPS信号は取れないので精度は低いけど逆に使うのはとても簡単。
ntpdでNMEA GPS Clockを利用するにはデバイス名がgps0などである必要があるので
/etc/devfs.confに下の1行を追記。
link cuaU0 gps0
#または
link ttyU0 gps0
cua*とtty*のどちらが良いかというのは今現在は不明。かなり以前は主に受信用ならtty、発信アリならcuaって住み分けがあったみたいに記憶しているが、実際はどちらも同じに使える。GPSモジュールを繋ぐという使用方法なら受信onlyなのでttyかなとも思うけど・・
変更したらdevfsを再起動。
# /etc/rc.d/devfs restart
/etc/ntp.confに下の2行を追記。
1 2 | server 127.127.20.0 mode 17 minpoll 4 prefer
fudge 127.127.20.0 refid GPS flag1 0
|
127.127.20.0はIPアドレスではない。
127.127.の後の20はリファレンス クロック ドライバのタイプ。ドライバのタイプが何を指すかは本来はこちらを見るのだと思うけどこちらの方が各タイプで何を設定して良いかがわかりやすいかも。今回は Generic NMEA GPS Receiverを使うので127.127.20.x。
127.127.20.xのmodeはNMEAセンテンスと通信速度の指定(合算)。
速度
4800bps: 0
9600bps: 16
19200bps: 32
38400bps: 48
57600bps: 64
115200bps: 80
NMEAセンテンス
$GPRMC: 1
$GPGGA: 2
$GPGLL: 4
$GPZDA/$GPZDG: 8
9600bpsで$GPRMCなら16 + 1 = 17となる。mode 17という指定。
115200bpsで$GPRMCなら80 + 1 = 81となる。mode 81という指定。
ntpdを再起動する。
# service ntpd restart
動作確認 (ntpdの起動・再起動後暫くしてから)
# ntpq -c clockvar
associd=0 status=0000 no events, clk_unspec,
device="NMEA GPS Clock",
timecode="$GPRMC,134444.00,A,nnnn.nnnnn,N,nnnnn.nnnnn,E,0.010,,251116,,,A*70",
poll=92, noreply=0, badformat=0, baddata=0, stratum=0, refid=GPS,
flags=0
NMEA GPS Clockで取得していること。timecodeでRMCセンテンスを使っていることなどが解る。badformatやbaddataが0なので、つまり異常なくGPSで時刻が取れている筈。
# ntpq -p -ccv -crv -ckern -csysinfo
remote refid st t when poll reach delay offset jitter
==============================================================================
+ntp1.jst.mfeed. 133.243.236.17 2 u 39 64 177 18.088 69.996 2.953
+ntp2.jst.mfeed. 133.243.236.17 2 u 35 64 177 14.488 70.424 4.932
*GPS_NMEA(0) .GPS. 0 l 11 16 377 0.000 -6.629 9.759
associd=0 status=0000 no events, clk_unspec,
device="NMEA GPS Clock",
timecode="$GPRMC,141030.00,A,nnnn.nnnnn,N,nnnnn.nnnnn,E,0.012,,110616,,,A*73",
poll=27, noreply=0, badformat=0, baddata=0, stratum=0, refid=GPS,
flags=0
associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
version="ntpd 4.2.8p8-a (1)", processor="amd64",
system="FreeBSD/10.3-RELEASE-p4", leap=00, stratum=1, precision=-21,
rootdelay=0.000, rootdisp=17.219, refid=GPS,
reftime=db069a4b.c21f8f7c Sat, Jun 11 2016 23:10:19.758,
clock=db069a56.e84ebeaf Sat, Jun 11 2016 23:10:30.907, peer=7628, tc=4,
mintc=3, offset=-6.628976, frequency=19.274, sys_jitter=9.759054,
clk_jitter=6.493, clk_wander=0.055
associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
pll offset: -6.34964
pll frequency: 19.2738
maximum error: 0.022554
estimated error: 0.006493
kernel status: pll nano
pll time constant: 4
precision: 1e-06
frequency tolerance: 495.911
pps frequency: 0
pps stability: 0
pps jitter: 0
calibration interval 0
calibration cycles: 0
jitter exceeded: 0
stability exceeded: 0
calibration errors: 0
associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
system peer: GPS_NMEA(0)
system peer mode: client
leap indicator: 00
stratum: 1
log2 precision: -21
root delay: 0.000
root dispersion: 17.219
reference ID: GPS
reference time: db069a4b.c21f8f7c Sat, Jun 11 2016 23:10:19.758
system jitter: 9.759054
clock jitter: 6.493
clock wander: 0.055
broadcast delay: -50.000
symm. auth. delay: 0.000
結果の最初の方のmfeedはGPS以外に時刻を取っている公開NTPサーバ
# ntptime
ntp_gettime() returns code 0 (OK)
time db069b74.9f79207c Sat, Jun 11 2016 23:15:16.622, (.622942655),
maximum error 8699 us, estimated error 2551 us, TAI offset 0
ntp_adjtime() returns code 0 (OK)
modes 0x0 (),
offset -1336.472 us, frequency 19.099 ppm, interval 1 s,
maximum error 8699 us, estimated error 2551 us,
status 0x2001 (PLL,NANO),
time constant 4, precision 0.001 us, tolerance 496 ppm,
ちなみに精度はこんな程度。
1PPS無しはやはり酷いね。オフセットがμ秒ではなく数ミリ秒のレベル。それでも多くは±5ミリ秒に収まるみたい。
私のNTPサーバは今Stratum幾つなの?
基本的には同期している時刻ソースのStratumの値 + 1
ntpq -c rl とか ntpq -c rv で出てくる中にStratum ○という値があるのがそれ。
似たようなオプションでntpq -c cl とか ntpq -c cv は同期している時刻ソースの値なので間違えないようにする。GPSならStratum 0になってるので時刻ソースだとわかる筈だけど、外部NTPサーバに同期していると例えばStratum 1を参照しているのを見て自分のNTPサーバがStratum 1だと勘違いすることがある。
NTPサーバのStratumの値は同期している時刻ソースによって変動するので例えばGPSに同期していればStratum 1だけどGPSから時刻が取れなくなってStratum 2のNTPサーバに同期するとStratum 3になる。
ということで?、わずか千円ちょっとでなんちゃってStratum 1なNTPサーバの完成。
(精度が普通にStratum 1に求められるレベルより3桁ほどゆるいので「なんちゃって」。しかし、精度は低くてもGPSから取ってるので一応Stratum 1ではある。)
そして、精度が低いといってもpool.ntp.orgで下手なNTPサーバに当たるとかネットワーク的に遠いNTPサーバから時刻を取るよりは遥かにマシ。時刻精度を求められないウェブサーバとかメールサーバ用程度ならこんなもんでも十分すぎるほど。
でも、いつか1PPS取れるものを何か買う。
関連記事:- NanoPi NEOとGPSモジュールでNTPサーバ PPS検証編
- NanoPi NEOとGPSモジュールでNTPサーバ PPS解決編
- NanoPi NEOの時刻のズレを直したい
- NanoPi NEOとGPSモジュールでNTPサーバ 高精度PPS編
- NanoPi NEOとGPSモジュールでNTPサーバ 簡易PPS編
- NanoPi NEOにGPSモジュールを繋いでNTPサーバ
- GPSモジュール
- GPSレシーバーでStratum 1なNTPサーバ ← いまここ