はじめに
RaspberryPi(ラズパイ) でPWMを使う方法を解説します。回路はLEDのみ、プログラム言語は「Python」ライブラリに「RPi.GPIO」を使います。
LEDにPWMを使うことで、LEDの点滅・調光が簡単に扱えるようになります。
記事内では懐かしの「RaspberryPi2」を使っていますが「RaspberryPi2〜4」「RaspberryPi Zeroシリーズ」なら解説と同じ方法でGPIOが使えます。
PWMは、Pulse Width Modulationの略で、GPIOと同じON/OFF信号を「指定した周期」で「くり返し」出力できる仕組みです。
この仕組みを使うと、入力の電圧は変えずに、ONのパルス幅(毎周期のONの幅)を変えるだけで、任意の電圧を作ることができます。
PWMでは以下の内容が変更できます。
- 周期(周波数):1秒間に何回ON/OFFさせるか
- Duty比 : 1周期中のON/OFF時間の割合
上記の仕組みは、モーターやスピーカーなど、いろいろな用途に使用されており、LEDに使うと簡単に光の明暗操作(調光)をすることができます。
環境
環境 | バージョンなど | 備考 |
RaspberryPi | 2 Model B | RaspberryPi 2/3/4 Zero各種でも使えます |
OS | RaspberryPi OS (bullseye) | 32bit版です |
Python | 3.9.2 | OS プリインストールのバージョンです |
ライブラリ | RPi.GPIO |
LEDの接続
RaspberryPiの「GPIO 13」ピンにLEDを接続します。抵抗は直結防止程度に手元にあった220Ωを使っています。
RaspberryPiで(Hardware)PWMが使えるのは、GPIO12,13ピンのみなので、どちらかを選択してください。
RaspberryPi ピンアサイン
※ RaspberryPi 公式のGitHubより引用
使用する部品
今回の回路では以下の部品を使います。
RaspberryPi 4 (8GBモデル)
スイッチやLEDをつなげて使うなら、価格が下がった「RaspberryPi4」がおすすめです。

ブレッドボード
国内サンハヤト製のブレッドボードです。少々堅めの指し心地ですが、海外製と違ってピン穴の番号がすべて印刷されており、品質も高いのでおすすめです。

LED
一般的な砲弾型のLEDでOKです。以下のようなセットで買っておくと、購入の手間がはぶけます。

抵抗
お手持ちのものでOKです。ない方は一度セットで揃えてしまうと送料と時間が節約できます。

