ところで、わが家には横幅が3メートルくらいの、すこし大きめの本棚があるんですが、これを作った時にどうしてだったか2cmくらい浮かせる設計にしていました。
僕はこういう隙間を見ると無性に光らせたくなってしまう人間なので、ここにLEDテープを貼って、間接照明にしてみようということになりました。
- 激安なLEDテープを取り付けてみた
- かっこよくフェードさせたい
- コントローラーはArduinoで作ろう
- 回路はこんな感じ
- ”かっこいい” フェードとは?―ウェーバー・フェヒナーの法則
- 実験してみる
- Arduinoスケッチ
- かっこよくなった!
激安なLEDテープを取り付けてみた
まず必要なのはLEDテープです、Aliexpressで5m約300円 (激安!)のものを見つけました。
冗談みたいな値段ですが、綺麗にリールに巻かれて無事に届きました。 選んだ色はWarm Light(電球色)です。
両面テープがついているので、取り付けは簡単です。電源は12Vなので、どこの家でもあまっている12V2AのACアダプターを繋ぎました。
品質の方はどうなのかといえば、3ヶ月ほどつけっぱなしにしています、がいまのところ全く問題ないので、いい買い物でした。
かっこよくフェードさせたい
さて、このままではACアダプタの抜き差しでON/OFFするしかないので、少々オシャ感に欠けます。
そこで、なめらかなフェードを実装して、オシャ感を出していきたいと思います。ついでに明るさの調節もできるとなお良しです。
コントローラーはArduinoで作ろう
オシャなフェード以外にも、リモコン付けたいとか環境光センサー付けたいとか、高機能な調光器を探すとキリがないので、拡張性をブチ上げるためにコントローラーはArduinoで自作します。
Arduinoと書きましたが、ライトのフェードなんかにArduinoを使うのは大げさなので、Arduino環境で使えるちっちゃいマイコン「Digispark」のクローン*1を使ってみます。Aliexpressで200円くらいでした。
Digisparkの使い方については、このあたりを参考にしました。Arduino IDEで少し設定するだけで簡単に使えます。
回路はこんな感じ
5V駆動のDigisparkから、FETで12V電源をスイッチングさせる回路です。
とりあえずの操作用に、ピン2にプッシュボタンを1つ付けてみました。
材料はこれだけです。
- Digispark
- LEDテープ 12V 電球色 3m
- プッシュボタン
- FET 2SK2232
- 抵抗 1MΩ
- 12Vの電源
ちなみに、Digisparkには3端子レギュレーターが載っているので、今回のように12V電源を使う時は、VIN端子に繋ぐだけで降圧してくれるので楽ちんです。
”かっこいい” フェードとは?―ウェーバー・フェヒナーの法則
さて、ただフェードさせるだけなら、for文でカウントしてPWM出力すればOKですが、今回目指すのは"かっこいい"フェードです 。
どうすればかっこよくなるでしょうか?ウーム。
ところで、人間の5感の知覚というのは、刺激量の対数に比例するそうで、この法則を「ウェーバー・フェヒナーの法則」といいます。
雑に説明すると「刺激が強くなるほど感覚が鈍感になる」という法則です。
つまり、線形に明るさを変えてしまうと、見た目上は最初一気に明るくなって、その後はほとんど変化しないように見えてしまいます。
そこで、コントローラーの出力を指数関数的に変化させることで、人間の目からは滑らかに変化して見えるようになります。
それに、○○の法則ってなんだかかっこいいじゃないですか、よって今回はこれを”かっこいいフェード”と定義したいと思います。
とはいえ対数とか指数関数とか、数学に対してフワッとした理解しか持ち合わせていない僕にとっては、だいぶハードルの高いテーマです。
すかさずGoogle先生に助けを求めたところ、ドンピシャな記事を見つけたので、こちらを参考にさせてもらいました。
実験してみる
とはいえ、はたしてそんなに変わるのかな?試しに光り方を比べてみたのがこちら。
なるほど...左が線形変化のフェード、右が指数変化のフェードです。 グラフと照らし合わせると一目瞭然ですね。
Arduinoスケッチ
※もっとシンプルな方法がありました。
ボタンを1つしか付けていないので、こんな操作を想定してスケッチを書いてみました。
- 電源ON
- フェードして点灯
- ボタンを押すたびに徐々に(10ステップ)暗くなって消灯
- 消灯状態でボタンを押すと2番に戻って繰り返し
そうして出来上がったコードがこちら!
/* 本棚の下のLEDテープをかっこよくフェードさせるスケッチ。 */ const int light_pin = 0; // LEDテープのコントロール const int led_pin = 1; // Digisparkの内蔵LED const int button_pin = 2; // プッシュボタン const int max_value = 255; // PWM出力の最大値 const int fade_step = 10; // フェードのステップ数 const double C = 255.0; // 用いるLEDに依存する定数 void setup() { pinMode(light_pin, OUTPUT); pinMode(led_pin, OUTPUT); pinMode(button_pin, INPUT_PULLUP); // 初期状態は点灯 fade(0, max_value); } void loop() { // 一旦ボタンを離してね button_wait(0); // fade_step刻みで暗くする for (int i = fade_step; i > 0; i--) { button_wait(1); fade(max_value / fade_step * i, max_value / fade_step * (i - 1)); } // 一旦ボタンを離してね button_wait(0); button_wait(1); // リセット(点灯) fade(0, max_value); } void button_wait(boolean flag) { // ボタンが押/離されるまで待つ while (digitalRead(button_pin) == flag) { delay(100); } } void fade(int start_value, int end_value) { // 開始値をセット int current_value = start_value; // 目標値に達していないうちはループ while (current_value != end_value) { // 目標値より小さい if (current_value < end_value) { ++current_value; } // 目標値より大きい if (current_value > end_value) { --current_value; } // 明るさを出力 analogWrite(light_pin, get_duty(current_value)); delay(5); } } int get_duty(double ratio) { // Weber-Fechnerの法則 return round(exp(log(255.0) - (1 - (ratio / 255.0)) * log(C))) - 1; }
かっこよくなった!
オシャな感じになったんじゃないかと思います、満足したので今日はここまで。
*1:クローンはめちゃくちゃ安い代わりに、P5がResetピン設定になっていてI/Oとしては使えないので、そこだけ注意が必要です