”明るさ”を変化させるということ
前回、前々回で行った制御では、LEDの”ON”と”OFF”のみの制御を行いました。


しかしながら、LEDを照明として考えると”明るさ”を変化させられた方が明らかに便利ですね。ArduinoでLEDの明るさを制御するには、PWM制御という方法を使います。
PWM制御って?
PWM(Pulse Width Modulation)は、日本語でいうと「パルス幅変調」。
普通、LEDの明るさを変えるには流す電流の量を調節します。電流の量を調節するには、加える電圧の大きさを調節すればいいのだけど、Arduinoのデジタル出力は5V一定で、値を変化させることができません。2.5Vで出力して!ってことができないわけです。そこでPWMの出番です。
※ここからしばらく小難しい話になります。やってられないという人は下の「準備完了!」まですっ飛ばしちゃって下さい。

PWM制御は、簡単にいうと「ものすごい高速で出力の”ON”と”OFF”を繰り返すことによって疑似的に出力を変化させる」ということです。上の図のように、一定の周期で出力(5V一定)をONOFF繰り返します。そのとき、周期T秒のうち出力を”ON”にしている時間τ(タウ)の割合によって、出力が変化します。例えば周期の半分の時間ONにしている場合は5V×50%=2.5Vの出力ですね。
図のような長方形の波形を”パルス”といい、そのパルスの幅(=ONの時間)によって出力を変化させるから、パルス幅変調というわけです。
あくまでArduinoは5Vを出力しているけど、「半分の時間しか出力してないから、電圧も相対的に半分だよね」という感じです。実際時間で積分すれば2.5V一定出力の場合と一致します。はじめは理解しにくい考え方だけど、マイコンの世界では超定番のテクニックなので慣れてしまいましょう。
ArduinoでPWM制御
ではこのPWM制御をArduinoで行う場合はどうすればいいのか。Arduinoのデジタルピン番号をよく見てみると、

上図のように番号の前に”~”がついているものがあります(3,5,6,9,10,11番ピン)。このピンがPWM出力に対応しているピンです。つまりLEDの明るさを制御したいならこのうちのいずれかのピンを使わないといけない。ってことですね。前回までの13番ピンや12番ピンは使えません。
続いてスケッチ上ではどのように表現すればよいのかが問題です。
今までのデジタル出力は、
digitalWrite(13,HIGH or LOW);
という命令でしたが、PWMの場合はこうなります。
analogWrite(11,255); //100%の出力
analogWrite(11,128); //50%の出力
はい。引っかかるポイントがいくつかありそうですね。まず命令がanalogWriteとなってます。単純に命令の名前なので、覚えましょう。問題はカッコの中身。11はピン番号なのでいいとして、そのあとの値が問題です。
255とか128とか。255で100%。128で50%。なんのこっちゃ。100%なら100でいいじゃん!と思う人も多いのでは。私も最初はそう思いました。
255とか128とかいう値は、理系の人々にとってはキリがよく見える数字だけど、そうでない人にはチンプンカンプンですね。この値、実はONにする割合(デューティー比)を指定する部分なんだけど、その値を「8ビットで指定」しているんです。
8ビット?
なんだかわけがわからなくなってきましたか?おそらくプログラミングの勉強をする人が大きくつまずくポイントの一つにぶつかっているような気配。めげずに頑張りましょう。
8ビット とは 2進数8ケタ の意味。
2進数がわからない人はググって下さい。
つまり
(00000000)2から
(11111111)2までの値です。
これって我々になじみ深い10進数に直すと
(0)10から
(255)10 となります。
つまりデューティー比を8ビットで表現すということは即ち、
「0~100%までの割合を、0~255という数値に換算して表す」
という意味なのです。これで、255が100%だった意味が理解できた!。あとは255を基準に、約半分の128で50%、4分の1の64で25%、という感じになります。
準備完了!さあやってみよう
とっても小難しいお勉強を経て、実際にPWM制御を行う準備ができました!さあやってみましょう!
配線

配線はいままで通り。LEDと抵抗をセットで使用します。ただし接続ピンがPWM出力に対応していないといけないので注意が必要です。ここでは11番ピンを使用します。
スケッチ
void loop(){
analogWrite(11,25); //10%の明るさでLEDを点灯
delay(1000); //1000ミリ秒待機
analogWrite(11,64); //25%の明るさでLEDを点灯
delay(1000);
analogWrite(11,255); //100%の明るさでLEDを点灯
delay(1000);
}
まずは明るさの変化を体感すべく、上のようなスケッチを作成してみましょう。
setup関数では、LEDをつないだ11番ピンをOUTPUTに設定。loop関数では、1秒おきに3段階の明るさで点灯するように記述してます。うまく実行できれば、LEDの明るさの変化が確認できるはず。すごい!
スケッチ2 じわーっと光らせる
先ほどのスケッチで、LEDの明るさ制御ができるようになりました。なら今度は、街にきらめくイルミネーションのようにお洒落に点灯させたい!と思うのが人の心。まるで蛍の光のように、じわじわ明るくなって、じわじわ消えていくような点灯をさせてみよう。
void setup(){
pinMode(11,OUTPUT);
}
void loop(){
int i;
for(i=0;i<=255;i++){ //フェードイン
analogWrite(11,i);
delay(10);
}
for(i=255;i>=0;i--){ //フェードアウト
analogWrite(11,i);
delay(10);
}
}
あれれ?いきなりスケッチが複雑になりました!これはfor文と言われる繰り返し命令によって蛍の光を実現するスケッチ。ここではfor文については割愛します。
このスケッチは簡単にいうと、
「明るさ(デューティー比)を0から255まで10ミリ秒ごとに上げて光らせる」=フェードイン のあと、
「明るさ(デューティー比)を255から0まで10ミリ秒ごとに下げて光らせる」=フェードアウト
ということをしてます。ああ!とてもきれいだなあ!
まとめ
LEDの”明るさ”を制御するには「PWM制御」という方法が必要
PWM出力の命令は analogWrite(ピン番号、デューティー比)
デューティー比は8ビットの値で表す
for文を使って明るさを制御するととても美しい
ただの点滅から、かなり制御っぽい内容になってきました!この辺りまでくると、Arduinoマイコンの楽しさにハマってくるのではないでしょうか?次回もお楽しみに。
Arduino UNOはAmazonでも買えます。
最初に買う参考書ならこちらがおススメ。