M5Stack + GPSユニット
M5Stack Core2 for AWSを使ってAWSとの通信やAlexaを試してきましたが、ここでいったんAWSを離れて送料を無料にするために購入したGPSユニットをせっかくだから動かしてみたいと思います。
一般的にはArduinoですが私はいつもESP-IDF & Eclipseでやるのでそちらベースでやっていきます。
ツールのインストールは”TTGO T-CameraをESP-IDF & Eclipseで動かす“でやっているので参照してみてください。
では始めましょう!!!
GPSユニットはUartなので青色のPortCに繋ぎます。
そしてファームウェアの構築をしていくわけですが、そもそもGPSユニットはどのように扱うかなど私の知識も資料類も少ないので、それで進める訳ではないのですがM5StackサイトのArduinoサンプルを動かそうとしてみました。
ですがこれはM5Stack Base用のようで(多分)、エラーしてしまいます。あまりArduinoをつついていてもしょうがないのでESP-IDF + Eclipseでやっていこうと思います。
ここでのESP-IDFは”TTGO T-CameraをESP-IDF & Eclipseで動かす“でやっていますが、GitHubのESP-IDFリボジトリーかESP-IDF Tools Installerで入手できます。
Arduinoではエラーはしてしまいますが、ざっくりコードを見ると何かコマンドを送ってそれに対してGPSデータが返ってくるとかではなくてGPSデータがたれ流しのようです。一応その前提でファームウェアを構築していきます。
GitHubからCloneできる”Core2-for-AWS-IoT-Edukit“には”Hardware-Features-Demo”というのがあり、これに”M5Stack Core2 for AWS”の大体の機能が実装されているのでこれをベースにしてやっていきます。
Eclipseを立ち上げ、「Import」→「Existing IDF Project」を選択して「Next」ボタンをクリックします。
「Project Name」を”M5StackGPS”とでもして、「Existing project Location」に”Hardware-Features-Demo”を指定して、「Copy project int workspace」にチェックを入れて「Finsih」ボタンをクリックします。
プロジェクトができたところでEclipse上側にあるドロップダウンリスト3個のうち一番右側を開いて”New ESP Target”を選択します。
「ESP Target」を選択してから「Next」ボタンをクリックして、表示された「ESP Target」ダイアログで、名前を”m5stack”などとして、「IDF Target」では”esp32″を選択して、「Serial Port」にはM5Stackが接続しているCOM番号を指定して、「Finsih」ボタンをクリックします。
これでとりあえず”M5StackGPS”プロジェクトができたので左上の緑丸に三角白の”Lounch in ‘Run’ mode”をクリックするとbuild/flashされてデモプログラムが走ります。
ここにGPSモジュールからのデータ受信を行うコードを足していきます。GPSモジュールはUartなので、”\ESP-IDF\examples\peripherals\uart\uart_async_rxtxtasks\main\uart_async_rxtxtasks_main.c”などのコードを移植すれば良さそうです。もちろん他のuartサンプルでもいいとは思いますが、本稿ではこのサンプルを参照していきます。
“uart_async_rxtxtasks”プロジェクトはその名の通り、受信/送信イベントが発生するとそれぞれのタスク関数が呼び出されます。送信イベントは使用しませんが、受信イベントは1000文字受信するごとにタスク関数が呼び出されます(文字数は任意)。
では必要コードを足していきます。
初期化を行う”init()”関数および”rx_task()”関数をコピーして、これらを呼び出し、TaskCreateするコードを”app_main()”関数内の無限ループ”for (;;)”の前に置きます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void init(void) { const uart_config_t uart_config = { .baud_rate = 9600, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_APB, }; // We won't use a buffer for sending data. uart_driver_install(UART_NUM_1, RX_BUF_SIZE * 2, 0, 0, NULL, 0); uart_param_config(UART_NUM_1, &uart_config); uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
static void rx_task(void *arg) { static const char *RX_TASK_TAG = "RX_TASK"; esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO); uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1); while (1) { const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 1000 / portTICK_RATE_MS); if (rxBytes > 0) { data[rxBytes] = 0; ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data); ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO); } } free(data); } |
1 2 3 4 5 6 7 |
char label_stash[200]; init(); xTaskCreate(rx_task, "uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL); for (;;) { BM8563_GetTime(&date); |
init()の中の.baud_rateはGPSユニットの仕様より9600にします。
さらに”driver/uart.h”をincludeして、”RX_BUF_SIZE”、”TXD_PIN”、”RXD_PIN”の定義を追加します。”TXD_PIN”、”RXD_PIN”はM5Stackの仕様よりそれぞれ14pin、13pinにします。
このプロジェクトを再度build/flashして、エラーなくデモプログラムが走ったら「Ctrl」+「Alt」+「Shift」+「T」で”Launch Terminal”ダイアログが開くので、”Serial Terminal”を選び、COM番号を選択すると、GPSユニットからのデータが観測できます。
これでGPUユニットの動作確認ができました。
が、せっかくLCDもついていることですし、ここから緯度、経度を抽出してLCDに表示させてみたいと思います。