ラズパイピコ(Raspberry Pi Pico)で「Lチカ(LEDを点滅させる)」ができた人、次はもう一歩進んでLEDの明るさを自由にコントロールしてみましょう!
今回は「PWM(パルス幅変調)」という仕組みを使って、LEDの明るさを100%、50%、25%と段階的に変化させます。初心者でも大丈夫。コードをそのまま写して実行すれば、すぐに「光の変化」が体験できます。
しかも、PWMを理解しておくと、次に「モーターの回転数制御」や「LEDフェード効果」など応用にもつながります。この記事では、Raspberry Pi PicoとMicroPythonを使って、楽しく学べる実験を進めていきましょう!
完成イメージ
LEDの明るさが3段階で変化するよ。
この記事でできること(目的とゴール)
この記事では以下のことを学びます:
- PWM(パルス幅変調)の基本的な考え方
- Raspberry Pi PicoでLEDの明るさを制御する方法
- 初心者向けコード → 中級者コード → リファクタリング済みコードへの流れ
PWMは「電気のON/OFFを高速で切り替えて、平均電力で明るさを調整する」技術なんだよ。電気を弱めてるわけじゃないの!
準備:必要な道具と環境
パーツ一覧
| 品名 | 役割 | 代替案 |
|---|---|---|
| Raspberry Pi Pico W | マイコン本体 | Pico(無印)でも可 |
| Micro USBケーブル | データ通信・電源供給 | Type-A to Micro USB(データ通信対応) |
| ブレッドボード | 配線用の土台 | 小型でもOK |
| ジャンパワイヤ(オス-オス) | 接続ケーブル | 色違いで用意すると便利 |
| LED(赤・黄・緑など) | 点灯テスト用 | 単色1つでも可 |
| 抵抗(220〜330Ω) | 電流制限 | 470Ωでも可 |
動作環境(筆者の検証環境)
- PC:MacBook Air (M1, macOS 15.5 arm64)
- エディタ:Thonny 4.1.6(Python 3.10.11, Tk 8.6.13)
- デバイス:Raspberry Pi Pico W(MicroPython)
もちろん、Windows や Linux 環境でも動作します。MicroPythonを導入していれば同じコードで実行可能です。
配線図


