スクラッチ&スクラップ

簡単なプログラミングや電子工作など。しょうもない工作の記録。

Arduino と NeoPixel で作る マクロリングライト

f:id:macrochelys99:20180209213351j:plain:w600

マクロ撮影に便利なマクロリングライトですが

影の出かたをお手軽にコントロールできるといいな、と。マクロなら被写体までの距離が近いのでLEDでも十分が光量が稼げるはず。既にYouTubeでやっている方がいたので、私も作ってみようと思います。

というわけで作りました

構造

Φ58mm→Φ77mm のステップアップリングに、3Dプリンタで造形したアタッチメントを介して NeoPixelリングを貼り付けています。

Adafruit 24 RGB LED Neopixel Ring [並行輸入品]

Adafruit 24 RGB LED Neopixel Ring [並行輸入品]

電気回路

可変抵抗(10kΩ)で分圧した電圧をArduinoのADポートに接続します。ADポート4本使って、明るさメイン側・明るさサブ側・幅・位置を設定します。あと2本使って色(色相・彩度)設定も予定していたのですが、ボリュームを付ける場所が足りないのと無駄な機能になりそうなので見送りました。

改良の余地

全てのNeoPixel の表面に白い丸シールを貼って光を拡散させているのですが、やはり前面にディフューザーが必要です。光沢のある物を撮影すると NeoPixel 1個1個が写り込んでしまいます。

スケッチ

#define   PIN_PIXELS        7
#define   PIXELS_N          24      // NeoPixel 総数
#define   PIN_BRI           A0
#define   PIN_SUB           A1
#define   PIN_POS           A2
#define   PIN_WID           A3

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(PIXELS_N, PIN_PIXELS, NEO_GRB + NEO_KHZ800);

int bri = 0;
int wid = 0;
int pos = 0;
int sub = 0;

void setup() {
  pixels.begin();
}

void loop() {
  if (load_vol()) {
    set_pixels();
    pixels.show();
  }
  delay(20);
}

boolean load_vol() {

  static int  prev_bri = 0;
  static int  prev_sub = 0;
  static int  prev_wid = 0;
  static int  prev_pos = 0;

  int         vol_bri = analogRead(PIN_BRI);
  int         vol_sub = analogRead(PIN_SUB);
  int         vol_wid = analogRead(PIN_WID);
  int         vol_pos = analogRead(PIN_POS);

  boolean     changed = false;

  int diff = 0; // AD値ノイズによるチラつき防止のため AD値が一定以上変化したときに設定に反映する

  diff = prev_bri - vol_bri;
  if (abs(diff) > 10) {
    bri = constrain(map(vol_bri, 10, 1000, 0, 255), 0, 255);
    prev_bri = vol_bri;
    changed = true;
  }


  diff = prev_wid - vol_wid;
  if (abs(diff) > 10) {
    wid = constrain(map(vol_wid, 10, 1000, 1, PIXELS_N + 1), 1, PIXELS_N + 1);
    prev_wid = vol_wid;
    changed = true;
  }

  diff = prev_pos - vol_pos;
  if (abs(diff) > 10) {
    pos = constrain(map(vol_pos, 256, 768, 0, PIXELS_N - 1), -PIXELS_N, PIXELS_N * 2 - 1);
    prev_pos = vol_pos;
    changed = true;
  }
  
  diff = prev_sub - vol_sub;
  if (abs(diff) > 10 || changed) {
    sub = constrain(map(vol_sub, 10, 1000, 0, bri), 0, 255);
    prev_sub = vol_sub;
    changed = true;
  }

  return changed;
}

void set_pixels() {
  for (int i = 0; i < PIXELS_N; i++) {
    if (jud_mainsub(i)) {
      pixels.setPixelColor(i, pixels.Color(gamma(bri), gamma(bri), gamma(bri)));
    } else {
      pixels.setPixelColor(i, pixels.Color(gamma(sub), gamma(sub), gamma(sub)));
    }
  }
}

boolean jud_mainsub(int i) {
  boolean r = false;
  int p = pos;
  while (p < 0) p += PIXELS_N;
  while (p >= PIXELS_N) p -= PIXELS_N;
  if (p - wid / 2 <= i && i <= p + wid / 2) r = true;
  if (p - wid / 2 <= i + PIXELS_N && i + PIXELS_N <= p + wid / 2) r = true;
  if (p - wid / 2 <= i - PIXELS_N && i - PIXELS_N <= p + wid / 2) r = true;

  return r;
}

PROGMEM const uint8_t gamma8[] = {
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,
  2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,
  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9, 10,
  10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
  17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
  25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
  37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
  51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
  69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
  90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
  115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
  144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
  177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
  215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255
};

unsigned char gamma(unsigned char input) {
  return pgm_read_byte(&gamma8[input]);
}