今回はPWM制御を使ってLEDの色を変えながら光らせたいと思います!
PWM制御の出来るとモーターの制御が出来たりと、遊びの幅が広がります!
本記事のゴール
PWM制御を使ってLEDの色を変化!
結果が気になる人は、「Contents」の「結果」へと飛んでください!
Contents
準備
PWM制御とは?
PWM制御の詳しい説明はまた別の記事でしたいと思っていますので、ここでは何となくのイメージを持てるくらいの軽い説明にしたいと思います。
まず結論から言うと、PWM制御の利点は
「見かけ上の電圧を変化させることができる」
ことです。
見かけ上という言葉は置いといて・・・、電圧を変化させることで例えばLEDだと光の強さを変えることが出来ます。
電圧が大きい→LEDの光も強い
電圧が小さい→LEDの光は弱い
つまり電圧を変更して機器を制御することをPWM制御と言います。
見かけ上という言葉については別の記事で説明したいと思いますが、本質的に大切なのは電圧を変更できることです。
これにより、LEDなら光の強さ、モーターなら回転数を制御できるからです。
さらに詳しい説明は以下のサイトが参考になります。
使用した部品
使用部品
- ラズベリーパイ zero WH
- Type-Bの充電ケーブル
- ブレッドボード
- ジャンプワイヤー
- RGB LED
- 抵抗(220Ω)×3
今回は普通のLEDではなくRGB LEDを使用しています。
これは赤・緑・青色のLEDが1つになったものです。
SODIAL(R) 50個 5mm ラウンドヘッド共通カソードRGBLEDライト発光のダイオード
【Amazonのページへ移動します】
配線・回路図
配線はこんな感じです。
回路図はこんな感じです。
LEDが3つあるだけなので、回路図はシンプルです。
Pythonでプログラムの作成・実行
ライブラリ(pigpio)のインストール
PWM制御にはpigpioというライブラリを使って行う事が多いみたいなので、まずはpigpioをインストールします。
インストールはこちらのサイトを参考にしました。
まずはターミナルにて以下のコマンドでインストールして下さい。
1 |
sudo apt-get install pigpio |
インストールが出来たら、pigpioを立ち上げる必要があるので、以下のコマンドを入力します。
1 |
sudo pigpiod |
ラズパイをシャットダウンした後に再び起動してpigpioを使用する場合は上記のコマンドをその都度入力する必要があります。
毎回コマンドを入力するのは面倒なので、ラズパイを起動したと同時に自動でpigpioを起動するように設定します。
設定の方法は以下のコマンドを打ち込むだけです。
1 |
sudo systemctl enable pigpiod |
コマンドを打ち込んだら一度再起動してください。
再起動のコマンドは以下の通りです。
1 |
sudo reboot |
これにてpigpioのインストール・使用環境の構築が出来ました。
Pythonでプログラムの作成
プログラムを作成していきます。
まずは完成したコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
#!/usr/bin/env python # -*- coding: utf-8 -*- import time import pigpio R_Pin = 17 #BCM Number of Red_Pin G_Pin = 27 #BCM Number of Green_Pin B_Pin = 22 #BCM Number of Blue_Pin LED_freq = 200 #frequency LED_range = 100 #Max of PWM LED_time = 0.2 pi = pigpio.pi() #access to GPIO pi.set_mode(R_Pin, pigpio.OUTPUT) #Set output Pin number pi.set_mode(G_Pin, pigpio.OUTPUT) #Set output Pin number pi.set_mode(B_Pin, pigpio.OUTPUT) #Set output Pin number pi.set_PWM_frequency(R_Pin, LED_freq ) #Set Frequency pi.set_PWM_frequency(G_Pin, LED_freq ) #Set Frequency pi.set_PWM_frequency(B_Pin, LED_freq ) #Set Frequency pi.set_PWM_range (R_Pin, LED_range ) #Set Max of PWM pi.set_PWM_range (G_Pin, LED_range ) #Set Max of PWM pi.set_PWM_range (B_Pin, LED_range ) #Set Max of PWM #Initial Condition pi.write(R_Pin,0) pi.write(G_Pin,0) pi.write(B_Pin,0) pi.set_PWM_dutycycle(R_Pin, LED_range) time.sleep(0.5) #Flashing try: R_light = LED_range G_light = 0 B_light = 0 d_light = 5 while True: #from Red to Red+Green while R_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(G_Pin, G_light) time.sleep(LED_time) G_light += d_light if G_light >= LED_range: d_light *= -1 #from Red+Green to Green while G_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(R_Pin, R_light) time.sleep(LED_time) R_light += d_light if R_light <= 0: d_light *= -1 #from Green to Green+Blue while G_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(B_Pin, B_light) time.sleep(LED_time) B_light += d_light if B_light >= LED_range: d_light *= -1 #from Green+Blue to Blue while B_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(G_Pin, G_light) time.sleep(LED_time) G_light += d_light if G_light <= 0: d_light *= -1 #from Blue to Blue+Red while B_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(R_Pin, R_light) time.sleep(LED_time) R_light += d_light if R_light >= LED_range: d_light *= -1 #from Blue+Red to Red while R_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(B_Pin, B_light) time.sleep(LED_time) B_light += d_light if B_light <= 0: d_light *= -1 except KeyboardInterrupt: pass #Release pi.write(R_Pin,0) pi.write(G_Pin,0) pi.write(B_Pin,0) print "Stop." |
それでは何をしているか見ていきます。
(参考サイトはこの章の最後に載せますので併せて見ると理解が深まると思います。)
7-9行目
1 2 3 |
R_Pin = 17 #BCM Number of Red_Pin G_Pin = 27 #BCM Number of Green_Pin B_Pin = 22 #BCM Number of Blue_Pin |
赤、緑、青色のBCM番号です。
10-12行目
1 2 3 |
LED_freq = 200 #frequency LED_range = 100 #Max of PWM LED_time = 0.2 |
「LED_freq」はPWM制御の周波数で、「LED_range」はPWMの範囲を表しています。
イメージ的には、周波数が大きいほど細かな色の変更が出来て、範囲が大きいほど光の強弱を細かく変えれます。
(ここのパラメータを変更して動かしてみましたが、影響は少なそうでした。また、説明が間違っている場合はこっそり教えて下さい。)
「LED_time」は発光時間[s]です。
14行目
1 |
pi = pigpio.pi() #access to GPIO |
GPIOピンにアクセスします。
15-17行目
1 2 3 |
pi.set_mode(R_Pin, pigpio.OUTPUT) #Set output Pin number pi.set_mode(G_Pin, pigpio.OUTPUT) #Set output Pin number pi.set_mode(B_Pin, pigpio.OUTPUT) #Set output Pin number |
GPIOの出力設定をします。
これにより、BCM番号に応じた処理を行う事が出来ます。
19-25行目
1 2 3 4 5 6 7 |
pi.set_PWM_frequency(R_Pin, LED_freq ) #Set Frequency pi.set_PWM_frequency(G_Pin, LED_freq ) #Set Frequency pi.set_PWM_frequency(B_Pin, LED_freq ) #Set Frequency pi.set_PWM_range (R_Pin, LED_range ) #Set Max of PWM pi.set_PWM_range (G_Pin, LED_range ) #Set Max of PWM pi.set_PWM_range (B_Pin, LED_range ) #Set Max of PWM |
これはBCM番号に応じた、PWM制御の周波数と範囲を設定しています。
28-31行目
1 2 3 4 |
#Initial Condition pi.write(R_Pin,0) pi.write(G_Pin,0) pi.write(B_Pin,0) |
初期値を設定していて、初めはどれも光っていません。
32-33行目
1 2 |
pi.set_PWM_dutycycle(R_Pin, LED_range) time.sleep(0.5) |
ここでPWM制御を行っており、赤色LEDを最大限光らせる指示を与えています。
「time.sleep」は赤の光を少し維持する目的で加えました(そちらの方が見栄えが良いかなと思って)。
36-93行目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
#Flashing try: R_light = LED_range G_light = 0 B_light = 0 d_light = 5 while True: #from Red to Red+Green while R_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(G_Pin, G_light) time.sleep(LED_time) G_light += d_light if G_light >= LED_range: d_light *= -1 #from Red+Green to Green while G_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(R_Pin, R_light) time.sleep(LED_time) R_light += d_light if R_light <= 0: d_light *= -1 #from Green to Green+Blue while G_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(B_Pin, B_light) time.sleep(LED_time) B_light += d_light if B_light >= LED_range: d_light *= -1 #from Green+Blue to Blue while B_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(G_Pin, G_light) time.sleep(LED_time) G_light += d_light if G_light <= 0: d_light *= -1 #from Blue to Blue+Red while B_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(R_Pin, R_light) time.sleep(LED_time) R_light += d_light if R_light >= LED_range: d_light *= -1 #from Blue+Red to Red while R_light == LED_range and d_light < 0: pi.set_PWM_dutycycle(B_Pin, B_light) time.sleep(LED_time) B_light += d_light if B_light <= 0: d_light *= -1 except KeyboardInterrupt: pass |
ここは長いですが、やっていることは繰り返しですので単純です。
まずは概要を。
- 赤・緑・青の光の強弱に初期値を与える
- 赤色から[赤+緑]色になるよう指示
- [赤+緑]色から緑色になるよう指示
- 緑色から[緑+青]色になるよう指示
- [緑+青]色から青色になるよう指示
- 青色から[青+赤]色になるよう指示
- [青+赤]色から赤色になるよう指示
- 2から7を「Ctrl+C」が入力されるまで続ける
図解すると以下の感じです。
またやっていることは以下の表のようにそれぞれのLEDの光の強さを調整しています。
値は光の強さの最大値を100として、5ずつ変化させています。
赤 | 緑 | 青 |
100 | 0 | 0 |
100 | 5 | 0 |
100 | 10 | 0 |
... | ... | ... |
100 | 100 | 0 |
95 | 100 | 0 |
90 | 100 | 0 |
... | ... | ... |
これでやっていることのイメージは出来たと思います。
それではさらに詳しく見ていきましょう!
1.赤・緑・青の光の強弱に初期値を与える
1 2 3 4 |
R_light = LED_range G_light = 0 B_light = 0 d_light = 5 |
「R_light~B_light」で初期値を与えており、表でいう所の1行目(赤100緑0青0)にあたります。
また「d_light」は光の値の変化量を表していて、今回は「d_light=5」としています。
2.赤色から[赤+緑]色になるよう指示
1 2 3 4 5 6 7 |
#from Red to Red+Green while R_light == LED_range and d_light > 0: pi.set_PWM_dutycycle(G_Pin, G_light) time.sleep(LED_time) G_light += d_light if G_light >= LED_range: d_light *= -1 |
while文の条件には
- 赤色の光の強さが最大値
- 光の変化量が正
としています。
1:赤色の光の強さが最大値のときに緑色の光の強さを変化させていくので、この条件を課しました。
2:while文では緑色の光の強さを大きくしていくため、光の変化量が正という条件を課しました。
「pi.set_PWM_dutycycle(G_Pin, G_light)」では、緑色の光が「G_light」の強さになるように指示しています。
そして「G_light += d_light」で光の強さを少しだけ強めています。
コードの最後の2行を言葉にすると、
「緑色の光の強さ(G_light)が最大値になったとき、光の変化量(d_light)を負にする」
となり、while文から抜け出すことが出来ます。
これ以降は同じことの繰り返しですので割愛します。
結果:プログラムの実行!
綺麗に光っていますね!!
狙い通りの挙動をしてくれて嬉しいです!!
まとめ:PWM制御を使ってLEDの色を変化させてみた!
今回はPWM制御を使ってLEDの色を変化させてみました!
コードもかなり丁寧に説明していますので、参考になるかと思います!!
ただコードは無駄に長くなっている感があるので、もう少しPythonの勉強をして簡潔に書けるようにしていきます。
見て下さってありがとうございました!
それでは!

こちらもCHECK
-
-
ラズパイの種類を価格と性能で比較
ラズベリーパイを使って電子工作をしたい!! と思ったが、幾つも種類があってどれを選べば良いか分からない・・・。 僕自身、電子工作をしたことがなくラズベリーパイも名前を知って ...
続きを見る