新しい中華GPSモジュールとChronyで作るNTPサーバ (後編)

前編中編で<怪しい中華GPSモジュールとChronyでNTPサーバが動くようになった。
しかし、シリアルポートの通信状況を眺めるとちょっと寒い状態。

  • MNEAセンテンスの流れる速度が遅い。初期値が9600bpsなので当然。
  • 無駄なNMEAセンテンスが大量に出てくる。
  • 出力頻度が異常。

基本的に安い汎用GPSモジュールはこんなの。1PPS無しならこれをそのままNTPサーバ用で使うのはあまり良いとは思わない。1PPS有りでも良くはないけどNMEA側の問題なので1PPSメインなら精度にはおそらく影響しないけど対応はするべきかな。

安く市販されているGPSモジュールの中でもu-bloxまたはその互換チップが載っている場合はUBXプロトコルのバイナリコマンドで制御できる。(u-bloxまたは互換のどのチップで使えるかは判らないけど対応しているのは結構多い)
この記事ではそのUBXコマンドでの制御について書く。その他のチップであればそれぞれ別の制御方法があると思うのでググって。

シリアル通信速度の変更

安いGPSモジュールは多くがシリアル速度の初期値が(4800bpsや)9600bps程度になっている。これでNMEAの複数種類のセンテンスを毎秒1回程度の頻度で流すようになっていたり。GPSアンテナのロケーションが良ければ多くの衛星を捉えられるはずで、この通信速度では無理が過ぎる。
そこで、GPSモジュールと接続するPCやシングルボードコンピュータの両方が対応するシリアル速度の範囲でなるべく速い速度を使うようにしたい。
GPSモジュール側の速度変更にはGPSモジュール(チップ)にコマンドを送信しなければならない。
多くは9600bps(4800bps)が初期値で19200bps, 38400bps, 57600bps, 115200bps程度まで対応。19200bpsまでしか対応しないとか逆に230400bps以上にも対応なんてのもあるけど、速度変更不可な製品もあるので注意。

UBXコマンド

9600bpsに変更
\xB5\x62\x06\x09\x0D\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x17\x2F\xAE

19200bpsに変更
\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

38400bpsに変更
\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

57600bpsに変更
\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

115200bpsに変更
\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コマンドで送りやすいように \x00のような書き方になってるけどバイナリ(Hex)で00ということね。
Linuxの多くに標準で入っているバックスラッシュでエスケープの-eオプション対応のechoコマンドが使えるなら以下のように送信。

$ sudo echo -e "UBXコマンド" > /dev/シリアルデバイス名
つまり、シリアルポートttyS1に繋がっているGPSモジュールの通信速度(出力速度)を9600bpsに設定するなら
$ sudo echo -e "\xB5\x62\x06\x09\x0D\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x17\x2F\xAE" > /dev/ttyS1

FreeBSDの場合はtcshの内部コマンドとしてのechoと/bin/shが使う/bin/echoの2種類がある。 /bin/echoは知らないが、linuxのechoコマンドのようにバックスラッシュでエスケープすることができるのでなければ個人的にはxxdを使う。

9600bpsに変更
B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 17 2F AE

19200bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 4B 00 00 07 00 03 00 00 00 00 00 48 57

38400bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 96 00 00 07 00 03 00 00 00 00 00 93 90

57600bpsに変更
B5 62 06 00 14 00 01 00 00 00 D0 08 00 00 00 E1 00 00 07 00 03 00 00 00 00 00 DE C9

115200bpsに変更
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

$ echo "UBXコマンド" | xxd -r -p > /dev/シリアルデバイス名
つまり、シリアルポートcuaU0に繋がっているGPSモジュールの通信速度(出力速度)を9600bpsに設定するなら
$ echo "B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 17 2F AE" | xxd -r -p > /dev/cuaU0

NMEAセンテンスの出力停止・再開

NEMA DTM (Datum Reference)
停止: B5 62 06 01 03 00 F0 0A 00 04 23
再開: B5 62 06 01 03 00 F0 0A 01 05 24

