明るさを変化させてみよう(PWMでアナログ出力)

ここでは、LEDの明るさを変化させることに挑戦します。

PWMとは

まずはPWMとは何かを説明します。
pwm_sample1.png
上のグラフに示されるような、ONとOFFを繰り返す電気信号をパルス信号と呼びます。例えば、使用しているArduino Duemilanove 328の場合、ONのときは5V、OFFのときは0Vの電圧値を出力します。

信号がONになっている時間をTon秒、OFFになっている時間をToff秒としたとき、T = Ton + Toffはこのパルス信号の周期といいます。f = 1 / Tはパルス信号の周波数で、単位はHzです。そして、Ton / Tのことをデューティー比と呼びます。上のグラフのパルス信号は、Ton = Toff なので、デューティー比は0.5です。

PWMはパルス信号のデューティー比を変化させて変調する変調方法で、Pulse Width Modulationの頭文字です。PWMで変調された信号をPWM信号と呼びます。デューティー比を変化させたときのパルス信号のいくつかを下のグラフに示します。
pwm_sample2.png

PWMでアナログ出力

Arduinoのピンの出力電圧は、0Vか5V、どちらかの電圧値しか出力できません。しかしPWM信号を使えば、0Vか5Vしか出力していないにもかかわらず、アナログ的に電圧を出力したことと同等な効果が得られます。例えば、PWMの周期を十分短くして、デューティー比を0.5に設定すれば、あたかも2.5Vの電圧を出力した場合と同等の効果が得られます。つまり、パルス信号の周期をT、ONの時間をTonとすると、(Ton / T) * 5V の電圧と同等の効果が得られます。PWMの周期は十分短くなければなりません。この授業で使用するArduino DuemilanoveのPWMの周波数は約490Hz、つまり周期は約2msです。

関数analogWrite()

Arduinoでは、関数analogWrite(pin, value)によって、PWM信号によりアナログ電圧出力を実現することができます。引数pinで出力するピンを指定します。そして、引数valueに0から255の間の数値を設定してデューティー比を指定します。引数valueが0のときデューティー比は0で、255のときがデューティー比は1です。アナログ出力電圧値で言うと、引数valueが0のとき0Vを出力し、255のときは5V、128のときは約2.5Vを出力します。

LEDの明るさを変化させるために

LEDの明るさを変化させるためには、LEDに流れる電流の量を調整しなければなりません。ここでは、LEDの回路に印可する電圧を変えることで、LEDに流れる電流の量を調整します。

ArduinoとLEDの接続を変更しよう

接続図

Arduino Duemilanoveでは、3番、5番、6番、9番、10番、11番のディジタルピンでのみ関数analogWrite()が使えます。これまでの回路では、LEDの点灯に13番ピンを使用していましたが、下の接続図を参考にして、13番ピンに接続していたジャンパピンを9番ピンに接続し直しましょう。
led_brightness_sample1.png
この回路の回路図は以下のようになります。
led_brightness_sample1_2.png
9番ピンのアナログ出力電圧値を0Vにすれば、LEDと抵抗の回路に5Vの電圧がかかり、順方向電流が流れ、LEDが点灯します。5Vにすると、LEDと抵抗の回路にかかる電圧値は0Vになるので、順方向電流が流れず、LEDは消灯します。また、9番ピンのアナログ出力電圧値を変化させると、LEDと抵抗の回路にかかる電圧値が変化し、それに応じて順方向電流の量も変わるため、LEDの明るさが変化します。

プログラムを書こう

LEDの接続が変更できたら、LEDの明るさを変化させるためのArduinoのプログラム(下のled_brightness_sample1)を、ArduinoのIDEを使って書きましょう。


// led_brightness_sample1

const int led_pin = 9;

void setup() {
}

void loop() {
  for ( int led_value = 0; led_value < 256; led_value += 10 ) {
    analogWrite( led_pin, led_value );
    delay( 30 );
  }
  for ( int led_value = 255; led_value > -1; led_value -= 10 ) {
    analogWrite( led_pin, led_value );
    delay( 30 );
  }
}
			

とりあえず実行してみよう

プログラムが完成したら実行してみましょう。LEDの明るさが変化したら成功です。

プログラムを理解しよう

まずは変数の宣言です。


const int led_pin = 9;
			
led_pinにLEDを接続するピンの番号を格納します。この変数はconstがついているので定数になります。

関数setup()では何もする必要はありません。。


void setup() {
}
			

つぎに、関数loop()を見てみます。


void loop() {
  for ( int led_value = 0; led_value < 256; led_value += 10 ) {
    analogWrite( led_pin, led_value );
    delay( 30 );
  }
  for ( int led_value = 255; led_value > -1; led_value -= 10 ) {
    analogWrite( led_pin, led_value );
    delay( 30);
  }
}
			
まず、for文の中にある、関数analogWrite()を説明します。

analogWrite( led_pin, led_value );
			
この関数で、引数led_pinで指定されたピンの出力電圧値を、引数led_valueで指定した電圧値に変更します。引数led_valueは0から255までの値をとり、例えば、0のときには0V、255のときには5Vの電圧値になります。

先に説明したことを考慮すると、led_valueが0のときにLEDは最も明るくなり、led_valueが255のときに最も暗くなります。

ここで、最初のfor文に注目します。


for ( int led_value = 0; led_value < 256; led_value += 10 ) {
  analogWrite( led_pin, led_value );
  delay( 30 );
}
			
このfor文では、約30msごとに変数led_valueを0から10刻みで増加させながら、引数led_pinで指定されたピンの出力電圧を変更しています。つまり、LEDの明るさがだんだんと暗くなっていきます。

二番目のfor文では、約30msごとに変数led_valueを255から10刻みで減少させながら、引数led_pinで指定されたピンの出力電圧を変更しています。つまり、LEDの明るさがだんだんと明るくなっていきます。


for ( int led_value = 255; led_value > -1; led_value -= 10 ) {
  analogWrite( led_pin, led_value );
  delay( 30 );
}
			

確認

関数analogWrite(pin, value)を使うと、PWM信号によりピンの出力電圧値をアナログ的に変化させることができます。例えば、引数valueが0のとき0Vを出力し、255のときは5V、128のときは約2.5Vを出力します。

Referenceへのリンク


back to "Arduino Tutorial"