できること

第51回 センサに反応して光る!フルカラーLEDテープを使ったイルミネーション電子工作 〜Arduinoでパーツやセンサーを使ってみよう

dsc_1759

前回はLEDテープの光らせ方の基本を学びました。今回は、センサから入力された値に応じて光り方が変わる、インタラクティブなイルミネーションを作ってみたいと思います!

今回の電子工作レシピ

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

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

目次

  1. センサ評価キットのセンサを使ってLEDテープを光らせる
  2. プログラムのカスタマイズについて
  3. 実際に光らせてみる
  4. まとめ

1.センサ評価キットのセンサを使ってLEDテープを光らせる

センサ評価キット本体をArduinoに装着して、センサパーツを取り付けます。第46回でも紹介した近接センサを使ってみます。完成のイメージは近接センサに手を近づけると、放射状に配置したLEDテープが手元から光を放つようなイメージで作成をしてみます。

写真1 センサ評価キットに近接センサを搭載

写真1 センサ評価キットに近接センサを搭載

いつもどおり下記の図にて、センサの取り付け箇所とセンサに必要な電圧を設定します。近接センサはI2C I/Fエリアなので青いエリアに取り付けを行い、ウェブサイトに必要電圧が書かれているのでそれを確認、近接センサは3Vなのでジャンパピンを真ん中の3Vの位置に設定します。

図1 センサ評価キットのセンサ取り付け箇所

図1 センサ評価キットのセンサ取り付け箇所

 

LEDテープの電源は前回と同様に5Vの電源を別に用意します。ArduinoのVCCや5Vから取ろうとすると、LEDテープで消費される電流が多い為、Arduinoが停止や故障してしまう可能性があるので注意してください。

 

写真2 LEDテープの電源は前回と同様に5Vの別の電源を確保します

写真2 LEDテープの電源は前回と同様にArduinoとは別に電源アダプタで5V電源を確保します

 

前回はLEDテープを1本だけつけましたが、今回はLEDテープを3本並列に接続します。接続方法は、並列なので1本の時と同じように信号線や電源、GNDは全て共通になります。接続して増やせる本数はLEDテープで実際に光らせるLEDの個数と、電源アダプターの電流容量によって変わります。

今回は、LEDテープのLED1個あたりで20mA程度、供給電流は1.3Aなので単純計算で65個くらいは一斉に点灯できますね。

図2 LEDテープの並列接続

図2 LEDテープの並列接続

 

写真2 Arduino本体から伸びるLEDテープ

写真2 Arduino本体から伸びるLEDテープ

ハード側の準備が整ったので、次はプログラムです。

 

2.プログラムのカスタマイズについて

フルカラーLEDテープを光らせるための信号制御は、「NeoPixel」というライブラリを使えば手軽にできることを前回紹介しました。今回も同様にNeoPixelを利用して進めていきます。

近接センサを入力にしたLEDテープ出力のプログラム

#include <Wire.h>
#include <RPR-0521RS.h>
#include <Adafruit_NeoPixel.h>


#define PIN 6       //信号端子のピン番号
#define LED_NUM 50  //LEDの数

RPR0521RS rpr0521rs;
Adafruit_NeoPixel ledtape = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);  //3つめのパラメータは使うLEDテープの制御ICがWS2812ならNEO_KHZ800 / WS2811ならNEO_KHZ400

int wait = 200;

void setup() {
  ledtape.begin();
  ledtape.show();   //一旦全てOFFの状態で反映
  
  byte rc;
  Serial.begin(9600);
  while (!Serial);
  Wire.begin();
  rc = rpr0521rs.init();
}

void loop() {
  byte rc;
  unsigned short ps_val;
  float als_val;
  byte near_far;
  Serial.println("=============================");
  
  rc = rpr0521rs.get_psalsval(&ps_val, &als_val);
  //センサの値が取得できたとき
  if (rc == 0) {
    Serial.print("PS:");
    Serial.print(ps_val);
    Serial.println();

    //近づいたときにLEDを発光させる
    if(ps_val > 5){
      ps_val  = 500 - ps_val;
      if(ps_val < 0){
         ps_val = 0;
      }
      simpleLED(ps_val/10);
    }
  
    if (als_val != RPR0521RS_ERROR) {
      Serial.print("ALS:");
      Serial.print(als_val);
      Serial.println();
    }
  }
  delay(5);  
}

