2012年4月29日日曜日

フルカラーLEDを使ったムードランプ

「スタンド的な物」?、こういう物はなんという名前がいいんでしょうか・・・
「ムードランプ」が一番合ってそうなので記事タイトルも変更しました。

以前のこのエントリーでフルカラーLEDをジワーっと色の変化をさせていますが、これをケースに入れて何かを乗せて照明できるようにしました。それだけです。

↑穴を開けたピンポン玉をかぶせ、更に100円ショップのガラスの器



ブートローダーも書き込めるようになったので、生328Pにブートローダー(optifix)を書き込み、フューズの設定で内部発振8MHz動作。スケッチで分周比1/8に設定し1MHzで動作させたところ、PWMの周波数が下がったためか、点滅が目につくので8MHz動作させます。PWM周波数の元になる?タイマの分周比を変更すれば点滅はなくなるかも?試してません。

電源は100円ショップのUSBチャージャー(DCDCコンバーター)。1本でも2本でも5Vを出力しますが、電池の持ちが悪いので5VDCアダプターを繋げられるようにします。

ケースは100円ショップなど見ましたがちょうどいいのがないので、厚紙で作りました。
木工ボンドは乾燥に時間が掛かるのでグルーガンでお手軽に。
紙なので適当に穴を開け、タクトスイッチ、トグルスイッチ、DCジャックをグルーガンで接着。
8mmのLEDが飛び出ているので頭を切って平らなものを置けるようにしてもいいかもしれません。

以前のスケッチに手を加え、フルモード(analogWriteのフルレンジで変化※)、LOWモード(フルモードの暗い部分1/4で変化※)、キャンドルモード(赤LEDがランダム点滅してロウソクのように)をタクトスイッチで切り替えます。
切り替えるとATMEGA328PのEEPROMにそのモードを記録し、次回電源を入れた時にそのモードで再開します。
※なぜかanalogWriteでLED消灯に近い部分になるとLEDの明るさの変化がスムーズでなくガクンガクンと暗くなってしまうので、その範囲に入らないようにランダム値を制限

無駄が多いかもだけど気にしない。
Arduinoスケッチ:

#include <EEPROM.h>

byte rnd_seed = 3;
byte led_r = 3;
byte led_g = 5;
byte led_b = 6;
                         //各モードのステップ数値は何回か合計した時必ず1.0にならなければならない
float step_val = 0.25;   //初期ステップ
float step_L = 0.25;     //LOWモード時のステップ
float step_F = 1.0;     //FULLモード時のステップ

byte val_min = 191;            //アノードコモンの場合数値が大きくなると暗くなる
byte val_max = 245;
byte val_min_L = 191;          //LOWモード下限
byte val_min_F = 0;            //FULLモード下限
byte val_max_L = 245;          //LOWモード上限
byte val_max_F = 245;          //FULLモード上限
/*カソードコモンならここを有効に(上の部分をコメントアウト)
byte val_min = 0;
byte val_max = 63;
byte val_min_L = 0;
byte val_min_F = 0;
byte val_max_L = 63;
byte val_max_F = 255;
*/

float led[3][4] = {
  {led_r,val_min,val_max,step_val},
  {led_g,val_min,val_max,step_val},
  {led_b,val_min,val_max,step_val}
};
byte pin = 0;
byte val = 1;
byte target = 2;
byte stp = 3;

byte mode = 0;      //初期モード
byte mode_pin = 8;  //切り替えボタンのピン
byte mode_num = 2;  //モードの数-1     0:LOW 1:FULL 2:CANDLE
boolean power_on = true;

int address = 77; //内蔵EEPROMアドレス mode保存用

void setup() {
  pinMode(mode_pin, INPUT);
  digitalWrite(mode_pin,HIGH);
  randomSeed(analogRead(rnd_seed));
  mode = EEPROM.read(address);
  if(mode <= mode_num){
    mode -= 1;
  }
  else{
    mode = -1;
  }
  mode_change();
}

void loop(){
  if(digitalRead(mode_pin) == LOW){
    mode_change();
  }
  for(int color = 0; color < 3; color++){
    if(led[color][val] == led[color][target]){
      led[color][target] = random(val_min,val_max + 1);
      int led_diff = led[color][target] - led[color][val];
      if(led_diff>0){
        led[color][stp] = step_val;
      }
      if(led_diff<0){
        led[color][stp] = -step_val;
      }
      if(led_diff==0){
        led[color][stp] = 0;
      }
    }
    analogWrite(led[color][pin], led[color][val]);
    led[color][val] += led[color][stp];
    delay(20);
  }
}

void mode_change(){
  mode += 1;
  if(mode > mode_num){
    mode = 0;
  }
  switch(mode){
    case 0:                 //LOWモード
      val_min = val_min_L;
      val_max = val_max_L;
      step_val = step_L;
      analogWrite(led_r,val_min);
      analogWrite(led_g,val_min);
      analogWrite(led_b,val_min);
      delay(2000);
      break;
    case 1:                 //FULLモード
      val_min = val_min_F;
      val_max = val_max_F;
      step_val = step_F;
      analogWrite(led_r,val_min);
      analogWrite(led_g,val_min);
      analogWrite(led_b,val_min);
      delay(2000);
      break;
    case 2:                 //CANDLEモード
      analogWrite(led_g,255);    //off アノードコモン
      analogWrite(led_b,255);    //off
      analogWrite(led_r,0);      //点灯
      delay(2000);
      candle_mode();
      break;
  }
  if(power_on==true){
    power_on=false;
  }
  else{
    EEPROM.write(address,mode);
  }
}

void candle_mode(){
  boolean flg_candle=true;
  analogWrite(led_g,255);
  analogWrite(led_b,255);
  while(flg_candle==true){
    analogWrite(led_r, random(0,256));
    delay(15);
    if(digitalRead(mode_pin) == LOW){
      flg_candle=false;
    }
  }
}



環境:ArduinoUnoR3、Arduino1.0



0 件のコメント:

コメントを投稿