PSoC5lpでGPSモジュール使ったロガーを作った


はじめに

車で移動したときのログがとれたら面白いなと思ってマイコンとGPSを組み合わせてロガーを作りました。
まあなんか躓いたところとか、何を使ってどうしたかとか、どうしてそうしたかとか書いていきます。

やったこと

PSoC5LPとGPSモジュールでロガーを作成したときのメモ書きになります。今回書くことは以下の3つです。

  • GPSモジュールから送信されるデータをパースする
  • SDカードへ書き込むこみ保存する
  • OLEDに表示する

使用したもの

だいたい秋月電子で手に入ります。

概略図

最終的にはきれいな箱に入れたいのですがとりあえず動くものを作るということで、ブレッドボードで作っていきます。

全体の構成として上の図のようになります。
これをもとにブレッドボードに配線していきます。
大きい液晶や6軸センサーは今回は接続してないので関係ないです。

電源電圧はSDカードを使うので3.3Vです。USBUART変換がUSBから3.3Vを取り出すのにちょうどよかったので使っています。
PSoCはピンアサインを自由に設定できるので部品の配置が柔軟になるのがいいですね。

PSoCのトップデザインはこんな感じです。

左のI2CはOLED用、真ん中のUARTはGPSの受信用、右のSPIはSDカードの書き込み用です。
実際にはデバッグ用にUSBUARTも追加しています。

GPSモジュールの読み取り

とりあえず読んでみる

GPSモジュールの動作確認も含めてPC上でGPSのデータを表示します。
GPSモジュールのTXとRXをPSoCにつなぎます。そして受け取ったデータをそのままUSBUARTでPCに流します。

NMEAフォーマットのデータが1秒毎に送られてくることを確認できたらオッケーです。

ディスプレイに表示するためにパースする

ログとして保存するならばNMEAフォーマットのままSDカードに保存すればいいのですが、ディスプレイに表示するためには、見やすいようにNMEAフォーマットから欲しい情報を取り出さないといけません。そこでArduino用に書かれたMicroNMEAというライブラリを使用します。

https://github.com/stevemarple/MicroNMEA

MicroNMEAはNMEAフォーマットのコンパクトなパーサです。Arduino用に書かれていると言っても実態はC++のコードなので移植は可能です。今回はちょっとだけPSoC用に書き換えてこのライブラリを使用します。
簡単にArduinoのスケッチを読むとMicroNMEA.cppMicroNMEA.hを追加すれば使えそうです。

手順としては以下になります。

  1. プロジェクトにMicroNMEAのライブラリを追加
  2. PSoC CreatorでC++をコンパイルできるようにする
  3. ライブラリを書き換え

まずPSoCのプロジェクトにライブラリを追加します。

Projectを開き上の画像のようにWorkspace Explorerの中のHeader Filesという項目で右クリック → Add → Existing Item...を選択します。そしてMicroNMEA.hを追加します。
同じようにしてSouce FilesにMicroNMEA.cppを追加します。

成功すれば上の画像のようになります。このときMicroNMEA.cppのプロパティを開いてFile Typeが上の画像のようにOTHESになっていたら、SOURCE_Cに変更してください。私はこれに気づかず1日溶かしましたorz

次に、C++をコンパイルするために一工夫

main.cmain.cppに変更します。そして#include <project.h>extern "C"で囲います。
具体的にはmain.cppの先頭を以下のように書き換えます。

#ifdef __cplusplus
extern "C" {
#endif
#include <project.h>
#ifdef __cplusplus
}
#endif

これでPSoCでC++が扱えるようになります。

最後にライブラリの書き換えを行います。
MicroNMEA.hの12行目の#include <Arduino.h>と33行目のstatic Stream &sendSentence(Stream &s, const char *sentence);をコメントアウトします。
MicroNMEA.h#include <project.h>を追記します。
MicroNMEA.cppの156行目からの#ifndef MICRONMEA_DEBUGから#endifまでをコメントアウトします。

これでコンパイルできるようになります。

ここまでくればもう一息です。
MicroNMEAのサンプルと同じように、GPSモジュールから流れてくるデータをnmea.processに流し込めばパースされた情報を読むことができるようになります。

簡単なコードになります。

char uart_buffer[100];
char gps_buffer[100];
MicroNMEA nmea(gps_buffer, sizeof(gps_buffer));

for(;;){
    if(g_ppsFlag){ //1秒毎にUSBUARTで送信
        sprintf(uart_buffer, "%02d:%02d:%02d\n", ((int)nmea.getHour(), (int)nmea.getMinute(),(int)nmea.getSecond());
        USBUART_1_PutString(uart_buffer);            
        sprintf(uart_buffer, "Lat:%ld\nLng:%ld\n", nmea.getLatitude(), nmea.getLongitude());
        USBUART_1_PutString(uart_buffer);
    }

    if(UART_GPS_GetRxBufferSize()){
        char word;
        word = UART_GPS_GetChar();
        nmea.process(word);
    }
}

表示機の実装

以前に自分が書いたQiitaの記事を見ながら実装しました。
PSoC5でI2C極小OLED、SSD1306を使う

表示したのは時刻、座標、高度と速度です。

SDカードへの書き込みの実装

ChaNさんのFatfsをPSoC用に書き換えたやつを使用しました。

https://github.com/hackingchips/PSoC_FatFs

流れてくるデータをそのままcsvに保存しています。

完成したのでドライブした

車のダッシュボードに取り付けてドライブしました。

香川から高知まで32号線を走りました。
SDカードに保存されたデータをu-bloxが配布しているu-centerというソフトウェアに入れるとログデータを再生することができます。
これは32号線の高度データをグラフにしたものです。途切れている部分はトンネル内だと思うので、だいたい正確に取得できてると思います。

終わりに

PSoC5lpとGPSモジュールを使ってロガーを作ることができました。その過程でPSoCでライブラリなど限定的ではありますがC++をコンパイルできるようにしました。今後は基板を作ったり、他にもセンサーを乗せるなど試みようと思います。

参考