はじめに
RaspberryPi PicoでMicroPythonを使って、PWMを使う方法を解説します。
GPIOなどでLEDのON/OFF(Lチカ)がした後は、LEDの高速点滅や、明るさを変えてみたい、と考える人も多いと思います。そんなときは「PWM」を使うのがおすすめです。
後述のように、プログラムのコード・配線も簡単なので、LEDをいろいろと光らせてみたい!という方はぜひご覧ください。
PWMは、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です。
※ 2022/09/10 ピンの説明に誤りがあったため、修正しました。
ピン番号 | 内容 | 備考 |
38 | GND | グラウンド |
36 | 3V3(OUT) | 電源(3.3V) |
25 | GP19 | 使用しません |
21 | GP16 | PWM出力に使います。 |
PWMを同時に使用する場合、周期の設定は8ピンまで。Dutyの設定は16ピンまでという制約があるようです。PWMを同時に使用する際はご注意ください。
Picoピンアサイン(Pin-Out)
※ Pico公式サイトより引用
使用する部品
今回の回路では、以下のものを使います。
ブレッドボード
国内サンハヤト製のブレッドボードです。少々堅めの指し心地ですが、海外製と違ってピン穴の番号がすべて印刷されており、品質も高いのでおすすめです。
LED
一般的な砲弾型のLEDでOKです。以下のようなセットで買っておくと、購入の手間がはぶけます。
抵抗
お手持ちのものでOKです。ない方は一度セットで揃えてしまうと送料と時間が節約できます。
プログラム概要
今回のプログラムの概要は以下の通りです。
- 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)
Pico/Pico Wだけ(PCなし)でプログラムを実行する場合は、ファイル名を「main.py」にして、Pico/Pico W本体に保存してください。
コードのポイント
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回使ってみたい」という方の参考になればうれしいです。
お知らせ
MicroPythonのプログラミングガイドブックが遂に発売!
「MicroPython」の本が遂にでました。
この一冊で、MicroPythonの言語仕様から、プログラミングの仕方まで”ガッツリ”学べます!。
内容は、普段別言語で開発している人や、これからマイコンを始める(工学系の)学生を対象としているので「初心者向け」ではありません。しかし、「自前のライブラリの作成」が目標なので、これ一冊で「ガッツリ」とMicroPythonを学ぶことができます。
全ての内容はここでは紹介しきれないので、詳細は以下のAmazonページをご覧ください。目次だけでも”ガッツリ”なのが確認できると思います。
Pico/Pico W関連のおすすめ本
RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。
PWMのあとは、I2Cも使ってみよう
このブログでは、PicoのI2C通信の使い方についても解説しています。PWMに慣れてきたらI2Cにもチャレンジしてみましょう。温度センサや小型ディスプレイが簡単に使えます。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。