e-DIY
照明

LEDの明るさを調整する2つの方法【PWM調光とアナログ調光】

LEDの調光

LEDの明るさを調整する方法には、

  • PWM調光
  • アナログ調光

の2つがあります。

今回はPWM調光とアナログ調光の違いと、それぞれのやり方を説明していきます。

アナログ調光

先にイメージしやすいアナログ調光について説明していきます。

アナログ調光とは、LEDに流す電流を連続的に変えることで明るさを調整する方法です。
LEDは電流を多く流すほど明るくなります。

LEDの明るさと電流の関係

アナログ調光の実験回路

アナログ調光の一番簡単な方法は、抵抗値を変えて流す電流を変化させる方法です。

このような回路でLEDに流す電流を調整します。

アナログ調光回路
アナログ調光回路

1kΩの抵抗は最大電流を決めるためのものです。
可変抵抗器は0Ω~10kΩまで変化します。

今回使ったLEDのVF(順方向電圧)は約2Vなので、可変抵抗器の抵抗が10kΩなら、LEDに流れる電流:IFは

IF = (5V – 2V)/11kΩ = 0.273mA

可変抵抗器の抵抗が0Ωなら、

IF = (5V – 2V)/1kΩ = 3mA

となります。

アナログ調光の実験結果

可変抵抗器のツマミを回して抵抗値を10kΩ⇒0Ωへ徐々に変化させていくと、このようにLEDの明るさが変化します。

PWM調光とは

PWMはPulse Width Modulationの略で、パルスの幅を変化させることで制御する方式です。

PWM調光とは、LEDを高速でオン・オフさせて明るさを調整する方法です。
目で追えないほど速くオン・オフを切り替えるので、残像現象でずっと点灯しているように見えます。

オンする時間(パルス幅)が長いほど明るくなり、短いと暗くなります。

PWM調光の原理

オンの期間とオフの期間の比率をDUTY(デューティ)といい、単位は%です。
オン期間とオフ期間が同じならDUTYは50%、全期間でオンなら100%となります。

ラズパイでLEDの明るさを制御する

それでは、ラズパイを使って実際にLEDをPWM調光してみましょう。

PWM調光の回路図

回路図はこのようにしました。

PWM調光回路図
PWM調光ブレッドボード

ラズパイ4Bの場合、PWMに対応しているGPIOポートは次の4つです。

  • PWM Channel0:GPIO 12、GPIO 18
  • PWM Channel1:GPIO 13、GPIO 19

今回はGPIO18を使います。

GPIO18がHi(3.3V)を出力するとLEDがオンし、GPIO18がLo(0V)だとLEDがオフします。
HiとLoの期間の比率を変えることでLEDの明るさを変えます。

220Ωは電流制限抵抗で、GPIO18がHiの時に流れる電流を決めています。
LEDに流れる電流:IFは、

IF = (3.3V – 2V) / 220Ω = 5.9mA

となります。

Pythonコード

指定したDUTYで光らせるコードです。

import RPi.GPIO as GPIO     #GPIO用のモジュール
import time                 #時間制御用のモジュール

LedPin = 12     #GPIO18を使用

global p
GPIO.setmode(GPIO.BOARD)       # GPIOを物理ピン番号で指定
GPIO.setup(LedPin, GPIO.OUT)   # LedPinを出力モードに設定
GPIO.output(LedPin, GPIO.LOW)  # LedPinの出力をLoにする 

p = GPIO.PWM(LedPin, 500)      # PWM周波数を500Hzに設定
p.start(0)                     # DUTYの初期値を0に設定

p.ChangeDutyCycle(80)		   # DUTYを80%に変更
time.sleep(5)				   # 5秒間待つ
GPIO.output(LedPin, GPIO.LOW)  # LedPinの出力をLoにする 
p.stop() # PWM停止
GPIO.cleanup()

GPIO18から500HzのPWM波形を出力します。
「ChangeDutyCycle」でDUTYを指定します。

DUTYが80%の時の結果

DUTY80%

DUTYが20%の時の結果

DUTY20%

オシロスコープの波形はGPIO18の出力をモニタしています。

DUTYの違いによってLEDの明るさが変化していることが分かります。

明るさを徐々に変化させる

PWMのDUTYを徐々に変化させることで、明るさを徐々に変化させることができます。

コードは次の通りです。

import RPi.GPIO as GPIO     #GPIO用のモジュール
import time                 #時間制御用のモジュール

LedPin = 12     #GPIO18を使用

def setup():
    global p
    GPIO.setmode(GPIO.BOARD)       # GPIOを物理ピン番号で指定
    GPIO.setup(LedPin, GPIO.OUT)   # LedPinを出力モードに設定
    GPIO.output(LedPin, GPIO.LOW)  # LedPinの出力をLoにする 

    p = GPIO.PWM(LedPin, 500)      # PWM周波数を500Hzに設定
    p.start(0)                     # DUTYの初期値を0%に設定

def loop():
    while True:                       # 無限ループ
        for dc in range(0, 101, 1):   # dc(Duty Cycle)を0%から100%まで1%ずつ大きくする
            p.ChangeDutyCycle(dc)     # DUTYをdcの値に変更する
            time.sleep(0.02)          # 20ms間待つ
        time.sleep(1)                 # 1s間待つ
        for dc in range(100, -1, -1): # dc(Duty Cycle)を100%から0%まで1%ずつ小さくする
            p.ChangeDutyCycle(dc)     # DUTYをdcの値に変更する
            time.sleep(0.02)          # 20ms間待つ
        time.sleep(1)                 # 1s間待つ

def destroy():
    GPIO.output(LedPin, GPIO.LOW)  # LedPinの出力をLoにする
    p.stop() # PWM停止
    GPIO.cleanup()

if __name__ == '__main__':     # プログラムが実行された時
    print ('Program is starting ... ')
    setup()
    try:
        loop()
    except KeyboardInterrupt:  # ctrl-cでプログラム終了
        destroy()

DUTYを1%ずつ、20msごとに変化させています。
このコードを実行した結果はこのようになります(少し早送りしているので、実際はもっとゆっくり変化します)

関連キーワード

フリーワード検索