WRO勢による EV3rt汎用Bluetoothロガーの開発

本記事は、ETロボコン&EV3 Advent Calendar 2018 9日目の記事です。
#自己紹介#

改めまして、高校生プログラマーのKoushiroです。中学1年生からロボットを始め、WROは2015年から参加し始め、2017・2018年にJapan大会に進出、FLLは2015-2016シーズンは予選落ち、2016-2017シーズンはJapan大会進出を果たしました。RCX→NXT→EV3と使用し、Mindstorms歴5年目となります。
2017年のWROレギュレーションから高校生に限り、EV3標準ソフトウェア以外の開発環境も使えることになり、EV3rtを使用し始めました。よってEV3rt使用歴は2年です。2018年のWROをもって現役は退き、現在は後輩の指導を行っています。その一環としてQiitaで[後輩たちのためのEV3rt講座](https://qiita.com/koushiro/items/4d18c877c93f823fc236)を連載しております。
![スクリーンショット (74).png](https://qiita-image-store.s3.amazonaws.com/0/183170/a8d71559-5806-4789-9acc-7448459c2b01.png)

#WROが終わってからの研究#
9月にWROが終了し、プロジェクトに一区切りがつきました。私には、大学受験の勉強が本格的に始まる前にどうしても作っておきたいものがありました。
EV3標準ソフトウェアには、PCとインテリジェントブロックと接続した時に、センサーの値を監視できる機能があります。
![スクリーンショット (72).png](https://qiita-image-store.s3.amazonaws.com/0/183170/e58895a2-56b4-2514-f6f8-06a681b35eca.png)
これ、あると何かと便利なんです。例えば、ライントレースに使用する黒線の値を測ったり、モーターの回転角を測ったり、言い出せばキリがないですが、なにせ便利なんです。
でも、EV3rtでセンサー値を見るには、ファイルに書き出したり、あるいは狭いLCDに書き込んだりしないといけません。僕も`fprintf`でtxtファイルに値を書き込み、Excelでロギングしていました。
ただ正直言って、面倒で使いづらいですよね。ということで、EV3rtでBluetooth経由でのセンサー値監視アプリを作ろうと決心したのであります。

#作成したソフトがこちら!!#
![スクリーンショット (73).png](https://qiita-image-store.s3.amazonaws.com/0/183170/7e7b3437-b06d-ce64-c14c-c6ad5036153b.png)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">本日Qiitaにて公開するKoushiro製作ソフト、「Connect to EV3」のご紹介。<br>EV3rtユーザー向けBluetoothロガーソフトです。<br>詳しくはQiitaのエントリーをご覧ください。<a href="https://t.co/jCeLM1AdJY">https://t.co/jCeLM1AdJY</a><a href="https://twitter.com/hashtag/qiita?src=hash&amp;ref_src=twsrc%5Etfw">#qiita</a> <a href="https://twitter.com/hashtag/EV3rt?src=hash&amp;ref_src=twsrc%5Etfw">#EV3rt</a> <a href="https://t.co/rWOKChsS6Y">pic.twitter.com/rWOKChsS6Y</a></p>&mdash; Koushiro0322 (@Koushiro_A) <a href="https://twitter.com/Koushiro_A/status/1071443582052007937?ref_src=twsrc%5Etfw">2018年12月8日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

名前は**"Connect to EV3"**です。
主な機能は以下の通り

- リモートスタート
- モーターの各種値受信・表示
- センサーの各種値受信・表示

冒頭説明したとおり、私は高校生でまだまだ未熟な者ですので、はっきり言ってプログラムに非効率な部分があるかと思います。
よって、実際のコードについて詳しくは本記事内では触れません。
ただ、このプログラムの使い方やロジック・プロセスに関しては話しておきたいと思います。

#プログラムファイルの配布#
今回作成したファイルを、ソースコード含め配布したいと思います。
Githubに関しては使い始めてまだ2カ月ほどで、ほとんど使い方がわかりませんが、なんとか用意しました。

[Githubのリンク](https://github.com/Koushiro-Achioku/Connect-to-EV3-Project)

また、本プロジェクト用の各種フォームがこちらです。(詳しい内容は本記事以下に記載しています)
[改変済みコードの公開申請フォーム](https://goo.gl/forms/mcXRMxrkYgHjyVe03)
[本プロジェクトに対する質問フォーム](https://goo.gl/forms/V4mojmRWqLbtfont1)

#開発環境・言語#
EV3側:TOPPERS/EV3rt (C)
PC側:Visual Studio (Visual C#)

#プログラム実行の流れ#
ここではざっくりとした流れのみ説明します。
実際に使用する際は配布zip同梱のReferenceというPDFファイルを熟読してからご使用ください。

##1.Bluetooth接続##
EV3とPCをBluetoothで接続します。
今回の通信は仮想シリアルポートを使用します。
それにあたり、通常の接続方法とは少し違うので、Referenceをよく確認してください。（Tera Termを普段から使っている方はそのままで大丈夫です。）

##2.Windows側のアプリを実行##
`"Connect_to_EV3.exe"`を実行します。
![スクリーンショット (48).png](https://qiita-image-store.s3.amazonaws.com/0/183170/58fa7281-d225-d634-264a-dbd8454598a3.png)
実行したらCOMポート開通させて、EV3とBluetooth通信を開始します。

##3.EV3側のアプリを実行します##
先にEV3_filesをコンパイルしておきましょう。
EV3にコンパイルしたappを転送します。
転送したアプリを実行すると、`"Please Start"`と出てきます。
![図1.jpg](https://qiita-image-store.s3.amazonaws.com/0/183170/14c77853-5cb5-6e40-d976-1935ff777cbb.jpeg)
これが出たらEV3は一度待機です。

##4.通信プログラムを開始##
再びPC側に戻り、上部`"Start"`ボタンを押します。
上手くセッティングできていれば、下部コンソール画面に値が流れ出します。

##5.センサー・モーターをConfig##
この段階では、センサーやモーターはConfigされておらず、値は常に0を返します。
これをPC側から選択し、正しい値を返すようにします。
(ここで正しいセンサー・モーターを選択しないと、フリーズしてしまいます。)

##完成!!##
ここまで完璧にできれば、各ポートごとにリアルタイムの値が表示されます。
ラグもあまりないので実用性はあると思っています!!

#通信の仕組み#
今回の通信では先ほども述べたように、**Bluetooth経由の仮想シリアルポート**を使っています。
通信は双方とも送受信可能で、以下のような通信を行います。

- PC->EV3 リモートスタート
- PC->EV3 センサー・モーターのConfig
- EV3->PC センサー・モーター値を返す

全ての通信がASCIIコードでの文字列送信により行われています。

リモートスタートは

```Form1.cs
serialPort1.Write("1");
```

センサー・モーターのConfigは

```Form1.cs
/*配列の宣言*/
public char[] port1 = new char[4] { '1', '0', '0', '0' };
/*port1[0]:ポート,port1[1]:センサー種類,port1[2]:取得モード,port1[3]:未指定*/

/*値の送信*/
string s = new string(port1);
if (serialPort1.IsOpen == true) { serialPort1.Write(s); }
```

センサー・モーターの値を返す時は

```app.c
static FILE     *bt = NULL;
bt = ev3_serial_open_file(EV3_SERIAL_BT);

fprintf(bt,"1%d,%d,%d#2%d,%d,%d#3%d,%d,%d#4%d,%d,%d#5%d#6%d#7%d#8%d#\r\n",
        data[0][0],data[1][0],data[2][0],data[0][1],data[1][1],data[2][1],data[0][2],data[1][2],data[2][2],data[0][3],data[1][3],data[2][3],
        data[0][4],data[0][5],data[0][6],data[0][7]);
```

というような具合です。
(一部抜粋、順序無関係なので、実際のプログラムとは異なります。実際の流れはソースコードを見てご自分でご確認ください。)

#プログラムの応用#
ここからはかなり高度かつ、自己責任的要素が伴いますのでご注意ください。

##任意のプログラムを書き込む##
`app.c`ファイル内の

```
/* 以下、main_taskとして任意のプログラムを記述可能(未確認) */
```

より下は、任意のプログラムを書き込める **は** **ず** です。
というのも、プログラミング方法が悪いのか、上手く値が返せていません。
でも、将来的には動きながら計測できたほうが良いと思うので、これは要検討です。

##任意のプログラムに組み込む##
上記のより発展バージョンです。
このプログラムは最初の接続が終わると、周期ハンドラが起動し、3つの関数が超高速周期で動きます。

```app.c
void bt_send(intptr_t unused)
{
    Send_value();
}
```

このうち、値を送信しているのは`Send_value();`なので、この関数をまるごと任意のプログラムに組み込み、本プログラム同様周期ハンドラでPC側に送信すれば、使うことができるでしょう。ただし、各ポートごとのセンサーの設定を配列に記憶させてあるので、そこらへんの理解が必要です。

#今後の追加予定機能#
- センサーの自動Config
- ログの清書&txtファイルでの保存
- モーターの起動ボタンを追加
- ソースコードの清書（特にセンサー値送受信）

#みなさんへのお願い#
本プログラム開発の発展のため、お願いがあります。使用に当たり、以下をご熟読ください。

```
【1】「Connect to EV3」(以下、本ソフト)の製作者はKoushiro Achiokuであり、TOPPERS/EV3のライセンスに沿った範囲で製作者としての権利を有するものとします。

【2-1】本ソフトには、発見済みを含めたいくつかのバグが確認されており、それによりインテリジェントブロック等に不具合が発生する可能性があります。解消に向け努力はしておりますが、個々の事象への責任は負いかねます。

【2-2】バグを発見した場合は、専用フォームに報告ください。

【3-1】本ソフトは多くの方に使っていただきたいという思いから、オープンソースとして配布いたします。アプリの使用、ならびにソースコードの改変は自由とします。ただし、改変によって生じた事象に関しては、一切の責任を負いません。

【3-2】改変後の二次配布も可とします。ただし、改変状況の調査のため、専用フォームへの申請のご協力をお願いします。これはアプリ開発の発展のためであります。

【4-1】本プロジェクト用のGithubリポジトリを用意しています。ご自由にお使いください。

【4-2】push/pull Requestする際は、自分のものだと明確にわかるブランチを作成して、そこにpushしてください。また、一括管理するため、専用フォームの方にも申請をお願いします。

【5】本プログラムのアップデートに当たり、みなさまのコードを使用させていただくことがあります。公開し、申請されたものに関しては、このことに同意したとみなします。
```

#最後に#
本ソフトはまだまだ初期段階であり、ここからさらなる発展をしていきたいと考えております。
TOPPERS/EV3rtの開発者様、ETロボコン参加者様、WRO参加者様、その他このプロジェクトに興味を持ってくださった方々、図々しいようですが、皆様のご協力をお願い致します。
ここまでお読みいただきありがとうございました。