エントリー

2009年12月11日の記事は以下のとおりです。

GPS時計 - 完結編

  • 2009/12/11 14:31
  • カテゴリー:make:

 GPS時計ですが,その後も毎日のように検討を続けていました。

 GPSを使って時刻情報を得ていながら,1秒近くずれるというのはもはや言語道断といえて,何とかなるならしてみたいし,駄目な場合でも駄目な理由を理解してからあきらめたいと思ったからです。

 さて,前回,UARTのボーレートを38400ボーにするということと,使っていないセンテンスは送出させないようにしたこと,それと1秒に1回だったデータの送信周期を1秒に2回にしたことで対応を図ったが,あまり良い結果が得られなかったことを書きました。最大で1秒弱の遅れは解消されず,遅れる時間も長かったり短かったりとバラツキがみられます。

 そして,根本的にGPS本来の精度の時計を作るなら,GPSモジュールから1PPSの信号を得なければどうにもならない,ということもはっきりしました。ここまでが前回までのお話です。

 一般論としてですが,どうもGPSモジュールから出てくる時刻情報は,実際の時刻よりも少しだけ進んでいるのが普通のようです。少しだけ進んだ時刻をマイコンが取り込み,その後やってくる1PPSの信号で表示を更新することで,GPS本来の精度の時計が実現出来るというわけです。

 今回使っているGT-720Fというモジュールはこの1PPSの信号が出ていませんので,そもそもGPS時計を作るのに適していないモジュールを選んでいることになります。

 それに,これまでいじった結果として感じるのですが,少し進んだ時刻が出ているかどうかもあやしいです。

 ということで,1PPSがないと正確な時計を作る事が出来ないなら,GT-720Fから1PPSの信号を引っ張り出せないか,と考えました。

 幸いないことに,GT-720Fで使われているベースバンドチップは,Venus621LPというもので,1PPS信号の出力を持つLSIです。きっと,モジュールのどこかに1PPS信号が出ているに違いないと考えました。

 そこで背面のシールドケースをあけ,1PPS信号を探したのですが,結論からいうと見つかりませんでした。Venus621はBGAパッケージのLSIですから,端子から直接信号を取り出せません。基板上のどこかに出してくれていることを期待したのですが,スルーホールや抵抗などの部品をすべてあたっても,1PPSの出ている箇所を見つけることができませんでした。

 ならば,と衛星をつかまえたことを示すLEDはどうだろう,と考えました。GT-720Fは,衛星をつかまえていない時はLEDが点灯,つかまえると一定間隔で点滅します。

 このLEDの点滅が1PPSに同期しているなら,1PPS信号として使えるでしょう。いい所に気が付いたと思ったのですが,残念ながら全く同期しておらず,無関係でした。この段階で,GT-720Fから1PPS信号を得る事はあきらめ,外したシールドケースを元に戻しました。寂しいですね。


 ここに至って,1秒近く遅れる,という人間の感覚でもばれてしまうズレを,せめて意識しないで済む程度にする,という消極的な方法しかなくなってしまいました。

 そのためには,前回も書きましたが,何らかの理由でずれた時刻が送られて来ても,更新周期を早めて表示を頻繁に行うのが有利です。周期が短いほど,ずれた時刻の表示が正しい時刻になるまでの時間が短くなります。

 そこで,GT-720Fの設定ツールを使って,更新周期を設定可能な最大である1秒間に10回に設定しました。

 また,ボーレートを19200ボーに下げました。これは,38400ボーに上げたところで数msしか高速化されませんし,96バイトとバッファサイズを大きくしてまでこのボーレートで受け取るのは無駄で,64バイトのバッファで受信可能な19200ボーが最適という判断です。

 前回書きましたが,バッファを64バイトにすれば,リングバッファの実現が条件分岐ではなく,ANDによるマスクという処理だけで可能となります。これは処理速度にもコードサイズにも有利です。

 さらに,LCDへのデータ転送タイミングには十分すぎる時間を確保してあったのですが,これを大幅に切り詰めました。LCDへの転送クロック周期はスペックでは500nsから1000ns程度なのに,2msと2000倍も長くとってありました。動作は確実でしょうが,処理時間の大半はLCDへの転送にかかっていたことになります。

 試したところ,確かに見た目のズレはかなり軽減されています。しかし,そのズレ方は一定ではなく,1/10秒くらい遅れているときもあれば,ほとんどずれていない時もあります。

 この違いはなんだろう・・・はっきりしないと,時計として全く信用できません。

 この疑問は,GPSモジュールの吐き出すセンテンスを直接PCで見た時に氷解しました。

 実は,GPGGAにしてもGPRMCにしても,時刻情報として

