google-site-verification: google3bd66dd162ef54c7.html

ArduinoでLEDの光量を滑らかに変化させる

 水草水槽のLED照明をタイマーを使って自動的にコントロールしたいと思っています。単純なON/OFFでは面白くないので、光量を滑らかに変化させてやることにします。真っ暗な状態からいきなり100%で点灯させると、水槽内の生物の健康に悪いかも知れません。また白色と赤色のLEDがあるので、パワーの比率を変えることで調色を行い、夜明けや夕暮れ時の雰囲気を作ってみたいと思います。

 ハードは以前作ったソーラータイマースイッチを改造するとして、これにいきなりLEDの制御プログラムを組み込むのはデバッグが大変になってしまいます。ということで、まずはLEDのコントロール部分だけのプログラムを作ってみました。

▼テスト中
LEDのPWM点灯テスト

▼回路図
LED調光テスト回路
 Arduino UNOを使い、白と赤の二つのLEDを抵抗を通して接続しただけです。

 作成したプログラムは以下の通りです。これだけでデモプログラムとして動くようになっています。
// LEDの明るさを滑らかに変化させるテストプログラム
// 明るさを指数変化させることで人間の感覚に合わせた。
// 新しい明るさと変化時間を指定すれば自動的にPWMでLEDの明るさを調節
// 2017/10/18 ラジオペンチ http://radiopench.blog96.fc2.com/
// 20171018LedAnalogDriveTest

unsigned long LC = 0; // ループカウンタ

float WhiteNow = 0.003; // 0.003は最小値 1/255=0.0039→0.003
float WhitePow = 0.0; // 白LED明るさ設定値
float WhiteSlope = 1.0; // 白LED明るさ変化率

float RedNow = 0.003; // 最小値指定
float RedPow = 0.0; // 赤LED明るさ設定値
float RedSlope = 1.0; // 赤LED明るさ変化率

int WhitePin = 5; // 白LEDピン(PWM可能ピンのみ指定可能)
int RedPin = 6; // 赤LEDピン(   〃        )

void setup() {
Serial.begin(115200);
}

void loop() {
timerDemo1(); // 動作パラメーター設定(demo1,demo2あり)
WhiteLedOut(); // 白LED制御ルーチン
RedLedOut(); // 赤LED制御ルーチン
LC++; // ループカウンタインクリ
Serial.flush();
delay(10); // ループ回転速度調整(Demo1=10,Demo2=1)
}

void WhiteLedOut() { // 赤色LED、指定光量まで指定変化率で明るさを変える
int WhiteBin; // 赤LEDのポートバイナリ設定値

WhiteBin = WhiteNow * 255; // ポート設定値計算
analogWrite(WhitePin, WhiteBin); // PWM出力

WhiteNow = WhiteNow * WhiteSlope; // 次回の光量を計算次回の光量を計算(slopeの値に従い毎回更新)
if (WhiteSlope > 1.0) { // 上昇中で
if (WhiteNow > WhitePow) { // 目標値を超えていたら
WhiteNow = WhitePow; // 目標値で止める
}
}
if (WhiteSlope < 1.0) { // 降下中で
if (WhiteNow < WhitePow) { // 目標値より下なら
WhiteNow = WhitePow; // 目標値で止める
}
if (WhiteNow < 0.003) { // 下限は
WhiteNow = 0.003; // 0.003で抑える(1/255=0.0039)
}
}
// Serial.print(LC);Serial.print(", ");
Serial.print(WhiteBin);
}

void RedLedOut() { // 赤色LED、指定光量まで指定変化率で明るさを変える
int RedBin; // 赤LEDのポートバイナリ設定値

RedBin = RedNow * 255; // ポート設定設定計算
analogWrite(RedPin, RedBin); // PWM出力

RedNow = RedNow * RedSlope; // 次回の光量を計算(slopeの値に従い毎回更新)
if (RedSlope > 1.0) { // 上昇中で
if (RedNow > RedPow) { // 目標値を超えていたら
RedNow = RedPow; // そこで止める
}
}
if (RedSlope < 1.0) { // 降下中で
if (RedNow < RedPow) { // 目標値より下なら
RedNow = RedPow; // 目標値で止める
}
if (RedNow < 0.003) { // 下限は
RedNow = 0.003; // 0.003で抑える(1/255=0.0039)
}
}
Serial.print(", "); Serial.println(RedBin);
}

