フルカラーLEDリングの自作(?)とArduino制御

 th_led-ring-10

フルカラーのLEDリングをArduinoで制御したくなって探してみたのですが、

こういうのや、

こういうのはあるのですが、自分が欲しいサイズのものが見当たりません。もうちょい大きいのが欲しいのですが、

かといって、これじゃあデカ過ぎです。

どうしよーかなーと思っていたところ、

2年前ぐらいにこんなのを買って放置していたのを思い出しました。これを細かく切って円形に並べてやれば、間隔はだいぶ大きくなってしまいそうですが、自分の希望するサイズのものにはできそうです。

ということで、やってみました。

 th_led-ring-1

とりあえず自分の欲しいサイズの円を描いて、

th_led-ring-2

その周りに一個一個切り離したLEDテープを並べます。この後半田付けするので、セロテープで仮止めしています。

th_led-ring-3

短く切った導線の芯を、一番内側のGNDを繋ぐように並べて、セロテープで仮止めします。このとき、Arduinoとの接続線を後でつけるために、一箇所だけ導線をつけずに開けておきます(写真右側)。

th_led-ring-4

半田付け。表面上での半田付けのため、後で簡単にポロっと外れてしまうことがあるので注意です。

th_led-ring-5

th_led-ring-6

同様に、信号線と5V線も半田付けしていきます。

th_led-ring-7

一箇所開けていた部分に、電源線、信号線、GND線を半田付けして、

th_led-ring-8

半田付けしている部分を絶縁テープで補強して完成。本当は円周上で線がむき出しになっているところもテープで覆った方が良いと思うのですが、一旦はこのままで進めます。

 th_led-ring-9

配線はこれだけ。光らせ方を切り替えるためのタクトスイッチはつけていますが、抵抗とかは(Arduinoの内部プルアップを使えば)不要なので、とてもシンプルです。

 

続いて、Arduinoの方のプログラムを書きます。まずはこちらからAdafruitのNeoPixel用のライブラリをダウンロードしてきて、Arduinoのlibrariesフォルダに突っ込みます。

基本的な使い方はスイッチサイエンスさんのこちらの記事がとても参考になります。この内容と、ライブラリに含まれるサンプルスケッチを参考にしながら、以下の2つを切り替えて光らせられるようにしました。

  1. すべてを白色にして、ゆっくり明るさを変化させる
  2. 緑色の円を描く

ソースコードはこんな感じです。

#include <Adafruit_NeoPixel.h>

#define NUM_OF_LED  8
#define BRIGHTNESS_MAX 128

#define MODE_PIN  8
#define CONTROL_PIN 9

#define MODE_0_INTERVAL 40 // ms
#define MODE_1_INTERVAL 20 // ms

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip)
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_OF_LED, CONTROL_PIN, NEO_GRB + NEO_KHZ400);

unsigned long last_control_time = 0;
uint8_t last_mode = HIGH;
uint8_t mode = -1;
boolean mode_changed = false;
int r = 0;
int g = 0;
int b = 0;
uint8_t led_index = 0;
boolean mode_1_up = true;

void setup() {
  pinMode(MODE_PIN, INPUT_PULLUP);
  pixels.begin();
  pixels.show(); // Initialize all pixels to 'off'
}

void loop(){
  uint8_t select_mode = digitalRead(MODE_PIN);
  if(last_mode == HIGH && select_mode == LOW){
    mode++;
    if(mode == 3){
      mode = 0;  
    }
    mode_changed = true;
  }
  last_mode = select_mode;

  unsigned long now = millis();

  switch(mode){
  case 0: // すべてを白色にして、ゆっくり明るさを変化させる

    // 初回のみ、色を初期状態に設定する
    if(mode_changed){
      r = 0; g = 0; b = 0;
      mode_changed = false;
    }

    if(now - last_control_time > MODE_0_INTERVAL){
      // 色を作る
      if(mode_1_up){
        r += 10; g += 10; b += 10;
        if(r > BRIGHTNESS_MAX){
          r = BRIGHTNESS_MAX; g = BRIGHTNESS_MAX; b = BRIGHTNESS_MAX;
          mode_1_up = false;  
        } 
      }else{
        r -= 10; g -= 10; b -= 10;
        if(r < 0){
          r = 0; g = 0; b = 0;
          mode_1_up = true;  
        }
      }

      // すべてのLEDに(ほぼ)同時に色の設定を反映させる
      for(uint8_t i=0;i<NUM_OF_LED;i++){
        pixels.setPixelColor(i, pixels.Color(r,g,b));
      }
      pixels.show();

      last_control_time = now;
    }

    break;////////////////////////////////////////////////

    case 1: // 緑の円を描く

    // 初回のみ、色を設定する
    if(mode_changed){
      r = 0; g = BRIGHTNESS_MAX; b = 0;
      mode_changed = false;
    }

    if(now - last_control_time > MODE_1_INTERVAL){

      for(uint8_t i=0;i<NUM_OF_LED;i++){
        if(i == led_index){
          pixels.setPixelColor(i, pixels.Color(r,g,b));
        }else{
          pixels.setPixelColor(i, pixels.Color(0,0,0));
        }       
      }
      pixels.show();

      led_index++;
      if(led_index >= NUM_OF_LED){
        led_index = 0;
      }

      last_control_time = now;
    }

    break;////////////////////////////////////////////////

    case 2: // 消灯

    // 初回のみ、色を消して設定する
    if(mode_changed){
      r = 0; g = 0; b = 0;
      for(uint8_t i=0;i<NUM_OF_LED;i++){
        pixels.setPixelColor(i, pixels.Color(r,g,b)); 
      }
      pixels.show();
      mode_changed = false;
    }

    break;////////////////////////////////////////////////

  }

  delay(20);
}

ライブラリがとても使いやすいので、結構簡単に、思いどおりに光らせることができると思います。

実際にはこんな感じで光ります。

 

輝度は半分ぐらいに落としていますが、それでも眩しいなら、光拡散用のキャップを切り開いて、各LEDを覆ってみてもいいかもしれません。その方が色も綺麗に混ざるかと思います。

ちょっと作りたいものがあるので、しばらくArduino工作が続く予定です。