Arduino と NeoPixel で作る マクロリングライト
マクロ撮影に便利なマクロリングライトですが
影の出かたをお手軽にコントロールできるといいな、と。マクロなら被写体までの距離が近いのでLEDでも十分が光量が稼げるはず。既にYouTubeでやっている方がいたので、私も作ってみようと思います。
というわけで作りました
構造
Φ58mm→Φ77mm のステップアップリングに、3Dプリンタで造形したアタッチメントを介して NeoPixelリングを貼り付けています。
Adafruit 24 RGB LED Neopixel Ring [並行輸入品]
- 出版社/メーカー: C&E
- メディア: エレクトロニクス
- この商品を含むブログを見る
電気回路
可変抵抗(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]); }