void WhiteSet(float x, float y) { // 白LEDの動作パラメーター設定(明るさ, 通過サイクル数)
if (x > 1.0) { // 上限をクランプ
x = 1.0;
}
if (x < 0.003) { // 下限をクランプ
x = 0.003;
}
WhitePow = x; // 明るさ設定値
WhiteSlope = pow(WhitePow / WhiteNow, 1.0 / y); // 係数 = 全変化率^(1/サイクル数)
}

void RedSet(float x, float y) { // 赤LED動作パラメーター設定(明るさ, 通過サイクル数)
if (x > 1.0) { // 上限をクランプ
x = 1.0;
}
if (x < 0.003) { // 下限をクランプ
x = 0.003;
}
RedPow = x;
RedSlope = pow(RedPow / RedNow, 1.0 / y); // 係数 = 全変化率^(1/サイクル数)
}

// 以下は動作テスト用のデーター
void timerDemo1() { // 動作デモ1(タイマー割込み周期=10msで実行)
if (LC == 0) RedSet(1.0, 50); // 100%まで 0.5秒
if (LC == 50) RedSet(0.0, 100); // 0%まで 1 秒
if (LC == 100) RedSet(0.5, 20); // 50%まで 0.2秒
if (LC == 200) RedSet(0.0, 200); // 0%まで 2 秒

if (LC == 20) WhiteSet(1.0, 100); // 100%まで 1 秒
if (LC == 150) WhiteSet(0.0, 20); // 0%まで 0.2秒
if (LC == 180) WhiteSet(0.2, 20); // 70%まで 0.2秒
if (LC == 300) WhiteSet(0.0, 80); // 0%まで 0.8 秒

if (LC > 400) {
// while (1);
LC = 0;
}
}

void timerDemo2() { // アクアリウム照明の模擬パターン (割込み周期を1msにすると1000倍速でデモ)
if (LC == 14400) { // 4:00
RedSet(0.2, 600); // 600秒かけて赤20%(朝焼け)
}
if (LC == 16200) { // 4:30
RedSet(0.1, 600); WhiteSet(0.1, 600); // 600秒かけて赤白10%点灯(夜明け待ち)
}
if (LC == 19800) { // 5:30 
RedSet(1.0, 600); WhiteSet(1.0, 600); // 600秒かけて赤白フル点灯(日中)
}
if (LC == 63000UL) { // 17:30
RedSet(0.1, 600); WhiteSet(0.1, 600); // 600秒かけて赤白10%点灯(夕暮れ、消灯待ち)
}
if (LC == 73800UL) { // 20:30 
RedSet(0.2, 600); WhiteSet(0.0, 600); // 600秒かけて赤20%、白消灯(真っ赤な夕焼け)
}
if (LC == 75600UL) { // 21:00
RedSet(0.0, 600); // 600秒かけて全消灯(夜間)
}
if (LC > 86400UL) { // 24:00
LC = 0;
}
}
プログラムのポイント
・ちょっと長いですが、100行目までがメインのプログラムで、以降はデモ用の点灯パターン定義です。

・PWMで使用出来るピンには制限があるので、その中から選びます。他にも制約条件があることがあるので要注意。

・メインのループは24から31行までで、単純な構造になっているので判り易いはずです。

・メインループの中でWhiteLedOut() 33行とRedLedOut() 57行を毎回呼び出して光量の設定を行っています。デモプログラムなので、ループを回るスピードは30行目のdelay(10)でやっていますが、ここはタイマー割り込みなどにした方がいいでしょう。もちろんこのままでも大丈夫です。なおループを回るスピードがLED点灯プログラムの時間単位になっています。

・発光パターンは102行目以降のtimerDemo1()で指定していますが、ポイントはRedSet()とWhiteSet()で、この関数の中で、明るさの変化率を計算しています。なお、PWMの値は0-255の整数しか使えずこれでは細かい変化が表現出来ないので、明るさは浮動小数点で計算・記憶し、最後に整数化することでPWMを行っています。

・明るさの変化はべき乗で計算(pow関数)していますが、消灯状態をゼロで表現すると計算がやっかいになります。そこで浮動小数点で 0.003という値にして誤魔化しています。この値は255倍しても1以下なのでLEDが点灯せず、事実上ゼロと見なすことが出来ます。このアイディアでプログラムの構造が少し簡単になりました。

▼Demo1のLEDの光量変化
LED点灯カーブ(指数変化)
 これはArduino IDEのシリアルプロッタに書いたLEDの光量変化グラフです。ちゃんと指数で変化しています。また変化中に新しいプログラム設定が入れば、それに従った変化になっています。

