2.3 LEDのフェード¶
今まで、デジタル出力として高レベルと低レベル(ONとOFF)の二つの出力信号しか使用していませんでした。 しかし、現実の利用シーンでは、多くのデバイスが単純にON/OFFだけで動作するわけではありません。例えば、モーターの速度を調整したり、デスクランプの明るさを調整したりといった場面があります。 以前は、これを達成するために抵抗を調整するスライダーが用いられましたが、それは信頼性に欠け、非効率的でした。 そのため、パルス幅変調(PWM)がこのような複雑な問題に対する実用的な解決策として登場しました。
パルスは高レベルと低レベルを含むデジタル出力です。これらのピンのパルス幅は、ON/OFFの速度を変更することで調整できます。
20ms(ほとんどの人が視覚的に保持する期間)という短い時間内で、LEDを点灯させ、消灯させ、再び点灯させると、消灯していたことに気づかず、光の明るさがわずかに弱くなるだけです。 この期間中にLEDが点いている時間が多いほど、明るくなります。 言い換えれば、サイクル内でパルスが広いほど、マイクロコントローラーから出力される「電気信号の強度」が大きくなります。 これがPWMがLEDの明るさ(またはモーターの速度)を制御する仕組みです。
Pico WがPWMを使用する際に注意すべき点がいくつかあります。この図を見てみましょう。
Pico Wは各GPIOピンでPWMをサポートしていますが、実際には独立したPWM出力が16個(30個ではない)あり、これらは左側のGP0からGP15までに分散されています。右側のGPIOのPWM出力は左側と同一です。
プログラミング中に同じPWMチャンネルを異なる目的で設定しないように注意が必要です。例えば、GP0とGP16は両方ともPWM_0Aです。
この知識を理解した上で、LEDのフェード効果を実現してみましょう。
必要なコンポーネント
このプロジェクトには、以下のコンポーネントが必要です。
全体のキットを購入する方が確実に便利です。リンクはこちら:
名前 |
このキットに含まれるアイテム |
リンク |
---|---|---|
ケプラーキット |
450+ |
以下のリンクから個別にも購入できます。
SN |
コンポーネント |
数量 |
リンク |
---|---|---|---|
1 |
1 |
||
2 |
Micro USBケーブル |
1 |
|
3 |
1 |
||
4 |
いくつか |
||
5 |
1(220Ω) |
||
6 |
1 |
回路図
このプロジェクトは、最初のプロジェクト 2.1 こんにちは、LED! と同じ回路ですが、信号のタイプが異なります。最初のプロジェクトではGP15から直接デジタルの高レベルと低レベル(0&1)を出力してLEDを点灯または消灯させていましたが、このプロジェクトではGP15からPWM信号を出力してLEDの明るさを制御します。
配線
コード
注釈
kepler-kit-main/micropython
のディレクトリにある2.3_fading_led.py
ファイルを開いたり、このコードをThonnyにコピーして、「Run Current Script」をクリックするか、単にF5を押して実行します。右下隅にある「MicroPython(Raspberry Pi Pico)」のインタプリタを選択するのを忘れないでください。
詳細なチュートリアルは、 コードを直接開いて実行する を参照してください。
import machine
import utime
led = machine.PWM(machine.Pin(15))
led.freq(1000)
for brightness in range(0,65535,50):
led.duty_u16(brightness)
utime.sleep_ms(10)
led.duty_u16(0)
このコードが実行されると、LEDの明るさが徐々に増していきます。
どのように動作するのか?
ここでは、GP15のPWM出力のデューティサイクルを変更することで、LEDの明るさを変更しています。以下の行に注目してください。
import machine
import utime
led = machine.PWM(machine.Pin(15))
led.freq(1000)
for brightness in range(0,65535,50):
led.duty_u16(brightness)
utime.sleep_ms(10)
led.duty_u16(0)
led = machine.PWM(machine.Pin(15))
は、GP15ピンをPWM出力として設定します。led.freq(1000)
はPWMの周波数を設定するために使用され、ここでは1000Hzに設定されています。つまり、1ms(1/1000)が1サイクルです。led.duty_u16()
はデューティサイクルを設定するために使用され、これは16ビットの整数(2^16=65536)です。0は0%のデューティサイクルを示し、各サイクルで高レベルを出力する時間が0%、すなわち、全てのパルスがオフになります。値65535は、デューティサイクルが100%であることを示し、パルス全体がオンになり、結果は「1」になります。値が32768の場合、パルスを半分オンにするので、LEDは全開時の半分の明るさになります。