#5 カラーセンサの使い方【SPIKE-RTでロボコンに出よう!!】

# 目次

https://qiita.com/koushiro/items/482162807339f4d18516

| 章 | タイトル | 内容 |
| :-: | :-: | :-: |
| 1 | [はじめに](#1-はじめに) | 今回やることの説明 |
| 2 | [カラーセンサの設定](#2-カラーセンサの設定) | 測定前のカラーセンサの設定 |
| 3 | [反射光・周辺光の測定](#3-反射光周辺光の測定) | 反射光・周辺光モードでの測定 |
| 4 | [RGBで色の測定](#4-rgbで色の測定) | RGBでの色の測定 |
| 5 | [HSVで色の測定](#5-hsvで色の測定) | HSVでの色の測定 |
| 6 | [ライトの設定](#6-ライトの設定) | カラーセンサのライトの設定 |
| 7 | [まとめ](#7-まとめ) | 今回のまとめ |

# 1. はじめに

前回はモータを動かすためのAPIを紹介しました。

ここから二回に渡りセンサの使い方を紹介していきます。
今回は、センサの中でも最も重要といっても過言ではない、**カラーセンサ**の使い方です。

カラーセンサのAPIの説明は以下のページに書かれています。本記事はそれをかみ砕いて、LEGO EducationのSPIKEソフトでの例も交えながら紹介していきます。

[SPIKE-RT C API Reference [Japanese] / カラーセンサ](https://spike-rt.github.io/spike-rt/ja/html/group__ColorSensor.html)

## カラーセンサの仕様

以下に示すのが、「SPIKEプライム カラーセンサー」 です。

![04_01-300x200.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/4086162f-a856-f7a9-9ed8-bd13fc1c60a2.jpeg)

中央部にあるフォトダイオードにより、色・反射光・周辺光りの測定が可能です。
又、フォトダイオードの周りにはLEDが3つ搭載されており、これらもプログラムにより光り方を変えることが出来ます。
詳しい仕様については以下👇をご覧ください。

https://afrel.co.jp/product/spike/technology-spike/prime/hardware/colorsensor/45911/

# 2. カラーセンサの設定

モータの時と同様に、センサを使う前には「ポート」と「カラーセンサ」の結びつけが必要です。

```c
pup_device_t *pup_color_sensor_get_device(pbio_port_id_t port);
```

関数名は`pup_color_sensor_get_device`で、「ポート」の情報により、「カラーセンサ」と「PUPデバイスポインタ」を結びつけます。
引数として、「ポート」を指定すると、戻り値として「PUPデバイスポインタ」が返ってきます。

使い方の例も示しておきます。

*Ex2-1. カラーセンサのセットアップ*

```c:spikert_5
#include <stdlib.h>
#include <stdio.h>
#include <kernel.h>

#include <spike/hub/system.h>

#include <color_test.h>

#include "spike/pup/motor.h"
#include "spike/pup/colorsensor.h"
#include "spike/pup/forcesensor.h"
#include "spike/pup/ultrasonicsensor.h"

#include "spike/hub/battery.h"
#include "spike/hub/button.h"
#include "spike/hub/display.h"
#include "spike/hub/imu.h"
#include "spike/hub/light.h"
#include "spike/hub/speaker.h"

#include <pbio/color.h>

#include "kernel_cfg.h"
#include "syssvc/serial.h"

pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);
}
```

はじめに`colorC`という名前で「PUPデバイスポインタ」を宣言しています。
`Main`関数に入ったら、`pup_color_sensor_get_device`関数により「ポートC」が「カラーセンサ」であると結び付けて、`colorC`に格納しています。

尚、前回もお伝えしましたが、ポートの定数`PBIO_PORT_ID_C`などを使うためには、内部のファイルを編集する必要があります。
編集方法については[前回の記事の2章](https://qiita.com/koushiro/items/0471376a9feb9b53b178#2-%E3%83%A2%E3%83%BC%E3%82%BF%E3%81%AE%E8%A8%AD%E5%AE%9A)をご覧ください。
ファイルの編集を避ける場合は、以下のようにポートを指定することも出来ます。

*Ex2-2. カラーセンサのセットアップ (ポート指定方法)*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device('C');
}
```

# 3. 反射光・周辺光の測定

ではカラーセンサの設定が出来たので、実際に値を測定していきましょう。
まずは、反射光と周辺光の測定方法からです。

## 反射光

反射光モードでは、カラーセンサのLEDを**点灯**させて、対象物から反射された光の強度を測定します。

```c
int32_t pup_color_sensor_reflection(pup_device_t *pdev);
```

関数名は`pup_color_sensor_reflection`で、反射光を測定します。
引数に「PUPデバイスポインタ」を入力すると、戻り値として「反射光」が整数値で返ってきます。

このモードですが、白地に引かれた黒線上をライントレースする時などには、色のことを考えなくて良いので有効です。

では、値を測定してディスプレイに表示する例を示します。

*Ex2-3. 反射光を測定する*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  while(1){
    int ref = pup_color_sensor_reflection(colorC);
    hub_display_number(ref);
  }
}
```

カラーセンサのセットアップを行った後、無限ループに入ります。
ループ内では、`pup_color_sensor_reflection`関数により反射光を測定し、変数`ref`に格納しています。
その変数の値を、`hub_display_number`関数を用いてハブディスプレイに表示しています。

## 周辺光

周辺光モードでは、カラーセンサのLEDを**消灯**させて、対象物の明るさを測定します。

```c
int32_t pup_color_sensor_ambient(pup_device_t *pdev);
```

関数名は`pup_color_sensor_ambient`で、周辺光を測定します。
引数に「PUPデバイスポインタ」を入力すると、戻り値として「周辺光」が整数値で返ってきます。

先ほど同様、値を測定してディスプレイに表示する例を示します。

*Ex3-1. 周辺光を測定する*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  while(1){
    int amb = pup_color_sensor_ambient(colorC);
    hub_display_number(amb);
  }
}
```

基本的には反射光の時と同様の構造で、カラーセンサのセットアップを行った後、無限ループに入り、ループ内で`pup_color_sensor_ambient`関数により周辺光を測定し、変数`amb`に格納しています。
その変数の値を、`hub_display_number`関数を用いてハブディスプレイに表示しています。

# 4. RGBで色の測定

いよいよ色の測定です。
色の測定方法にはいくつかの方法があるのですが、まずは **RGB** での測定方法から解説していきます。

## RGBとは

「色」には様々な表現があります。
「赤」や「青」という名前も色の表現の一つですが、その「赤」や「青」は人によって個人差がありますよね。

これを、数値によって定量的に表そうというのが「色空間」と呼ばれるものです。
この「色空間」にもさまざまな種類があり、それぞれに得意・不得意があるため、時と場合に応じて使い分けています。

それでは本題の **RGB色空間** ですが、光の三原色である<font color="Red">赤(Red)</font>、<font color="LimeGreen">緑(Green)</font>、<font color="DodgerBlue">青(Blue)</font>の混ざり具合で色を表現するものです。

![AdditiveColorMixing.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/9d0a7a45-8d91-3e0a-87eb-4bee14930589.png)

(出典: Wikipedia - RGB https://ja.wikipedia.org/wiki/RGB)

それぞれにパラメータがあり、<font color="Red">赤</font>であれば(255, 0, 0)、<font color="LimeGreen">緑</font>であれば(0, 255, 0)、<font color="DodgerBlue">青</font>であれば(0, 0, 255)のように表現されます。
(各パラメータごとに8bitでの表現を想定し、値の範囲は$0\sim255$)

https://ja.wikipedia.org/wiki/RGB

## 測定方法

では、測定するための関数を紹介します。

```c
pup_color_rgb_t pup_color_sensor_rgb(pup_device_t *pdev);
```

関数名は`pup_color_sensor_rgb`で、対象物の色をRGB形式で測定します。
引数には「PUPデバイスポインタ」を入力します。
戻り値として、R・G・Bそれぞれの値が返されるのですが、この時これらの値は`pup_color_rgb_t`という構造体で返されます。

ここで、構造体`pup_color_rgb_t`について、その定義を記しておきます。

```c
typedef struct {
  uint16_t r, g, b;
} pup_color_rgb_t;
```

構造体`pup_color_rgb_t`の中に、int型変数`r`、`g`、`b`が用意されています。

尚、色の測定と構造体の説明については、[EV3rtの記事](https://qiita.com/koushiro/items/86c8855c85c5a6658030#%E6%A7%8B%E9%80%A0%E4%BD%93%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)で詳しく説明しておりますので、そちらも是非ご覧ください。

では、測定した値をハブディスプレイに表示してい見たいと思います。

*Ex4-1. 色をRGBで測定する*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  while(1){
    // 色の検出 (trueならLED点灯)
    pup_color_rgb_t rgb = pup_color_sensor_rgb(colorC);

    char str[32];
    sprintf(str, "R:%d G:%d B:%d", rgb.r, rgb.g, rgb.b);
    hub_display_text_scroll(str, 100);
  }
}
```

先ほど同様セットアップを行った後、無限ループに入ります。
`pup_color_sensor_rgb`関数により測定した値を、構造体変数`rgb`に格納します。

ここで、ハブディスプレイに3桁以上の値を表示したいため、`hub_display_text_scroll`関数を使用しています。
ハブディスプレイの表示については別の回で詳しく解説しますが、ここでも簡単にだけ説明しておくと、char型配列`str`内に文字列を格納したいため、`sprintf`関数を用いております。
これにより完成した文字列`str`を`hub_display_text_scroll`関数に渡して、値を表示しています。

尚、`pup_color_sensor_rgb`により値が格納される際、値は正規化されておらず、私が確認する限り最大で900くらいの値が出ています。
よって、実際に使用する際にはパーセンテージ(混合の割合)に変換するなどして、正規化する必要があるかと思います。

例えばこんな感じ👇

*Ex4-2. 色をRGBで測定する(正規化済み)*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  while(1){
    // 色の検出 (trueならLED点灯)
    pup_color_rgb_t rgb = pup_color_sensor_rgb(colorC);

    double all = rgb.r + rgb.g + rgb.b;
    double r_rate = rgb.r / all;
    double g_rate = rgb.g / all;
    double b_rate = rgb.b / all;

    char str[32];
    sprintf(str, "R:%lf G:%lf B:%lf", r_rate, g_rate, b_rate);
    hub_display_text_scroll(str, 100);
  }
}
```

上記の例では、赤・緑・青の合計値を`all`に格納し、赤であれば元の値を`all`で割ることにより赤の混合割合を算出し、`r_rate`に保存しています。同様に、緑と青の混合割合も計算しています。
実際に上のサンプルなどで値を測定し、確かめてみて下さい。

# 5. HSVで色の測定

先ほどは色の表現方法として「RGB色空間」を用いましたが、ここからはまた別の色空間を使用していきます。
それが、**「HSV色空間」** です。

## HSV色空間

HSVとは **Hue (色相)** 、 **Saturation (彩度)** 、 **Value (明度)** の三要素で表す色空間です。
字面で見てもわかりにくいので、以下に図を示します。

![300px-HSV_cylinder.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/ff32f2fb-0e60-0c6c-7a24-42cadaa50618.jpeg)

(出典: Wikipedia - HSV色空間 https://ja.wikipedia.org/wiki/RGB)

https://ja.m.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93

まずHue(色相)ですが、これは**色の種類**を表しており、具体的には**色相環における角度**を表しています。
色は光の波長の違いにより変化しますが、これを連続的に繋げたものが色相環です。

測定においては、基準に対して何度差があるかを値として示します。
SPIKE-RTにおいては、赤の部分に基準($0$)が設定されており、以下のように値が変化していきます。

![Hue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/ea57c32a-225c-22ab-4e40-7e3c571c8998.png)

(あくまでイメージであるため、実際の測定値とは異なることがあります。)

続いてSaturation(彩度)は、**色の鮮やかさ**を表す値です。
視覚的に説明すると、上図の円柱の外側に行けば行くほど色がビビット(鮮明)になり、値は大きくなります。
一方、円柱の内側に行けば行くほど色はくすみ、値は小さいくなります。
値の範囲は$0 \sim 100$です。

最後にValue(明度)は、**色の明るさ**を表す値です。
こちらも上図で説明すると、円柱の高さ方向が明度に相当し、円柱の上の方へ行くほど明るくなり、値は大きくなります。
一方、底の方へ行くほど色は黒くなり、値は小さくなります。
こちらも値の範囲は$0 \sim 100$です。

## 測定方法

では、測定するための関数を紹介します。

```c
pup_color_hsv_t pup_color_sensor_hsv(pup_device_t *pdev, bool surface);
```

関数名は`pup_color_sensor_hsv`で、対象物の色をHSV形式で測定します。
第一引数には「PUPデバイスポインタ」を入力します。
又、第二引数はLEDの点灯状況を指定するもので、`True`なら点灯、`False`であれば消灯します。
戻り値として、H・S・Vそれぞれの値が返されるのですが、この時これらの値は`pup_color_hsv_t`という構造体で返されます。

ここで、構造体`pup_color_hsv_t`について、その定義を記しておきます。

```c
/** HSV color. */
typedef struct {
    /** The hue component. 0 to 359 degrees. */
    uint16_t h;
    /** The saturation component. 0 to 100 percent. */
    uint8_t s;
    /** The value component. 0 to 100 percent. */
    uint8_t v;
} pbio_color_hsv_t;

typedef pbio_color_hsv_t pup_color_hsv_t;
```

構造体`pup_color_hsv_t`は、もともと別で存在する構造体`pbio_color_hsv_t`をリネームしたもので、その`pbio_color_hsv_t`はメンバとしてint型変数`h`(範囲$0\sim359$)、`s`(範囲$0\sim100$)、`v`(範囲$0\sim100$)を持っています。

ではRGBの時と同様に、測定した値をハブディスプレイに表示してい見たいと思います。

*Ex5-1. 色をHSVで測定する*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  while(1){
    // 色の検出 (trueならLED点灯)
    pup_color_hsv_t hsv = pup_color_sensor_hsv(colorC, true);

    char str[32];
    sprintf(str, "H:%d S:%d V:%d", hsv.h, hsv.s, hsv.v);
    hub_display_text_scroll(str,100);
  }
}
```

カラーセンサの設定を行った後無限ループに入り、HSVでの測定を行います。
測定した値は構造体変数`hsv`に入るため、それらを`sprintf`関数内で取り出し、char型配列`str`に格納してハブディスプレイへ表示できるようにしています。

この`pup_color_sensor_hsv`関数を使う方法が基本の測り方になるかと思います。
Hueの値を用いて、「ここからここまでの値の範囲であれば<font color="Red">赤</font>」のような条件分岐を作ることで色判定が可能になります。
ただし、白や黒といった、Hueの変化に現れない色を判定したい場合は、他のSaturationやValueの値も使う必要があるでしょう。

ちなみに、HSVの色判定については以下の記事で詳しく解説されています。
下記の記事はmicroPython用に書かれたもので言語が異なりますが、考え方自体は同じなのでぜひ参考にしてみてください。

https://nlabs-hack.com/%E3%80%90%E8%89%B2%E8%AA%AD%E3%81%BF%E3%80%91rgb%E5%80%A4%E3%82%92hsv%E8%89%B2%E7%A9%BA%E9%96%93%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%A6%E8%89%B2%E8%AA%AD%E3%81%BF/

## 測定可能な色を限定する

さて、先ほどはHSVの値をそのまま取得しましたが、SPIKE-RTには測定可能な色を限定してHSVを取得する関数があります。
まずは以下にその関数を示します。

```c
pup_color_hsv_t pup_color_sensor_color(pup_device_t *pdev, bool surface);
```

関数名は`pup_color_sensor_color`で、対象物の色をHSV形式で測定します。
ただし、HSVの値は、事前に設定した色に限定して返されます。
引数、および戻り値に関しては`pup_color_sensor_hsv`関数と全く同じです。

ここで、「測定可能な色が限定される」の部分について、もう少し詳しく記したいと思います。
`pup_color_sensor_color`関数を使うにあたり、内部で「特定の色のHSV値」が定義されています。

```c
pup_color_hsv_t cb_color_map_default[] = {
    { PBIO_COLOR_HUE_RED, 100, 100 }, // Red
    { PBIO_COLOR_HUE_YELLOW, 100, 100 }, // Yellow
    { PBIO_COLOR_HUE_GREEN, 100, 100 }, // Green
    { PBIO_COLOR_HUE_BLUE, 100, 100	}, // Blue
    { 0, 0, 100	}, // White
    { 0, 0, 0	}, // None
};
```

HSVを格納するための構造体`pup_color_hsv_t`を用いて、構造体配列`cb_color_map_default`が定義されています。
上から順番に、赤・黄・緑・青・白・無しのHSV値が定義されています。

尚、各色の定数についても以下のように定義されています。
```c
typedef enum {
    /** Red. */
    PBIO_COLOR_HUE_RED = 0,
    /** Orange. */
    PBIO_COLOR_HUE_ORANGE = 30,
    /** Yellow. */
    PBIO_COLOR_HUE_YELLOW = 60,
    /** Green. */
    PBIO_COLOR_HUE_GREEN = 120,
    /** Spring green. */
    PBIO_COLOR_HUE_SPRING_GREEN = 150,
    /** Cyan. */
    PBIO_COLOR_HUE_CYAN = 180,
    /** Blue. */
    PBIO_COLOR_HUE_BLUE = 240,
    /** Violet. */
    PBIO_COLOR_HUE_VIOLET = 270,
    /** Magenta. */
    PBIO_COLOR_HUE_MAGENTA = 300,
} pbio_color_hue_t;
```

その上で`pup_color_sensor_color`関数ですが、対象物のHSV値を測定した後、`cb_color_map_default`の各値と比較して、一番近い組み合わせのHSV値に変換して返します。

例えば、得られたHSV値が$(10, 80, 80)$のとき、一番近いHSV値の組み合わせは赤の$(0, 100, 100)$となります。従って、戻り値は$(0, 100, 100)$となります。

この関数を使うことで、得られる値が限定されるので、条件分岐がやりやすくなるかと思います。
例えば👇こんな感じ

```c
pup_color_hsv_t hsv = pup_color_sensor_color(colorC, true);

if(hsv.v == 0){
    // 無し
}
else if(hsv.s == 0){
    // 白
}
else if(hsv.h == PBIO_COLOR_HUE_RED){
    // 赤
}
else if(hsv.h == PBIO_COLOR_HUE_YELLOW){
    // 黄
}
else if(hsv.h == PBIO_COLOR_HUE_GREEN){
    // 緑
}
else if(hsv.h == PBIO_COLOR_HUE_BLUE){
    // 青
}
else{
    // エラー状態
}
```

HSVの生値の場合、条件式は不等号を用いて範囲で指定する必要がありますが、`pup_color_sensor_color`関数では得られる値の組み合わせが分かっているため、条件式も簡略化出来ます。

## 測定可能色の再定義

`pup_color_sensor_color`関数を用いると、測定可能な色を限定できることをお話しましたが、事前に定義された色の組み合わせ`cb_color_map_default`が必ずしもそれぞれの環境で適合するとは限りません。
そこで、測定可能な色を自分で再定義することが出来るので、その方法を紹介します。

まず`cb_color_map_default`と同じ要領で、構造体`pup_color_hsv_t`で構造体配列を宣言します。

```c
pup_color_hsv_t color_map_edit[] = {
    { 352, 91, 95 }, //Red
    { 56, 53, 100 }, //Yellow
    { 155, 62, 46 }, //Green
    { 212, 93, 72 }, //Blue
    { 195, 80, 97 }, // Skyblue
    { 345, 76, 50 }, // Purple
    { 0, 5, 80 }, //White
    { 0, 0, 0 },//None
};
```

今回は、`color_map_edit`という配列名で、上記の8色分HSV値の組み合わせを定義しました。
ここでのHSV値は、`pup_color_sensor_hsv`関数を用いてHSVの生値を測定して決めました。
尚、色の組み合わせは30色まで定義可能です。

次に、定義した構造体配列を元に、測定可能色を再定義していきます。
そこで使うのが、以下の関数です。

```c
pup_color_hsv_t *pup_color_sensor_detectable_colors(int32_t size, pup_color_hsv_t *colors);
```

関数名は`pup_color_sensor_detectable_colors`で、`pup_color_sensor_color`関数で測定可能な色を再定義します。
第一引数には、再定義に用いる構造体配列の色の組み合わせの数を入力します。
第二引数には、再定義に用いる構造体配列を指定します。

それでは、構造体配列の定義から測定可能色の再定義、そこからHSVの測定までの流れを示したいと思います。

*Ex5-2. 色をHSVで測定する(測定色限定)*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);
  
  pup_color_hsv_t color_map_edit[] = {
    { 352, 91, 95 }, //Red
    { 56, 53, 100 }, //Yellow
    { 155, 62, 46 }, //Green
    { 212, 93, 72 }, //Blue
    { 195, 80, 97 }, // Skyblue
    { 345, 76, 50 }, // Purple
    { 0, 5, 80 }, //White
    { 0, 0, 0 },//None
  };

  pup_color_sensor_detectable_colors(8, color_map_edit);

  while(1){
    // 色の検出 (trueならLED点灯)
    pup_color_hsv_t hsv = pup_color_sensor_color(colorC, true);
    char str[32];
    sprintf(str, "H:%d S:%d V:%d", hsv.h, hsv.s, hsv.v);
    hub_display_text_scroll(str,100);
  }
}
```

構造体配列`color_map_edit`として、測定色を8色分定義した後、`pup_color_sensor_detectable_colors`関数を実行して測定可能色を再定義しています。

その後は無限ループに入り、`pup_color_sensor_color`関数を実行して色を測定し、ハブディスプレイに表示しています。

この測定可能色再定義→限定色測定の流れを使うと、かなりの精度で色判定を正確に行えるのではと思います。
ただし、測定可能色を増やせば増やすほど、意図しない色に判定されたりもするので、これらは自分で良い塩梅を見極める必要があります。

# 6. ライトの設定

最後に小ネタとして、カラーセンサのライトの制御について解説しておきます。
SPIKE Primeのカラーセンサには、3つのLEDが入っています。
これらのLEDの点灯・消灯・および点灯時の明るさ(パーセント)を個別に指定することが出来ます。

![color_led.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183170/739d267f-327f-55db-e40f-ce7b7ac9f34a.jpeg)

## ライト全消灯

まずは、3つのLEDを全て消す関数です。

```c
pbio_error_t pup_color_sensor_light_off(pup_device_t *pdev);
```

関数名は`pup_color_sensor_light_off`で、3つのLEDを全て消灯します。
引数には「PUPデバイスポインタ」を入力します。

この関数を実行することで、「PUPデバイスポインタ」により指定したポートのカラーセンサのLEDを全消灯します。

## ライト全点灯

続いて、3つのLEDを全て点ける関数です。

```c
pbio_error_t pup_color_sensor_light_on(pup_device_t *pdev);
```

関数名は`pup_color_sensor_light_on`で、3つのLEDを全て点灯します。
引数には「PUPデバイスポインタ」を入力します。

この関数を実行することで、「PUPデバイスポインタ」により指定したポートのカラーセンサのLEDを全点灯します。
また、この時の明るさは指定できる最大の値(100%)で、デフォルトの状態よりもかなり明るいです。

## ライトの明るさを個別に指定

最後に、LEDを1個ずつ個別に明るさを変更する関数です。

```c
pbio_error_t pup_color_sensor_light_set(pup_device_t *pdev, int32_t bv1, int32_t bv2, int32_t bv3);
```

関数名は`pup_color_sensor_light_set`で、LEDを1個ずつ個別に明るさを変更します。
第一引数には「PUPデバイスポインタ」を入力します。
第二・三・四引数には、それぞれのLEDでの明るさを$0\sim100$の範囲で指定します。

これらの関数の使い方についても簡単に例をしめしておきます。

*Ex6-1. カラーセンサのLEDを設定*

```c
pup_device_t *colorC;

void Main(intptr_t exinf)
{
  colorC = pup_color_sensor_get_device(PBIO_PORT_ID_C);

  pup_color_sensor_light_off(colorC); // 全部消す
  dly_tsk(3*1000*1000);

  pup_color_sensor_light_on(colorC); // 全部MAXで点ける
  dly_tsk(3*1000*1000);

  pup_color_sensor_light_set(colorC, 10, 10, 10); // 任意の値で点ける
  dly_tsk(3*1000*1000);

  pup_color_sensor_light_set(colorC, 100, 0, 0); // LED一つだけを点灯することも出来る
  dly_tsk(3*1000*1000);
}
```

これらの関数について、実用性があるのかは微妙ですが、APIとして用意されているので紹介しました。

# 7. まとめ

今回は、センサの中でもかなり重要なカラーセンサの使い方を解説しました。
関数の種類も沢山あり、何から使えばいいか迷う(困る)ところですが、状況に応じて使い分けられるようになりましょう。

次回はカラーセンサ以外の他のセンサを紹介します。
フォースセンサ(力センサ)と、超音波センサの2つですね。

前回: [#4 モータの使い方](https://qiita.com/koushiro/items/0471376a9feb9b53b178)
次回: [#6 フォースセンサと超音波センサの使い方](https://qiita.com/koushiro/items/02ee8221aabec0ba1d4c)