◆まとめ
 ArduinoでPWMを使ってLEDの明るさを変化させることはよく行われていますが、この記事のように指数変化(等比級数)させている例は少ないと思います。もしPWMのパラメーターを一定値で変化(等差級数)させた場合、光量が少ない時は明るさが大きく変わり、光量が大きくなるとほとんど明るさが変わらないように見えます。これは人間の感覚が刺激を対数圧縮しているためですが、これを打ち消してあたかも自然な光量変化をしているように見せるためには、この記事のように指数変化させる必要があります。

 これでシンプルなインターフェイスでLEDの光量をプログラムできるようになりました。今後は、ソーラータイマースイッチに組み込んでアクアライトコントローラーに作り替えて行きたいと思います。ただ、このプログラムは増築を重ねた旅館のようにグチャグチャの構造になっているので、修正はかなり面倒そうです。地道にやっていきたいと思います。

ミニ水草水槽の照明に赤色LEDを追加

 ダイソーの電球型LEDを使って小さな水草水槽を動かしています。調べてみると、植物の生育には赤い光があったほうが良いらしいので、照明に赤色LEDを追加することにしました。

▼5mmの砲弾型の赤色LEDを追加
ライトヘッドに赤色LED追加
 円周上に10個あるのが最初からある白色LEDで、その少し内側にあった通気用の穴を拡大して赤色LEDを4個取り付けました。LEDを5個取り付けた方が配置のバランスが良いのですが、2個直列ペアで使うので4個だけになりました。

▼配線
裏面の配線
 裏側で配線します。LEDはホットボンドで固定しました。LEDの足は放熱の助けになるので出来るだけ長く残した方がいいです。

▼回路図
回路図
 上の点線内がオリジナルの3060の白色LEDで、18Ωの電流制限抵抗が各LEDに入っています。

 D10~13が今回追加した赤色LEDの回路です。使ったLEDは秋月の「超高輝度5mm広角赤色LED OS5RKA5B61P」で波長は625nmです。

 電流制限抵抗が二つのLEDの間に入っていますが、配線の都合でこうなっただけで特に意味はありません。また51Ωがパラになっているのは手持ちの関係です。赤色LEDの順電圧は低いので2個直列で点灯させています。この赤色LEDは60mAまで流せるのですが、30mAくらいに抑えて使っています。

 アノードコモンの配線になっていますが、これは後でPWMで調光することを考えたためです。アノードコモンにしておけばn-MOSのパワーFETが使えるので少し有利になるはずです。

 それと、+5Vの配線はオリジナルのUSBケーブルを使わず、新たに追加した線の方を使った方が良いです。オリジナルのUSBケーブルの配線抵抗は高いので、電圧ドロップが大きいです。これを往復で使うとドロップが二倍になってしまうので、そのロスを少なくするために、片道だけで使うように配線しました。つまり、USBケーブルの二本の線は白と赤色LEDのローサイド側の配線に使います。なお、電源電圧5VでLEDの電流は合計で約380mAでした。

▼点灯している様子
点灯した状態
 この写真は電流を絞って撮影しています。

配光
 赤色光はこの写真のように少し指向性があります。ただ実際にはガラス瓶の蓋で光が拡散されるので、これほどはっきりした指向性は無くなるはずです。

▼使用状態
アクアライト
 赤色LEDの光が上の方に漏れています。

 赤色を追加したことで、赤い水草の色が鮮やかになりました。白色の照明は電球色なので少し黄ばんでいます、というか少しライムが入っているのですが、こっちはもっと色温度が高い方が水草の緑色が綺麗になります。

◆今後の予定
 現在の照明はソーラータイマースイッチを使い、夕方の消灯時刻にオフセットをかけて使っているのですが、最大に延長しても夜の7時過ぎには消灯してしまうのでちょっと寂しい感じです。もっと遅くまで点灯させれば綺麗なインテリアになるのですが、1日の点灯時間が長くなり過ぎて、植物などに悪影響がありそうです。

 ということで困っていたのですが、良い方法を思いつきました。夜はフルパワーで光らせる必要は無いので、例えば10%くらいに減光して点灯させれば、それだけでインテリアのポイントライトになるはずです。減光はArduinoのPWMを使えば簡単に出来るはずです。

 ついでだから、いきなり点灯させるのではなく、徐々に明るくなるようにすると、自然な夜明けと夕暮れを表現出来そうです。それに、こうすればエビをびっくりさせることもないはずです。さらに赤色LEDの明るさを独立して制御すれば、夕焼けを表現したり、真っ赤な照明にするなどの演出も出来るはずです。

 そんなことで、すごく面白そうなのでやってみたいと思います。まずは、滑らかにLEDの明るさを変えるプログラム作りから始めます。

