後輩たちのためのEV3rt講座③(センサーを使う-①)

今回はセンサーを使っていきます。
いくつか紹介しますが、私があまり使わないAPIは雑い説明しかしません笑。
さらに、持っていないセンサーも載っているので、さすがにそれは説明できません…ご了承ください…
各自調べてください。
[EV3RT C API Reference 各種センサ](http://www.toppers.jp/ev3pf/EV3RT_C_API_Reference/group__ev3sensor.html)
#まずはコンフィグ#
モーターのときもそうでしたが、まずはコンフィグ(「これを使います〜」みたいな**宣言**的なこと)をしなければいけません。対応表とともにコンフィグ方法を記しておきます。

```app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン　*/
    ev3_sensor_config (0,COLOR_SENSOR);
    ev3_sensor_config (1,ULTRASONIC_SENSOR);
    ev3_sensor_config (2,GYRO_SENSOR);
    ev3_sensor_config (3,TOUCH_SENSOR);
```

ここでは

| ポート | 接続センサー |
|:-:|:-:|
| ポート1 | EV3カラーセンサー |
| ポート2 | 超音波センサー |
| ポート3 | ジャイロセンサー |
| ポート4 | タッチセンサー |

のように接続しています。この通りにセンサーを接続していないとプログラムは動きません。

ポートの番号は
![スクリーンショット 2018-09-10 12.39.06.png](https://qiita-image-store.s3.amazonaws.com/0/183170/d0a830ea-c211-c415-eaad-2e75fc69bcd8.png)
もしくは
![スクリーンショット 2018-09-10 12.39.55.png](https://qiita-image-store.s3.amazonaws.com/0/183170/effe4bdd-96eb-12df-e495-8e93745d73a0.png)
つまり

| ポート番号 | 列挙型① | 列挙型② |
|:-:|:-:|:-:|
| 1 | EV3_PORT_1 | 0 |
| 2 | EV3_PORT_2 | 1 |
| 3 | EV3_PORT_3 | 2 |
| 4 | EV3_PORT_4 | 3 |

という風にプログラムします。

センサーはの対応表はこちら
![スクリーンショット 2018-09-10 12.39.13.png](https://qiita-image-store.s3.amazonaws.com/0/183170/c7ce5355-96ad-d24f-bcb4-7a2d2cd3cb7f.png)

では実際に使用していきたいと思います。
#(ⅰ)EV3カラーセンサー#
![45506.jpeg](https://qiita-image-store.s3.amazonaws.com/0/183170/0954093c-297b-a9d2-0716-ff2c80b4d1f0.jpeg)
EV3のセンサーの中で一番使うと言っても過言ではないセンサーだと思います。
EV3rtで取得できるEV3カラーセンサーの値は4種類です。

- 反射光モード
- 周辺光モード
- カラーモード
- RGBモード

それでは一つ一つ説明していきましょう

##①反射光モード##
教育版ソフトウェアでいうこれ↓
![スクリーンショット 2018-09-10 12.37.17.png](https://qiita-image-store.s3.amazonaws.com/0/183170/5835ca4e-d89c-4aca-60f6-763d1a2fd1e3.png)
赤い光が出てるやつですね

```app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン　*/
    ev3_sensor_config (0,COLOR_SENSOR);
    int reflect_value=ev3_color_sensor_get_reflect(0);
```
この例だとreflect_valueという変数に値を入れています。
この変数をwhile文などで常時取得すればライントレースや線合わせなどなど、いろんなことができると思います。

##②周辺光モード##
教育版ソフトウェアでいうこれ↓
![スクリーンショット 2018-09-10 13.05.14.png](https://qiita-image-store.s3.amazonaws.com/0/183170/1c23d874-94dc-92a8-1932-ff6e79c8e978.png)
青い光が出るやつです。プログラム方法は反射光と全く同じです。

```app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン　*/
    ev3_sensor_config (0,COLOR_SENSOR);
    int ambient_value=ev3_color_sensor_get_ambient(0);
```

##③カラーモード##
教育版ソフトウェアでいうこれ↓
![スクリーンショット 2018-09-10 13.09.07.png](https://qiita-image-store.s3.amazonaws.com/0/183170/ef91c0ef-5a41-1904-866c-a2de1593b7df.png)
EV3カラーセンサーの強みである、色の読み取りです。
まずはプログラム方法がこちら

```app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン　*/
    ev3_sensor_config (0,COLOR_SENSOR);
    int color_value=ev3_color_sensor_get_color(0);
```
![スクリーンショット 2018-09-10 13.20.52.png](https://qiita-image-store.s3.amazonaws.com/0/183170/ce3340ed-1dfa-98b9-3a8b-2ae7c55a7857.png)
![スクリーンショット 2018-09-10 13.20.59.png](https://qiita-image-store.s3.amazonaws.com/0/183170/4fcf8923-8f7e-b7df-d101-6abc5181daad.png)
↑がAPIの対応表
↓は教育版ソフトウェアのカラー対応表
![スクリーンショット 2018-09-10 13.19.34.png](https://qiita-image-store.s3.amazonaws.com/0/183170/09683b5f-d02a-deca-991a-070f5187d7a0.png)
これで取得できる値は教育版ソフトウェアと全く同じです。
近年のWROなどは色付きオブジェクトがたくさん出てくるのでこれは重要ですよね。

ただ、EV3カラーセンサーの色判定は、はっきり言って**ガバガバ**です笑
センサーから0.5cm〜2cmくらいの距離に対象物がないと、判定は正しく行われないことが非常に多いです。
さあこれを解決する方法が次にご紹介する**RGBモード**です。
これはすごいですよ…

##④RGBモード##
モードとしてはカラーモードに非常に似ています。違う点として、ソフトウェアが勝手に判断した赤とか青とかの数字ではなく、生データの`R値` `G値` `B値` に分解した値を取得することができるのです。これはEV3カラーセンサーの**隠しモード**などと呼ばれており、教育版ソフトウェアで使用することができません。ここまでに紹介した反射光・周辺光・カラーモードとは違ってプログラム方法が特殊です。これは詳しく説明します。まずはプログラム方法から。

```app.c
void main_task(intptr_t unused)
{
　　rgb_raw_t rgb_val;//(1)

    /* コンフィグゾーン　*/
    ev3_sensor_config (0,COLOR_SENSOR);

    int rval=0;
    int gval=0;
    int bval=0;
    ev3_color_sensor_get_rgb_raw(0,&rgb_val);//(2)
    
    rval=rgb_val.r;//R値
    gval=rgb_val.g;//G値
    bval=rgb_val.b;//B値
}
```
まず、RGBモードで値を取得するには、EV3rtの特殊な変数を使用する必要があります。
型はrgb_raw_tです。つまり(1)でrgb_valという変数名で宣言をしています。
さて、その次にRGBで取得した値を格納するためのint変数を3つ宣言しておきます。

そして(2)の部分。これでRGBモードで値を取得します。ただし格納先は(1)の変数rgb_valです。ここからRGBのそれぞれの値に分解する必要があります。分解方法は(2)の下の部分。`(変数).r`とすると`R値`、`(変数).g`とすると`G値`、`(変数).b`とすると`B値`が取得できます。今回の例では取得した値を宣言しておいた3つの変数に格納しています。

【追記】
もう少しちゃんと専門的に書き直します。
`rgb_raw_t rgb_val;`ですが、これはrgb_raw_tという名前の構造体です。
続いて、`ev3_color_sensor_get_rgb_raw(0,&rgb_val);`の第二引数ですが、これは構造体のアドレスが引数として指定されています。よって、名前の前に`&`がついています。
('19/9/17 追記)

さてさて、RGBの値が取得できると何ができるか？
色判定ロジックを自分で作ることができるのです。
当たり前ですが赤色ブロックならRの値が高く、緑ブロックならGが高め、青ブロックならBが高め、という風になります。色判定させたい対象物の色データをRGBで先にロギングしておくことで、より精密な色判定ができるようになるのです。

私は以下のようなExcelファイルを自作して、ロジックを組んでいました。
3つの値を駆使して確実な色判定ソフトを作るのです。
![スクリーンショット 2018-09-10 14.15.31.png](https://qiita-image-store.s3.amazonaws.com/0/183170/f058da8b-330f-614e-128f-5e53ac532b08.png)
例えば、赤と黄はRの値が高いが緑と青は非常に低い。こういうのをif文で多重分岐してやって、特定するわけです。

以上で、EV3カラーセンサーの紹介は終わりです。


やべぇ書きすぎた…
#(ⅱ)タッチセンサー#
![41HWJ5U4BEL._SX425_.jpg](https://qiita-image-store.s3.amazonaws.com/0/183170/6ffe38c2-8cba-f1ff-56b8-0f424e11ef9a.jpeg)
あまりこの記事が長くなるとアレなのでここで小物を1つ紹介しておきましょう。
タッチセンサーは非常にシンプルなセンサーで、はじめてのプログラミングでよく使われますね。
上記のカラーセンサーと異なり、帰ってくる値は

- ON(押されている)
- OFF(離れている)

のどちらかということになるので、プログラム方法も簡単です。
基本的にはIf文で`True`か`False`を判断することとなるでしょう。

![スクリーンショット 2018-09-16 05.43.10.png](https://qiita-image-store.s3.amazonaws.com/0/183170/5e5124b5-660e-34fd-ec3e-29028143e5cd.png)

```app.c
void main_task(intptr_t unused)
{
    /* コンフィグゾーン　*/
    ev3_sensor_config (0, TOUCH_SENSOR);
    if(ev3_touch_sensor_is_pressed(0)==true){
        //処理
　　}
}
```

もちろん`ev3_touch_sensor_is_pressed`を使用して変数に格納することもできますが、
![スクリーンショット 2018-09-16 05.43.18.png](https://qiita-image-store.s3.amazonaws.com/0/183170/c2aa0b9a-b2bd-b9f0-7ba1-6b1089d75f31.png)
前に言ったとおりEV3rtの標準Cライブラリはbool型に対応していませんので、includeしなければいけません。(詳しくは第1回で)

#まとめ#
今回はカラーセンサーとタッチセンサーについて紹介しました。
次回も引き続きセンサーの紹介をしていきたいと思います。
また、Hitecnic Color Sensorについては別の番外編の記事で紹介しているので合わせて御覧ください。
[後輩たちのためのEV3rt講座番外編(HiTechnicカラーセンサーについて)](https://qiita.com/koushiro/items/058c1f18a5f5282e2817)

次回:[第4回](https://qiita.com/koushiro/items/d7fe9cf4f116d1f4f470)
前回:[第2回](https://qiita.com/koushiro/items/46b6a9a29df6d459a6e7)