NEMA GBS (GPS Satellite Fault Detection)
停止: B5 62 06 01 03 00 F0 09 00 03 21
再開: B5 62 06 01 03 00 F0 09 01 04 22

NEMA GGA (Global Positioning System Fix Data)
停止: B5 62 06 01 03 00 F0 00 00 FA 0F
再開: B5 62 06 01 03 00 F0 00 01 FB 10

NEMA GLL (Geographic Position - Latitude/Longitude)
停止: B5 62 06 01 03 00 F0 01 00 FB 11
再開: B5 62 06 01 03 00 F0 01 01 FC 12

NEMA GRS (GPS Range Residuals)
停止: B5 62 06 01 03 00 F0 06 00 00 1B
再開: B5 62 06 01 03 00 F0 06 01 01 1C

NEMA GSA (GPS DOP and active satellites)
停止: B5 62 06 01 03 00 F0 02 00 FC 13
再開: B5 62 06 01 03 00 F0 02 01 FD 14

NEMA GST (GPS Pseudorange Noise Statistics)
停止: B5 62 06 01 03 00 F0 07 00 01 1D
再開: B5 62 06 01 03 00 F0 07 01 02 1E

NEMA GSV (Satellites in view)
停止: B5 62 06 01 03 00 F0 03 00 FD 15
再開: B5 62 06 01 03 00 F0 03 01 FE 16

NEMA RMC (Recommended Minimum Navigation Information)
停止: B5 62 06 01 03 00 F0 04 00 FE 17
再開: B5 62 06 01 03 00 F0 04 01 FF 18

NEMA VTG (Track made good and Ground speed)
停止: B5 62 06 01 03 00 F0 05 00 FF 19
再開: B5 62 06 01 03 00 F0 05 01 00 1A

NEMA ZDA (Time & Date - UTC, day, month, year and local time zone)
停止: B5 62 06 01 03 00 F0 08 00 02 1F
再開: B5 62 06 01 03 00 F0 08 01 03 20


NEMA GNS
停止: B5 62 06 01 08 00 F0 0D 00 00 00 00 00 00 0C 7E
再開: B5 62 06 01 08 00 F0 0D 01 01 01 01 01 00 11 92

NEMA THS (True Heading and Status)
停止: B5 62 06 01 08 00 F0 0E 00 00 00 00 00 00 0D 85
再開: B5 62 06 01 08 00 F0 0E 01 01 01 01 01 00 12 99

NEMA VLW (Distance Traveled through Water)
停止: B5 62 06 01 08 00 F0 0F 00 00 00 00 00 00 0E 8C
再開: B5 62 06 01 08 00 F0 0F 01 01 01 01 01 00 13 A0

Linuxの多くに標準で入っているバックスラッシュでエスケープの-eオプション対応のechoコマンドが使えるなら以下のように送信。
$ sudo echo -e "UBXコマンド" > /dev/シリアルデバイス名
つまり、シリアルポートttyS1に繋がっているGPSモジュールのNMEA GSVセンテンスの出力を停止するなら
$ sudo echo -e "\xB5\x62\x06\x01\x03\x00\xF0\x03\x00\xFD\x15" > /dev/ttyS1
echo -e で送信する場合は一覧のコマンドの空白文字部分を\xに置き換える。
FreeBSD等で、バックスラッシュのエスケープが不可なechoを使うなら
% echo "UBXコマンド" | xxd -r -p > /dev/シリアルデバイス名

FreeBSDで、シリアルポートcuaU0に繋がっているGPSモジュールのNMEA GSVセンテンスの出力を停止するなら
% echo "B5 62 06 01 08 00 F0 03 00 00 00 00 00 00 02 38"  | xxd -r -p > /dev/cuaU0

実際にはなんのNMEAセンテンスが流れているか調べてから不要な種類の出力を停止する。
NTPサーバをntpdで動かしてNMEAをntpdで直接受け取って使用する場合、つまりリファレンスクロックドライバ127.127.20.xを使うならmodeで使用するセンテンスの種類を選択するので、RMC, GGA, GLL, ZDA/ZDGから選んで他は捨てる。普通はRMCを使うので他はすべて要らない。
gpsdを使う場合でもRMC(とVTG)以外は要らないんじゃないかしら。

