フルカラーLEDの基本・使い方(ソフト制御編)

フルカラー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とは | 東芝 半導体&ストレージ製品

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万色調光できるはずだが、実際に目で判断できる色の種類は不明