【Arduino】LEDを点灯させるさまざまな方法

ArduinoのスタートアップといえばLチカですが、さらにもう一歩踏み込んでいつもと異なるLEDのつなぎ方やdigitalwrite以外の関数を使ったLEDの点灯をやってみたいと思います。

 

By: Mike Deal

 


LEDのつなぎ方

ArduinoでLEDを制御する場合、ほとんどの場合は直接Arduinoから電力を供給してLEDを点灯させますが、配線をちょっと変えれば別の電源から電力を供給してarduinoで制御することができます。

Arduinoから直接LEDを点灯させるつなぎ方

LED_gnd

図は一般的な回路構成によくある13PINとGNDにLEDをつなげた回路です。

この回路構成だとマイコンの12PINがHighになったときに5Vが供給されるので、スケッチ上でもHighで点灯、Lowで消灯と直感的にLEDのオンオフを把握することができます。

フルカラーLEDやマトリクスLEDでカソードコモンとなっている場合はこのつなぎ方でOKです

 

別電源からLEDを点灯させるつなぎ方

LED_5v

この回路構成では12PINと5Vを接続しています。この配線の場合、ボードに搭載されている5Vレギュレータから直接電力を供給しています。

この回路構成の場合、Highの時に13PINから5Vが供給され5V側の電圧と釣り合うためLEDは点灯しなくなります。逆に13PINがLowになると5V側からArduino側に電流が流れLEDは点灯します。

マイコンや論理ICは電気を送り出す能力よりも電気を引き込む能力の方が強いので、場合によってはこちらの回路構成をとらざるを得ない場合があるかもしれません。また、LEDを点灯させるような状態が多く、マイコンの消費電流を下げたい場合は出力ピンをOFFでLEDを点灯させたほうがいいので、この回路構成にする場合もあります。

また、フルカラーLEDやマトリクスLEDでアノードコモンとなっている場合はこの考え方じゃないと動きません。

 

おなじみのdigitalWrite関数でLEDを点滅させる

LED点灯やその他様々なところでお世話になるのがdigitalWrite関数です。

この関数は5VとGNDの出力を制御する関数です。HIGH出力時は5Vを出力し、LOW出力時は0V(GND)となります。

最も簡単なオンとオフを切り替える関数なので様々なところで使います。下の画像はdigitalWite関数でLEDを点滅させている様子です。

void setup() {
pinMode(11, OUTPUT);
}

void loop() {
digitalWrite(11, HIGH);   // 点灯
delay(1000);          
digitalWrite(11, LOW);    // 消灯
delay(1000);              // 
}

 

led_digital

digitalwriteでLEDが動作する様子(クリックで動きます)

PWMで明るさを調整できるanalogWrite関数

analogWrite関数はデジタル出力をPWMを使って疑似的にアナログ出力を行う関数です。

この関数は安定した方形波を出力する関数です。方形波のデューティ比は関数上で指定できるのでLEDの明るさを自由に調整することができます。

例えば、LEDの明るさを調節したり、ボンヤリ点灯させる際などにも便利です。

void setup() {
}
void loop() {
  int a = 0;
  for (a = 0; a <= 255; a++)    //点灯
  {
    analogWrite(11, a);
    delay(5);
  }
  for (a = 255; a >= 0; a--)    //消灯
  {
    analogWrite(11, a);
    delay(5);
  }
  delay(500);
}
analogwriteでLEDが動作する様子(クリックで動きます)

analogwriteでLEDが動作する様子(クリックで動きます)

 

フルカラーLEDを使ってみる

colorled

単色LEDの点滅だけでは面白みがないのでフルカラーLEDを使ってみます。フルカラーLEDは赤・青・緑それぞれのLEDが一つのパッケージに収められており、それぞれの色で調光を行うことで様々な色を表現することができます。

さて、通常のLED点滅であれば、digitalWrite関数でON/OFFを指定し、明るさの調整は抵抗の電流制限で行いますが、フルカラーLEDの場合は表現したい色に合わせて3つのLEDの光量を調光しなければいけません。そのためには先述のanalogWrite関数を使用します。

フルカラーLEDは3つのLEDが内蔵されているため、配線もそれに準じて取り付けます。アノードコモンかカソードコモンかで配線が変わるのでこの辺注意しましょう。

今回は秋月電子で購入したフルカラーLED OSTA5131Aを使います。

LED_color

 

全色表示できるようなスケッチを考える

さて、せっかくのフルカラーLEDなので本当にフルカラー(1677万7216色)で表示させたいわけなんですが、参考になるサイトを見ても滑らかに色合いを変化して表示できるスイッチてなかなかないんですよね。

よーく調べてみると三色のLEDを全色滑らかに出せるようなアルゴリズムが地味に難しいようです。(for文で逐次色を切り替えたり、rand関数を使えば一発解決ではあるのですが…)

というわけで、簡単にフルカラーを表示できるようなスケッチを考えたのがこちらです↓

 

#define LED_RED 9             //赤LED PIN番号
#define LED_BLUE 10           //青LED PIN番号
#define LED_GREEN 11          //緑LED PIN番号
#define LED_RED_TIME 5        //赤LED 周期
#define LED_BLUE_TIME 6       //青LED 周期
#define LED_GREEN_TIME 7      //緑LED 周期

int red = 0, blue = 0, green = 0;
int f_red = 0, f_blue = 0, f_green = 0;
// 初期化
void setup() {

  // LEDのピンを出力に
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
}

// メインループ
void loop() {

  if (f_red == 0) {
    red = red + LED_RED_TIME;
    if (red >= 250) {
      f_red = 1;
    }
  }
  else {
    red = red - LED_RED_TIME;
    if (red <= 0) {
      f_red = 0;
    }
  }
  analogWrite(LED_RED, red);
delay(50);

  if (f_blue == 0) {
    blue = blue + LED_BLUE_TIME;
    if (blue >= 200) {
      f_blue = 1;
      blue=200;
    }
  }
  else {
    blue = blue - LED_BLUE_TIME;
    if (blue <= 0) {
      f_blue = 0;
      blue=0;
    }
  }
  analogWrite(LED_BLUE, blue);
delay(30);

  if (f_green == 0) {
    green = green + LED_GREEN_TIME;
    if (green >= 200) {
      f_green = 1;
      green=200;
    }
  }
  else {
    green = green - LED_GREEN_TIME;
    if (green <= 0) {
      f_green = 0;
            green=0;
    }
  }
  analogWrite(LED_GREEN, green);
delay(20);
}


 

3色の光量を周期的に変化するようにして、それぞれの周期を微妙にずらして色が滑らかに変化するようにしました。バイオリズムと似たような考えです。もうちょっと周期の差を無くしたりもっと別の複雑なアルゴリズムにしていけば色の表現度をもっと上げることもできるでしょうが、とりあえず今回はこれで満足です。

カメラ越しにLEDを撮影すると変化がわかりにくいので、丸めた紙を被せて色の変化がわかるようにしました。

ledgif

フルカラーLEDが動作する様子(クリックで動きます)