シリアルポートを覗いて、流れているのがこんな感じとする。(u-bloxのUBX-G7020の例)
$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
$GPTXT,01,01,02,LLC FFFFFFFF-FFFFFFFD-FFFFFFFF-FFFFFFFF-FFFFFFFD*2E
$GPRMC,124330.00,A,3568.51751,N,13975.28000,E,0.019,,070720,,,A*71
$GPGGA,124330.00,3568.51751,N,13975.28000,E,1,07,0.84,113.9,M,34.9,M,,*58
$GPGSV,3,1,11,05,28,123,31,10,02,310,22,13,41,049,50,15,66,011,38*77
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,20*74
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124330.00,A,A*62
$GPRMC,124331.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*77
$GPGGA,124331.00,3568.51751,N,13975.28000,E,1,07,0.84,114.0,M,34.9,M,,*5A
$GPGSV,3,1,11,05,28,123,30,10,02,310,21,13,41,049,50,15,66,011,37*7A
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,17*70
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124331.00,A,A*6E
$GPRMC,124332.00,A,3568.51751,N,13975.28000,E,0.020,,070720,,,A*71
$GPGGA,124332.00,3568.51751,N,13975.28000,E,1,07,0.84,114.2,M,34.9,M,,*5E
$GPGSV,3,1,11,05,28,123,30,10,02,310,21,13,41,049,50,15,66,011,37*7A
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,42,24,57,207,16*71
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124332.00,A,A*68
$GPRMC,124333.00,A,3568.51751,N,13975.28000,E,0.032,,070720,,,A*74
$GPGGA,124333.00,3568.51751,N,13975.28000,E,1,07,0.89,114.4,M,34.9,M,,*53
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,14*72
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124333.00,A,A*6E
$GPRMC,124334.00,A,3568.51751,N,13975.28000,E,0.044,,070720,,,A*74
$GPGGA,124334.00,3568.51751,N,13975.28000,E,1,07,0.89,114.6,M,34.9,M,,*50
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,13*75
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124334.00,A,A*6F
$GPRMC,124335.00,A,3568.51751,N,13975.28000,E,0.025,,070720,,,A*76
$GPGGA,124335.00,3568.51751,N,13975.28000,E,1,07,0.84,114.7,M,34.9,M,,*59
$GPGSV,3,1,11,05,28,123,30,10,02,310,20,13,41,049,49,15,66,011,38*7C
$GPGSV,3,2,11,18,48,270,,20,32,313,23,21,18,313,43,24,57,207,13*74
$GPGSV,3,3,11,28,14,059,36,42,48,165,,50,48,196,*40
$GPGLL,3568.51751,N,13975.28000,E,124335.00,A,A*6A
$GPRMC,124336.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*7F
$GPGGA,124336.00,3568.51751,N,13975.28000,E,1,07,0.84,114.8,M,34.9,M,,*5C
$GPGSV,3,1,11,05,28,123,30,10,02,310,19,13,41,049,49,15,66,011,38*76
$GPGSV,3,2,11,18,48,270,,20,32,313,22,21,18,313,43,24,57,207,13*75
RMC以外を停めるとこんな感じ。
$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
$GPTXT,01,01,02,LLC FFFFFFFF-FFFFFFFD-FFFFFFFF-FFFFFFFF-FFFFFFFD*2E
$GPRMC,124709.00,A,3568.51751,N,13975.28000,E,0.022,,070720,,,A*7E
$GPRMC,124710.00,A,3568.51751,N,13975.28000,E,0.003,,070720,,,A*76
$GPRMC,124711.00,A,3568.51751,N,13975.28000,E,0.012,,070720,,,A*7A
$GPRMC,124712.00,A,3568.51751,N,13975.28000,E,0.023,,070720,,,A*7F
$GPRMC,124713.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*75
$GPRMC,124714.00,A,3568.51751,N,13975.28000,E,0.018,,070720,,,A*7C
$GPRMC,124715.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*78
$GPRMC,124716.00,A,3568.51751,N,13975.28000,E,0.019,,070720,,,A*77
$GPRMC,124717.00,A,3568.51751,N,13975.28000,E,0.012,,070720,,,A*7E
$GPRMC,124718.00,A,3568.51751,N,13975.28000,E,0.021,,070720,,,A*77
$GPRMC,124719.00,A,3568.51751,N,13975.28000,E,0.003,,070720,,,A*77
$GPRMC,124720.00,A,3568.51751,N,13975.28000,E,0.008,,070720,,,A*76
$GPRMC,124721.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*7B
$GPRMC,124722.00,A,3568.51751,N,13975.28000,E,0.023,,070720,,,A*7B
$GPRMC,124723.00,A,3568.51751,N,13975.28000,E,0.016,,070720,,,A*7C
$GPRMC,124724.00,A,3568.51751,N,13975.28000,E,0.063,,070720,,,A*7D
$GPRMC,124725.00,A,3568.51751,N,13975.28000,E,0.013,,070720,,,A*79
$GPRMC,124726.00,A,3568.51751,N,13975.28000,E,0.028,,070720,,,A*77
$GPRMC,124727.00,A,3568.51751,N,13975.28000,E,0.030,,070720,,,A*70
$GPRMC,124728.00,A,3568.51751,N,13975.28000,E,0.035,,070720,,,A*7A
$GPRMC,124729.00,A,3568.51751,N,13975.28000,E,0.015,,070720,,,A*70
こんな感じでRMC以外の余計なセンテンスの出力が抑制される。(座標は弄ってる)

