M5Stackで作る車載GPS速度計

きっかけ

オートクルーズで法定速度ぴったりの実速度で走りたかった。

できること

  • GPS速度、高度、方位を表示します(最大10Hz)
  • 夜間はディスプレイを暗くします(18時~6時 JST)
  • USBの電源供給と連動して電源をOn/Off(スリープ)します

f:id:toripoyo:20200216031336j:plain

ハード

標準のGPSモジュール(M5STACK-GPS-02)を使いました。
NEO-M8Nというモジュールが内臓されており、最大で秒間10回のGPS情報を得られます。

ソフト

Arduino環境で開発します。
ソースはGithubにあります

GPSモジュールからのデータの取得とフォーマット変換

GPSモジュールから送られてくるNMEAデータを扱うために、TinyGPS++というライブラリを使います。
最小限の構成にすると、以下のようなコードになります。

#include <M5Stack.h>
#include <TinyGPS++.h>
HardwareSerial hSerial(2);

void setup()
{
  hSerial.begin(115200);  // もし初期状態のモジュールを使いたいなら9600bps
}

TinyGPSPlus tGPS;
void loop()
{
  // Receive GPS Data
  while (hSerial.available() > 0)
  {
    tGPS.encode(hSerial.read());
  }

  int nowSpeed = (int)(tGPS->speed.kmph()); 
  print(nowSpeed); // あとはご自由に
}

全機能の入ったコードはGithubを参照。

GPSモジュールとM5Stackとの通信

GPSモジュールとはシリアル通信でやり取りします。
このモジュールはデフォルトが 1Hz / 9600bps ですが、5Hz/10Hzで使いたい場合には通信が間に合いません。
そこで、私の場合は 5Hz / 115200bps に設定変更して使っています。

GPSモジュールの設定変更

初回だけやれば良いです。 コマンドのパケットを作るのが面倒なので、U-Centerを使ってPCから設定変更します。
PCとGPSモジュールは直接シリアル通信させても良いですが、配線が面倒なので…

  • PC <-> M5Stack の通信に使うシリアルポート
  • M5Stack <-> GPSモジュール の通信に使うシリアルポート

を、ソフトウェア的に直結します。
これで、M5StackにUSBケーブルを刺すだけで、PCからGPSモジュールを認識できます。

コードは以下のとおり。

  while (1)
  {
    while (hSerial.available() > 0)
    {
      Serial.write(hSerial.read());
    }
    while (Serial.available() > 0)
    {
      hSerial.write(Serial.read());
    }
  }

私の場合は、起動直後の画面でボタンを押すことで、このモードに入らせるようにしています。
f:id:toripoyo:20200216034708j:plain

U-Centerを使って 5Hz / 115200bps に設定する方法は、以下の資料が参考になります。
NEO-M8P、M8Tの設定方法

感想

  • 速度情報の更新頻度が高いので気持ちがいい。スマホGPSだとこうはいかない。
  • 方位が出るので方向音痴にはありがたい。

今後やりたいこと

  • ELM327 + M5StackのBluetooth を使ってOBD情報の取得
    • GPS情報が無い区間はOBDからの速度情報を利用?
  • 加速度検知
    • 現在のエンジンパワーの表示