M5Stackとカラーセンサでカラーピッカーとカラーミキサーを作る

はじめに

先日開催されたROHM OPEN HACK CHALLENGE2018の最終審査に関するツイートが私のタイムラインに流れてきました。
open.rohm.com


どの作品も素晴らしいものでしたが、私が特に好きだったものは優秀賞に選ばれた『絵の具カラーピッカー「絵のピック」』でした。


「絵のピック」について簡単に説明すると、カラーセンサで対象の色を読み取り、読み取った色を実際に絵の具を使用して作ってくれるものです。(詳細は下記参照)
open.rohm.com

この作品を見て、私も似たようなものを作りたいと思いましたが、なかなか実現することが難しいため、簡易的に、かつ似たようなことが出来るものをM5Stackとカラーセンサを用いて作りましたのでご紹介します。

完成品

今回作成した機能は2つです。
1つ目の機能は色の読み取りです(カラーピッカー)。こちらはカラーセンサを用いて実現しています。読み取った色をディスプレイに表示しています。



2つ目の機能は読み取った2つの色を混ぜることです(カラーミキサー)。1つ目の機能を用いて色を2回読み取り、それらを混ぜ合わせた色をディスプレイに表示しています。


開発環境

準備物

  • M5Stack Gray

M5Stack Gray(9軸IMU搭載)

M5Stack Gray(9軸IMU搭載)

※M5Stackであればどのシリーズ(Basic,FIRE等)でも問題ないと思います。

  • カラーセンサ

  • ジャンパーワイヤ(オス-メス)

前提

Arduino IDEによるM5Stackの開発環境の構築が出来ている方を対象としています。

1.M5Stackとカラーセンサを繋ぐ

カラーセンサの接続に関して、こちらを参考に繋ぎました。
nn-hokuson.hatenablog.com

私は以下のようにカラーセンサとM5Stackを繋ぎましたが、M5Stackのピンの仕様について理解できていないのでこれが正しいかは保証できません。ご了承ください。

カラーセンサ M5Stack
S0 1
S1 16
S2 17
S3 21
OUT 22
VCC 5V
0E G
GND G

2.キャリブレーション用のスケッチ例

1.で参考にした記事より引用

センサから得られる値はお使いの環境で多少変化すると思うので、キャリブレーションする必要があります。
白色の紙をセンシングした時のRGB値と、黒色の紙をセンシングした時のRGB値を調べて、whiteRGB、blackRGBの値に代入して下さい。


よって、まずは下記のスケッチを書き込み、キャリブレーションします。こちらも先程の記事内のスケッチを参考にしております。

#include <M5Stack.h>

#define S0 1
#define S1 16
#define S2 17
#define S3 21
#define sensorOut 22

void setup() {
  M5.begin();
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);
  
  Serial.begin(9600);
}

void loop(void) {
   
  if (M5.BtnA.wasPressed()){
    digitalWrite(S2,LOW);
    digitalWrite(S3,LOW);
    int r = pulseIn(sensorOut, LOW);
    //r = map(constrain(r,blackR,whiteR), whiteR, blackR,0,255);
    delay(100); 
  
    digitalWrite(S2,HIGH);
    digitalWrite(S3,HIGH);
    int g = pulseIn(sensorOut, LOW);
    //g = map(constrain(g,blackG,whiteG), whiteG, blackG,0,255);
    delay(100); 
    
    digitalWrite(S2,LOW);
    digitalWrite(S3,HIGH);
    int b = pulseIn(sensorOut, LOW);
    //b = map(constrain(b,blackB,whiteB), whiteB, blackB,0,255);
    delay(100); 

    Serial.println(String(r) + "," + String(g) + "," + String(b) );
  }
  M5.update();
}


対象物にカラーセンサを当ててM5Stackの左のボタンを押すことでシリアルモニタにRGB値が表示されます。

3.カラーピッカーとカラーミキサーのスケッチ例

下記のスケッチを書き込みます。2.で検出したwhiteRGB、blackRGBにそれぞれ変更してから書き込んでください。

#include <M5Stack.h>

#define S0 1
#define S1 16
#define S2 17
#define S3 21
#define sensorOut 22

int whiteR = 151;
int whiteG = 160;
int whiteB = 120;
int blackR = 14;
int blackG = 14;
int blackB = 11;

boolean flag = false;
int beforeR = 0;
int beforeG = 0;
int beforeB = 0;
int r = 0;
int g = 0;
int b = 0;
int alpha = 128;

uint16_t getColor(uint8_t red, uint8_t green, uint8_t blue){
  return ((red>>3)<<11) | ((green>>2)<<5) | (blue>>3);
}

void setup() {
  M5.begin();
  M5.Lcd.setBrightness(200);
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  
  digitalWrite(S0,HIGH);
  digitalWrite(S1,LOW);
  
  Serial.begin(9600);
}

void loop(void) {
   
  if (M5.BtnA.wasPressed()){
    beforeR = r;
    beforeG = g;
    beforeB = b;
      
    digitalWrite(S2,LOW);
    digitalWrite(S3,LOW);
    r = pulseIn(sensorOut, LOW);
    r = map(constrain(r,blackR,whiteR), whiteR, blackR,0,255);
  
    digitalWrite(S2,HIGH);
    digitalWrite(S3,HIGH);
    g = pulseIn(sensorOut, LOW);
    g = map(constrain(g,blackG,whiteG), whiteG, blackG,0,255);
    
    digitalWrite(S2,LOW);
    digitalWrite(S3,HIGH);
    b = pulseIn(sensorOut, LOW);
    b = map(constrain(b,blackB,whiteB), whiteB, blackB,0,255);

    Serial.println(String(r) + "," + String(g) + "," + String(b) );
    M5.Lcd.fillScreen(getColor(r,g,b));
  }else if(M5.BtnB.wasPressed()){
    M5.Lcd.fillScreen(getColor(r*((double)alpha/255)+beforeR*(1-(double)alpha/255),g*((double)alpha/255)+beforeG*(1-(double)alpha/255),b*((double)alpha/255)+beforeB*(1-(double)alpha/255)));
  }
  
  M5.update();
}


左のボタンを押すことで色の読み取り、2つの色を読み取った後に真ん中のボタンを押すことで2色を混ぜた後の色がディスプレイに表示されます。


スケッチ作成時に参考にしたもの
qiita.com

oshiete.goo.ne.jp

おわりに

M5Stackとカラーセンサでカラーピッカーとカラーミキサーを作る方法をご紹介しました。

現実世界に存在する色を読み取ってディスプレイに表示できるだけでも楽しいので、良ければ試してみてください。