目的地を追加したい
「GPSを使って目的地の方向と直線距離を表示する」ガジェットを作り、指差しユニットも追加して楽しく使っているのですが、日ごろよく使う目的地6か所のcoordinate(緯度、経度)はArduinoプログラムにハードコードされていて、車の中で新たな目的地の設定をすることができない。一度だけ行くような場所をコードにわざわざ書き込むのも無駄な気がする。一時的に、かつ簡単に目的地登録ができたらなあとずっと考えていました。ガジェットのコントローラー部分は、Adafruitのmetro mini、いわゆるArduino UNOと同等のものなので、住所を検索して緯度経度を設定する、などという高度なことはできません。あらかじめ調べておいた緯度経度を外から流し込む、ならできそうです。どうやるか?実際の操作はどんな感じ?自分がそれを使っている様子を何度も想像空想妄想して、以下の調子に固まりました。
- 行きたい場所のcoordinateは携帯電話のgoogle mapで調べてとる。場所を検索、タップ長押し、coordinateを表示させてコピー。
- ガジェットを入力待ちにする。今あるボタン長押し、あるいはダブルタップでもいいが、間違って入力待ちモードに突入すると面倒。専用のボタンを普段押しづらいところに追加配置。
- 入力待ち時にはLED(青)が小さく光ってお知らせ。
- 調べたcoordinateを、テンキーのようなものから入力、ではかっこ悪いので、bluetoothで流し込む。
- 目的地は使われてない9番にセットされる。LED(青)が消える。
うむ。たしかにテンキーから入力はカッコ悪い。使わないとき邪魔だし。coordinateの桁数は結構長いので、覚えられなかったり打ち間違えたりして嫌な感じになりたくない。Bluetoothを使いたい。接続、入力だけの簡単なインターフェースなら前に練習で作ったAndroid appをどこかを参考に改変すれば書けそうな気がするし。google mapからのコピペで済むならそれが一番!
ということで方針が決まりました。
追加改造部分について
改造部分を図1に示します。
- (A)入力待ちモードを知らせる青色LED(3mmの小さめのもの)をいまあるボタンの下に追加。Pin 12を使用。
- (B)入力待ちモードに突入するためのボタンは基板の裏側に設置。外部抵抗でpull down、pin 7で読み取り。ここなら間違えて押してしまう可能性は低い。
- (C)Bluetooth moduleはHC-05を本体基板とは別の基板にのせた。HC-05はシリアルで接続できる。GPSユニット用のSoftware serial portに加えてもう一つportを作って接続。Pin 4 (Rx), 5 (Tx)を使用。複数のSoftware serialを使ったのは今回が最初。.listen()で切り替えて使うのがポイント。HC-05側のRx入力は検索で得た接続例を参考に分圧抵抗で3Vぐらいになるようにした。
- Arduinoプログラムを一部改変。裏のボタンが押されたら入力モード突入。ちび青LEDを点灯させてsoftware serial portをHC-05からのものに切り替え。送られてきたlatitude, longitudeを取得して変数にセット。後はLEDを消してlistening serial portをGPSユニットからのものに戻す。
携帯電話側からの緯度経度送信
最初の予定では簡単なUIをもつAndroid appを書こうと思っていたのですが、テスト用に探して使ったSerial Bluetooth Terminalというアプリがそのまま便利!使わせていただくことにして、アプリは書かず。
使い方は簡単で、図2に示す通りです。
- 0. ガジェット側:入力待ちモード突入ボタンを押す。青色LED点灯。
- 1.左上のhamburger icon(三本線)をタップしてDevicesを選ぶ
- 2.HC-05を選ぶとすぐに接続tryが始まります
- 3.Connectedとでれば接続完了
- 4.google mapで目的地を検索、ドロップピンあるいは目的の場所を長めにタップするとcoordinateが検索バーに入ります。これをコピー。
- 5.Serial Bluetooth Teminal appに戻ってペースト(コード側ではcommaとスペース一つがlatitude, longitudeの間にあることを期待しているので、確かにそうなっていることを確認)
- 6.送信
で、うまくいくと青色LEDが消えて番号9が表示されるという段取りです。
そんでどうなの
一か所だけですが、その場で目的地を設定できるのは便利です。少しして気が付いたのですが、Serial Bluetooth Terminal上では送信内容に名前をつけて保存しておけるので(M1-M6)、この機能を使えば6か所まではガジェット側のコードを書き換えることなく設定することができます。これは便利。
Arduino code
つぎはぎだらけなのと、Serialへのprint前後に余計な待ちがたくさん入っていてきれいとはいいがたい状態ですが、記録のためGithubにのせておきました(myGPS-proto-7seg-servo-bluetooth.ino)。
以前からsoftware serialって複数作れるのか、作れれば便利なのに、と思いながら調べずにいました。あれこれ調べ回りながら、試しながらコードを完成させたのでよく覚えていませんが、結局Arduino本家のdocumentationのページが一番役立ったと記憶しています。
ポイントは一度に一つのportを待つことしかできないので、.listen()で入力待ちのportを切り替えること、setup()で最後に.begin()されたものがloop開始時での入力待ちになるということです。今回、最初のコードではHC-05を接続したmySerial2.begin()がsetup()の最後にあり、一つ目のserial portにつながっているGPSからの情報がまるで拾えなくて困りました。気が付いてしまえばなんでもないことだったんですが。