出力頻度の変更

シリアル速度を十分に早めて出力するセンテンスの種類を絞ったなら出力頻度を変える必要はないかもしれないが、シリアル速度を変更できない場合には出力頻度を3秒に1回程度〜10秒に1回程度にに落とした方が良いかもしれない。

1Hz (1秒に1回): B5 62 06 08 06 00 E8 03 01 00 01 00 01 39
5Hz (1秒に5回): B5 62 06 08 06 00 C8 00 01 00 01 00 DE 6A B5 62 06 08 00 00 0E 30
10Hz (1秒に10回): B5 62 06 08 06 00 64 00 01 00 01 00 7A 12 B5 62 06 08 00 00 0E 30
0.33Hz (3秒に1回): B5 62 06 08 06 00 B8 0B 01 00 01 00 D9 41 B5 62 06 08 00 00 0E 30
0.2Hz (5秒に1回): B5 62 06 08 06 00 88 13 01 00 01 00 B1 49 B5 62 06 08 00 00 0E 30
0.1Hz (10秒に1回): B5 62 06 08 06 00 10 27 01 00 01 00 4D DD B5 62 06 08 00 00 0E 30
0.05Hz (20秒に1回): B5 62 06 08 06 00 20 4E 01 00 01 00 84 00 B5 62 06 08 00 00 0E 30

コマンドの送り方は前述。

GPSモジュールの再起動・初期化

任意のタイミングでGPSモジュールを再起動させたいときに、場合によってはコールドスタートまたはウォームスタートさせたいということもある筈。

コールドスタート: B5 62 06 04 04 00 FF B9 02 00 C8 8F
ウォームスタート: B5 62 06 04 04 00 01 00 02 00 11 6C
工場出荷状態(初期化): B5 62 06 09 0D 00 FF FF 00 00 00 00 00 00 FF FF 00 00 07 1F 9E

この記事のUBXコマンドはu-bloxまたはその互換チップでないと機能しません。また、u-bloxまたはその互換チップであるからといって全てで機能するとは限りませんし一部が機能したりしなかったりするかもしれません。送信しようとしているチップに合ったコマンドをメーカーの提供している資料等で調べることをオススメします。

一応、中華なATGM332Dというラベルの貼られたu-blox互換チップではこのページのUBXコマンドは機能しています。

次回はNTPサーバの時刻の調整をやるかやらないか。

関連記事: