Raspberry Pi Zero WでGPSビーコンを自作

TOYOTAのコネクテッドカーには「カーファインダー」という機能があります。車両の位置情報を常時サーバーに送信して、ユーザはスマホアプリから今車両がどこにあるかを確認できるというものです。

地図&GPS好きな私はこれにはかなり期待していました。例えば同居人と待ち合わせをする時に迎えに接近するクルマの位置がリアルタイムにわかれば迎えられる側もいい場所に移動したりできます。例えばどちらの方向から接近してくるかで道路のどっち側で待つべきか判断できます。雨が降っている時に無駄に早くから路肩で待たず、どこかで雨宿りをして待つこともできます。

従来、スマホアプリで「友達を探す(現「探す」)」だったりFacebook MessengerやGoogle Mapsなどあらゆる位置情報共有機能を試してきましたが、どれも更新頻度が低すぎてそういうリアルタイムなモニタリングには不足でした。調子がいい時悪い時のムラがあったり。特に金属の箱の中である車内ではスマホのGPSが充分な精度を出せないということも関係してるのでしょう。試した中ではGlympseががまずまずの更新頻度と精度ですがマイナーな上に共有開始までの手数がやや多く、めんどくさがりの同居人にはなかなか使ってもらえず。

そこでもう車両の搭載機能ならば、運転する側はなんの操作もいらずに少なくとも車両->迎えを待つ側の共有はできるだろう!と期待したわけです。ところがいざ納車されていてガッカリ。リアルタイムで動く様子が見えないどころか、目的地についてもまだ出発地にいることになっているとか、何十分というレベルで更新が途絶えることもしばし。また地図表示までの操作の手数も多い。トヨタのアプリは最初にTOYOTA/LEXUS IDというのでログインして使うのですが、さらにこのカーファインダーを使う際にはT-CONNECT IDというのでログインが必要です。しかも後者はセッションが数分しか保持されないので、基本毎回パスコードを入れなければなりません(IDは記憶してくれる)。そしてやっと表示が出たと思ったらスクロールもズームもできない地図画面だし、自分(アプリを起動してる人)の位置も出ません。「マップで開く」的なボタンで標準地図アプリに遷移してようやく自分の位置とあわせてスクロール/ズーム可能な地図閲覧ができる、という体たらくです。TOYOTAのコネクテッド周りのアプリは総じて残念なところが多すぎます。しかも事前に試せないので百万単位の買い物をしたあとで判明してもどうしようもありません。せっかく力を入れるのならもう少し本気で取り組んで欲しいものです。

■なら自分で作っちゃえと

代替品として最近何社かから発売されている子どもの見守り端末なんかも検討しましたが数百円とはいえ月額費用がかかる上、バッテリー優先で更新頻度が分単位なので上記のような用途には不足します。

そこで目に付いたのが以前別件で使用したRaspberry Pi Zero Wです。これにGPSモジュールを取り付ければ緯度経度時刻は取得できますし、車内なら電源もUSB 5Vならいくらでもとれるのでバッテリーの心配も不要。しかも我が車にはWi-Fiまでとんでますから、LTEモジュールも追加の維持費も不要。取得した緯度経度情報をWebサーバーに投げるスクリプトさえ作ってしまえば、あとはWebサーバー側でそれを保存して表示するこれまた簡単なページを作れば良いということになります。

ということで作って見たハードウェアがこちら。

SDカードはサイズ比較用です。いい感じのケースが見つかりました。フットプリントはZeroサイズで上に少し高くなっている造り。右に出ているのはGPSアンテナ。電波が遮断されやすい車内で使うので外付けアンテナにしました。奥に見えるのがmicroUSB端子の電源線です。このサイズなら車内のどこにでも設置できます。アンテナ側(SDカードスロット側)は少し大きく口があいているので、少しホコリなどが入りやすいかも知れません。テープかなにかで目張りしておこうかな。


こちらが中身。使っているGPSモジュールは秋月のみちびき/1PPS対応のものです。

Raspberry Pi Zero Wはヘッダーピンが半田付けされてないWをもともともっていたので、それにハンマーヘッダーソケットを追加。GPSモジュールにヘッダーピンを半田付けすれば直接刺さるんじゃないかという思惑があったんですが、実際には接続する5ピンのうちシリアルのTxとRxが反転した並びになっていたので断念。結局直接半田付けしました。今買える(買いやすい)Zero Wは正確にはZero WHというヘッダーピン(オス)がついているものなので、また別の固定方法が必要かもです。ちなみにGPSモジュールの裏にはバックアップ用のコイン電池がついているのであまりZeroと密着はできないです。

こちらの六角ネジで高さをあわせてGPSモジュールを固定しまいた。自作PCケースにマザーボードを固定するのによく使うアレですね。アレの少し細いヤツ(M2)が長さも色々でセットになっており、複数継ぎ足して望みに近い長さにできるというものです。

ちなみにケースのネジ穴はあいてなかったので、別途ねじ切りタップも買って自分で開けました。ちょい斜めになってしまったのが残念…

というわけでハード的にはZero W、GPS、SDカード、ケースに細々とした配線部材で6~7千円くらいでしょうか。部材はかなりたっぷり買えてしまったので、仮に追加で作ろうとすれば5千円くらいで作れるのかも知れません。

■ソフト面の工夫

ソフト面はOSとしてはRaspberry Piの基本OSであるRaspbianの最新リリースBusterを使用。GUI環境などはいらないのでLite版です。GPSモジュールはシリアル接続で、1PPS信号という精度を上げるための信号はGPIO経由で入ってきますが、いずれにせよgpsdというデーモンを動かしておけばいい感じに管理してくれます。他のツールからはソケット通信でアクセスする感じ(なので複数のGPSクライアントからの同時接続も可能)。

Pythonでgpsdから取得してWebに投げるサンプルが落ちていたので、それを改良して使っています。当初、一旦ローカルにSQLiteなどで保存して送信なども考えてたんですが、そもそもリアルタイム測位データに用があるのと、システムをROM化することで電源管理を簡略化できると気付いたのでローカルには基本的にデータを保存しない仕様にしました。ROM化というのは起動時にSDカードからソフトを読み込んだ後は、その後のディスク書き換えをRAMディスクに行うように仕向けるというもので、SDカードをメインストレージにして劣化が懸念されるRaspberry Pi界隈ではよく使われる手法のようです。RAMディスク上のデータは電源をブチ切りした場合は当然失われます。図書館やネットカフェのPCのように、次回電源投入時はすべてが元通りに起動するというわけです。これも簡単な切り替えスクリプトで実現できました。諸々多くの先人の資産のお陰で、かなり短い期間で目論み通りの仕組みを実現することができました。この場を借りてお礼申し上げます。

逆にサーバー側のPHP+MySQLな部分はほぼゼロから自作中。Google Maps API v3を使って地図表示をしています。個人で使う分にはまず課金対象量には達しないだろうと。こちらはまだ調整中ですが、追々見られるものができたらスクショくらいは晒したいなと。

2023.04.26追記

クルマを乗り換えたので移設作業をしました。当初、時刻のみで緯度経度がn/aのままで測位ができずに悩みましたが、なんのことはない、GPS基板からアンテナのコネクタが外れてましたw。移設の際に引っ張られてしまったのかも知れません。気休めにホットボンドで固定をしておきました。

初号機は設置して3年半ほど経っているようですが、普段はROM化してあるせいかSDカードも普通に読み書きできて劣化の兆候はなさそうです。

ただ衛星位置情報(almanac)を保持するコイン電池の出力が2.7Vまで落ちていたので、新品に交換しておきました。ググるとクルマのスマートキーなどだと2.8Vを切ったら交換、ということだったので充分危険域。新品は3.3Vでした。これでまたしばらく大丈夫でしょう。実害を感じなかったので気にしてませんでしたが、弐号機の方もそろそろ替え時きてるかも知れません…