GPIOは基本的に「0」か「1」だけど
前回はRaspberry Pi Pico W(以下:Pico W)を使用して作成した電子回路上のLEDを点灯・消灯を繰り返して点滅させました。
GPIOポートから出力する信号を、点灯の時は1、消灯の時は0にして、これを繰り返して点滅させたわけです。
この場合、LEDの明るさは点灯時は「100%」、消灯時は「0%」になります。
では、半分くらいの明るさでLEDを点灯したい、などはできるのでしょうか?
明るさの調整は「PWM」出力で
結論を先に言うと、GPIOポートに接続したLEDの明るさ調節は「できます」。
これを実現するには「PWM」を使います。PWMはGPIOポートが出力する0と1の信号の長さと出るタイミングを変化させることによって、明るさが「変化しているように見える」ものです。
PWMとは?
PWM(Pulse Width Modulation)とは、パルス幅変調のことで、デジタル信号を使ってアナログ的な量を制御する手法です。簡単に言うと、短いパルスを高速で繰り返し出し、そのパルスの幅(オンの時間)を調整することで、平均的な電圧値を変化させる方法です。
PWMでLEDの明るさを変える仕組み
PWM出力をLEDの電源として使用すると、LEDに電流を流し続けるのではなく、短いパルス状に電流を供給します。このパルスの幅を調整することで、LEDに流れる電流の平均値を変化させ、結果としてLEDの明るさを調整することができます。
Dury比が100%の場合は点灯、0%の場合は消灯となります。パルスの繰り返し(周波数)は人間の目がちらつきを感じない程度の周波数にすることが一般的です。
- パルス幅が長い場合(Duty比=大)
LEDに電流が流れている時間が長いため、平均的な電流値が大きくなり、LEDは明るく光ります。 - パルス幅が短い場合(Duty比=小)
LEDに電流が流れている時間が短いため、平均的な電流値が小さくなり、LEDは暗く光ります。
この図をLEDに当てはめると、Duty比50%の時は半分の明るさ、25%の時は25%の明るさとなります。
PWMを用いると、LEDの場合は明るさの変化、パルスモーターの場合は「モータの回転速度」などをコントロールすることが可能です。
プログラムを作ってみましょう
回路は「Raspberry Pi Pico WでLEDをピカピカさせよう(Lチカ)」のものをそのまま利用します。
今回作成するプログラムは、LEDの明るさが0%(消灯)から100%(全点灯)まで明るさをPWMで変化させます。
通常、Duty比は0~1.0となりますが、Duty比の制御にduty_u16を使用すると、0を0、1.0を65535までの16ビットの値で指定できます。例えば、半分の明るさ(Duty比0.5)はduty_u16で表すと32767です。
#GPIOピンを制御するために、machineモジュールをインポート import machine #時間を制御するために、utimeモジュールをインポート import utime #GPIO15をPWM出力ピンとして設定 led_pin = machine.Pin(15, machine.Pin.OUT) #GPIO15をPWMで制御 led_pwm = machine.PWM(led_pin) #PWMのパルス周波数(ちらつかないように) led_pwm.freq(1000) while True:#無限ループ for brightness in range(65535): #Duty比0%が0、100%が65535 led_pwm.duty_u16(brightness) utime.sleep(0.0001) #各段階の明るさごとに0.0001秒待機 #以下は暗くなる動き for brightness in range(65535, 0, -1): led_pwm.duty_u16(brightness) utime.sleep(0.0001)
Thonnyで上記のプログラムコードを入力し実行しましょう。回路と接続は前回のLチカのものをそのまま使います(プログラムだけ変更します)。
LEDがゆっくり明るくなったり暗くなったりするはずです。
プログラムが正しく動いたら、Pico Wにmain.pyとして保存しておきましょう。
アナログ的な出力にはPWM出力
今回は、LEDの明るさの制御にPWM出力を用いました。LEDは通常ONかOFFしかありませんが、PWMを使用すると明るさのコントロールが可能です。
PWMを使用するとパルスモーターの動作速度などもコントロールできるため、マイコン利用には欠かせないものとなっています。