できること

第42回 Arduinoでカラーセンサ! 〜Arduino+センサの開発が劇的に楽になる!ローム・センサ評価キットを試してみた

DSC_0196

Arduino+各種センサの電子工作が「劇的」にラクになるとウワサのロームセンサ評価キット

前回までは、地磁気センサを使って、そのベーシックな使い方を学びました。引き続き今回は、これまでの連載では一度もさわっていない、「カラーセンサ」を通して、さらにウワサを検証していきます。

今回の電子工作レシピ

完成までの時間目安:60分
必要なパーツ

※ロームセンサ評価キットは下記サイトから購入できます!
チップワンストップ
ザイコストア

カラーセンサとは?

その名のとおり、色のデータを取得することができるセンサーです。カラーセンサは他に「色センサ」、「色識別センサ」、「色判別センサ」、「デジタルカラーセンサ」などとも呼ばれることが多いようです。カラーセンサのしくみは、可視光を内部の赤(R)、緑(G)、青(B)のそれぞれのセンサにフィルタをかけて信号を分けることでデータを取得できるようになっています。

ロームセンサ評価キットでは、カラーセンサモジュールとして「BH1745NUC」が搭載されています。

写真1 カラーセンサモジュールBH1745NUC

写真1 カラーセンサモジュールBH1745NUC

写真2 カラーセンサモジュールBH1745NUC

写真2 カラーセンサモジュールBH1745NUC

 

カラーセンサを試してみる

さっそく、カラーセンサをArduinoで使ってみたいと思います。

 

カラーセンサの取り付け

カラーセンサの取り付けは、以下の図を参考に確認すると、地磁気センサ同様、I2C I/Fエリアですね。電源電圧は、地磁気センサの場合1.8Vでしたが、カラーセンサでは、3Vなので、左上の電源電圧の切り替えジャンパピンを差し替えて3Vのところにセットします。

図1 センサシールドの接続方法解説

図1 センサシールドの接続方法解説

 

写真3 カラーセンサを取り付け

写真3 カラーセンサを取り付け

 

取り付けが完了したら、Arduinoのプログラム側を設定していきます。

カラーセンサ用のライブラリのインストール

こちらも地磁気センサの時と同様にセンサを利用するためのライブラリをインストールします。カラーセンサの解説ページの下部からソフトウェアのダウンロードより、ライブラリファイルをダウンロードします。

図2 カラーセンサ用ライブラリのダウンロード

図2 カラーセンサ用ライブラリのダウンロード

 

ファイルがダウンロードできたら、Arduino IDEを開いてライブラリの追加から、ダウンロードしたファイル「BH1745NUC.zip」を選択すれば、カラーセンサの動作準備が完了です。

写真9 ライブラリの追加

写真4 ライブラリ「BH1745NUC」の追加

 

ライブラリの追加が無事完了していると、「スケッチの例」および、「ライブラリを使用」の欄にBH1745NUCの表記が確認できます。

写真4 ライブラリにBH1745NUCが追加される

写真5 ライブラリにBH1745NUCが追加される

 

カラーセンサのサンプルスケッチを動かす

スケッチの例から、BH1745NUCのサンプルスケッチプログラムを呼び出します。このプログラムは、単純にカラーセンサで取得した値を表示するプログラムです。
※サンプルスケッチのコンパイルが通らない場合、Arduino IDEが古い可能性がありますので、最新のArduino IDEでお試しください。

BH1745NUCのサンプルスケッチプログラム

/*****************************************************************************
 BH1745NUC.ino

 Copyright (c) 2016 ROHM Co.,Ltd.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
******************************************************************************/
#include <Wire.h>
#include <BH1745NUC.h>

BH1745NUC bh1745nuc(BH1745NUC_DEVICE_ADDRESS_39);

void setup() {
 byte rc;

 Serial.begin(9600);
 while (!Serial);
 
 Wire.begin();
 
 rc = bh1745nuc.init();
}

void loop() {
 byte rc;
 unsigned short rgbc[4];
 
 rc = bh1745nuc.get_val(rgbc);
 if (rc == 0) {
 Serial.write("BH1745NUC (RED) = ");
 Serial.println(rgbc[0]);
 Serial.write("BH1745NUC (GREEN) = ");
 Serial.println(rgbc[1]);
 Serial.write("BH1745NUC (BLUE) = ");
 Serial.println(rgbc[2]);
 Serial.write("BH1745NUC (CLEAR) = ");
 Serial.println(rgbc[3]); 
 Serial.println();
 }
 delay(500);
}

 

写真5 カラーセンサのサンプルプログラム動作結果

写真6 カラーセンサのサンプルプログラム動作結果

 

シリアルモニタに表示される数値を見ると、RED、GREEN、BLUEに加えてCLEARの表記がありますね。このCLEARは可視光の波長の強さを取得できる値になります。シリアルモニタを眺めながら色のついたものをセンサに近づけたり光を近づけたりすると、センサの値が変化するのがわかると思います。センサを覆い隠してしまうと、光自体がセンサに入らないため、CLEARの値が小さくなります。その場合は、RGBの数値も小さくなって色の判別が難しそうです。それとは逆にカラーLEDなどでセンサを照らしてみると数値は10,000を超えて検出することができました。カラーLEDなどで入力するには相性がよさそうです。

 

カラーセンサで色を解析してフルカラーLEDで表示してみる

