2021年3月12日金曜日

Nucleo64+ArduinoLCD+MPU6050の明日はどっちだ? (承前。GPS追加搭載。)

前回、加速度センサつなげて温度計つなげて、って所までで止めてて、GPSもつなぎたいな…というところで終わりにしていたんですが、その時までにGPSを試していなかったのか、と言うと、そういうわけではなく、GPS側の設定の問題と、シリアルの取扱い方が判らなくて、詰まってたんです。

手元にあるのはUART接続の古いGPSモジュールなので、UART経由でデータを読んでやる必要があります。

ArduinoにはTinyGPSPlusと言う優れものがあり、年末のArduino UNOではそれ使いました。mbedにもそのポーティングがあるんですが、先だって書いたとおり、それがmbedいくつ向けか、という微妙な点があります。それに纏わり引っかかった、mbedにおけるシリアルの取り扱いの変遷があります。

 リアルタイム性を含めてのことなのかなとも思いますが、シリアルやらでデータを交換する時に、C言語までの知識ではgetc()/putc()使う、って教わるように思うんですが(本職の皆さん違ってたらごめんなさい)、getc()もputc()も、mbed 2にはあれど、mbed 6には存在しないんです。
おまけに、mbedには、2014年頃まで、トラ技誌に付録でついたLPC11U35のボードのおかげか(そいつが前回記事で、なんとmbed 6はサポート外なんかい…となったきっかけなんですけど)、日本国内で流行った時期があった関係で、概ね2016年以前のmbed実績のblogなどは、mbed 2、ほぼそれで書かれており、getc()/putc()を使用、せいぜい、serialとrawserialという区分けまでで、はて、mbed 6はどうしたら…となっていたわけです。

Mbedサイトで、シリアルにはBufferedとUnbufferedがあって、getc()じゃなくてread()で取り込む…てのは読んで判ったわけですが、どちら使ってもOSが落ちhaltしちゃう。前回の時は、そこまで追求できなかったんです。
で、改め、unbufferedの時、何で落ちてるのか調べようと思って始めたのが今回なんですが、なぜかdebuggerを使うようbuildすると、もうdebuggerとの通信の時点でOSが落ちちゃう。OSが吐くログは、STLink絡みで問題があるようだけど、とてもそんな所までデバッグする能力はないので、bufferedでどこまで動くか見てみよう、ということで、取り込んだものをprintfさせてみると、どうもnon-printable charを拾っている感じ。これはもしかして、TinyGPSPlusが要求するNMEAを喋ってないんじゃないの?とようやく思い当たりました。


GPSモジュール自体は、NMEAを出力するよう設定して、バックアップバッテリを接続していたので、NMEAのままだと思い込んでいたんですが(古いので、それがないと、電源投入時に、NMEAではない初期状態の出力になっちゃう)、何かのはずみにバッテリへの結線が外れてたんです…。つまりGPSデフォルトで出力していました。それでTinyGPSPlusが解釈できていないことが原因だったと。

それを直し、改めてNMEAを出力するよう設定して走らせてみると…
右の写真ではまだ衛星補足していませんが、時間が取れていることから、ようやく、GPSが出力するデータを読めるようになったようです。衛星捕捉できれば、ちゃんとLAT・LNG表示してくれます。

写真では分かり辛いですが、Arduino LCDを載せたF411RE、SK-16に、クッション付き両面テープを置いて張り付け、その左がわちょうどUSBコネクタの下あたりにGY-521を、同じように両面テープで張り付け、手前側にGPSバックアップ用CR1220が張り付けてあります。 
GPSと、Arduino LCDに搭載されているmicroSDへの書き込み開始スイッチを蓋に張り付けてやって、なんとか収まるようにしました(LCD+F411REの背が微妙に高いのと、ちょいと配線量が多くて、ふたがちゃんとしまりきらないですが…)。

これでも、LM75Aによると、F411REとLCDの間は、LCDバックライトで温められてるとはいえども36℃ほどで収まっているようです。

それにしても、ここに持ってくるまでに、こんなに時間掛かるとは…(何分古いGPSなので、時計はrolloverしてます…)。mbedにはだいぶ悩まされました。
性質的には、GPSはunbufferedで動かす必要があるようには思うんですけど、OSクラッシュは、GPSがNMEA話しているかどうかには関係なく、私程度のソフトウエア知識では対応できましぇーん!


3/29追記:

 昨晩、なぜUnbufferedSerialだとクラッシュするのか、はっと気づきました。プログラムフロー的に非同期な扱いをする部分で、同期乗り換えを必要とすることやっちゃダメっすよね。
さっきそれ直して、UnbufferedSerialを使ってGPSを読み、エンコードし、加速度センサなどの出力と併せて表示できるようにできました。
これで、GPSの時刻データも毎秒表示されます(buffered serialで、バッファしたもの解釈させると、取りこぼしの上数分単位でしか更新できなかったんです…)。

サンプルコードがあるからって、それを鵜呑みにしといちゃダメすね…。特にBuffered Serial / Unbuffered Serialみたいなtiming issueがある実装に対しては。

0 件のコメント:

コメントを投稿