Python Raspberry Pi Pico WOKWi プログラム 回路 電子工作 高専3年生

【Raspberry Pi Pico入門③】PWM制御の基礎【アナログ出力】

前回はスイッチを使ったLED制御を学びました。

今回はLEDの光る明るさを変える制御について学んでゆきます。

PWMとは

PWM(Pulse Width Modulation)とは、「電気を点けたり消したりする時間の割合を調整することで、出力の強さを変える技術」です。

矩形波(方形波)において周期Tに占めるHの時間tの割合(デューティ比)を変化させることで、疑似的なアナログ出力を実現することができます(実際のアナログ出力ではないので注意してください)。

PWMは、DCモータの回転速度制御やLEDの明るさの制御(調光)などに利用されています。また、人型ロボットの関節などに利用されるRCサーボモータの制御にも利用されています。

「analog」という名称であるが、電圧が変化している訳ではなく、あくまで疑似アナログ出力なので注意してください。

たとえば…

  • 点灯:消灯 = 1:1(50%) → 明るさ中くらい
  • 点灯:消灯 = 9:1(90%) → 明るさ強め
  • 点灯:消灯 = 1:9(10%) → 明るさ弱め

これを**とても速い速度(数千回/秒)**で繰り返すことで、LEDは「チカチカ」せず、明るさが変わったように見えます。

例題1

LEDの明るさを指定して点灯

以下のようなプログラムになります。

from machine import Pin, PWM
import time

led = PWM(Pin(15))       # GPIO15をPWM出力に設定
led.freq(1000)           # PWMの周波数を1000Hzに設定

led.duty_u16(32768)      # デューティ比50%(最大65535の半分)
  • PWM(Pin(15)):GPIO15ピンにPWMを出力
  • freq(1000):1秒間に1000回の速さで点滅(チラつき防止)
  • duty_u16(x):PWMの強さを0〜65535の値で指定
    例:65535 = 最大出力(明るさ100%)、0 = OFF

例題2

明るさをだんだん変える

from machine import Pin, PWM
import time

led = PWM(Pin(15))
led.freq(1000)

while True:
    # 徐々に明るく
    for i in range(0, 65536, 1024):
        led.duty_u16(i)
        time.sleep(0.01)
    
    # 徐々に暗く
    for i in range(65535, -1, -1024):
        led.duty_u16(i)
        time.sleep(0.01)
  • range(0, 65536, 1024):明るさを0→最大まで増やす
  • range(65535, -1, -1024):明るさを最大→0まで減らす
  • time.sleep(0.01):変化の速度(速くするとアニメーションも速くなる)

課題6

ボタンを押すごとに明るさを段階的に切り替わる回路を作成せよ。

ボタン(GPIO14)を押すたびに、LEDの明るさが
 →「OFF → 弱 → 中 → 強 → OFF…」と繰り返し切り替わる

押しっぱなしでは反応せず、「押された瞬間」だけ反応

解答例はこちら
from machine import Pin, PWM
import time

led = PWM(Pin(15))
led.freq(1000)

button = Pin(14, Pin.IN, Pin.PULL_DOWN)

# 明るさの段階をリストで管理
levels = [0, 20000, 40000, 65535]
level_index = 0

prev = 0  # 前回のボタン状態

while True:
    current = button.value()

    # 押された瞬間だけ反応(エッジ検出)
    if prev == 0 and current == 1:
        level_index = (level_index + 1) % len(levels)  # インデックスを循環
        led.duty_u16(levels[level_index])              # 明るさを設定

    prev = current
    time.sleep(0.01)

課題7

2つのボタンを使ってLEDの明るさを手動調整する回路を作成せよ。

ボタンA(GPIO14)を押すたびに明るさを「+5000」

ボタンB(GPIO13)を押すたびに明るさを「−5000」

明るさは 0〜65535の範囲内に収める

解答例はこちら
from machine import Pin, PWM
import time

led = PWM(Pin(15))
led.freq(1000)

btn_up = Pin(14, Pin.IN, Pin.PULL_DOWN)
btn_down = Pin(13, Pin.IN, Pin.PULL_DOWN)

duty = 0
led.duty_u16(duty)

prev_up = 0
prev_down = 0

while True:
    current_up = btn_up.value()
    current_down = btn_down.value()

    # 明るさを上げる
    if prev_up == 0 and current_up == 1:
        duty += 5000
        if duty > 65535:
            duty = 65535
        led.duty_u16(duty)

    # 明るさを下げる
    if prev_down == 0 and current_down == 1:
        duty -= 5000
        if duty < 0:
            duty = 0
        led.duty_u16(duty)

    prev_up = current_up
    prev_down = current_down
    time.sleep(0.01)

課題8

課題7のLEDに対する出力の変化(PWM)をオシロスコープを使って観察し、報告せよ。

オシロスコープは下記の記事を参考にしてください。

次回はこちら

Follow me!

-Python, Raspberry Pi Pico, WOKWi, プログラム, 回路, 電子工作, 高専3年生
-, , , , ,

PAGE TOP