4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

後輩たちのためのEV3rt講座⑪(UART通信)

Last updated at Posted at 2019-06-13

#はじめに
事の始まりは2019年のロボカップジュニア・ジャパンオープン大会を観戦しに行った時、WROとは違いロボットの作製にあたって制限が少なく、個性豊かなロボットが多く見られた。
ロボカップとWROの難易度を比較するわけではないが、ロボカップの方がセンサーを多く使用しなければならない傾向にある。しかしながらEV3には入力ポートが4つしか無い。
ここで登場するのがデイジーチェーンである。
6a0120a6ffc261970b019b002de736970d-320wi.jpg
(画像は『ロボジョイくらぶ・マイスターブログ EV3のデイジーチェーンモード』より)
親機となるインテリジェントブロックに子機となるインテリジェントブロックを接続し、ポートを増やすという方法。
開発をEV3だけに統一することができるため、初心者によく用いられる簡単な手法である。

ここで私はあることを感じた。
「EV3rtでデイジーチェーンは可能なのか??」

言うのを忘れていたが、EV3rtはデイジーチェーンをサポートしていない。
中の人によると今後の開発課題であるらしい。

私は選手が会場で競技を行っている中、EV3rtのC言語Referenceとにらめっこしていた。
そして、気になる記述を見つけた。
スクリーンショット 2019-06-13 15.46.55.png

「『ゆーえーあーるてぃー』ってなんぞや?」

#UARTとは
界隈の人なら知ってて当たり前。「なんでお前知らんねん」

はい、頑張って調べました。
ざっくりいうと、非同期式の通信部品・方式の一つで、シリアル通信とパラレル通信を変換するものだそう。
NXTではI2Cで通信をしていたが、EV3ではこれに加えUARTで通信できるようになった。

詳しくはこちら->電子工作初心者のために シリアル通信方式を分かりやすくまとめてみた

#EV3rtとUART
私のUARTの記事でお伝えしましたが、EV3はセンサーポート1からUARTの信号を入出力することが出来ます。
そして、EV3rtはソフト側でこれをサポートしています。
ここでキーとなるのが、EV3rtのBluetooth通信です。
あの時、Bluetoothの接続を仮想シリアルポートに繋ぐものとし、1つのファイルとしてプログラムを組みましたよね。
なんと、UARTも、1つのファイルとして扱うことができるのです!!素晴らしい!!

百聞は一見にしかず、Referenceを見てみましょう。
スクリーンショット 2019-06-13 16.11.00.png
引数を見ると**serial_port_t**となっているのがわかるでしょうか。
ここで先程の画像を見ていただきたいのですが、ここで引数にEV3_SERIAL_UARTを指定することで任意のデバイスとUART通信ができるのです!!

#実際の使い方
もうここからはBluetoothの時とほぼ変わりませんが、とりあえずやってみましょう。
今回はConnect to EV3のソース・コード一部抜粋したものを例に見てみたいと思います。

##接続する時

app.c
static FILE     *bt = NULL;  //ファイルポインタ   

switch (mode)
    {
        case 0:
            bt = ev3_serial_open_file(EV3_SERIAL_BT);
            ev3_lcd_fill_rect(0,0,EV3_LCD_WIDTH,EV3_LCD_HEIGHT,EV3_LCD_WHITE);
            ev3_lcd_draw_string("Please Start",20,0);
            ev3_lcd_draw_string("BT Mode",20,20);
            break;
        case 1:
            bt = ev3_serial_open_file(EV3_SERIAL_UART);
            ev3_lcd_fill_rect(0,0,EV3_LCD_WIDTH,EV3_LCD_HEIGHT,EV3_LCD_WHITE);
            ev3_lcd_draw_string("Please Start",20,0);
            ev3_lcd_draw_string("UART Mode",20,20);
            break;
        default:
            bt = ev3_serial_open_file(EV3_SERIAL_BT);
            ev3_lcd_fill_rect(0,0,EV3_LCD_WIDTH,EV3_LCD_HEIGHT,EV3_LCD_WHITE);
            ev3_lcd_draw_string("Please Start",20,0);
            ev3_lcd_draw_string("BT Mode",20,20);
            break;
    }

本プログラムはmodeという変数でBT接続とUART接続を切り替えられるようになっています。
でも違いはファイルポインタbtに**ev3_serial_open_file(EV3_SERIAL_BT);と書き込むか、ev3_serial_open_file(EV3_SERIAL_UART);**と書き込むかの違いだけです。
超簡単ですね!!

##データの受信

app.c
while(1){
   uint8_t c = fgetc(bt);
   if(c=='1'){
       break;
   }
}

これはプログラム冒頭のPCとの同期部分です。
PC側から'1'という文字が送られてきたらbreakし、この先のメインプログラムのサイクルハンドラへと進んでいきます。
注目してもらいたいのはfgetc関数です。
BT通信のときにもお伝えしたとおり、C言語標準のファイル操作関数を使用できます。
ということは、fgetc以外にも…

app.c
fgets(str,5,bt);

こんなのも使えます。
(意味はファイルポインタbtから4文字分受け取り、char配列strにブチ込む。(指定引数が5なのは一番最後にヌル文字が入るからです。詳しくはググってください。))

##データの送信

app.c
fprintf(bt,"%d\r\n",data[0][0]);

先程同様、C言語標準のファイル操作関数であるfprintf関数を使用しています。
(意味はファイルポインタbtにint二次元配列dataのインデックス[0][0]の値と改行コード\r\nを送信)

ちなみに、あまりにもソースコードが汚かったためわかりやすくしましたが、実際この関数に引数を何十個も入れて全センサーの値をPC側に送信しています。

#デイジーチェーンの話はどこへ行った?
はい、今模索中です。
というのも学業及び生活のほうが忙しく、それどころではないので中断中ですが、来年になったらまた再開したいと思います。
最終目標はEV3rtでのデイジーチェーンです。
本物と遜色ない程度に仕上げたいですねぇ。

何かアドバイス等あればコメントお願いします。
うちのクラブでもEV3rtでロボカップ出場を若干検討していますので〜〜

次回:未定
前回:第10回

4
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?