◆水槽近況
 水槽の運転を始めたのが10月2日。ミナミヌマエビを2匹入れていたのですが、残念なことに8日目の朝に1匹が死んいました。残る一匹は元気で脱皮とかやってます。植物の方は特に異常は無く、少し成長してきたので水面付近の葉を少しカットして、水中に光が入り易くしてやりました。
 あと、ごく僅かですがガラス瓶にコケが付着し始めています。エビ君が一匹では手が回らないのかもしれませんが、照明時間を短かくした方が良いのかも知れません。

Arduinoとアナログ電力量計で作った電力ロガーの測定事例

 完成した誘導式電力量計を使った消費電力ロガーは、消費電力がゼロ近くになるとうまく測定出来ないという問題があります。でも、データーが変になったところは後である程度は修正出来ます。それにSDカードに記録しているので長時間の記録が可能という特長があります。

 ということで実際に記録を採ってみました。まずはウォーターサーバーです

▼ウォーターサーバー(クリクラ サーバー04Le)消費電力測定中
ウォーターサーバーの消費電力測定中

▼生データー
ウォーターサーバー生データ
 大きなピークは回転検出穴でパルス割れが発生したため発生しています。また、円盤の回転が止まるとデーターが更新されなくなるため同じ値が連続して記録されています。

 このような異常値を取り除いたのが次のグラフです。

▼ウォーターサーバーの消費電力
ウォーターサーバー消費電力
 約27時間の連続測定結果で、記録間隔は1分です。

 80ワット付近の値は冷凍用のコンプレッサーの動作時、330ワット付近の値は加熱ヒーターの動作時で、410ワット付近の値はその両方が動作している状態と思われます。半日くらい電源を切った状態からスタートしたので、定常状態に持って行くために、最初はヒーターとコンプレッサーが動き続けています。

 平均の消費電力はエクセルで簡単に計算出来ますが、異常値の修正処理がうまくいっていない可能性があるので、あえて細かい値は書きませんが、およそ50Wくらいの消費電力になっていました。

 次は冷蔵庫です。この冷蔵庫の消費電力は以前回路を使って測定したことがあるのでその時の結果と比較出来るはずです。なお、前回は皮相電力測定でしたが今回は有効電力測定になっています。

▼冷蔵庫の消費電力測定中
冷蔵庫の消費電力
 この冷蔵庫は3年前に買った物で、PanasonicのNR-F568XGで、555リットルの6ドアです。

▼エクセルで測定結果の整理中
ロガーの出力をエクセルで整理中

▼生データー
冷蔵庫消費電力、生データ
 クリーピング防止穴の誤検出が原因の大きなピークがあります。

▼異常値を除いた消費電力
パナソニック冷蔵庫の消費電力
 約92時間分のデーターです。180ワットくらいのピークは霜取りを行っているものと思われ、その後消費電力が100ワットくらいになっているのは温度の上がったコンデンサを再度冷やしているのだと思います。
 定常状態では50ワットくらいで運転していて、時々コンプレッサを止めているようです。コンプレッサが止まっている状態の消費電力は7ワットくらいで、これは主にドアまわりの結露防止ヒーターの消費電力ではないかと思います。
 なおこの測定期間全体の平均消費電力は51.2Wでした。

 同時に記録しているデーターです。

▼温度(CPU温度)
温度変化
 このところ涼しくなったので、その様子が記録されているようです。

▼周囲の明るさ
明るさ
 このグラフは下側が明るい状態を示しています。ということで値が上に張り付いている期間は部屋が真っ暗だったことを表しています。このロガーはRTCを持たないので正確な時刻は判りませんが、明るさのデーターがあれば、およその時刻を推定することが可能です。

◆まとめ
 異常値が記録されてしまう問題を何とかする必要がありますが、そこそこ使えるデーターロガーが出来ました。SDメモリーカードなのでデーター量を気にしないでいいのが嬉しいです。

 ところである程度予想していたのですが、ウォーターサーバーの消費電力はかなり大きかったです。大雑把に言うと、最近の大型冷蔵庫と同じくらいの消費電力はあるようです。我が家では使わない時は出来るだけメイン電源を切るようにしていましたが、こういう使い方で正解だったと思います。
 冷蔵庫の消費電力は各社が熾烈な競争を行った結果ここまで下がった訳ですが、ウォーターサーバーでもこのような競争が行われて欲しいところです。
カレンダー
09 | 2017/10 | 11
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード