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

フルカラーLEDとしてOSTA5131A(OptoSupply社)を利用します。一番長い線が共通のカソード(GND)で、上からR(赤)、GND,B(青),G(緑)
の順です。色により発光効率が異なる為、同じ電流を流しても白色にはなりません。許容最大電流は50mAです。
色を設定するには、RGB各LEDの発光強度を調整すればよいのですが、この強度の調整法にPWM: Power Width Modulation
があります。この方法は、一定区間の中で通電する割合(時間幅)を変更して平均的な電力を調整する方法です。下図は、25%、50%、75%
の電力制御の説明図です。横方向が時間で、立ち上がっている間スイッチをオンにして通電します。

通電幅を0にすればオフ、繰り返し期間と通電期間を同じにすれば、完全オン状態になります。PWM制御は少々荒っぽい手法なので、制御可能な対象は限定されますが
LED の発光強度を調整することは可能です。
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にし通電を停止します。OnPeriodが255に近づくと強い発光になります。繰り返し周期は、delay_us(10);で定まり、ここでは10μ秒です。
カソードコモン型LEDを同じパターンで複数点灯する場合は次のように、PNP型トランジスタ(2SA1015)を利用します。トランジスタ1個で10個くらいのフルカラーLEDを同時に点灯できます。この場合、PICの端子がLのときLEDが点灯しますから、プログラムで設定しているPICの端子の値(output_high
と output_low)を逆にする必要があります。


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

//蛍発光
#include <16F873A.h>
//#include <16F88.h>
//FullColor LED 最長:GND red,gnd,blue,green
//サイン波に従う点燈
//
#fuses HS,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT
#use delay(clock = 20000000)
#include <stdlib.h>
#define nump 34
int aryr[]={0,25,49,72,92,112,130,167,172,186,
200,220,240,220,200,180,181,173,164,155,
119,92,84,75,66,58,50,42,35,28,21,15,9,4};
int aryg[]={0,25,39,42,52,63,73,87,92,96,
100,120,140,160,180,190,201,213,184,165,
140,132,104,85,76,68,40,42,35,28,21,15,9,4};
int aryb[]={0,15,19,12,12,22,20,27,22,26,
20,30,34,40,40,40,50,53,54,55,
59,52,64,65,66,88,100,120,94,72,50,30,19,4};
int i,j,k;
int lmr,lmg,lmb;
int rv;
long dly;
void main(){
while(1){
//PWM loop
output_toggle(PIN_C1);
for(i=0;i<nump;i++){
//pwm start
lmr=aryr[i];
lmb=aryb[i];
lmg=aryg[i];
rv=50;
//rv=rand()%10 + 15;
for(j=0;j<rv;j++){
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
//pwm stop
for(k=0;k<255;k++){
if(k==lmr) output_low(PIN_B0);
if(k==lmb) output_low(PIN_B1);
if(k==lmg) output_low(PIN_B2);
} //k
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
}//j
}//i
for(i=0;i<4;i++){//変数は1バイト
//delay_ms(rand());
}
delay_ms(500);
}//while
}