では、サンプルでカラーセンサの動作が確認できたら、それを使って応用してみたいと思います。まずは、きちんと色データを扱えるようにするために、カラーセンサで色を判別→判別した色をフルカラーLEDで表示するというシンプルな回路を作ってみたいと思います。

カラーセンサの値をフルカラーLEDで表現するスケッチプログラム

#include <Wire.h>
#include <BH1745NUC.h>

BH1745NUC bh1745nuc(BH1745NUC_DEVICE_ADDRESS_39);

void setup() {
  byte rc;

  Serial.begin(9600);
  while (!Serial);
  
  Wire.begin();
  
  rc = bh1745nuc.init();

  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}

void loop() {
  byte rc;
  unsigned short rgbc[4];
  
  rc = bh1745nuc.get_val(rgbc);

  int rVal  = 0;
  int gVal  = 0;
  int bVal  = 0;

  int maxVal  = 0;
  if (rc == 0) {
    for(int i=0;i&amp;amp;lt;3;i++){
      if(maxVal &amp;amp;lt; rgbc[i]){
        maxVal  = rgbc[i];
      }
    }

    rVal  =  (float(rgbc[0])/maxVal)*255;
    gVal  =  (float(rgbc[1])/maxVal)*255;
    bVal  =  (float(rgbc[2])/maxVal)*255;

    Serial.print(rVal);   
    Serial.print(",");
    Serial.print(gVal);
    Serial.print(",");
    Serial.print(bVal);
    Serial.print(",");
    Serial.print(rgbc[3]);
    Serial.println("  ");

  }
  analogWrite(9,rVal);
  analogWrite(10,gVal);
  analogWrite(11,bVal);
  delay(500);
  analogWrite(9,LOW);
  analogWrite(10,LOW);
  analogWrite(11,LOW);
  delay(500);
}


for(int i=0;i<3;i++){
if(maxVal < rgbc[i]){
maxVal = rgbc[i];
}
}
rVal = (float(rgbc[0])/maxVal)*255;
gVal = (float(rgbc[1])/maxVal)*255;
bVal = (float(rgbc[2])/maxVal)*255;

このプログラムでは、サンプルプログラムの一部を改変しています。赤色で指定した部分で、RGBで一番大きな値を取得して、それを最大値(maxVal)として変数に確保した上で、その最大値と比較したRGBそれぞれの色の強さの割合を算出(float(rgbc[0])/maxValの部分)しています。そして、AnalogWriteは0~255までの値を出力できるので、色の強さの割合にAnalogWriteの最大値255をかけてやることで、検出した色を大まかにRGBに置き換えてフルカラーLEDに出力するようにしています。

試用するフルカラーLEDの特性にもよりますが、RGBそれぞれの値がうまく反映されないときは、LEDの抵抗値を調整するか、プログラム側で小さい値は無視するなどの工夫をしてみることで段階にわけた色の取得ができるかと思います。下のプログラムでは赤色文字の部分でそれぞれの値が50以下の場合、値を無視する=0にする処理を加えてみました。


//それぞれの色の閾値を設定
if(rVal < 50){
rVal = 0;
}
if(gVal < 50){
gVal = 0;
}
if(bVal < 50){
bVal = 0;
}

カラーセンサの値をフルカラーLEDで表現するスケッチプログラム2

#include <Wire.h>
#include <BH1745NUC.h>

BH1745NUC bh1745nuc(BH1745NUC_DEVICE_ADDRESS_39);

void setup() {
  byte rc;

  Serial.begin(9600);
  while (!Serial);
  
  Wire.begin();
  
  rc = bh1745nuc.init();

  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
}

void loop() {
  byte rc;
  unsigned short rgbc[4];
  
  rc = bh1745nuc.get_val(rgbc);

  int rVal  = 0;
  int gVal  = 0;
  int bVal  = 0;

  int maxVal  = 0;
  if (rc == 0) {

    for(int i=0;i&amp;amp;lt;3;i++){
      if(maxVal &amp;amp;lt; rgbc[i]){
        maxVal  = rgbc[i];
      }
    }

    rVal  =  (float(rgbc[0])/maxVal)*255;
    gVal  =  (float(rgbc[1])/maxVal)*255;
    bVal  =  (float(rgbc[2])/maxVal)*255;

    //それぞれの色の閾値を設定
    if(rVal &amp;amp;lt; 50){
      rVal = 0;
    }
    if(gVal &amp;amp;lt; 50){
      gVal = 0;
    }
    if(bVal &amp;amp;lt; 50){
      bVal = 0;
    }

    Serial.print(rVal);   
    Serial.print(",");
    Serial.print(gVal);
    Serial.print(",");
    Serial.print(bVal);
    Serial.print(",");
    Serial.print(rgbc[3]);
    Serial.println("  ");

  }
  analogWrite(9,rVal);
  analogWrite(10,gVal);
  analogWrite(11,bVal);
  delay(100);
}

 

こちらのほうだと、色がはっきり反映されているのがわかりますね。全体として、やはりこれまでよりさくっとお手軽に動くモノができた印象です。

まとめ

カラーセンサ、使い方次第でなにやら面白そうなことができそうですね。次回は、カラーセンサに加えて、気圧センサや温度センサなど複数のセンサを組み合わせて、ちょっと知的な照明デバイスを作成してみたいと思います!

アバター画像

電子工作や新しいデバイスをこよなく愛するエンジニア。日常生活のちょっとしたことを電子工作で作って試して、おもしろく過ごしたいと日々考えています。

高専ロボコン2019出場ロボット解剖計画