
フルカラーLEDの基本・使い方(ソフト制御編)
「フルカラーLEDを使ったみた(ハード制御編)」でフルカラーLEDを使って
7色(赤・緑・青・シアン・イエロー・マゼンタ・白)を発光させました。
前回はハード制御編ということで、抵抗を用いて色の明るさを調整しました。
今回はソフト制御編の紹介です。
ラズベリーパイのGPIOとPWMを使って色彩を調整してみたいと思います!
色彩について
制御できる色の数はどれくらいある?
色彩というのはその名の通り青・黄・赤などの「いろどり」です。扱える色彩の数は制御できる機器のビット数によって異なります。今回はRGBを8ビットずつ制御ができるpigpioを使用します。pigpioは比較的PWMを正確に制御できる特徴があります。
それではRGBを8ビットずつ調整として、何色を表現できるのでしょうか?
まずは扱えるビット数を計算してみましょう。
8ビット(R)+8ビット(G)+8ビット(B)=24ビットの調整ができます。
では実際に何色になるのでしょうか?
24 ビット = 2 ^ 24 = 16777216(通り) = 約1677万 (色)
とんでもない数ですね。
どうやって色彩を変えるのか?
フルカラーLEDに流れる入力電圧を変化させることで、色彩を変更できます。
「フルカラーLEDを使ったみた(ハード制御編)」では可変抵抗を用いて電圧を制御していますが、ソフト側では「PWM」を使って制御します。
PWMを含め、他にどのような変調方式があるかをざっと紹介します。

今回は、一番使いやすいSoftWare PWMというものを使用します。(SoftWare PWMの説明は省略)
用意するもの
ラズベリーパイ
ブレッドボード
ジャンパー線
フルカラーLED(アノードコモン)
抵抗220Ω × 3個 (抵抗セットがお得です)
回路を設計しよう
配線の仕方は?
こんな感じになります。だいぶシンプルです。

抵抗値に関して、「フルカラーLEDを使ってみた」では光度の関係でRGBそれぞれで異なる抵抗値にしていましたが、今回はPWMで制御するので同じ抵抗値で進めていきます。GPIOはお好きなところを選択してください。私はGPIO13,GPIO19,GPIO26を使用しています。
RGBは同じ抵抗値でいいの?
結果的に問題ありません!
ただし、白色を調光した際にうまく白く再現できない可能性があります。なぜかというと、ホワイトバランスと光度を計算されていないからです。一例ですが、私のLEDの計算した電流量の比率は以下になります。(計算方法はこちら)
赤:緑:青 = 6(mA) : 8(mA) : 4(mA) = 3 : 4 : 2
上記の比率を加味するとどう違うかを画像で比較します。
比率の設定なし

比率を設定済

上の画像のほうがやや青みがかって見えると思います。上記のようなホワイトバランスも考えて、RGBの光度をPWMで制御していきます。
プログラムを作成しよう
単色点灯
単色点灯のソースコードは以下になります。
#coding: UTF-8
import pigpio import time #RGBのポート番号の設定
GPIO_R = 13
GPIO_G = 26
GPIO_B = 19
def main():
#ホワイトバランスの設定
max_val = 255.0col = [max_val/ 4, max_val / 3, max_val / 2]
#pigpioの初期化
pi = pigpio.pi()
#周波数の設定
pi.set_PWM_frequency(GPIO_R,200)
pi.set_PWM_frequency(GPIO_G,200)
pi.set_PWM_frequency(GPIO_B,200)
#PWMの設定("白"に設定)
pi.set_PWM_dutycycle(GPIO_R,col[0])
pi.set_PWM_dutycycle(GPIO_G,col[1])
pi.set_PWM_dutycycle(GPIO_B,col[2])
if name =='main':
main()
複数色点灯
複数色点灯のソースコードは以下になります。
#coding: UTF-8
import pigpio
import time #RGBのポート番号の設定
GPIO_R = 13
GPIO_G = 26
GPIO_B = 19
def main():
#ホワイトバランスの設定
max_val = 255
zero = (max_val-1)
base_col = [max_val/3, max_val/4 , max_val/2]
#色の定義
red = [base_col[0],zero,zero]
green = [zero,base_col[1],zero]
blue = [zero,zero,base_col[2]]
yellow = [base_col[0],base_col[1],zero]
mazenta = [base_col[0],zero,base_col[2]]
sian = [zero,base_col[1],base_col[2]]
white = base_col
#pigpioの設定
pi = pigpio.pi()
#周波数の設定
pi.set_PWM_frequency(GPIO_R,200)
pi.set_PWM_frequency(GPIO_G,200)
pi.set_PWM_frequency(GPIO_B,200)
#各色を2回分ループ
for i in range(2):
for col in [red,green,blue,yellow,mazenta,white]: #PWMの設定
pi.set_PWM_dutycycle(GPIO_R,col[0])
pi.set_PWM_dutycycle(GPIO_G,col[1])
pi.set_PWM_dutycycle(GPIO_B,col[2])
#スリープ
time.sleep(1)
if __name__ =='__main__':
main()
グラデーション点灯
グラデーション点灯のソースコードは以下になります。(配置先はこちら)
#coding: UTF-8
import pigpio
import time
#RGBのポート番号の設定
GPIO_R = 13
GPIO_G = 26
GPIO_B = 19
#刻み幅の設定
STEP = 100
#スリープ時間の設定
SEC = 0.01
#pigpioの設定
pi = pigpio.pi()
def main():
#ホワイトバランスの設定
max_val = 255
zero = (max_val-1)
base_col = [max_val/3, max_val/4 , max_val/2]
#色の定義
red = [base_col[0],zero,zero]
green = [zero,base_col[1],zero]
blue = [zero,zero,base_col[2]]
yellow = [base_col[0],base_col[1],zero]
mazenta = [base_col[0],zero,base_col[2]]
sian = [zero,base_col[1],base_col[2]]
white = base_col
#周波数の設定
pi.set_PWM_frequency(GPIO_R,200)
pi.set_PWM_frequency(GPIO_G,200)
pi.set_PWM_frequency(GPIO_B,200)
#PWMの設定(初期の色を"白"に設定)
pi.set_PWM_dutycycle(GPIO_R,white[0])
pi.set_PWM_dutycycle(GPIO_G,white[1])
pi.set_PWM_dutycycle(GPIO_B,white[2])
#グラデーション(赤→緑)
change_color_gradation(red,green)
#グラデーション(緑→赤)
change_color_gradation(green,red)
#RGBごとの刻み幅の算出
def get_rgb_incriment(col1,col2):
rgb_inc = []
for i in range(3):
rgb_inc.append(float(col2[i] - col1[i])/STEP)
return rgb_inc
#col1からcol2へ徐々に色を変更
def change_color_gradation(col1,col2):
#刻み幅の算出
rgb_inc = get_rgb_incriment(col1, col2)
for i in range(STEP):
for color, GPIO in enumerate([GPIO_R,GPIO_G,GPIO_B]):
#PWMの設定
pi.set_PWM_dutycycle(GPIO,col1[color] + (i) * rgb_inc[color])
#スリープ
time.sleep(SEC)
if __name__ =='__main__':
main()
まとめ
● pigpioがすごく便利。ただ、デーモンを起動させるのが面倒
● ソフトの調光(PWM)はハードの調光(抵抗値)に比べて簡単
● 理論的には1667万色調光できるはずだが、実際に目で判断できる色の種類は不明