安全上の注意
- LEDには極性(+と−)があります。長い脚が+側です。
- 抵抗を必ず直列に入れましょう。入れ忘れるとLEDが焼ける危険があります。
- 静電気が強い日や金属テーブル上では、手で基板を触る前に放電しておきましょう。
まずは動くだけのベタ打ちコード(初学者)
最初はPWMを使わず、LEDの点灯・消灯を高速に繰り返して明るさを「擬似的に」変える方法から始めます。
from machine import Pin
from time import sleep
# 定数定義
LED_PIN = 15
LED_ON = 1
LED_OFF = 0
PWM_STEP_TIME = 0.005
# 初期化
led = Pin(LED_PIN, Pin.OUT)
# メインループ
while True:
# --- 通常点灯(100% duty) ---
for i in range(20):
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_ON)
sleep(PWM_STEP_TIME)
# --- 50% duty(擬似) ---
for i in range(20):
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_OFF)
sleep(PWM_STEP_TIME)
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_OFF)
sleep(PWM_STEP_TIME)
# --- 25% duty(擬似) ---
for i in range(20):
led.value(LED_ON)
sleep(PWM_STEP_TIME)
led.value(LED_OFF)
sleep(PWM_STEP_TIME)
led.value(LED_OFF)
sleep(PWM_STEP_TIME)
led.value(LED_OFF)
sleep(PWM_STEP_TIME)
単純ですが、これでもLEDの明るさが少しずつ変わって見えます。 この方法は「PWMっぽい」挙動を再現していますが、実際のPWM機能を使ったほうがシンプルで滑らかです。
リファクタリング①:PWMを使ってシンプルに
MicroPythonには、PWM制御を簡単に扱えるクラスがあります。これを使うとコードが一気にすっきりします。
from machine import Pin, PWM
from time import sleep
# 定数定義
LED_PIN = 15
PWM_FREQ_HZ = 1000 # 周波数(1kHz)
HOLD_SECONDS = 1.0 # 各デューティ比の表示時間(秒)
# 初期化
pwm = PWM(Pin(LED_PIN))
pwm.freq(PWM_FREQ_HZ)
# メインループ
while True:
# --- 100% duty ---
pwm.duty_u16(65535) # 最大値(明るさMAX)
sleep(HOLD_SECONDS)
# --- 50% duty ---
pwm.duty_u16(32768) # 約半分
sleep(HOLD_SECONDS)
# --- 25% duty ---
pwm.duty_u16(16384) # 約1/4
sleep(HOLD_SECONDS)
このように、pwm.duty_u16() に値(0〜65535)を渡すだけで、LEDの明るさを自由に制御できます。 数字が大きいほどLEDが明るくなります。
リファクタリング②:きれいで再利用しやすい形に
もう少しプログラムを整理して、見やすく・保守しやすくしてみましょう。 関数を定義してデューティ比をリスト化することで、追加や変更も簡単になります。
from machine import Pin, PWM
from time import sleep
# ==========================
# 定数定義
# ==========================
LED_PIN = 15 # LED接続ピン
PWM_FREQ_HZ = 1000 # PWM周波数(Hz)
HOLD_SECONDS = 1.0 # 各デューティ比の表示時間(秒)
# デューティ比リスト(比率で指定)
DUTY_RATIOS = [1.0, 0.5, 0.25]
# ==========================
# 関数定義
# ==========================
def set_brightness(pwm, ratio):
"""LEDの明るさをデューティ比で設定"""
duty_value = int(65535 * ratio)
pwm.duty_u16(duty_value)
sleep(HOLD_SECONDS)
# ==========================
# メイン処理
# ==========================
def main():
pwm = PWM(Pin(LED_PIN))
pwm.freq(PWM_FREQ_HZ)
while True:
for ratio in DUTY_RATIOS:
set_brightness(pwm, ratio)
# ==========================
# 実行部
# ==========================
if __name__ == "__main__":
main()
関数化することで「明るさを設定する」という目的が明確になり、コード全体が読みやすくなりました。 また、デューティ比を増やすだけでステップ数を簡単に変更できます。
仕組みを理解する(技術解説)
PWMは「一定周期の中でON時間とOFF時間を切り替える」ことで平均電力を調整します。 LEDのような目に見えるものでは、ONの割合が増えるほど明るく見えるのです。
たとえば、周期が1msの場合:
- ON 100% → 常に光る(明るい)
- ON 50% → 半分だけ光る(中くらい)
- ON 25% → ちらっと光る(暗い)
この制御は、LEDだけでなく「モーターの回転制御」「音量調整」「サーボ制御」にも応用される重要な基礎技術です。
🔹なぜ周期を1msにしたのか <PWM_FREQ_HZ = 1000 # PWM周波数(Hz)>
人間の目は0.02秒(=20ms)より速い点滅を「点滅」として認識できません。
つまり、1ms周期(1kHz)なら目には「チラチラ」せず滑らかな光に見えるのです。
トラブルシューティング
もしうまく動かない場合は、以下を確認しましょう。
| 症状 | 原因 | 対処法 |
|---|---|---|
| LEDが光らない | 極性ミスまたはピン番号間違い | LEDの向き(長い脚が+)を確認 |
| 常に点灯している | GPIOが常にHIGHになっている | プログラムを再実行、またはリセットボタンを押す |
| 明るさが変わらない | PWM周波数やデューティ設定ミス | pwm.freq()とduty_u16()の値を見直す |
| LEDが焼けた | 抵抗未使用 | 220〜330Ωの抵抗を必ず直列に挟む |
まとめ/次回予告
今回は、PWM制御を使ってLEDの明るさを変化させる方法を学びました。
- PWMはON/OFFの割合で明るさを制御する技術
- MicroPythonではPWMクラスを使えば簡単に扱える
- 関数化することで再利用性も向上
次回はこのPWMを応用して、LEDをなめらかにフェードイン・フェードアウトさせる方法に挑戦します。 ブックマークしておくと、次の記事もすぐに見つけられますよ!
-120x68.png)
コメント