はじめに
RaspberryPi PicoでMicroPythonを使って、PWMを使う方法を解説します。PWMの確認にはLEDを使い、点滅・調光させるコードを解説します。
GPIOと同じON/OFF信号を「指定した周期」で「くり返し」出力できる仕組みです。以下の内容を設定できます。
- 周期(周波数):1秒間に何回ON/OFFさせるか
- Duty比 : 1周期中のON/OFF時間の割合
PWMはモーターやスピーカーなど、いろいろな用途に使用でき、LEDに使うと点滅・明るさを簡単に変えることができます。
必要な部品はLEDと抵抗だけで、見た目にも分かりやすいので、今回はLEDを使ってPWMを解説します。
環境
この記事は以下の環境で作成しています。
環境 | バージョン | 備考 |
開発用PC | Windows11 | Windows10でもOK |
ボード | RaspberryPi Pico | |
開発環境 | Thonny 3.3.13 |

LEDの接続
PicoのGP16ピンにLEDを接続します。抵抗は直結防止程度に手元にあった220Ωを使っています。PWMはすべてのGPIOピンで使用できます。
『GPIOの記事』で使った回路をそのまま使っているので、タクトスイッチがついています。今回は使わないので、接続しなくてもOKです。
PWMを同時に使用する場合、周期の設定は8ピンまで。Dutyの設定は16ピンまでという制約があるようです。PWMを同時に使用する際はご注意ください。
Picoピンアサイン

使用する部品と機器
今回の回路では、以下のものを使います。
RaspberryPi Pico

ブレッドボード

LED

抵抗
プログラム概要
今回のプログラムの概要は以下の通りです。
- PWMを設定する
- PWMでLEDを点滅させる
- PWMでLEDを点灯させて暗くする
- LEDを消灯する
実行結果
プログラムを実行すると、以下のようにLEDが光ります。
点滅

点灯 → 暗くする → 消灯
全体コード
全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。
import machine
import time
from machine import PWM
# GP16をPWMに使うための設定です
Led = PWM(machine.Pin(16, machine.Pin.OUT))
# 周期を1秒間に10回(10Hz)に設定します
Led.freq(10)
# 1回の周期の内、8割ON(Duty比:80)になるように設定します
# Duty比は、0~65536の範囲なので、Duty比:80は「52429」です。
Led.duty_u16(52429)
# 上のコードでDuty比を設定するとLEDが点滅するので、2秒待機します
time.sleep(2)
# Duty比は変えずに、周期を1000Hzに変更します。
# この周期になると、人の目では点滅ではなく、点灯に見えます
Led.freq(1000)
time.sleep(2)
# Duty比を10にセットします
# 周期が早い状態でDutyを下げると、LEDは暗く見えます
Led.duty_u16(3277)
time.sleep(2)
# Duty比0にセットすると、LEDが消灯します
Led.duty_u16(0)
time.sleep(2)
PCなし(Pico単体)でプログラムを実行したい場合は「main.py」にファイル名を変更して、Picoにアップロードしてください。
コードのポイント
PWMの設定
使用するピンをGPIOの出力として設定し、さらにPWM関数の()内に入れることで、PWM用のピンとして設定できます。
前回のGPIO出力の設定コードは以下でしたが、
# Led(出力)の設定です。
Led = machine.Pin(16, machine.Pin.OUT)
今回はそれをPWM()でさらに囲みます。
# GP16をPWMに使うための設定です
Led = PWM(machine.Pin(16, machine.Pin.OUT))
周期・Duty比の設定
freq関数を使って、ON/OFFを1秒間に何回変化させるか(周期)を設定します。
設定後、duty_u16関数でDuty比を設定することで、信号が出力されます。
duty_u16関数はその名の通り、Duty比を16ビット( 0~65536)で表します。そのためDuty比を80にしたい場合は、65536×0.8 ≒ 52429 と設定します。
# 周期を1秒間に10回(10Hz)に設定します
Led.freq(10)
# 1回の周期の内、半分ON(Duty比:80)になるように設定します
# Duty比は、0~65536の範囲なので、Duty比:80は「52429」です。
Led.duty_u16(52429)
freq関数に10以下の数値を設定すると「数値が小さい」としてエラーになります。10以上の値を設定してください。
上記のように周期をかなり遅い10ヘルツに設定すると、目視でPWM信号(8割ON, 2割OFF)の出力を確認することができます。
周期とDuty比の変更
再度freq関数を使って周期を変更します。
# Duty比は変えずに、周期を1000Hzに変更します。
# この周期になると、人の目では点滅ではなく、点灯に見えます
Led.freq(1000)
time.sleep(2)
# Duty比を10にセットします
# 周期が早い状態でDutyを下げると、LEDは暗く見えます
Led.duty_u16(3277)
time.sleep(2)
Duty比は変えていないのでLEDは点滅するはずですが、1000Hzにすると変化が早すぎて、人間の目には「点灯」しているように見えます(扇風機の羽のイメージ)。
目視では点灯に見えますが、信号的にはON/OFFの繰り返し(PWM)なので、Duty比を変更することが可能です。
また、Duty比を下げる(0に近くする)と、LEDに対する「平均電圧」を下げることができるので、基準となる電圧などは変えずに、Duty比だけで、LEDを暗くすることができます(LED調光)。


LEDの消灯
duty_u16関数に「0」を設定すると、Duty比が「0」(ON:0割, OFF10割)となるので、LEDが消灯します。
# Duty比0にセットすると、LEDが消灯します
Led.duty_u16(0)
time.sleep(2)

まとめ
RaspberryPi PicoでMicroPythonを使って、PWMを使う方法を解説しました。
LEDを使って簡単に試すことができるので、是非遊んでみてください。「PWMってどう使うの?」「1回使ってみたい」という方の参考になればうれしいです。
UdemyでRaspberryPiが学べます(無料あり)
UdemyにはRaspberryPiの講座があります。
教育・趣味以外にも広がりを見せている「RaspberryPiなどのIoT機器」ですが、大人向け・仕事向けのセミナーは少なく、探すのも面倒な状況です。
Udemyには『RaspberryPi』『Pico』『Arduino』の使い方や、基礎/実践が学べる講座が多数公開されています。無料で視聴できるものもあるので「研修で使いたい」「自分のアイデアを形にしたい」という方はUdemyを活用してみてください。
以下は、RaspberryPiの講座一覧です。
PWMができたらI2Cも使ってみよう
このブログでは、PicoのI2C通信の使い方についても解説しています。PWMに慣れてきたらI2Cにもチャレンジしてみましょう。温度センサや小型ディスプレイが簡単に使えます。
応援・要望お待ちしてます
ブログを見ていて「この辺を詳しく知りたい」「このライブラリの使い方を知りたい」「こんなことで困ってる」...etc があれば、コメント・問い合わせ・Twitterで教えてください。質問・ご要望に合わせて解説記事を作ります。
ブログを気に入っていただけたり、「応援してもいいよ」という方がいたら、ブログやSNSでの紹介をお願いします。 あたたかい応援は、中の人の更新の大きな励みになります。