まなびサイエンス

Arduino で LED を点灯させる ~ PWM 制御で「蛍の光」

  • 公開 2017/04/02
  • 更新 2017/10/11
カバーイメージ

 Arduino IDE でプログラミングを行い、作成したプログラムと Arduino で LED を点灯/消灯/点滅させることができるようになりました。この記事では、LED を点灯させるところまで少し戻って、PWM 制御で LED を明るく点灯させたり、薄暗く点灯させたりしてみます。LED の光り方を上手く制御すると、蛍の光のようにぼんやり光るオモチャを作れます。

PWM; Pulse Width Modulation; パルス幅変調

 Arduino 単体では、いくら頑張っても ON (5V)か OFF (0V)のデジタル量しか出力できません。つまり、全力(5V)で LED を点灯させるか、または全力で(0V)で LED を消灯させることしかできないので、例えば 3.75V のような中途半端な電圧(アナログ値)で、LED をぼんやりと点灯させることはできないのです。
 そこで、Arduino で LED の明暗を制御するには、パルス幅変調と呼ばれる仕組みを利用します。LED のオンとオフを人間の目には判らないくらい高速に切り替えると、一見して LED は点灯しているように見えるのですが、高速にオン/オフを切り替える中で、より長い時間オンが続けば LED は明るく見えますし、反対に、より長い時間オフが続けば LED は暗く見えるように錯覚してしまいます。このように、電圧をパルス(Pulse)状に出力し、このパルスの通電時間(=幅; Width)を変える(Modulate)ことで、LED の見た目の明るさを制御する方法が PWM と呼ばれる仕組みです。実際に出力されているのはデジタル値ですが、疑似的にアナログ値が出力されているように見せているわけです。

 百聞は一見にしかず、とりあえず、パルス幅変調で LED を点灯させている例を見てみましょう。

 画面左半分に、LED の電源電圧をオシロスコープで測定したグラフが表示されています。グラフで、太ったり細ったりしている長方形が 5V の電圧がオンになっているパルスで、パルスとパルスの間はオフの状態です。ここで、PWM の 1 周期の時間に対するオン時間の比率を デューティー比; duty ratio と言い、デューティー比が 100% では、常にオン、デューティー比が 0% では、常にオフになります。

 このデューティー比の変化と、右側のブレッドボード上の LED の明るさの変化に注意してみると、デューティー比が高くなると LED は明るくなり、反対にデューティー比が低くなると LED が暗くなることが判ります。ここでは、1 秒間に約 2,000 回*1のスピードでオン/オフを繰り返しているのですが、あまりにも高速でオン/オフするため、人間の目には点滅しているようには全く見えません。

Arduino で PWM を使う

 Arduino で PWM を使うには、オン/オフをデジタル量で制御する digitalWrite の替わりに、analogWrite を使います。analogWrite を利用すれば、PWM 出力のデューティー比を 256 段階で制御できます。Fig.1 は、この analogWrite を使って、11番ポートと 9 番ポートに出力された PWM の電圧波形を測定したところです。


Fig.1

 11 番ポートのデューティー比はおおよそ 50%(=128/256) ですので、オン時間とオフ時間がおおよそ同じになっています。また、9 番ポートのデューティー比はおおよそ 25%(=64/256) であることが判ります。

蛍の光 LED

 先の動画にある蛍の光のようにぼんやりと光る LED を作ってみます。電子回路は以前に組んだものをそのまま使うことができます(Fig.2 )。11 番ポートを LED に接続してください。


Fig.2

 また、スケッチは次のようになります。

void setup() {
  // put your setup code here, to run once:
  pinMode( 11, OUTPUT );
}

int val = 0; // 現在の明るさ
int dir = 1; // 明るさの変化方向

void loop() {
  // put your main code here, to run repeatedly:
  analogWrite( 11, val );
  val = val + dir;
  if( val ==   0 ) dir =  1;
  if( val == 255 ) dir = -1;
  delay( 5 );
}

スケッチの解説

  • 3 行目 … 11 番ポートを出力に設定します。
  • 6 行目 … val は、LED の現在の明るさ(0~255)のための変数*2です。
  • 7 行目 … dir は、LED の明るさが変化する方向のための変数です。dir1 の時、LED は次第に明るくなります。dir-1 の時、LED は次第に暗くなります。
  • 11 行目 … 11 番ポートに、デューティー比 val で電圧を出力します。
  • 12 行目 … 明るさを dir だけ変化させます。
  • 13 行目 … 次第に暗くなって、明るさが 0 になったら、今度は次第に明るくなるようにします。
  • 14 行目 … 次第に明るくなって、明るさが 255 になったら、今度は次第に暗くなるようにします。
  • 15 行目 … 明るさがゆっくり変化するよう、少しの間だけ待ちます。
  1. *1 データシートを見ると 11 番ポートの PWM は 1.96kHz 動作です
  2. *2 変数の解説はまた後日

カテゴリー

過去ログ