int LEDtale[10];  //LEDの軌跡用配列

//
//個別で光らせる
//
void simpleLED(int delaytime){
  uint16_t i, j;
  j=0;
  for(i=0; i < ledtape.numPixels(); i++) {
    ledtape.setPixelColor(i, rotateColor(((i) * 256 / ledtape.numPixels()) & 255));
    LEDtale[0]  = rotateColor(((i) * 256 * 9/10 / ledtape.numPixels()) & 255);

    for(j=1; j < 10; j++){
      LEDtale[j]  = rotateColor(((i) * 256 * (10-j)/10 / ledtape.numPixels()) & 255);
      uint16_t m = i-j;
      if(m < 0){
        m += 50;
      }
      ledtape.setPixelColor(m, LEDtale[j]);
    }

    ledtape.show();
    for(j=1; j < 10; j++){
      uint16_t m = i-j;
      if(m < 0){
        m += 50;
      }
      delay(0);
      ledtape.setPixelColor(m, ledtape.Color(0,0,0));
      ledtape.show();
    }
    ledtape.setPixelColor(i, ledtape.Color(0,0,0));
    ledtape.show();
  }
  ledtape.show();
  delay(delaytime);
}


//RGBの色の移り変わり関数
uint32_t rotateColor(byte WheelPos) {
  if(WheelPos < 85) {
   return ledtape.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return ledtape.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return ledtape.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

 

前回のプログラムと変更点は大きく2点ほどあります。1つ目は、近接センサの入力処理を加えていること、2つ目はLEDテープの光り方を変えていることです。

1つ目の近接センサの入力はセンサ評価キットのサンプルスケッチおよび、以前の記事を確認していただければと思います。ポイントはセンサから入力された数値をどう扱うかですが、単純にif文などでセンサに反応があったらLEDテープを光らせるオン/オフだけでも良いのですが、センサの値をLEDテープを光らせる関数に渡して、LEDテープの光らせ方を変えるとより一層インタラクティブ感が演出できます。

//近づいたときにLEDを発光させる
    if(ps_val > 5){
      ps_val  = 500 - ps_val;
      simpleLED(ps_val/10); //センサの値をLEDテープの光らせ方に使う
    }

 

simpleLED関数がLEDテープを光らせる関数なのですが、LEDテープの始点から終点まで1つずつ光らせる処理にしています。ただ、それだと少し演出として弱いので、今回さらに配列を利用してLEDテープがある程度線状に光るようにしています。配列には、今現在光っているLEDの位置から数えて10個前まで光り方を配列に保存しておいて、光らせるようにしています。

int LEDtale[10];  //LEDの軌跡用配列

 

この光らせ方のプログラムは、実際にいろいろ試行錯誤しながら素敵!と思うような演出にカスタマイズしてみてください。

 

3.実際に光らせてみる

準備が整ったので、光らせてみます。

手を近づけるとLEDテープがほとばしっていますね。近づける距離が変わるとLEDテープからの光の速さも変わるようになっています。

また、暗い場所で光らせると手から光が放たれているようにみえますね。

 

まとめ

今回は、センサ評価キットと組み合わせて手軽にできるインタラクティブなイルミネーションを作ってみました。これを発展させて、照明デバイス作成の回で紹介したセンサを組み合わせて気温や湿度で色や光り方を変えたり、ひたすら大きく、LEDの数も多くするなど演出次第で大規模なイルミネーションもできちゃいます。

冬シーズンに向けて街中のイルミネーションに負けずにDIYイルミネーションデバイスを作ってみてはいかがでしょうか?

 

アバター画像

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

RoboMaster 2019 参戦ファーストステップガイド