プログラム概要
今回のプログラムの概要は以下の通りです。
- GPIOの番号指定の設定をする。
- GPIO・PWMを設定する
- PWMでLEDを点滅させる
- PWMでLEDを暗くする
- PWMでLEDを消灯する
実行結果
プログラムを実行すると、以下のようにLEDが光ります。
点滅・点灯
調光(暗く)・消灯
全体コード
全体コードは以下の通りです。詳細は後述する「コードのポイント」で解説します。
# RPi.GPIOのライブラリを「GPIO」という名前で使います
import RPi.GPIO as GPIO
import time
# GPIOのピン番号指定を「BCM」に設定します
GPIO.setmode(GPIO.BCM)
# 設定を確認。BCMの場合は「11」が返ります
mode = GPIO.getmode()
print(mode)
# PWMに使うピンに名前をつけます
PWM = 13
# PWMに使うピンを「Out」に設定します
GPIO.setup(PWM,GPIO.OUT)
# PWMに使うピンと周波数(1秒間に10回)を設定します
pwm = GPIO.PWM(PWM,10)
# PWMの制御を開始します
# 1周期の内,8割がONになるように設定します(Duty:80)
pwm.start(80)
time.sleep(2)
# Dutyは変えずに、周波数を1000に変更します
# この周波数になると、人の目ではLEDが点灯しているように見えます
pwm.ChangeFrequency(1000)
time.sleep(2)
# Dutyを「20」に設定します
# 周波数が早い状態で、Dutyを下げると、LEDが暗くなったように見えます
pwm.ChangeDutyCycle(10)
time.sleep(2)
# Dutyを「0」に設定します
# LEDが消灯します
pwm.ChangeDutyCycle(0)
time.sleep(2)
print("done.")
# GPIOの設定を解除します
GPIO.cleanup(PWM)
コードのポイント
ピン番号の指定方法の設定
ピン番号の指定方法をsetmode関数で設定します。
# GPIOのピン番号指定を「BCM」に設定します
GPIO.setmode(GPIO.BCM)
# 設定を確認。BCMの場合は「11」が返ります
mode = GPIO.getmode()
print(mode)
指定の種類は「GPIO〇〇の番号を指定する”BCM”」「ピンの物理的な番号を指定する”BOARD”」の二種類がありますが、今回は「GPIO〇〇」の「BCMの方式」を使います。
選択した指定はgetmode関数で確認できます。
名称 | 指定 | 設定 | getmode() |
BCM | RPi.GPIO.BCM | GPIO〇〇と記載のある番号 | 11 |
BOARD | RPi.GPIO.BOARD | 基板のピン番号(1~40) | 10 |
※ 未設定の場合は「-1」が返ります。
GPIOの設定(出力)
output関数を使って、PWMに使うピンをGPIOの出力に設定します。
引数には「ピン番号」「入力・出力の指定」を渡します。
# PWMに使うピンに名前をつけます
PWM = 13
# PWMに使うピンを「Out」に設定します
GPIO.setup(PWM,GPIO.OUT)
内容 | 設定 | 説明 |
ピン番号 | 13 | GPIO13 (BCM形式です) |
入出力指定 | RPi.GPIO.OUT | 出力用に設定 |
PWMの設定
PWM関数を使って、上で出力に設定済みのピン番号と、PWMの周波数を設定します。
# PWMに使うピンと周波数(1秒間に10回)を設定します
pwm = GPIO.PWM(PWM,10)
内容 | 設定 | 説明 |
ピン番号 | 13 | GPIO13 (BCM形式です) |
周波数 | 10 | 単位は[Hz]です。 0.1単位で指定できます |
PWM出力の開始
start関数でDuty比を設定すると、PWM出力が始まります。
# PWMの制御を開始します
# 1周期の内,8割がONになるように設定します(Duty:80)
pwm.start(80)
time.sleep(2)
上記コードでは、周期をかなり遅く(10Hz)しているので、Duty比による点滅を目視で確認することができます(LEDを点滅させたいときに便利です).
周波数の変更
ChangeFrequency関数でPWMの周波数を変更することができます。
# Dutyは変えずに、周波数を1000に変更します
# この周波数になると、人の目ではLEDが点灯しているように見えます
pwm.ChangeFrequency(1000)
time.sleep(2)
上記コードは、周波数の変更だけでDuty比は変えていません。そのため、LEDは変わらず点滅していますが、周期が早いので人の目では「点灯」しているように見えます(扇風機の羽のイメージです)。
Duty比の変更
ChangeDutyCycle関数でDuty比を変更することができます。
設定範囲は0.0~100.0で「0」を指定するとPWM出力が停止します。
# Dutyを「20」に設定します
# 周波数が早い状態で、Dutyを下げると、LEDが暗くなったように見えます
pwm.ChangeDutyCycle(10)
time.sleep(2)
# Dutyを「0」に設定します
# LEDが消灯します
pwm.ChangeDutyCycle(0)
time.sleep(2)
LEDの明るさを電気的に変えるには電圧値・抵抗値の変更が必要で、プログラムで制御するには大変です。それに対してPWMなら、電圧を変えずにDuty比だけで明るさを調整することが出来ます。
まとめ
RaspberryPi でPythonを使って、PWMを使う方法を解説しました。
LED1つで出来るので、ぜひ遊んでみてください。参考になればうれしいです。
おすすめ書籍
MicroPythonのプログラミングガイドブックがついに登場!
「MicroPython」の専門書がついに発売になりました!
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方までが、”ガッツリ”学べます!
別言語を使っている人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学びたい人におすすめの内容となっています。
全ての内容はここでは紹介しきれないので、詳細は以下からご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。

質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。