133227.999

 というデータが,13時32分28秒の段階で送り出されていることがあるようなのです。

 27.999秒というのは,もうほとんど28秒なのですが,1/10秒以下を無視してしまうと,27秒と表示されてしまいます。

 もし,1秒間に1度の更新周期なら,次のデータは28.999秒となり,実際の時刻である29秒との表示のズレは,またしても1秒出てきてしまいます。こうして,GPSモジュールが何かのきっかけでxx.999ではなく,xx.000を出してくれるようになるまで,この1秒の遅れは続きます。

 もし1秒間に2回の更新を行う場合,送られて来るデータは

133227.999 133228.500 132228.999 133229.500

 という順番で出てくる事になり,ズレは0.5秒まで軽減されます。とはいえ,0.5秒のズレはばれてしまいますね。

 さらに,もしなんらかの理由で,

133228.000 133229.000

 という形で送られて来るようになると,.xxxを無視して表示すれば,ほとんどずれることなく表示が出来る事になります。

 さらに調べていくと,.xxxの部分は一定ではなくばらつくこと,バラツキの大きさによって遅れる時間が変わることも分かりました。

 これが,表示時刻が不規則に遅れる理由でした。

 少し実験をします。PCで.999というデータが出ていることを確認した上で,実機の表示を1/10秒まで表示させてみました。すると秒の桁が,

11.1 -> 11.2 -> 11.3 ... -> 11.8 -> 11.9 -> 11.9 -> 12.1 -> 12.2 ...

 という具合に変化します。1/10秒にゼロが表示されないことと,1秒の桁は11.9では変わらず12.1で変わるので,実際の時刻よりも1/10秒遅れているのがよくわかります。

 また,PCで.000で揃ったデータが出ている状態で同様に確認すると,ほとんど同時に表示も変化するようになります。これではっきりしました。

 そこで,暫定的に.999になったら秒のデータに1を加えるという簡易的な方法を試してみたところ,表示は概ねずれることなく更新されるようになったのですが,

18.8 -> 18.9 -> 19.0 -> 19.1 ... 19.8 -> 19.9 -> 1:.0 -> 20.1 ...

 という変則的な表示となり,見た目が非常に悪くなりました。キャラクタコードに1を加えただけの手抜きはダメで,やっぱり真面目にやるしかありません。

 そこで,さらに大幅な変更をします。日付はともかくとして,時刻だけはちゃんと処理する事にしましょう。日付は24時間に一度変化しますが,GPSからのデータの取得はは1秒おきですので,1秒だけ32日とか出てしまうことが考えられますが,まあいいでしょう。メモリも足りませんし。

 このため,これまで直接リングバッファの値を表示用の関数に渡していたものを,一度グローバル変数に取り込んで,文字列-から数値への変換,補正や表示を行う事にしました。

 あと,潜在的なバグとして日付の処理に問題があり,UTCで9日をJSTに変換するところでくだらないミスをしていたため,10日とならず,0:日と表示されていました。配列の宣言のミスで,暴走一歩手前だったことも白状します。お恥ずかしい。

 そうこうして出来た最終的なソースが,以下です。


続きを読む

ページ移動

  • 前のページ
  • 次のページ
  • ページ
  • 1

ユーティリティ

2009年12月

- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -

検索

エントリー検索フォーム
キーワード

ユーザー

新着画像

新着エントリー

過去ログ

Feed