フルカラーLEDの発色実験

  1. フルカラー発光

    1. 目的

       赤、緑、青の三色が組み込まれた発光ダイオードを利用し、各色の強さをPICで制御し、フルカラー発光の実験を行います。

  2. 色の制御

    1. フルカラー発光素子

       近年、青色の発光ダイオードが開発され、赤、青、緑、の色の強さを調節することで、発光ダイオードを用いてフルカラーの発光が可能になりました。ここでは、この発光ダイオードを用いて、超小型プロセッサのプログラムでフルカラーを発光させる実験を行います。


      フルカラーLEDとしてOSTA5131A(OptoSupply社)を利用します。一番長い線が共通のカソード(GND)で、上からR(赤)、GND,B(青),G(緑) の順です。色により発光効率が異なる為、同じ電流を流しても白色にはなりません。許容最大電流は50mAです。

    2. PWM制御

       色を設定するには、RGB各LEDの発光強度を調整すればよいのですが、この強度の調整法にPWM: Pulse Width Modulation があります。この方法は、一定区間の中で通電する割合(時間幅)を変更して平均的な電力を調整する方法です。下図は、25%、50%、75% の電力制御の説明図です。横方向が時間で、立ち上がっている間スイッチをオンにして通電します。


      通電幅を0にすればオフ、繰り返し期間と通電期間を同じにすれば、完全オン状態になります。PWM制御は少々荒っぽい手法なので、制御可能な対象は限定されますが LED の発光強度を調整することは可能です。

    3. PWMのプログラム制御

       PICはハードウエアによるPWM制御も可能ですが、制御可能な信号は1本のみです。ここでは、3本の制御が必要ですから、ソフトウエアでPWMを実現します。1周期の制御は次のようになります。Periodは繰り返し期間で、今回 255 とします。OnPeriod が通電期間で、0から OnPeriod の時刻まで通電することにします。LEDはポートBのB0端子に接続します。

         output_high(PIN_B0);
         Period=0;
         while(Period<255){
            if(Period == OnPeriod) output_low(pin_B0);
            Period ++;
            delay_us(10);
         }

       最初、output_high(PIN_B0); でB0端子をオン、Periodを0にします。次に繰り返しの中で、Periodを増し、これが、OnPeriod になったら、B0端子を0にし通電を停止します。繰り返し周期は、delay_us(10);で定まり、ここでは10μ秒です。

    4. HSVカラーモデル

       RGBの強さを調整すれば多種の色を出すことができますが、狙った色を出すよう、調整することは困難です。HSVカラーモデルは、H(Hue)を0から360まで変化させると、赤>黄>緑>青緑>青>紫>赤 と回る色の輪を生成できます。Sは色の度合いで1.0のとき最大(鮮やかな色)、0.0のとき最小(白)となります、Vは明るさで1.0のとき一番明るく、0.0のとき黒になります。
       このHSVモデルの値(h=0..360、s=0.0..1.0、v=0.0..1.0) から RGBの強さ r,g,b を求めるには次のようなプログラムになります。s,v は少数(float)型変数です。r、g、b は 0..255 の範囲の整数です。

          i = (int)(h/60.0);
          f = h/60.0f -i; 
          p1=(int)(v*(1-s)*255.0);
          p2=(int)(v*(1-s*f)*255.0);
          p3=(int)(v*(1-s*(1-f))*255.0);
          vi=(int)(v*255);
          if(i==0) {r = vi ;g = p3 ;b = p1;}
          if(i==1) {r = p2 ;g = vi ;b = p1;}
          if(i==2) {r = p1 ;g = vi;b = p3;}
          if(i==3) {r = p1 ;g = p2 ;b = vi;}
          if(i==4) {r = p3 ;g = p1 ;b = vi;}
          if(i==5) {r = vi ;g = p1 ;b = p2;}

      s,v = 1.0 としてhを0から360まで変化させると、鮮やかな色の変化を見ることができます。下にhueに対する r,g,b の計算値を示します。

       hue : red  gren blue
         0 :  255    0    0 //red
        15 :  255   63    0
        30 :  255  127    0
        45 :  255  191    0
        60 :  255  255    0
        75 :  191  255    0
        90 :  127  255    0 
       105 :   63  255    0
       120 :    0  255    0 //green
       135 :    0  255   63
       150 :    0  255  127
       165 :    0  255  191
       180 :    0  255  255
       195 :    0  191  255
       210 :    0  127  255
       225 :    0   63  255
       240 :    0    0  255 //blue
       255 :   63    0  255
       270 :  127    0  255
       285 :  191    0  255
       300 :  255    0  255
       315 :  255    0  191
       330 :  255    0  127
       345 :  255    0   63
  3. PICの演算機能

    1. PICのデータ

       PICは8bit計算機です。PICが1命令で実行できる計算は8bitの加減算だけです。ここで使用するC言語の int 型はunsigned(符号なし) の 8bitですから表現できる範囲は 0..255 です。255以上の整数を利用するには
       long B;
      のように、long 型を指定します。これで、16ビットの整数が利用できます。少数の場合は
       float C:
      のように宣言します。

    2. PICの演算機能

       PICが1命令で実行できる計算は8bitの加減算、シフト、論理演算(AND,OR,NOT)だけです。16bitの加減算や乗除算、少数の計算は8bitの加減算を組み合わせプログラムで行います。人が筆算で計算する場合、10進数1桁単位ですから、これは、4bit程度の演算を組み合わせていることになります。
       演算に必要な関数はコンパイラが自動的に付加しています。プログラムのサイズが1200バイトと大きくなっているのは、この演算用の関数が付加されているからです。

  4. 回路制作

    1. 必要な部品

      回路配線用パッチボード
      PIC:16F648
      発光ダイオード(OSTA5131A)
      抵抗 3本

    2. 回路図

       B0,B1,B2 に LED のRGB 端子を接続します。LED共通のグランド線を電源のグランドバーに接続します。
      プログラムを送る込むシリアル通信の部分は省略しています。


    3. 回路の動作

      PICに電源が入ると、自動的にプログラムを実行開始します。RGB に対応する信号はRB0,RB1,RB2から出力されます。この信号は、色別に時間とともにPWM方式で、電力制御されます。発光ダイオードは、消費電力が少ないので、PICで直接点灯できます。ただし、直結すると、電力超過になりますから、抵抗素子を利用して、流れる電流を制限します。
       この抵抗値を変えると、色のカラーバランスが変化します。適当な値を選択して下さい。
      発光はかなり強いので、直視すると目が疲れます。紙で遮蔽をすると見やすくなります。

    4. 回路の組み立て

         PICの1ピンを左下にし、パッチボードに写真のように差し込みます。次に発光ダイオードを差し込みます。一番長い線が左から3番目になるように向きを定め、パッチボードの中央の溝より上の部分に差し込みます。左から3番の長い線は、各LED共通のー側の電源線ですから、このピンをパッチボードの下側のー電源バーに接続します。
       LEDの各色の電源はPICのB2,B1,B0,から供給されます。このピンと、LEDの左から1(緑),2(青),4(赤),の端子を抵抗を介して接続します。抵抗値は数百Ωで、この値により発光の強度が変化します。カラーバランスの良い値を選択して下さい。ここでは、赤を470オーム、緑、青を330オームとしました。同じ電流では赤が一番強く発色し、ついで緑、青の順になります。
        最後に、電源部(アダプタ)の赤い線を、ボードの+電源バーに、黒い線をボード下のー電源バーに接続します。

    5. 抵抗のカラーコード

      抵抗の値はカラーコードで示します。左から、第1,2,コードで値、第3コードで桁を示します。最後の4桁目は精度の値で、通常金色をしています。金色のリングを右側にしてカラーコードを読みます。各カラーは次の値となります。赤からは、いわゆる虹の色です。
       黒:0、茶:1、赤:2、橙:3、黄:4、緑:5、青:6、紫:7、灰:8、白:9

       (茶=1),(黒=0),(橙=3),の場合、10kΩ
       (橙=3),(灰=8),(茶=1),の場合、380Ω
       (赤=2),(紫=7),(茶=1),の場合、270Ω

  5. プログラム(C言語)

    1. プログラム

       色を定める変数hを 0..360 まで、順に変化させます。s,vは1.0に固定します。hsvからrgbに変換します。ここで、hは255を超えますから long 型にする必要があります。
       次に、pwm のループに入ります。赤色の場合、ループの入り口で output_high(PIN_B0); により点灯し、ループの値が rgb の値に達したら output_low(PIN_B0); 消灯します。同じ色を10回繰り返して表示しています。この10の値を変更することで、色の変化する速度を調整できます。

    2. ソース

      #include <16F873A.h>
      
      //FullColor LED 最長:GND red,gnd,blue,green
      #fuses HS,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT
      #use delay(clock = 20000000)
      
      int j,k;
      
      float s=1.0,v=1.0,f;
      long h;
      int i,vi;
      int p1,p2,p3;
      int r,g,b;
      
      void main(){
        set_tris_b(0);
        set_tris_a(0xF);
        
        h=0;
        while(1){
      
           //hsvからrgbへの変換   
          i = (int)(h/60.0);
          f = h/60.0f -i; 
          p1=(int)(v*(1-s)*255.0);
          p2=(int)(v*(1-s*f)*255.0);
          p3=(int)(v*(1-s*(1-f))*255.0);
              vi=(int)(v*255);
              
          if(i==0) {r = vi ;g = p3 ;b = p1;}
              if(i==1) {r = p2 ;g = vi ;b = p1;}
              if(i==2) {r = p1 ;g = vi;b = p3;}
              if(i==3) {r = p1 ;g = p2 ;b = vi;}
              if(i==4) {r = p3 ;g = p1 ;b = vi;}
              if(i==5) {r = vi ;g = p1 ;b = p2;}
              
          //PWM loop               
          for(j=0;j<10;j++){  
                output_high(PIN_B0);
                output_high(PIN_B1);
                output_high(PIN_B2);
                
           for(k=0;k<255;k++){
            if(k==r) output_low(PIN_B0);
            if(k==g) output_low(PIN_B1);
            if(k==b) output_low(PIN_B2);
           }    
          }
          
        h=h+1;
        if(h>=360) h=0;
          
        }//while
      }

  6. 発展


    1. プログラムを調整する

       h や j のループを変更して、色の変化範囲や変化する速度を調整してください。また、色だけでなく飽和度(s)や明度(v)を変化してください。

    2. 異なる点灯パターンにする

      異なる点灯パターンにするには、LEDを異なるPICの端子に接続します。この場合、端子毎にプログラムを作成する必要があります。Aポートまで利用すれば、4パターンまで増設できます。


    3. 同じパターンで同時に点灯する

       同じパターンで複数のフルカラーLEDを点灯する場合は供給電力をアップする必要があります。次のように、PNP型トランジスタ(2SA1015)を利用します。トランジスタ1個で10個くらいのフルカラーLEDを同時に点灯できます。この場合、PICの端子がLの場合LEDが点灯しますから、プログラムで設定しているPICの端子の値(output_high と output_low)を逆にする必要があります。
       トランジスタはこちらを参照してください。