わかめの開発日記

ArduinoやRaspberry Pi で作ったものを紹介します

PWM制御を使って LEDの明るさを変化させる

Arduinoを使ったPWM制御の方法を紹介

こんにちは、wakamelabです。
Arduinoを使ってPWM制御を行い、LEDの明るさを変化させたので、そのやり方を紹介します。

使用するもの

Arduino UNO 本体 :1個
・ブレッドボード:1個
・LED:2個
・330Ω抵抗:2個
・ジャンパー線(オス-オス):5本

PWM制御とは何か

PWMとは、Palse Width Modulation の略です。直訳すると、パルス幅の調整という意味になります。
その意味の通り、PWM制御とはパルス幅を制御することで単位時間あたりの電圧を調整するための制御です。
何故、パルス幅を調整することで電圧を調整できるのか詳しく説明していきます。


f:id:wakamelab:20200606154344p:plain
このようなONとOFFを繰り返す電気信号をパルスといいます。
Arduinoでは、ONの時に5V、OFFの時に0Vの電圧を出力します。
ONとOFFを合わせた時間を周期といいます。周期の逆数を取ったものが周波数です。
周期の単位は秒(s)で、周波数の単位はヘルツ(Hz)です。ヘルツは(1/s)と同じ意味です。
周期が1秒、つまり0.5秒ON、0.5秒OFFの場合、周波数は1 / 1 = 1ヘルツです。
周期が0.1秒の場合では、周波数は1 / 0.1 = 10ヘルツです。
周波数は、周期が短くなればなるほど大きくなります。

f:id:wakamelab:20200606154633p:plain
パルス1周期中のONとOFFの比率をDuty比(デューティー比)と言います。
この図のパルスは、ONとOFFの比が 5 : 5 (=1 : 1) のため、Duty比は50です。

f:id:wakamelab:20200606154945p:plain
このパルスでは、ONとOFFの比が 2 : 8 (=1 : 4)のため、Duty比は20です。

f:id:wakamelab:20200606155016p:plain
このパルスでは、ONとOFFの比が 9 : 1 のため、Duty比は90です。

PWM制御とはパルスの幅、つまりDuty比を制御する方法となります。
Duty比を変化させることで、なぜLEDの明るさが変化するのでしょうか。
例として、Duty比50の場合を考えてみます。
1周期が1秒だった場合、Duty比50では、ON(5V)が0.5秒、OFFが0.5秒となります。
1周期あたりの電圧の平均値は2.5Vとなり、常時ONであるDuty比100の場合(5.0V)の半分となります。
PWM制御とは、このようにパルス幅の比であるDuty比を調整し、1周期中の電圧の出力値の
平均を変化させる制御となります。

Duty比50のパルスでLEDを点灯させると、常に5Vを与えているLEDと比較し
明るさは半分になります。

プログラムの紹介

ではArduinoを使って、実際にPWM制御をさせるプログラムを書いてみましょう。

以下にPWM制御のサンプルプログラムを紹介します。
このプログラムをArduino IDEに記述してみてください。

#define LED 4
#define LED_PWM 5

byte pwm_value = 0;
byte decrement_flg = 0;

void setup() {

  pinMode(LED, OUTPUT);
  pinMode(LED_PWM, OUTPUT);

  delay(1000);
}

void loop() {

  if (decrement_flg == 0) {
    pwm_value++;
  } else {
    pwm_value--;
  }

  if (pwm_value == 255) {
    decrement_flg = 1;
  } else if (pwm_value == 0) {
    decrement_flg = 0;
  }

  digitalWrite(LED, HIGH);

  analogWrite(LED_PWM, pwm_value);

  delay(4);
}

では、プログラムの意味を解説します。

#define LED 4
#define LED_PWM 5

使用するピン番号の定義です。
通常通りに点灯させるLEDを4番ピンに、PWMで明るさを調整するLEDを5番ピンに接続します。
4番ピンに接続するLEDは明るさの比較のために使用します。
PWMを使えるピンは、3, 5, 6, 9, 10, 11 ピンに限定されています。
ピン番号の横に~が書いてあるピンです。

byte pwm_value = 0;
byte decrement_flg = 0;

1バイト型の変数を宣言しています。 Byte型もchar型と同じく1バイトの型宣言です。
変数"pwm_value"の値を変化させることで、デューティー比を変化させLEDの明るさを変更します。
変数"decrement_flg"は、明るくさせる(デューティー比をプラスする)のか、暗くさせる(デューティー比をマイナスする)のかを判定するための変数です。

  pinMode(LED, OUTPUT);
  pinMode(LED_PWM, OUTPUT);

LEDのピンとPWMに使うピンを出力に設定しています。
PWMに使用するピンは定する必要はありませんので、省略しても大丈夫です。

  if (decrement_flg == 0) {
    pwm_value++;
  } else {
    pwm_value--;
  }

変数"pwm_value"の値を変化させることで、デューティー比を変化させています。

    1. (インクリメント)は、変数の値に1を足す処理です。
    • (デクリメント)は、変数から1を引く処理です。
  if (pwm_value == 255) {
    decrement_flg = 1;
  } else if (pwm_value == 0) {
    decrement_flg = 0;
  }

pwm_valueの値によってdecrement_flgを1か0にしています。
まずpwm_valueは0、decrement_flgは0から始まります。
pwm_valueにどんどん1が足されていきpwm_valueの値が255となったときdecrement_flgが1となります。
そこからpwm_valueの値から1が引かれていき、0となったときdecrement_flgが0となります。
これを繰り返すことで、duty値を0→255、255→0と変化させ、明るさを変えているのです。

  digitalWrite(LED, HIGH);

4番ピンに接続したLEDを点灯させています。

  analogWrite(LED_PWM, pwm_value);

このanalogWrite() 関数がPWM制御を行うための関数です。
analogWrite(ピンの番号、 Duty比) として使用します。
かりにくいのですが、第2引数に入れた値がそのままDuty比になるわけではありません。
この値には 0 ~ 255までの値を入れることが可能で、0の時は0%、255の時に100%となります。
第2引数に入るDuty比 pwm_value が増減することで、LEDの明るさが変化しています。

  delay(4);

処理を4ms停止させます。変数 pwm_value は0~255の値を行ったり来たりするため、4ms*255で約1秒、つまり0V→5Vに1秒、5V→0Vに1秒かかるため、全体として2秒周期を繰り返すための待ち時間です。

配線方法

では配線方法を紹介します。

f:id:wakamelab:20200607000820j:plain

配線は単純で、4番ピンと5番ピンをLEDに接続するだけです。
LEDには配線の向きがあり、端子の長い方(アノード)を4番ピン、5番ピンと接続し、短い方(カソード)をArduinoのGNDに接続します。

実行する

配線が完了したらArduinoにソフトを書き込み、PWMを実行してください。

youtu.be

この動画のように、片方のLEDが常時点灯、片方のLEDの明るさが変化すれば成功です。

Arduino 基本学習キットの紹介

当社では、Arduinoを始めたい人に向けたスターターキットを販売しております。
このキットを使えば、当記事の内容であるPWM制御も試すことができます。

気になる方は以下のURLよりアクセスしてみて下さい。

ホームページ:
www.wakamelab.com

販売サイト:https://wakamelab.thebase.in/items/25680573